├── .clangd ├── sounds ├── C.ogg └── SDL.ogg ├── screenshot.png ├── images ├── C-logo.png └── background.png ├── fonts └── freesansbold.ttf ├── music └── freesoftwaresong-8bit.ogg ├── src ├── init_sdl.h ├── load_media.h ├── main.c ├── bubble.h ├── player.h ├── text.h ├── game.h ├── main.h ├── load_media.c ├── init_sdl.c ├── text.c ├── player.c ├── game.c └── bubble.c ├── Video04 ├── init_sdl.h ├── load_media.h ├── main.c ├── load_media.c ├── game.h ├── main.h ├── init_sdl.c └── game.c ├── Video05 ├── init_sdl.h ├── load_media.h ├── main.c ├── game.h ├── main.h ├── init_sdl.c ├── load_media.c └── game.c ├── Video06 ├── init_sdl.h ├── load_media.h ├── main.c ├── game.h ├── text.h ├── load_media.c ├── main.h ├── init_sdl.c ├── text.c └── game.c ├── Video07 ├── init_sdl.h ├── load_media.h ├── bubble.h ├── bubble_text.h ├── main.c ├── game.h ├── text.h ├── load_media.c ├── main.h ├── init_sdl.c ├── text.c ├── game.c ├── bubble.c └── bubble_text.c ├── Video08 ├── init_sdl.h ├── load_media.h ├── main.c ├── bubble.h ├── text.h ├── player.h ├── game.h ├── load_media.c ├── main.h ├── init_sdl.c ├── text.c ├── player.c ├── game.c └── bubble.c ├── Video09 ├── init_sdl.h ├── load_media.h ├── main.c ├── bubble.h ├── player.h ├── text.h ├── game.h ├── main.h ├── load_media.c ├── init_sdl.c ├── text.c ├── player.c ├── game.c └── bubble.c ├── README.md ├── Video01 └── main.c ├── Makefile ├── Video02 └── main.c └── Video03 └── main.c /.clangd: -------------------------------------------------------------------------------- 1 | CompileFlags: 2 | Add: ["-I/opt/homebrew/include"] 3 | -------------------------------------------------------------------------------- /sounds/C.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/sounds/C.ogg -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/screenshot.png -------------------------------------------------------------------------------- /sounds/SDL.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/sounds/SDL.ogg -------------------------------------------------------------------------------- /images/C-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/images/C-logo.png -------------------------------------------------------------------------------- /fonts/freesansbold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/fonts/freesansbold.ttf -------------------------------------------------------------------------------- /images/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/images/background.png -------------------------------------------------------------------------------- /music/freesoftwaresong-8bit.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C/HEAD/music/freesoftwaresong-8bit.ogg -------------------------------------------------------------------------------- /src/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video04/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video05/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video06/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video07/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video08/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video09/init_sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef INIT_SDL_H 2 | #define INIT_SDL_H 3 | 4 | #include "game.h" 5 | 6 | bool game_init_sdl(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video04/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video05/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video06/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video07/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video08/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video09/load_media.h: -------------------------------------------------------------------------------- 1 | #ifndef LOAD_MEDIA_H 2 | #define LOAD_MEDIA_H 3 | 4 | #include "game.h" 5 | 6 | bool game_load_media(struct Game *g); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /Video07/bubble.h: -------------------------------------------------------------------------------- 1 | #ifndef BUBBLE_H 2 | #define BUBBLE_H 3 | 4 | #include "main.h" 5 | 6 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 7 | SDL_Color inner_color, SDL_Color outer_color); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /Video07/bubble_text.h: -------------------------------------------------------------------------------- 1 | #ifndef BUBBLE_H 2 | #define BUBBLE_H 3 | 4 | #include "main.h" 5 | 6 | bool bubble_create(SDL_Surface **surf, SDL_Color outer_color, 7 | SDL_Color inner_color, const char *str, float size, 8 | int radius); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /Video04/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | game_run(game); 10 | 11 | exit_status = EXIT_SUCCESS; 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /Video05/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | game_run(game); 10 | 11 | exit_status = EXIT_SUCCESS; 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /Video06/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | game_run(game); 10 | 11 | exit_status = EXIT_SUCCESS; 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /Video07/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | game_run(game); 10 | 11 | exit_status = EXIT_SUCCESS; 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /Video08/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | game_run(game); 10 | 11 | exit_status = EXIT_SUCCESS; 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /Video04/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | return true; 11 | } 12 | -------------------------------------------------------------------------------- /Video09/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | if (game_run(game)) { 10 | exit_status = EXIT_SUCCESS; 11 | } 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | 3 | int main(void) { 4 | bool exit_status = EXIT_FAILURE; 5 | 6 | struct Game *game = NULL; 7 | 8 | if (game_new(&game)) { 9 | if (game_run(game)) { 10 | exit_status = EXIT_SUCCESS; 11 | } 12 | } 13 | 14 | game_free(&game); 15 | 16 | return exit_status; 17 | } 18 | -------------------------------------------------------------------------------- /src/bubble.h: -------------------------------------------------------------------------------- 1 | #ifndef BUBBLE_H 2 | #define BUBBLE_H 3 | 4 | #include "main.h" 5 | 6 | SDL_Surface *bubble_surface(SDL_Surface *src_surf, int radius, 7 | SDL_Color outer_color); 8 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 9 | SDL_Color inner_color, SDL_Color outer_color); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Video08/bubble.h: -------------------------------------------------------------------------------- 1 | #ifndef BUBBLE_H 2 | #define BUBBLE_H 3 | 4 | #include "main.h" 5 | 6 | SDL_Surface *bubble_surface(SDL_Surface *src_surf, int radius, 7 | SDL_Color outer_color); 8 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 9 | SDL_Color inner_color, SDL_Color outer_color); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Video09/bubble.h: -------------------------------------------------------------------------------- 1 | #ifndef BUBBLE_H 2 | #define BUBBLE_H 3 | 4 | #include "main.h" 5 | 6 | SDL_Surface *bubble_surface(SDL_Surface *src_surf, int radius, 7 | SDL_Color outer_color); 8 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 9 | SDL_Color inner_color, SDL_Color outer_color); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /Video04/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | 6 | struct Game { 7 | SDL_Window *window; 8 | SDL_Renderer *renderer; 9 | SDL_Texture *background; 10 | SDL_Event event; 11 | bool is_running; 12 | }; 13 | 14 | bool game_new(struct Game **game); 15 | void game_free(struct Game **game); 16 | void game_run(struct Game *g); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Video04/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define SDL_FLAGS SDL_INIT_VIDEO 13 | 14 | #define WINDOW_TITLE "Random Colors" 15 | #define WINDOW_WIDTH 800 16 | #define WINDOW_HEIGHT 600 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Video06/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | #include "text.h" 6 | 7 | struct Game { 8 | SDL_Window *window; 9 | SDL_Renderer *renderer; 10 | SDL_Texture *background; 11 | struct Text *text; 12 | SDL_Event event; 13 | bool is_running; 14 | }; 15 | 16 | bool game_new(struct Game **game); 17 | void game_free(struct Game **game); 18 | void game_run(struct Game *g); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Video07/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | #include "text.h" 6 | 7 | struct Game { 8 | SDL_Window *window; 9 | SDL_Renderer *renderer; 10 | SDL_Texture *background; 11 | struct Text *text; 12 | SDL_Event event; 13 | bool is_running; 14 | }; 15 | 16 | bool game_new(struct Game **game); 17 | void game_free(struct Game **game); 18 | void game_run(struct Game *g); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /Video07/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_H 2 | #define TEXT_H 3 | 4 | #include "main.h" 5 | 6 | struct Text { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | float x_vel; 11 | float y_vel; 12 | }; 13 | 14 | bool text_new(struct Text **text, SDL_Renderer *renderer); 15 | void text_free(struct Text **text); 16 | void text_update(struct Text *t); 17 | void text_draw(const struct Text *t); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Video08/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_H 2 | #define TEXT_H 3 | 4 | #include "main.h" 5 | 6 | struct Text { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | float x_vel; 11 | float y_vel; 12 | }; 13 | 14 | bool text_new(struct Text **text, SDL_Renderer *renderer); 15 | void text_free(struct Text **text); 16 | void text_update(struct Text *t); 17 | void text_draw(const struct Text *t); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | #include "main.h" 5 | 6 | struct Player { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | const bool *keystate; 11 | }; 12 | 13 | bool player_new(struct Player **player, SDL_Renderer *renderer); 14 | void player_free(struct Player **player); 15 | void player_update(struct Player *p); 16 | void player_draw(const struct Player *p); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Video08/player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | #include "main.h" 5 | 6 | struct Player { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | const bool *keystate; 11 | }; 12 | 13 | bool player_new(struct Player **player, SDL_Renderer *renderer); 14 | void player_free(struct Player **player); 15 | void player_update(struct Player *p); 16 | void player_draw(const struct Player *p); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Video09/player.h: -------------------------------------------------------------------------------- 1 | #ifndef PLAYER_H 2 | #define PLAYER_H 3 | 4 | #include "main.h" 5 | 6 | struct Player { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | const bool *keystate; 11 | }; 12 | 13 | bool player_new(struct Player **player, SDL_Renderer *renderer); 14 | void player_free(struct Player **player); 15 | void player_update(struct Player *p); 16 | void player_draw(const struct Player *p); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_H 2 | #define TEXT_H 3 | 4 | #include "main.h" 5 | 6 | struct Text { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | float x_vel; 11 | float y_vel; 12 | }; 13 | 14 | bool text_new(struct Text **text, SDL_Renderer *renderer); 15 | void text_free(struct Text **text); 16 | void text_update(struct Text *t, Mix_Chunk *sdl_sound); 17 | void text_draw(const struct Text *t); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Video09/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_H 2 | #define TEXT_H 3 | 4 | #include "main.h" 5 | 6 | struct Text { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | SDL_FRect rect; 10 | float x_vel; 11 | float y_vel; 12 | }; 13 | 14 | bool text_new(struct Text **text, SDL_Renderer *renderer); 15 | void text_free(struct Text **text); 16 | void text_update(struct Text *t, Mix_Chunk *sdl_sound); 17 | void text_draw(const struct Text *t); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /Video05/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | 6 | struct Game { 7 | SDL_Window *window; 8 | SDL_Renderer *renderer; 9 | SDL_Texture *background; 10 | TTF_Font *text_font; 11 | SDL_Texture *text_image; 12 | SDL_FRect text_rect; 13 | SDL_Event event; 14 | bool is_running; 15 | }; 16 | 17 | bool game_new(struct Game **game); 18 | void game_free(struct Game **game); 19 | void game_run(struct Game *g); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Video08/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | #include "player.h" 6 | #include "text.h" 7 | 8 | struct Game { 9 | SDL_Window *window; 10 | SDL_Renderer *renderer; 11 | SDL_Texture *background; 12 | struct Text *text; 13 | struct Player *player; 14 | SDL_Event event; 15 | bool is_running; 16 | }; 17 | 18 | bool game_new(struct Game **game); 19 | void game_free(struct Game **game); 20 | void game_run(struct Game *g); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /Video06/text.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXT_H 2 | #define TEXT_H 3 | 4 | #include "main.h" 5 | 6 | struct Text { 7 | SDL_Renderer *renderer; 8 | SDL_Texture *image; 9 | TTF_Font *font; 10 | SDL_Surface *text_surf; 11 | SDL_FRect rect; 12 | float x_vel; 13 | float y_vel; 14 | }; 15 | 16 | bool text_new(struct Text **text, SDL_Renderer *renderer); 17 | void text_free(struct Text **text); 18 | void text_update(struct Text *t); 19 | void text_draw(const struct Text *t); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Video05/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define SDL_FLAGS SDL_INIT_VIDEO 14 | 15 | #define WINDOW_TITLE "Creating Text" 16 | #define WINDOW_WIDTH 800 17 | #define WINDOW_HEIGHT 600 18 | 19 | #define WHITE_COLOR (SDL_Color){255, 255, 255, 255} 20 | 21 | #define TEXT_SIZE 80 22 | #define TEXT_STR "SDL" 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Video06/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | // if (!SDL_SetTextureScaleMode(g->text_image, SDL_SCALEMODE_NEAREST)) { 11 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 12 | // SDL_GetError()); 13 | // return false; 14 | // } 15 | 16 | return true; 17 | } 18 | -------------------------------------------------------------------------------- /Video06/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define SDL_FLAGS SDL_INIT_VIDEO 14 | 15 | #define WINDOW_TITLE "Moving Text" 16 | #define WINDOW_WIDTH 800 17 | #define WINDOW_HEIGHT 600 18 | 19 | #define WHITE_COLOR (SDL_Color){255, 255, 255, 255} 20 | 21 | #define TEXT_SIZE 80 22 | #define TEXT_STR "SDL" 23 | #define TEXT_VEL 3 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Video07/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | // if (!SDL_SetTextureScaleMode(g->text_image, SDL_SCALEMODE_NEAREST)) { 11 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 12 | // SDL_GetError()); 13 | // return false; 14 | // } 15 | 16 | return true; 17 | } 18 | -------------------------------------------------------------------------------- /Video08/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | // if (!SDL_SetTextureScaleMode(g->text_image, SDL_SCALEMODE_NEAREST)) { 11 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 12 | // SDL_GetError()); 13 | // return false; 14 | // } 15 | 16 | return true; 17 | } 18 | -------------------------------------------------------------------------------- /src/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | #include "player.h" 6 | #include "text.h" 7 | 8 | struct Game { 9 | SDL_Window *window; 10 | SDL_Renderer *renderer; 11 | SDL_Texture *background; 12 | struct Text *text; 13 | struct Player *player; 14 | Mix_Chunk *c_sound; 15 | Mix_Chunk *sdl_sound; 16 | Mix_Music *music; 17 | SDL_Event event; 18 | bool is_running; 19 | }; 20 | 21 | bool game_new(struct Game **game); 22 | void game_free(struct Game **game); 23 | bool game_run(struct Game *g); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Video09/game.h: -------------------------------------------------------------------------------- 1 | #ifndef GAME_H 2 | #define GAME_H 3 | 4 | #include "main.h" 5 | #include "player.h" 6 | #include "text.h" 7 | 8 | struct Game { 9 | SDL_Window *window; 10 | SDL_Renderer *renderer; 11 | SDL_Texture *background; 12 | struct Text *text; 13 | struct Player *player; 14 | Mix_Chunk *c_sound; 15 | Mix_Chunk *sdl_sound; 16 | Mix_Music *music; 17 | SDL_Event event; 18 | bool is_running; 19 | }; 20 | 21 | bool game_new(struct Game **game); 22 | void game_free(struct Game **game); 23 | bool game_run(struct Game *g); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /Video07/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define SDL_FLAGS SDL_INIT_VIDEO 15 | 16 | #define WINDOW_TITLE "Creating Text" 17 | #define WINDOW_WIDTH 800 18 | #define WINDOW_HEIGHT 600 19 | 20 | #define WHITE_COLOR (SDL_Color){255, 255, 255, 255} 21 | #define BLUE_COLOR (SDL_Color){137, 180, 250, 255} 22 | #define BUBBLE_RADIUS 15 23 | 24 | #ifndef M_PI 25 | #define M_PI 3.14159265358979323846 26 | #endif 27 | 28 | #define TEXT_SIZE 100 29 | #define TEXT_STR "SDL" 30 | #define TEXT_VEL 3 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /Video08/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define SDL_FLAGS SDL_INIT_VIDEO 15 | 16 | #define WINDOW_TITLE "Bubble Text" 17 | #define WINDOW_WIDTH 800 18 | #define WINDOW_HEIGHT 600 19 | 20 | #define WHITE_COLOR (SDL_Color){255, 255, 255, 255} 21 | #define BLUE_COLOR (SDL_Color){137, 180, 250, 255} 22 | #define BUBBLE_RADIUS 15 23 | 24 | #ifndef M_PI 25 | #define M_PI 3.14159265358979323846 26 | #endif 27 | 28 | #define TEXT_SIZE 100 29 | #define TEXT_STR "SDL" 30 | #define TEXT_VEL 3 31 | 32 | #define PLAYER_VEL 5 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define SDL_FLAGS SDL_INIT_VIDEO 16 | #define MIX_FLAGS MIX_INIT_OGG 17 | 18 | #define WINDOW_TITLE "Bubble Text" 19 | #define WINDOW_WIDTH 800 20 | #define WINDOW_HEIGHT 600 21 | 22 | #define WHITE_COLOR (SDL_Color){255, 255, 255, 255} 23 | #define BLUE_COLOR (SDL_Color){137, 180, 250, 255} 24 | #define BUBBLE_RADIUS 15 25 | 26 | #ifndef M_PI 27 | #define M_PI 3.14159265358979323846 28 | #endif 29 | 30 | #define TEXT_SIZE 100 31 | #define TEXT_STR "SDL" 32 | #define TEXT_VEL 3 33 | 34 | #define PLAYER_VEL 5 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /Video09/main.h: -------------------------------------------------------------------------------- 1 | #ifndef MAIN_H 2 | #define MAIN_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define SDL_FLAGS SDL_INIT_VIDEO 16 | #define MIX_FLAGS MIX_INIT_OGG 17 | 18 | #define WINDOW_TITLE "Bubble Text" 19 | #define WINDOW_WIDTH 800 20 | #define WINDOW_HEIGHT 600 21 | 22 | #define WHITE_COLOR (SDL_Color){255, 255, 255, 255} 23 | #define BLUE_COLOR (SDL_Color){137, 180, 250, 255} 24 | #define BUBBLE_RADIUS 15 25 | 26 | #ifndef M_PI 27 | #define M_PI 3.14159265358979323846 28 | #endif 29 | 30 | #define TEXT_SIZE 100 31 | #define TEXT_STR "SDL" 32 | #define TEXT_VEL 3 33 | 34 | #define PLAYER_VEL 5 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | g->c_sound = Mix_LoadWAV("sounds/C.ogg"); 11 | if (!g->c_sound) { 12 | fprintf(stderr, "Error loading Chunk: %s\n", SDL_GetError()); 13 | return false; 14 | } 15 | 16 | g->sdl_sound = Mix_LoadWAV("sounds/SDL.ogg"); 17 | if (!g->sdl_sound) { 18 | fprintf(stderr, "Error loading Chunk: %s\n", SDL_GetError()); 19 | return false; 20 | } 21 | 22 | g->music = Mix_LoadMUS("music/freesoftwaresong-8bit.ogg"); 23 | if (!g->music) { 24 | fprintf(stderr, "Error loading Music: %s\n", SDL_GetError()); 25 | return false; 26 | } 27 | 28 | return true; 29 | } 30 | -------------------------------------------------------------------------------- /Video09/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | g->c_sound = Mix_LoadWAV("sounds/C.ogg"); 11 | if (!g->c_sound) { 12 | fprintf(stderr, "Error loading Chunk: %s\n", SDL_GetError()); 13 | return false; 14 | } 15 | 16 | g->sdl_sound = Mix_LoadWAV("sounds/SDL.ogg"); 17 | if (!g->sdl_sound) { 18 | fprintf(stderr, "Error loading Chunk: %s\n", SDL_GetError()); 19 | return false; 20 | } 21 | 22 | g->music = Mix_LoadMUS("music/freesoftwaresong-8bit.ogg"); 23 | if (!g->music) { 24 | fprintf(stderr, "Error loading Music: %s\n", SDL_GetError()); 25 | return false; 26 | } 27 | 28 | return true; 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Screenshot](screenshot.png) 2 | 3 | # An in-depth guide to getting started with SDL3 in the C Language. 4 | 5 | # ArchLinux instructions. 6 | You will need to make sure SDL3, SDL3_image, SDL3_ttf and SDL3_mixer is installed. 7 | ``` 8 | sudo pacman -S --needed base-devel sdl3 9 | ``` 10 | ``` 11 | cd 12 | git clone https://aur.archlinux.org/sdl3_image-git.git 13 | cd sdl3_image-git 14 | makepkg -i 15 | ``` 16 | ``` 17 | cd 18 | git clone https://aur.archlinux.org/sdl3_ttf-git.git 19 | cd sdl3_ttf-git 20 | makepkg -i 21 | ``` 22 | ``` 23 | cd 24 | git clone https://aur.archlinux.org/sdl3_mixer-git.git 25 | cd sdl3_mixer-git 26 | makepkg -i 27 | ``` 28 | ``` 29 | cd 30 | git clone https://github.com/ProgrammingRainbow/Beginners-Guide-to-SDL3-in-C 31 | cd Beginners-Guide-to-SDL3-in-C 32 | make run 33 | ``` 34 | The Makefile supports these commands: 35 | ``` 36 | make rebuild 37 | make clean 38 | make release 39 | make debug 40 | SRC_DIR=Video8 make rebuild run 41 | ``` 42 | # Controls 43 | Space - Changes background Color\ 44 | Arrows - Moves sprite\ 45 | M - Toggles music mute\ 46 | Escape - Quits 47 | -------------------------------------------------------------------------------- /Video04/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 10 | if (!g->window) { 11 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 12 | return false; 13 | } 14 | 15 | g->renderer = SDL_CreateRenderer(g->window, NULL); 16 | if (!g->renderer) { 17 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 18 | return false; 19 | } 20 | 21 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 22 | if (!icon_surf) { 23 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 24 | return false; 25 | } 26 | 27 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 28 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 29 | SDL_DestroySurface(icon_surf); 30 | return false; 31 | } 32 | SDL_DestroySurface(icon_surf); 33 | 34 | return true; 35 | } 36 | -------------------------------------------------------------------------------- /Video05/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | if (!TTF_Init()) { 10 | fprintf(stderr, "Error initializing SDL3_ttf: %s\n", SDL_GetError()); 11 | return false; 12 | } 13 | 14 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 15 | if (!g->window) { 16 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 17 | return false; 18 | } 19 | 20 | g->renderer = SDL_CreateRenderer(g->window, NULL); 21 | if (!g->renderer) { 22 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 27 | if (!icon_surf) { 28 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 29 | return false; 30 | } 31 | 32 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 33 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 34 | SDL_DestroySurface(icon_surf); 35 | return false; 36 | } 37 | SDL_DestroySurface(icon_surf); 38 | 39 | return true; 40 | } 41 | -------------------------------------------------------------------------------- /Video06/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | if (!TTF_Init()) { 10 | fprintf(stderr, "Error initializing SDL3_ttf: %s\n", SDL_GetError()); 11 | return false; 12 | } 13 | 14 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 15 | if (!g->window) { 16 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 17 | return false; 18 | } 19 | 20 | g->renderer = SDL_CreateRenderer(g->window, NULL); 21 | if (!g->renderer) { 22 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 27 | if (!icon_surf) { 28 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 29 | return false; 30 | } 31 | 32 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 33 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 34 | SDL_DestroySurface(icon_surf); 35 | return false; 36 | } 37 | SDL_DestroySurface(icon_surf); 38 | 39 | return true; 40 | } 41 | -------------------------------------------------------------------------------- /Video07/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | if (!TTF_Init()) { 10 | fprintf(stderr, "Error initializing SDL3_ttf: %s\n", SDL_GetError()); 11 | return false; 12 | } 13 | 14 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 15 | if (!g->window) { 16 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 17 | return false; 18 | } 19 | 20 | g->renderer = SDL_CreateRenderer(g->window, NULL); 21 | if (!g->renderer) { 22 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 27 | if (!icon_surf) { 28 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 29 | return false; 30 | } 31 | 32 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 33 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 34 | SDL_DestroySurface(icon_surf); 35 | return false; 36 | } 37 | SDL_DestroySurface(icon_surf); 38 | 39 | return true; 40 | } 41 | -------------------------------------------------------------------------------- /Video08/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | if (!TTF_Init()) { 10 | fprintf(stderr, "Error initializing SDL3_ttf: %s\n", SDL_GetError()); 11 | return false; 12 | } 13 | 14 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 15 | if (!g->window) { 16 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 17 | return false; 18 | } 19 | 20 | g->renderer = SDL_CreateRenderer(g->window, NULL); 21 | if (!g->renderer) { 22 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 27 | if (!icon_surf) { 28 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 29 | return false; 30 | } 31 | 32 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 33 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 34 | SDL_DestroySurface(icon_surf); 35 | return false; 36 | } 37 | SDL_DestroySurface(icon_surf); 38 | 39 | return true; 40 | } 41 | -------------------------------------------------------------------------------- /Video05/load_media.c: -------------------------------------------------------------------------------- 1 | #include "load_media.h" 2 | 3 | bool game_load_media(struct Game *g) { 4 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 5 | if (!g->background) { 6 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 7 | return false; 8 | } 9 | 10 | g->text_font = TTF_OpenFont("fonts/freesansbold.ttf", TEXT_SIZE); 11 | if (!g->text_font) { 12 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 13 | return false; 14 | } 15 | 16 | SDL_Surface *surf = 17 | TTF_RenderText_Blended(g->text_font, TEXT_STR, 0, WHITE_COLOR); 18 | if (!surf) { 19 | fprintf(stderr, "Error rendering text to Surface: %s\n", 20 | SDL_GetError()); 21 | return false; 22 | } 23 | 24 | g->text_rect.w = (float)surf->w; 25 | g->text_rect.h = (float)surf->h; 26 | 27 | g->text_image = SDL_CreateTextureFromSurface(g->renderer, surf); 28 | SDL_DestroySurface(surf); 29 | surf = NULL; 30 | if (!g->text_image) { 31 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 32 | SDL_GetError()); 33 | return false; 34 | } 35 | 36 | // if (!SDL_SetTextureScaleMode(g->text_image, SDL_SCALEMODE_NEAREST)) { 37 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 38 | // SDL_GetError()); 39 | // return false; 40 | // } 41 | 42 | return true; 43 | } 44 | -------------------------------------------------------------------------------- /src/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | if (!TTF_Init()) { 10 | fprintf(stderr, "Error initializing SDL3_ttf: %s\n", SDL_GetError()); 11 | return false; 12 | } 13 | 14 | if ((Mix_Init(MIX_FLAGS) & MIX_FLAGS) != MIX_FLAGS) { 15 | fprintf(stderr, "Error initializing SDL3_mixer: %s\n", SDL_GetError()); 16 | return false; 17 | } 18 | 19 | SDL_AudioSpec audiospec = {0}; 20 | audiospec.format = MIX_DEFAULT_FORMAT; 21 | audiospec.channels = MIX_DEFAULT_CHANNELS; 22 | audiospec.freq = MIX_DEFAULT_FREQUENCY; 23 | 24 | if (!Mix_OpenAudio(0, &audiospec)) { 25 | fprintf(stderr, "Error Opening Audio: %s\n", SDL_GetError()); 26 | return false; 27 | } 28 | 29 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 30 | if (!g->window) { 31 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 32 | return false; 33 | } 34 | 35 | g->renderer = SDL_CreateRenderer(g->window, NULL); 36 | if (!g->renderer) { 37 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 38 | return false; 39 | } 40 | 41 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 42 | if (!icon_surf) { 43 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 44 | return false; 45 | } 46 | 47 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 48 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 49 | SDL_DestroySurface(icon_surf); 50 | return false; 51 | } 52 | SDL_DestroySurface(icon_surf); 53 | 54 | return true; 55 | } 56 | -------------------------------------------------------------------------------- /Video09/init_sdl.c: -------------------------------------------------------------------------------- 1 | #include "init_sdl.h" 2 | 3 | bool game_init_sdl(struct Game *g) { 4 | if (!SDL_Init(SDL_FLAGS)) { 5 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 6 | return false; 7 | } 8 | 9 | if (!TTF_Init()) { 10 | fprintf(stderr, "Error initializing SDL3_ttf: %s\n", SDL_GetError()); 11 | return false; 12 | } 13 | 14 | if ((Mix_Init(MIX_FLAGS) & MIX_FLAGS) != MIX_FLAGS) { 15 | fprintf(stderr, "Error initializing SDL3_mixer: %s\n", SDL_GetError()); 16 | return false; 17 | } 18 | 19 | SDL_AudioSpec audiospec = {0}; 20 | audiospec.format = MIX_DEFAULT_FORMAT; 21 | audiospec.channels = MIX_DEFAULT_CHANNELS; 22 | audiospec.freq = MIX_DEFAULT_FREQUENCY; 23 | 24 | if (!Mix_OpenAudio(0, &audiospec)) { 25 | fprintf(stderr, "Error Opening Audio: %s\n", SDL_GetError()); 26 | return false; 27 | } 28 | 29 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 30 | if (!g->window) { 31 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 32 | return false; 33 | } 34 | 35 | g->renderer = SDL_CreateRenderer(g->window, NULL); 36 | if (!g->renderer) { 37 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 38 | return false; 39 | } 40 | 41 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 42 | if (!icon_surf) { 43 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 44 | return false; 45 | } 46 | 47 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 48 | fprintf(stderr, "Error setting Window Icon: %s\n", SDL_GetError()); 49 | SDL_DestroySurface(icon_surf); 50 | return false; 51 | } 52 | SDL_DestroySurface(icon_surf); 53 | 54 | return true; 55 | } 56 | -------------------------------------------------------------------------------- /Video01/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define SDL_FLAGS SDL_INIT_VIDEO 8 | 9 | #define WINDOW_TITLE "Open Window" 10 | #define WINDOW_WIDTH 800 11 | #define WINDOW_HEIGHT 600 12 | 13 | struct Game { 14 | SDL_Window *window; 15 | SDL_Renderer *renderer; 16 | }; 17 | 18 | bool game_init_sdl(struct Game *g); 19 | void game_free(struct Game *g); 20 | void game_run(struct Game *g); 21 | 22 | bool game_init_sdl(struct Game *g) { 23 | if (!SDL_Init(SDL_FLAGS)) { 24 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 25 | return false; 26 | } 27 | 28 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 29 | if (!g->window) { 30 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 31 | return false; 32 | } 33 | 34 | g->renderer = SDL_CreateRenderer(g->window, NULL); 35 | if (!g->renderer) { 36 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 37 | return false; 38 | } 39 | 40 | return true; 41 | } 42 | 43 | void game_free(struct Game *g) { 44 | if (g->renderer) { 45 | SDL_DestroyRenderer(g->renderer); 46 | g->renderer = NULL; 47 | } 48 | 49 | if (g->window) { 50 | SDL_DestroyWindow(g->window); 51 | g->window = NULL; 52 | } 53 | 54 | SDL_Quit(); 55 | } 56 | 57 | void game_run(struct Game *g) { 58 | SDL_Delay(100); 59 | 60 | SDL_RenderClear(g->renderer); 61 | 62 | SDL_RenderPresent(g->renderer); 63 | 64 | SDL_Delay(5000); 65 | } 66 | 67 | int main(void) { 68 | bool exit_status = EXIT_FAILURE; 69 | 70 | struct Game game = {0}; 71 | 72 | if (game_init_sdl(&game)) { 73 | game_run(&game); 74 | 75 | exit_status = EXIT_SUCCESS; 76 | } 77 | 78 | game_free(&game); 79 | 80 | return exit_status; 81 | } 82 | -------------------------------------------------------------------------------- /Video07/text.c: -------------------------------------------------------------------------------- 1 | #include "text.h" 2 | #include "bubble.h" 3 | 4 | bool text_new(struct Text **text, SDL_Renderer *renderer) { 5 | *text = calloc(1, sizeof(struct Text)); 6 | if (*text == NULL) { 7 | fprintf(stderr, "Error Calloc of New Text.\n"); 8 | return false; 9 | } 10 | struct Text *t = *text; 11 | 12 | t->renderer = renderer; 13 | 14 | SDL_Surface *surf = bubble_create_text(TEXT_STR, TEXT_SIZE, BUBBLE_RADIUS, 15 | WHITE_COLOR, BLUE_COLOR); 16 | if (!surf) { 17 | return false; 18 | } 19 | 20 | t->rect.w = (float)surf->w; 21 | t->rect.h = (float)surf->h; 22 | 23 | t->image = SDL_CreateTextureFromSurface(t->renderer, surf); 24 | SDL_DestroySurface(surf); 25 | surf = NULL; 26 | if (!t->image) { 27 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 28 | SDL_GetError()); 29 | return false; 30 | } 31 | 32 | t->x_vel = TEXT_VEL; 33 | t->y_vel = TEXT_VEL; 34 | 35 | return true; 36 | } 37 | 38 | void text_free(struct Text **text) { 39 | if (*text) { 40 | struct Text *t = *text; 41 | 42 | if (t->image) { 43 | SDL_DestroyTexture(t->image); 44 | t->image = NULL; 45 | } 46 | 47 | t->renderer = NULL; 48 | 49 | free(t); 50 | t = NULL; 51 | *text = NULL; 52 | 53 | printf("Free Text.\n"); 54 | } 55 | } 56 | 57 | void text_update(struct Text *t) { 58 | t->rect.x += t->x_vel; 59 | t->rect.y += t->y_vel; 60 | 61 | if (t->rect.x + t->rect.w > WINDOW_WIDTH) { 62 | t->x_vel = -TEXT_VEL; 63 | } else if (t->rect.x < 0) { 64 | t->x_vel = TEXT_VEL; 65 | } 66 | if (t->rect.y + t->rect.h > WINDOW_HEIGHT) { 67 | t->y_vel = -TEXT_VEL; 68 | } else if (t->rect.y < 0) { 69 | t->y_vel = TEXT_VEL; 70 | } 71 | } 72 | 73 | void text_draw(const struct Text *t) { 74 | SDL_RenderTexture(t->renderer, t->image, NULL, &t->rect); 75 | } 76 | -------------------------------------------------------------------------------- /Video08/text.c: -------------------------------------------------------------------------------- 1 | #include "text.h" 2 | #include "bubble.h" 3 | 4 | bool text_new(struct Text **text, SDL_Renderer *renderer) { 5 | *text = calloc(1, sizeof(struct Text)); 6 | if (*text == NULL) { 7 | fprintf(stderr, "Error Calloc of New Text.\n"); 8 | return false; 9 | } 10 | struct Text *t = *text; 11 | 12 | t->renderer = renderer; 13 | 14 | SDL_Surface *surf = bubble_create_text(TEXT_STR, TEXT_SIZE, BUBBLE_RADIUS, 15 | WHITE_COLOR, BLUE_COLOR); 16 | if (!surf) { 17 | return false; 18 | } 19 | 20 | t->rect.w = (float)surf->w; 21 | t->rect.h = (float)surf->h; 22 | 23 | t->image = SDL_CreateTextureFromSurface(t->renderer, surf); 24 | SDL_DestroySurface(surf); 25 | surf = NULL; 26 | if (!t->image) { 27 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 28 | SDL_GetError()); 29 | return false; 30 | } 31 | 32 | t->x_vel = TEXT_VEL; 33 | t->y_vel = TEXT_VEL; 34 | 35 | return true; 36 | } 37 | 38 | void text_free(struct Text **text) { 39 | if (*text) { 40 | struct Text *t = *text; 41 | 42 | if (t->image) { 43 | SDL_DestroyTexture(t->image); 44 | t->image = NULL; 45 | } 46 | 47 | t->renderer = NULL; 48 | 49 | free(t); 50 | t = NULL; 51 | *text = NULL; 52 | 53 | printf("Free Text.\n"); 54 | } 55 | } 56 | 57 | void text_update(struct Text *t) { 58 | t->rect.x += t->x_vel; 59 | t->rect.y += t->y_vel; 60 | 61 | if (t->rect.x + t->rect.w > WINDOW_WIDTH) { 62 | t->x_vel = -TEXT_VEL; 63 | } else if (t->rect.x < 0) { 64 | t->x_vel = TEXT_VEL; 65 | } 66 | if (t->rect.y + t->rect.h > WINDOW_HEIGHT) { 67 | t->y_vel = -TEXT_VEL; 68 | } else if (t->rect.y < 0) { 69 | t->y_vel = TEXT_VEL; 70 | } 71 | } 72 | 73 | void text_draw(const struct Text *t) { 74 | SDL_RenderTexture(t->renderer, t->image, NULL, &t->rect); 75 | } 76 | -------------------------------------------------------------------------------- /src/text.c: -------------------------------------------------------------------------------- 1 | #include "text.h" 2 | #include "bubble.h" 3 | 4 | bool text_new(struct Text **text, SDL_Renderer *renderer) { 5 | *text = calloc(1, sizeof(struct Text)); 6 | if (*text == NULL) { 7 | fprintf(stderr, "Error Calloc of New Text.\n"); 8 | return false; 9 | } 10 | struct Text *t = *text; 11 | 12 | t->renderer = renderer; 13 | 14 | SDL_Surface *surf = bubble_create_text(TEXT_STR, TEXT_SIZE, BUBBLE_RADIUS, 15 | WHITE_COLOR, BLUE_COLOR); 16 | if (!surf) { 17 | return false; 18 | } 19 | 20 | t->rect.w = (float)surf->w; 21 | t->rect.h = (float)surf->h; 22 | 23 | t->image = SDL_CreateTextureFromSurface(t->renderer, surf); 24 | SDL_DestroySurface(surf); 25 | surf = NULL; 26 | if (!t->image) { 27 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 28 | SDL_GetError()); 29 | return false; 30 | } 31 | 32 | t->x_vel = TEXT_VEL; 33 | t->y_vel = TEXT_VEL; 34 | 35 | return true; 36 | } 37 | 38 | void text_free(struct Text **text) { 39 | if (*text) { 40 | struct Text *t = *text; 41 | 42 | if (t->image) { 43 | SDL_DestroyTexture(t->image); 44 | t->image = NULL; 45 | } 46 | 47 | t->renderer = NULL; 48 | 49 | free(t); 50 | t = NULL; 51 | *text = NULL; 52 | 53 | printf("Free Text.\n"); 54 | } 55 | } 56 | 57 | void text_update(struct Text *t, Mix_Chunk *sdl_sound) { 58 | t->rect.x += t->x_vel; 59 | t->rect.y += t->y_vel; 60 | 61 | if (t->rect.x + t->rect.w > WINDOW_WIDTH) { 62 | t->x_vel = -TEXT_VEL; 63 | Mix_PlayChannel(-1, sdl_sound, 0); 64 | } else if (t->rect.x < 0) { 65 | t->x_vel = TEXT_VEL; 66 | Mix_PlayChannel(-1, sdl_sound, 0); 67 | } 68 | if (t->rect.y + t->rect.h > WINDOW_HEIGHT) { 69 | t->y_vel = -TEXT_VEL; 70 | Mix_PlayChannel(-1, sdl_sound, 0); 71 | } else if (t->rect.y < 0) { 72 | t->y_vel = TEXT_VEL; 73 | Mix_PlayChannel(-1, sdl_sound, 0); 74 | } 75 | } 76 | 77 | void text_draw(const struct Text *t) { 78 | SDL_RenderTexture(t->renderer, t->image, NULL, &t->rect); 79 | } 80 | -------------------------------------------------------------------------------- /Video09/text.c: -------------------------------------------------------------------------------- 1 | #include "text.h" 2 | #include "bubble.h" 3 | 4 | bool text_new(struct Text **text, SDL_Renderer *renderer) { 5 | *text = calloc(1, sizeof(struct Text)); 6 | if (*text == NULL) { 7 | fprintf(stderr, "Error Calloc of New Text.\n"); 8 | return false; 9 | } 10 | struct Text *t = *text; 11 | 12 | t->renderer = renderer; 13 | 14 | SDL_Surface *surf = bubble_create_text(TEXT_STR, TEXT_SIZE, BUBBLE_RADIUS, 15 | WHITE_COLOR, BLUE_COLOR); 16 | if (!surf) { 17 | return false; 18 | } 19 | 20 | t->rect.w = (float)surf->w; 21 | t->rect.h = (float)surf->h; 22 | 23 | t->image = SDL_CreateTextureFromSurface(t->renderer, surf); 24 | SDL_DestroySurface(surf); 25 | surf = NULL; 26 | if (!t->image) { 27 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 28 | SDL_GetError()); 29 | return false; 30 | } 31 | 32 | t->x_vel = TEXT_VEL; 33 | t->y_vel = TEXT_VEL; 34 | 35 | return true; 36 | } 37 | 38 | void text_free(struct Text **text) { 39 | if (*text) { 40 | struct Text *t = *text; 41 | 42 | if (t->image) { 43 | SDL_DestroyTexture(t->image); 44 | t->image = NULL; 45 | } 46 | 47 | t->renderer = NULL; 48 | 49 | free(t); 50 | t = NULL; 51 | *text = NULL; 52 | 53 | printf("Free Text.\n"); 54 | } 55 | } 56 | 57 | void text_update(struct Text *t, Mix_Chunk *sdl_sound) { 58 | t->rect.x += t->x_vel; 59 | t->rect.y += t->y_vel; 60 | 61 | if (t->rect.x + t->rect.w > WINDOW_WIDTH) { 62 | t->x_vel = -TEXT_VEL; 63 | Mix_PlayChannel(-1, sdl_sound, 0); 64 | } else if (t->rect.x < 0) { 65 | t->x_vel = TEXT_VEL; 66 | Mix_PlayChannel(-1, sdl_sound, 0); 67 | } 68 | if (t->rect.y + t->rect.h > WINDOW_HEIGHT) { 69 | t->y_vel = -TEXT_VEL; 70 | Mix_PlayChannel(-1, sdl_sound, 0); 71 | } else if (t->rect.y < 0) { 72 | t->y_vel = TEXT_VEL; 73 | Mix_PlayChannel(-1, sdl_sound, 0); 74 | } 75 | } 76 | 77 | void text_draw(const struct Text *t) { 78 | SDL_RenderTexture(t->renderer, t->image, NULL, &t->rect); 79 | } 80 | -------------------------------------------------------------------------------- /Video06/text.c: -------------------------------------------------------------------------------- 1 | #include "text.h" 2 | 3 | bool text_new(struct Text **text, SDL_Renderer *renderer) { 4 | *text = calloc(1, sizeof(struct Text)); 5 | if (*text == NULL) { 6 | fprintf(stderr, "Error in Calloc of New Text.\n"); 7 | return false; 8 | } 9 | struct Text *t = *text; 10 | 11 | t->renderer = renderer; 12 | 13 | t->font = TTF_OpenFont("fonts/freesansbold.ttf", TEXT_SIZE); 14 | if (!t->font) { 15 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 16 | return false; 17 | } 18 | 19 | t->text_surf = TTF_RenderText_Blended(t->font, TEXT_STR, 0, WHITE_COLOR); 20 | if (!t->text_surf) { 21 | fprintf(stderr, "Error creating outer text Surface: %s\n", 22 | SDL_GetError()); 23 | return false; 24 | } 25 | 26 | t->rect.w = (float)t->text_surf->w; 27 | t->rect.h = (float)t->text_surf->h; 28 | 29 | t->image = SDL_CreateTextureFromSurface(t->renderer, t->text_surf); 30 | if (!t->image) { 31 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 32 | SDL_GetError()); 33 | return false; 34 | } 35 | 36 | t->x_vel = TEXT_VEL; 37 | t->y_vel = TEXT_VEL; 38 | 39 | return true; 40 | } 41 | 42 | void text_free(struct Text **text) { 43 | if (*text) { 44 | struct Text *t = *text; 45 | 46 | if (t->image) { 47 | SDL_DestroyTexture(t->image); 48 | t->image = NULL; 49 | } 50 | if (t->text_surf) { 51 | SDL_DestroySurface(t->text_surf); 52 | t->text_surf = NULL; 53 | } 54 | if (t->font) { 55 | TTF_CloseFont(t->font); 56 | t->font = NULL; 57 | } 58 | 59 | t->renderer = NULL; 60 | 61 | free(t); 62 | t = NULL; 63 | *text = NULL; 64 | 65 | printf("Text free.\n"); 66 | } 67 | } 68 | 69 | void text_update(struct Text *t) { 70 | t->rect.x += t->x_vel; 71 | t->rect.y += t->y_vel; 72 | if (t->rect.x + t->rect.w > WINDOW_WIDTH) { 73 | t->x_vel = -TEXT_VEL; 74 | } 75 | if (t->rect.x < 0) { 76 | t->x_vel = TEXT_VEL; 77 | } 78 | if (t->rect.y + t->rect.h > WINDOW_HEIGHT) { 79 | t->y_vel = -TEXT_VEL; 80 | } 81 | if (t->rect.y < 0) { 82 | t->y_vel = TEXT_VEL; 83 | } 84 | } 85 | 86 | void text_draw(const struct Text *t) { 87 | SDL_RenderTexture(t->renderer, t->image, NULL, &t->rect); 88 | } 89 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TARGET = beginners-guide-sdl3-c 2 | BUILD_DIR = .build 3 | SRC_DIR ?= src 4 | CC ?= gcc 5 | 6 | CFLAGS_BASE = -std=c11 7 | 8 | CFLAGS_STRICT = -Wstrict-aliasing=2 -Wall -Wextra -Werror -Wpedantic \ 9 | -Wwrite-strings -Wconversion -Wmissing-declarations \ 10 | -Wmissing-include-dirs -Wfloat-equal -Wsign-compare -Wundef \ 11 | -Wcast-align -Wswitch-default -Wimplicit-fallthrough \ 12 | -Wempty-body -Wuninitialized -Wmisleading-indentation \ 13 | -Wshadow -Wmissing-prototypes -Wstrict-prototypes \ 14 | -Wold-style-definition 15 | 16 | CFLAGS_RELEASE = -O3 -march=native -flto=auto -fno-plt -fomit-frame-pointer 17 | 18 | CFLAGS_DEBUG = -O0 -g3 -ggdb3 -fno-strict-aliasing -fstack-protector-strong \ 19 | -DDEBUG -fno-omit-frame-pointer 20 | 21 | LDLIBS_BASE = -lm 22 | 23 | LDLIBS_RELEASE = -flto 24 | 25 | LDLIBS_DEBUG = 26 | 27 | SRCS = $(wildcard $(SRC_DIR)/*.c) 28 | OBJS = $(addprefix $(BUILD_DIR)/, $(notdir $(SRCS:.c=.o))) 29 | DEPS = $(OBJS:.o=.d) 30 | 31 | ifeq ($(OS),Windows_NT) 32 | PKG_CONFIG := $(shell where pkg-config >NUL 2>&1 && echo "yes" || echo "no") 33 | CLEAN = del /f $(TARGET).exe & if exist $(BUILD_DIR) rmdir /s /q $(BUILD_DIR) 34 | MKDIR = if not exist $(BUILD_DIR) mkdir 35 | else 36 | CFLAGS_DEBUG += -fsanitize=address -fsanitize-address-use-after-scope \ 37 | -ftrapv 38 | LDLIBS_DEBUG += -fsanitize=address -fsanitize-address-use-after-scope 39 | PKG_CONFIG := $(shell command -v pkg-config >/dev/null 2>&1 && echo "yes" || echo "no") 40 | CLEAN = $(RM) $(TARGET) && $(RM) -r $(BUILD_DIR) 41 | MKDIR = mkdir -p $(BUILD_DIR) 42 | endif 43 | 44 | ifeq ($(PKG_CONFIG),yes) 45 | CFLAGS_BASE += $(shell pkg-config --cflags sdl3 sdl3-image sdl3-ttf sdl3-mixer) 46 | LDLIBS_BASE += $(shell pkg-config --libs sdl3 sdl3-image sdl3-ttf sdl3-mixer) 47 | else 48 | $(error "pkg-config is not available. Please install pkg-config.") 49 | endif 50 | 51 | CFLAGS ?= $(CFLAGS_BASE) 52 | LDLIBS ?= $(LDLIBS_BASE) 53 | 54 | $(BUILD_DIR): 55 | $(MKDIR) 56 | 57 | $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) 58 | $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ 59 | 60 | $(TARGET): $(OBJS) 61 | $(CC) $(LDLIBS) $^ -o $@ 62 | 63 | -include $(DEPS) 64 | 65 | .PHONY: all clean run rebuild release debug 66 | 67 | all: $(TARGET) 68 | 69 | release: CFLAGS = $(CFLAGS_BASE) $(CFLAGS_STRICT) $(CFLAGS_RELEASE) 70 | release: LDLIBS = $(LDLIBS_BASE) $(LDLIBS_RELEASE) 71 | release: all 72 | 73 | debug: CFLAGS = $(CFLAGS_BASE) $(CFLAGS_STRICT) $(CFLAGS_DEBUG) 74 | debug: LDLIBS = $(LDLIBS_BASE) $(LDLIBS_DEBUG) 75 | debug: all 76 | 77 | clean: 78 | $(CLEAN) 79 | 80 | run: $(TARGET) 81 | ./$< 82 | 83 | rebuild: clean all 84 | -------------------------------------------------------------------------------- /Video04/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_events(struct Game *g); 7 | void game_draw(struct Game *g); 8 | 9 | bool game_new(struct Game **game) { 10 | *game = calloc(1, sizeof(struct Game)); 11 | if (*game == NULL) { 12 | fprintf(stderr, "Error Calloc of New Game.\n"); 13 | return false; 14 | } 15 | struct Game *g = *game; 16 | 17 | if (!game_init_sdl(g)) { 18 | return false; 19 | } 20 | 21 | if (!game_load_media(g)) { 22 | return false; 23 | } 24 | 25 | g->is_running = true; 26 | 27 | srand((unsigned)time(NULL)); 28 | 29 | return true; 30 | } 31 | 32 | void game_free(struct Game **game) { 33 | if (*game) { 34 | struct Game *g = *game; 35 | 36 | if (g->background) { 37 | SDL_DestroyTexture(g->background); 38 | g->background = NULL; 39 | } 40 | 41 | if (g->renderer) { 42 | SDL_DestroyRenderer(g->renderer); 43 | g->renderer = NULL; 44 | } 45 | if (g->window) { 46 | SDL_DestroyWindow(g->window); 47 | g->window = NULL; 48 | } 49 | 50 | SDL_Quit(); 51 | 52 | free(g); 53 | 54 | g = NULL; 55 | *game = NULL; 56 | 57 | printf("All Clean!\n"); 58 | } 59 | } 60 | 61 | void game_render_color(struct Game *g) { 62 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 63 | (Uint8)rand(), 255); 64 | } 65 | 66 | void game_events(struct Game *g) { 67 | while (SDL_PollEvent(&g->event)) { 68 | switch (g->event.type) { 69 | case SDL_EVENT_QUIT: 70 | g->is_running = false; 71 | break; 72 | case SDL_EVENT_KEY_DOWN: 73 | switch (g->event.key.scancode) { 74 | case SDL_SCANCODE_ESCAPE: 75 | g->is_running = false; 76 | break; 77 | case SDL_SCANCODE_SPACE: 78 | game_render_color(g); 79 | break; 80 | default: 81 | break; 82 | } 83 | break; 84 | default: 85 | break; 86 | } 87 | } 88 | } 89 | 90 | void game_draw(struct Game *g) { 91 | SDL_RenderClear(g->renderer); 92 | 93 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 94 | 95 | SDL_RenderPresent(g->renderer); 96 | } 97 | 98 | void game_run(struct Game *g) { 99 | while (g->is_running) { 100 | game_events(g); 101 | 102 | game_draw(g); 103 | 104 | SDL_Delay(16); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Video08/player.c: -------------------------------------------------------------------------------- 1 | #include "player.h" 2 | #include "bubble.h" 3 | 4 | bool player_new(struct Player **player, SDL_Renderer *renderer) { 5 | *player = calloc(1, sizeof(struct Player)); 6 | if (*player == NULL) { 7 | fprintf(stderr, "Error Calloc of New Player.\n"); 8 | return false; 9 | } 10 | struct Player *p = *player; 11 | 12 | p->renderer = renderer; 13 | 14 | // p->image = IMG_LoadTexture(p->renderer, "images/C-logo.png"); 15 | // if (!p->image) { 16 | // fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 17 | // return false; 18 | // } 19 | 20 | SDL_Surface *surf = IMG_Load("images/C-logo.png"); 21 | if (!surf) { 22 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *bubble_surf = bubble_surface(surf, BUBBLE_RADIUS, WHITE_COLOR); 27 | SDL_DestroySurface(surf); 28 | surf = NULL; 29 | if (!bubble_surf) { 30 | return false; 31 | } 32 | 33 | p->image = SDL_CreateTextureFromSurface(p->renderer, bubble_surf); 34 | SDL_DestroySurface(bubble_surf); 35 | bubble_surf = NULL; 36 | if (!p->image) { 37 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 38 | SDL_GetError()); 39 | return false; 40 | } 41 | 42 | if (!SDL_GetTextureSize(p->image, &p->rect.w, &p->rect.h)) { 43 | fprintf(stderr, "Error getting Texture Size: %s\n", SDL_GetError()); 44 | return false; 45 | } 46 | 47 | p->keystate = SDL_GetKeyboardState(NULL); 48 | 49 | // if (!SDL_SetTextureScaleMode(p->image, SDL_SCALEMODE_NEAREST)) { 50 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 51 | // SDL_GetError()); 52 | // return false; 53 | // } 54 | 55 | return true; 56 | } 57 | void player_free(struct Player **player) { 58 | if (*player) { 59 | struct Player *p = *player; 60 | 61 | if (p->image) { 62 | SDL_DestroyTexture(p->image); 63 | p->image = NULL; 64 | } 65 | 66 | p->renderer = NULL; 67 | p->keystate = NULL; 68 | 69 | free(p); 70 | p = NULL; 71 | *player = NULL; 72 | 73 | printf("Free Player.\n"); 74 | } 75 | } 76 | 77 | void player_update(struct Player *p) { 78 | if (p->keystate[SDL_SCANCODE_LEFT] || p->keystate[SDL_SCANCODE_A]) { 79 | p->rect.x -= PLAYER_VEL; 80 | } 81 | if (p->keystate[SDL_SCANCODE_RIGHT] || p->keystate[SDL_SCANCODE_D]) { 82 | p->rect.x += PLAYER_VEL; 83 | } 84 | if (p->keystate[SDL_SCANCODE_UP] || p->keystate[SDL_SCANCODE_W]) { 85 | p->rect.y -= PLAYER_VEL; 86 | } 87 | if (p->keystate[SDL_SCANCODE_DOWN] || p->keystate[SDL_SCANCODE_S]) { 88 | p->rect.y += PLAYER_VEL; 89 | } 90 | } 91 | 92 | void player_draw(const struct Player *p) { 93 | SDL_RenderTexture(p->renderer, p->image, NULL, &p->rect); 94 | } 95 | -------------------------------------------------------------------------------- /Video09/player.c: -------------------------------------------------------------------------------- 1 | #include "player.h" 2 | #include "bubble.h" 3 | 4 | bool player_new(struct Player **player, SDL_Renderer *renderer) { 5 | *player = calloc(1, sizeof(struct Player)); 6 | if (*player == NULL) { 7 | fprintf(stderr, "Error Calloc of New Player.\n"); 8 | return false; 9 | } 10 | struct Player *p = *player; 11 | 12 | p->renderer = renderer; 13 | 14 | // p->image = IMG_LoadTexture(p->renderer, "images/C-logo.png"); 15 | // if (!p->image) { 16 | // fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 17 | // return false; 18 | // } 19 | 20 | SDL_Surface *surf = IMG_Load("images/C-logo.png"); 21 | if (!surf) { 22 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *bubble_surf = bubble_surface(surf, BUBBLE_RADIUS, WHITE_COLOR); 27 | SDL_DestroySurface(surf); 28 | surf = NULL; 29 | if (!bubble_surf) { 30 | return false; 31 | } 32 | 33 | p->image = SDL_CreateTextureFromSurface(p->renderer, bubble_surf); 34 | SDL_DestroySurface(bubble_surf); 35 | bubble_surf = NULL; 36 | if (!p->image) { 37 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 38 | SDL_GetError()); 39 | return false; 40 | } 41 | 42 | if (!SDL_GetTextureSize(p->image, &p->rect.w, &p->rect.h)) { 43 | fprintf(stderr, "Error getting Texture Size: %s\n", SDL_GetError()); 44 | return false; 45 | } 46 | 47 | p->keystate = SDL_GetKeyboardState(NULL); 48 | 49 | // if (!SDL_SetTextureScaleMode(p->image, SDL_SCALEMODE_NEAREST)) { 50 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 51 | // SDL_GetError()); 52 | // return false; 53 | // } 54 | 55 | return true; 56 | } 57 | void player_free(struct Player **player) { 58 | if (*player) { 59 | struct Player *p = *player; 60 | 61 | if (p->image) { 62 | SDL_DestroyTexture(p->image); 63 | p->image = NULL; 64 | } 65 | 66 | p->renderer = NULL; 67 | p->keystate = NULL; 68 | 69 | free(p); 70 | p = NULL; 71 | *player = NULL; 72 | 73 | printf("Free Player.\n"); 74 | } 75 | } 76 | 77 | void player_update(struct Player *p) { 78 | if (p->keystate[SDL_SCANCODE_LEFT] || p->keystate[SDL_SCANCODE_A]) { 79 | p->rect.x -= PLAYER_VEL; 80 | } 81 | if (p->keystate[SDL_SCANCODE_RIGHT] || p->keystate[SDL_SCANCODE_D]) { 82 | p->rect.x += PLAYER_VEL; 83 | } 84 | if (p->keystate[SDL_SCANCODE_UP] || p->keystate[SDL_SCANCODE_W]) { 85 | p->rect.y -= PLAYER_VEL; 86 | } 87 | if (p->keystate[SDL_SCANCODE_DOWN] || p->keystate[SDL_SCANCODE_S]) { 88 | p->rect.y += PLAYER_VEL; 89 | } 90 | } 91 | 92 | void player_draw(const struct Player *p) { 93 | SDL_RenderTexture(p->renderer, p->image, NULL, &p->rect); 94 | } 95 | -------------------------------------------------------------------------------- /src/player.c: -------------------------------------------------------------------------------- 1 | #include "player.h" 2 | #include "bubble.h" 3 | 4 | bool player_new(struct Player **player, SDL_Renderer *renderer) { 5 | *player = calloc(1, sizeof(struct Player)); 6 | if (*player == NULL) { 7 | fprintf(stderr, "Error Calloc of New Player.\n"); 8 | return false; 9 | } 10 | struct Player *p = *player; 11 | 12 | p->renderer = renderer; 13 | 14 | // p->image = IMG_LoadTexture(p->renderer, "images/C-logo.png"); 15 | // if (!p->image) { 16 | // fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 17 | // return false; 18 | // } 19 | 20 | SDL_Surface *surf = IMG_Load("images/C-logo.png"); 21 | if (!surf) { 22 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 23 | return false; 24 | } 25 | 26 | SDL_Surface *bubble_surf = bubble_surface(surf, BUBBLE_RADIUS, WHITE_COLOR); 27 | SDL_DestroySurface(surf); 28 | surf = NULL; 29 | if (!bubble_surf) { 30 | return false; 31 | } 32 | 33 | p->image = SDL_CreateTextureFromSurface(p->renderer, bubble_surf); 34 | SDL_DestroySurface(bubble_surf); 35 | bubble_surf = NULL; 36 | if (!p->image) { 37 | fprintf(stderr, "Error creating Texture from Surface: %s\n", 38 | SDL_GetError()); 39 | return false; 40 | } 41 | 42 | if (!SDL_GetTextureSize(p->image, &p->rect.w, &p->rect.h)) { 43 | fprintf(stderr, "Error getting Texture Size: %s\n", SDL_GetError()); 44 | return false; 45 | } 46 | 47 | p->keystate = SDL_GetKeyboardState(NULL); 48 | 49 | // if (!SDL_SetTextureScaleMode(p->image, SDL_SCALEMODE_NEAREST)) { 50 | // fprintf(stderr, "Error setting texture scale mode: %s\n", 51 | // SDL_GetError()); 52 | // return false; 53 | // } 54 | 55 | return true; 56 | } 57 | void player_free(struct Player **player) { 58 | if (*player) { 59 | struct Player *p = *player; 60 | 61 | if (p->image) { 62 | SDL_DestroyTexture(p->image); 63 | p->image = NULL; 64 | } 65 | 66 | p->renderer = NULL; 67 | p->keystate = NULL; 68 | 69 | free(p); 70 | p = NULL; 71 | *player = NULL; 72 | 73 | printf("Free Player.\n"); 74 | } 75 | } 76 | 77 | void player_update(struct Player *p) { 78 | if (p->keystate[SDL_SCANCODE_LEFT] || p->keystate[SDL_SCANCODE_A]) { 79 | p->rect.x -= PLAYER_VEL; 80 | } 81 | if (p->keystate[SDL_SCANCODE_RIGHT] || p->keystate[SDL_SCANCODE_D]) { 82 | p->rect.x += PLAYER_VEL; 83 | } 84 | if (p->keystate[SDL_SCANCODE_UP] || p->keystate[SDL_SCANCODE_W]) { 85 | p->rect.y -= PLAYER_VEL; 86 | } 87 | if (p->keystate[SDL_SCANCODE_DOWN] || p->keystate[SDL_SCANCODE_S]) { 88 | p->rect.y += PLAYER_VEL; 89 | } 90 | } 91 | 92 | void player_draw(const struct Player *p) { 93 | SDL_RenderTexture(p->renderer, p->image, NULL, &p->rect); 94 | } 95 | -------------------------------------------------------------------------------- /Video05/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_events(struct Game *g); 7 | void game_draw(struct Game *g); 8 | 9 | bool game_new(struct Game **game) { 10 | *game = calloc(1, sizeof(struct Game)); 11 | if (*game == NULL) { 12 | fprintf(stderr, "Error Calloc of New Game.\n"); 13 | return false; 14 | } 15 | struct Game *g = *game; 16 | 17 | if (!game_init_sdl(g)) { 18 | return false; 19 | } 20 | 21 | if (!game_load_media(g)) { 22 | return false; 23 | } 24 | 25 | g->is_running = true; 26 | 27 | srand((unsigned)time(NULL)); 28 | 29 | return true; 30 | } 31 | 32 | void game_free(struct Game **game) { 33 | if (*game) { 34 | struct Game *g = *game; 35 | 36 | if (g->text_image) { 37 | SDL_DestroyTexture(g->text_image); 38 | g->text_image = NULL; 39 | } 40 | if (g->text_font) { 41 | TTF_CloseFont(g->text_font); 42 | g->text_font = NULL; 43 | } 44 | if (g->background) { 45 | SDL_DestroyTexture(g->background); 46 | g->background = NULL; 47 | } 48 | 49 | if (g->renderer) { 50 | SDL_DestroyRenderer(g->renderer); 51 | g->renderer = NULL; 52 | } 53 | if (g->window) { 54 | SDL_DestroyWindow(g->window); 55 | g->window = NULL; 56 | } 57 | 58 | TTF_Quit(); 59 | SDL_Quit(); 60 | 61 | free(g); 62 | 63 | g = NULL; 64 | *game = NULL; 65 | 66 | printf("All Clean!\n"); 67 | } 68 | } 69 | 70 | void game_render_color(struct Game *g) { 71 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 72 | (Uint8)rand(), 255); 73 | } 74 | 75 | void game_events(struct Game *g) { 76 | while (SDL_PollEvent(&g->event)) { 77 | switch (g->event.type) { 78 | case SDL_EVENT_QUIT: 79 | g->is_running = false; 80 | break; 81 | case SDL_EVENT_KEY_DOWN: 82 | switch (g->event.key.scancode) { 83 | case SDL_SCANCODE_ESCAPE: 84 | g->is_running = false; 85 | break; 86 | case SDL_SCANCODE_SPACE: 87 | game_render_color(g); 88 | break; 89 | default: 90 | break; 91 | } 92 | break; 93 | default: 94 | break; 95 | } 96 | } 97 | } 98 | 99 | void game_draw(struct Game *g) { 100 | SDL_RenderClear(g->renderer); 101 | 102 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 103 | SDL_RenderTexture(g->renderer, g->text_image, NULL, &g->text_rect); 104 | 105 | SDL_RenderPresent(g->renderer); 106 | } 107 | 108 | void game_run(struct Game *g) { 109 | while (g->is_running) { 110 | game_events(g); 111 | 112 | game_draw(g); 113 | 114 | SDL_Delay(16); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Video06/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_events(struct Game *g); 7 | void game_update(struct Game *g); 8 | void game_draw(const struct Game *g); 9 | 10 | bool game_new(struct Game **game) { 11 | *game = calloc(1, sizeof(struct Game)); 12 | if (*game == NULL) { 13 | fprintf(stderr, "Error Calloc of New Game.\n"); 14 | return false; 15 | } 16 | struct Game *g = *game; 17 | 18 | if (!game_init_sdl(g)) { 19 | return false; 20 | } 21 | 22 | if (!game_load_media(g)) { 23 | return false; 24 | } 25 | 26 | if (!text_new(&g->text, g->renderer)) { 27 | return false; 28 | } 29 | 30 | g->is_running = true; 31 | 32 | srand((unsigned)time(NULL)); 33 | 34 | return true; 35 | } 36 | 37 | void game_free(struct Game **game) { 38 | if (*game) { 39 | struct Game *g = *game; 40 | 41 | if (g->text) { 42 | text_free(&g->text); 43 | } 44 | 45 | if (g->background) { 46 | SDL_DestroyTexture(g->background); 47 | g->background = NULL; 48 | } 49 | 50 | if (g->renderer) { 51 | SDL_DestroyRenderer(g->renderer); 52 | g->renderer = NULL; 53 | } 54 | if (g->window) { 55 | SDL_DestroyWindow(g->window); 56 | g->window = NULL; 57 | } 58 | 59 | TTF_Quit(); 60 | SDL_Quit(); 61 | 62 | free(g); 63 | 64 | g = NULL; 65 | *game = NULL; 66 | 67 | printf("All Clean!\n"); 68 | } 69 | } 70 | 71 | void game_render_color(struct Game *g) { 72 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 73 | (Uint8)rand(), 255); 74 | } 75 | 76 | void game_events(struct Game *g) { 77 | while (SDL_PollEvent(&g->event)) { 78 | switch (g->event.type) { 79 | case SDL_EVENT_QUIT: 80 | g->is_running = false; 81 | break; 82 | case SDL_EVENT_KEY_DOWN: 83 | switch (g->event.key.scancode) { 84 | case SDL_SCANCODE_ESCAPE: 85 | g->is_running = false; 86 | break; 87 | case SDL_SCANCODE_SPACE: 88 | game_render_color(g); 89 | break; 90 | default: 91 | break; 92 | } 93 | break; 94 | default: 95 | break; 96 | } 97 | } 98 | } 99 | 100 | void game_update(struct Game *g) { text_update(g->text); } 101 | 102 | void game_draw(const struct Game *g) { 103 | SDL_RenderClear(g->renderer); 104 | 105 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 106 | text_draw(g->text); 107 | 108 | SDL_RenderPresent(g->renderer); 109 | } 110 | 111 | void game_run(struct Game *g) { 112 | while (g->is_running) { 113 | game_events(g); 114 | 115 | game_update(g); 116 | 117 | game_draw(g); 118 | 119 | SDL_Delay(16); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Video07/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_events(struct Game *g); 7 | void game_update(struct Game *g); 8 | void game_draw(const struct Game *g); 9 | 10 | bool game_new(struct Game **game) { 11 | *game = calloc(1, sizeof(struct Game)); 12 | if (*game == NULL) { 13 | fprintf(stderr, "Error Calloc of New Game.\n"); 14 | return false; 15 | } 16 | struct Game *g = *game; 17 | 18 | if (!game_init_sdl(g)) { 19 | return false; 20 | } 21 | 22 | if (!game_load_media(g)) { 23 | return false; 24 | } 25 | 26 | if (!text_new(&g->text, g->renderer)) { 27 | return false; 28 | } 29 | 30 | g->is_running = true; 31 | 32 | srand((unsigned)time(NULL)); 33 | 34 | return true; 35 | } 36 | 37 | void game_free(struct Game **game) { 38 | if (*game) { 39 | struct Game *g = *game; 40 | 41 | if (g->text) { 42 | text_free(&g->text); 43 | } 44 | 45 | if (g->background) { 46 | SDL_DestroyTexture(g->background); 47 | g->background = NULL; 48 | } 49 | 50 | if (g->renderer) { 51 | SDL_DestroyRenderer(g->renderer); 52 | g->renderer = NULL; 53 | } 54 | if (g->window) { 55 | SDL_DestroyWindow(g->window); 56 | g->window = NULL; 57 | } 58 | 59 | TTF_Quit(); 60 | SDL_Quit(); 61 | 62 | free(g); 63 | 64 | g = NULL; 65 | *game = NULL; 66 | 67 | printf("All Clean!\n"); 68 | } 69 | } 70 | 71 | void game_render_color(struct Game *g) { 72 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 73 | (Uint8)rand(), 255); 74 | } 75 | 76 | void game_events(struct Game *g) { 77 | while (SDL_PollEvent(&g->event)) { 78 | switch (g->event.type) { 79 | case SDL_EVENT_QUIT: 80 | g->is_running = false; 81 | break; 82 | case SDL_EVENT_KEY_DOWN: 83 | switch (g->event.key.scancode) { 84 | case SDL_SCANCODE_ESCAPE: 85 | g->is_running = false; 86 | break; 87 | case SDL_SCANCODE_SPACE: 88 | game_render_color(g); 89 | break; 90 | default: 91 | break; 92 | } 93 | break; 94 | default: 95 | break; 96 | } 97 | } 98 | } 99 | 100 | void game_update(struct Game *g) { text_update(g->text); } 101 | 102 | void game_draw(const struct Game *g) { 103 | SDL_RenderClear(g->renderer); 104 | 105 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 106 | text_draw(g->text); 107 | 108 | SDL_RenderPresent(g->renderer); 109 | } 110 | 111 | void game_run(struct Game *g) { 112 | while (g->is_running) { 113 | game_events(g); 114 | 115 | game_update(g); 116 | 117 | game_draw(g); 118 | 119 | SDL_Delay(16); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Video08/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_events(struct Game *g); 7 | void game_update(struct Game *g); 8 | void game_draw(const struct Game *g); 9 | 10 | bool game_new(struct Game **game) { 11 | *game = calloc(1, sizeof(struct Game)); 12 | if (*game == NULL) { 13 | fprintf(stderr, "Error Calloc of New Game.\n"); 14 | return false; 15 | } 16 | struct Game *g = *game; 17 | 18 | if (!game_init_sdl(g)) { 19 | return false; 20 | } 21 | if (!game_load_media(g)) { 22 | return false; 23 | } 24 | 25 | if (!text_new(&g->text, g->renderer)) { 26 | return false; 27 | } 28 | if (!player_new(&g->player, g->renderer)) { 29 | return false; 30 | } 31 | 32 | g->is_running = true; 33 | 34 | srand((unsigned)time(NULL)); 35 | 36 | return true; 37 | } 38 | 39 | void game_free(struct Game **game) { 40 | if (*game) { 41 | struct Game *g = *game; 42 | 43 | if (g->player) { 44 | player_free(&g->player); 45 | } 46 | if (g->text) { 47 | text_free(&g->text); 48 | } 49 | 50 | if (g->background) { 51 | SDL_DestroyTexture(g->background); 52 | g->background = NULL; 53 | } 54 | 55 | if (g->renderer) { 56 | SDL_DestroyRenderer(g->renderer); 57 | g->renderer = NULL; 58 | } 59 | if (g->window) { 60 | SDL_DestroyWindow(g->window); 61 | g->window = NULL; 62 | } 63 | 64 | TTF_Quit(); 65 | SDL_Quit(); 66 | 67 | free(g); 68 | 69 | g = NULL; 70 | *game = NULL; 71 | 72 | printf("All Clean!\n"); 73 | } 74 | } 75 | 76 | void game_render_color(struct Game *g) { 77 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 78 | (Uint8)rand(), 255); 79 | } 80 | 81 | void game_events(struct Game *g) { 82 | while (SDL_PollEvent(&g->event)) { 83 | switch (g->event.type) { 84 | case SDL_EVENT_QUIT: 85 | g->is_running = false; 86 | break; 87 | case SDL_EVENT_KEY_DOWN: 88 | switch (g->event.key.scancode) { 89 | case SDL_SCANCODE_ESCAPE: 90 | g->is_running = false; 91 | break; 92 | case SDL_SCANCODE_SPACE: 93 | game_render_color(g); 94 | break; 95 | default: 96 | break; 97 | } 98 | break; 99 | default: 100 | break; 101 | } 102 | } 103 | } 104 | 105 | void game_update(struct Game *g) { 106 | text_update(g->text); 107 | player_update(g->player); 108 | } 109 | 110 | void game_draw(const struct Game *g) { 111 | SDL_RenderClear(g->renderer); 112 | 113 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 114 | text_draw(g->text); 115 | player_draw(g->player); 116 | 117 | SDL_RenderPresent(g->renderer); 118 | } 119 | 120 | void game_run(struct Game *g) { 121 | while (g->is_running) { 122 | game_events(g); 123 | 124 | game_update(g); 125 | 126 | game_draw(g); 127 | 128 | SDL_Delay(16); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Video02/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define SDL_FLAGS SDL_INIT_VIDEO 8 | 9 | #define WINDOW_TITLE "Close Window" 10 | #define WINDOW_WIDTH 800 11 | #define WINDOW_HEIGHT 600 12 | 13 | struct Game { 14 | SDL_Window *window; 15 | SDL_Renderer *renderer; 16 | SDL_Event event; 17 | bool is_running; 18 | }; 19 | 20 | bool game_init_sdl(struct Game *g); 21 | bool game_new(struct Game **game); 22 | void game_free(struct Game **game); 23 | void game_events(struct Game *g); 24 | void game_draw(struct Game *g); 25 | void game_run(struct Game *g); 26 | 27 | bool game_init_sdl(struct Game *g) { 28 | if (!SDL_Init(SDL_FLAGS)) { 29 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 30 | return false; 31 | } 32 | 33 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 34 | if (!g->window) { 35 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 36 | return false; 37 | } 38 | 39 | g->renderer = SDL_CreateRenderer(g->window, NULL); 40 | if (!g->renderer) { 41 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 42 | return false; 43 | } 44 | 45 | return true; 46 | } 47 | 48 | bool game_new(struct Game **game) { 49 | *game = calloc(1, sizeof(struct Game)); 50 | if (*game == NULL) { 51 | fprintf(stderr, "Error Calloc of New Game.\n"); 52 | return false; 53 | } 54 | struct Game *g = *game; 55 | 56 | if (!game_init_sdl(g)) { 57 | return false; 58 | } 59 | 60 | g->is_running = true; 61 | 62 | return true; 63 | } 64 | 65 | void game_free(struct Game **game) { 66 | if (*game) { 67 | struct Game *g = *game; 68 | 69 | if (g->renderer) { 70 | SDL_DestroyRenderer(g->renderer); 71 | g->renderer = NULL; 72 | } 73 | 74 | if (g->window) { 75 | SDL_DestroyWindow(g->window); 76 | g->window = NULL; 77 | } 78 | 79 | SDL_Quit(); 80 | 81 | free(g); 82 | 83 | g = NULL; 84 | *game = NULL; 85 | 86 | printf("All Clean!\n"); 87 | } 88 | } 89 | 90 | void game_events(struct Game *g) { 91 | while (SDL_PollEvent(&g->event)) { 92 | switch (g->event.type) { 93 | case SDL_EVENT_QUIT: 94 | g->is_running = false; 95 | break; 96 | case SDL_EVENT_KEY_DOWN: 97 | switch (g->event.key.scancode) { 98 | case SDL_SCANCODE_ESCAPE: 99 | g->is_running = false; 100 | break; 101 | default: 102 | break; 103 | } 104 | break; 105 | default: 106 | break; 107 | } 108 | } 109 | } 110 | 111 | void game_draw(struct Game *g) { 112 | SDL_RenderClear(g->renderer); 113 | 114 | SDL_RenderPresent(g->renderer); 115 | } 116 | 117 | void game_run(struct Game *g) { 118 | while (g->is_running) { 119 | game_events(g); 120 | 121 | game_draw(g); 122 | 123 | SDL_Delay(16); 124 | } 125 | } 126 | 127 | int main(void) { 128 | bool exit_status = EXIT_FAILURE; 129 | 130 | struct Game *game = NULL; 131 | 132 | if (game_new(&game)) { 133 | game_run(game); 134 | 135 | exit_status = EXIT_SUCCESS; 136 | } 137 | 138 | game_free(&game); 139 | 140 | return exit_status; 141 | } 142 | -------------------------------------------------------------------------------- /Video07/bubble.c: -------------------------------------------------------------------------------- 1 | #include "bubble.h" 2 | 3 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 4 | int radius, int x, int y); 5 | 6 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 7 | int radius, int x, int y) { 8 | SDL_BlitSurface( 9 | src_surf, NULL, target_surf, 10 | &(SDL_Rect){radius + x, radius + y, src_surf->w, src_surf->h}); 11 | SDL_BlitSurface( 12 | src_surf, NULL, target_surf, 13 | &(SDL_Rect){radius + x, radius - y, src_surf->w, src_surf->h}); 14 | SDL_BlitSurface( 15 | src_surf, NULL, target_surf, 16 | &(SDL_Rect){radius - x, radius + y, src_surf->w, src_surf->h}); 17 | SDL_BlitSurface( 18 | src_surf, NULL, target_surf, 19 | &(SDL_Rect){radius - x, radius - y, src_surf->w, src_surf->h}); 20 | SDL_BlitSurface( 21 | src_surf, NULL, target_surf, 22 | &(SDL_Rect){radius + y, radius + x, src_surf->w, src_surf->h}); 23 | SDL_BlitSurface( 24 | src_surf, NULL, target_surf, 25 | &(SDL_Rect){radius + y, radius - x, src_surf->w, src_surf->h}); 26 | SDL_BlitSurface( 27 | src_surf, NULL, target_surf, 28 | &(SDL_Rect){radius - y, radius + x, src_surf->w, src_surf->h}); 29 | SDL_BlitSurface( 30 | src_surf, NULL, target_surf, 31 | &(SDL_Rect){radius - y, radius - x, src_surf->w, src_surf->h}); 32 | } 33 | 34 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 35 | SDL_Color inner_color, SDL_Color outer_color) { 36 | TTF_Font *font = TTF_OpenFont("fonts/freesansbold.ttf", size); 37 | if (!font) { 38 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 39 | return NULL; 40 | } 41 | 42 | SDL_Surface *surf = TTF_RenderText_Blended(font, str, 0, outer_color); 43 | if (!surf) { 44 | fprintf(stderr, "Error rendering text to Surface: %s\n", 45 | SDL_GetError()); 46 | 47 | TTF_CloseFont(font); 48 | return NULL; 49 | } 50 | 51 | SDL_Surface *target_surf = SDL_CreateSurface( 52 | surf->w + radius * 2, surf->h + radius * 2, SDL_PIXELFORMAT_ARGB32); 53 | if (!target_surf) { 54 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 55 | TTF_CloseFont(font); 56 | SDL_DestroySurface(surf); 57 | return NULL; 58 | } 59 | 60 | // // Polar Coordinates Trigonometry Algorithm 61 | // for (int index = 0; index < (2 * M_PI * radius); index++) { 62 | // double rad = (double)index / radius; 63 | // int x = (int)(cos(rad) * radius) + radius; 64 | // int y = (int)(sin(rad) * radius) + radius; 65 | // 66 | // SDL_BlitSurface(surf, NULL, target_surf, 67 | // &(SDL_Rect){x, y, surf->w, surf->h}); 68 | // } 69 | 70 | // Bresenham's Circle Drawing Algorithm 71 | // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm 72 | int x = 0; 73 | int y = radius; 74 | int d = 3 - 2 * radius; 75 | blit_symmetric_points(surf, target_surf, radius, x, y); 76 | while (y >= x) { 77 | x++; 78 | if (d > 0) { 79 | y--; 80 | d = d + 4 * (x - y) + 10; 81 | } else { 82 | d = d + 4 * x + 6; 83 | } 84 | blit_symmetric_points(surf, target_surf, radius, x, y); 85 | } 86 | 87 | SDL_DestroySurface(surf); 88 | surf = NULL; 89 | surf = TTF_RenderText_Blended(font, str, 0, inner_color); 90 | TTF_CloseFont(font); 91 | font = NULL; 92 | if (!surf) { 93 | fprintf(stderr, "Error rendering text to Surface: %s\n", 94 | SDL_GetError()); 95 | SDL_DestroySurface(target_surf); 96 | return NULL; 97 | } 98 | 99 | SDL_BlitSurface(surf, NULL, target_surf, 100 | &(SDL_Rect){radius, radius, surf->w, surf->h}); 101 | 102 | SDL_DestroySurface(surf); 103 | 104 | return target_surf; 105 | } 106 | -------------------------------------------------------------------------------- /Video07/bubble_text.c: -------------------------------------------------------------------------------- 1 | #include "bubble_text.h" 2 | 3 | void blit_symmetric_points(SDL_Surface *text_surf, SDL_Surface *target_surf, 4 | int radius, int x, int y); 5 | 6 | void blit_symmetric_points(SDL_Surface *text_surf, SDL_Surface *target_surf, 7 | int radius, int x, int y) { 8 | SDL_BlitSurface( 9 | text_surf, NULL, target_surf, 10 | &(SDL_Rect){radius + x, radius + y, text_surf->w, text_surf->h}); 11 | SDL_BlitSurface( 12 | text_surf, NULL, target_surf, 13 | &(SDL_Rect){radius + x, radius - y, text_surf->w, text_surf->h}); 14 | SDL_BlitSurface( 15 | text_surf, NULL, target_surf, 16 | &(SDL_Rect){radius - x, radius + y, text_surf->w, text_surf->h}); 17 | SDL_BlitSurface( 18 | text_surf, NULL, target_surf, 19 | &(SDL_Rect){radius - x, radius - y, text_surf->w, text_surf->h}); 20 | SDL_BlitSurface( 21 | text_surf, NULL, target_surf, 22 | &(SDL_Rect){radius + y, radius + x, text_surf->w, text_surf->h}); 23 | SDL_BlitSurface( 24 | text_surf, NULL, target_surf, 25 | &(SDL_Rect){radius + y, radius - x, text_surf->w, text_surf->h}); 26 | SDL_BlitSurface( 27 | text_surf, NULL, target_surf, 28 | &(SDL_Rect){radius - y, radius + x, text_surf->w, text_surf->h}); 29 | SDL_BlitSurface( 30 | text_surf, NULL, target_surf, 31 | &(SDL_Rect){radius - y, radius - x, text_surf->w, text_surf->h}); 32 | } 33 | 34 | bool bubble_create(SDL_Surface **target_surf, SDL_Color outer_color, 35 | SDL_Color inner_color, const char *str, float size, 36 | int radius) { 37 | 38 | TTF_Font *font = TTF_OpenFont("fonts/freesansbold.ttf", size); 39 | if (!font) { 40 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 41 | return false; 42 | } 43 | 44 | SDL_Surface *text_surf = TTF_RenderText_Blended(font, str, 0, outer_color); 45 | if (!text_surf) { 46 | fprintf(stderr, "Error rendering text to Surface: %s\n", 47 | SDL_GetError()); 48 | TTF_CloseFont(font); 49 | return false; 50 | } 51 | 52 | *target_surf = 53 | SDL_CreateSurface(text_surf->w + radius * 2, text_surf->h + radius * 2, 54 | SDL_PIXELFORMAT_ARGB32); 55 | if (!text_surf) { 56 | fprintf(stderr, "Error creating target Surface: %s\n", SDL_GetError()); 57 | SDL_DestroySurface(text_surf); 58 | TTF_CloseFont(font); 59 | return false; 60 | } 61 | 62 | // // Polar Coordinates Trigonometry Algorithm 63 | // for (int index = 0; index < (2 * M_PI * radius); index++) { 64 | // double rad = (double)index / radius; 65 | // int x = (int)(cos(rad) * radius) + radius; 66 | // int y = (int)(sin(rad) * radius) + radius; 67 | // 68 | // SDL_BlitSurface(text_surf, NULL, *target_surf, 69 | // &(SDL_Rect){x, y, text_surf->w, text_surf->h}); 70 | // } 71 | 72 | // Bresenham's Circle Drawing Algorithm 73 | // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm 74 | int x = 0; 75 | int y = radius; 76 | int d = 3 - 2 * radius; 77 | blit_symmetric_points(text_surf, *target_surf, radius, x, y); 78 | while (y >= x) { 79 | x++; 80 | if (d > 0) { 81 | y--; 82 | d = d + 4 * (x - y) + 10; 83 | } else { 84 | d = d + 4 * x + 6; 85 | } 86 | blit_symmetric_points(text_surf, *target_surf, radius, x, y); 87 | } 88 | 89 | SDL_DestroySurface(text_surf); 90 | text_surf = NULL; 91 | text_surf = TTF_RenderText_Blended(font, str, 0, inner_color); 92 | if (!text_surf) { 93 | fprintf(stderr, "Error rendering text to Surface: %s\n", 94 | SDL_GetError()); 95 | SDL_DestroySurface(text_surf); 96 | TTF_CloseFont(font); 97 | return false; 98 | } 99 | 100 | SDL_BlitSurface(text_surf, NULL, *target_surf, 101 | &(SDL_Rect){radius, radius, text_surf->w, text_surf->h}); 102 | 103 | SDL_DestroySurface(text_surf); 104 | TTF_CloseFont(font); 105 | 106 | return true; 107 | } 108 | -------------------------------------------------------------------------------- /src/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_toggle_music(void); 7 | void game_events(struct Game *g); 8 | void game_update(struct Game *g); 9 | void game_draw(const struct Game *g); 10 | 11 | bool game_new(struct Game **game) { 12 | *game = calloc(1, sizeof(struct Game)); 13 | if (*game == NULL) { 14 | fprintf(stderr, "Error Calloc of New Game.\n"); 15 | return false; 16 | } 17 | struct Game *g = *game; 18 | 19 | if (!game_init_sdl(g)) { 20 | return false; 21 | } 22 | if (!game_load_media(g)) { 23 | return false; 24 | } 25 | 26 | if (!text_new(&g->text, g->renderer)) { 27 | return false; 28 | } 29 | if (!player_new(&g->player, g->renderer)) { 30 | return false; 31 | } 32 | 33 | g->is_running = true; 34 | 35 | srand((unsigned)time(NULL)); 36 | 37 | return true; 38 | } 39 | 40 | void game_free(struct Game **game) { 41 | if (*game) { 42 | struct Game *g = *game; 43 | 44 | Mix_HaltMusic(); 45 | Mix_HaltChannel(-1); 46 | 47 | if (g->music) { 48 | Mix_FreeMusic(g->music); 49 | g->music = NULL; 50 | } 51 | if (g->sdl_sound) { 52 | Mix_FreeChunk(g->sdl_sound); 53 | g->sdl_sound = NULL; 54 | } 55 | if (g->c_sound) { 56 | Mix_FreeChunk(g->c_sound); 57 | g->c_sound = NULL; 58 | } 59 | 60 | if (g->player) { 61 | player_free(&g->player); 62 | } 63 | if (g->text) { 64 | text_free(&g->text); 65 | } 66 | 67 | if (g->background) { 68 | SDL_DestroyTexture(g->background); 69 | g->background = NULL; 70 | } 71 | 72 | if (g->renderer) { 73 | SDL_DestroyRenderer(g->renderer); 74 | g->renderer = NULL; 75 | } 76 | if (g->window) { 77 | SDL_DestroyWindow(g->window); 78 | g->window = NULL; 79 | } 80 | 81 | Mix_CloseAudio(); 82 | 83 | Mix_Quit(); 84 | TTF_Quit(); 85 | SDL_Quit(); 86 | 87 | free(g); 88 | 89 | g = NULL; 90 | *game = NULL; 91 | 92 | printf("All Clean!\n"); 93 | } 94 | } 95 | 96 | void game_render_color(struct Game *g) { 97 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 98 | (Uint8)rand(), 255); 99 | Mix_PlayChannel(-1, g->c_sound, 0); 100 | } 101 | 102 | void game_toggle_music(void) { 103 | if (Mix_PausedMusic()) { 104 | Mix_ResumeMusic(); 105 | } else { 106 | Mix_PauseMusic(); 107 | } 108 | } 109 | 110 | void game_events(struct Game *g) { 111 | while (SDL_PollEvent(&g->event)) { 112 | switch (g->event.type) { 113 | case SDL_EVENT_QUIT: 114 | g->is_running = false; 115 | break; 116 | case SDL_EVENT_KEY_DOWN: 117 | switch (g->event.key.scancode) { 118 | case SDL_SCANCODE_ESCAPE: 119 | g->is_running = false; 120 | break; 121 | case SDL_SCANCODE_SPACE: 122 | game_render_color(g); 123 | break; 124 | case SDL_SCANCODE_M: 125 | game_toggle_music(); 126 | break; 127 | default: 128 | break; 129 | } 130 | break; 131 | default: 132 | break; 133 | } 134 | } 135 | } 136 | 137 | void game_update(struct Game *g) { 138 | text_update(g->text, g->sdl_sound); 139 | player_update(g->player); 140 | } 141 | 142 | void game_draw(const struct Game *g) { 143 | SDL_RenderClear(g->renderer); 144 | 145 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 146 | text_draw(g->text); 147 | player_draw(g->player); 148 | 149 | SDL_RenderPresent(g->renderer); 150 | } 151 | 152 | bool game_run(struct Game *g) { 153 | if (!Mix_PlayMusic(g->music, -1)) { 154 | fprintf(stderr, "Error playing Music: %s\n", SDL_GetError()); 155 | return false; 156 | } 157 | 158 | while (g->is_running) { 159 | game_events(g); 160 | 161 | game_update(g); 162 | 163 | game_draw(g); 164 | 165 | SDL_Delay(16); 166 | } 167 | 168 | return true; 169 | } 170 | -------------------------------------------------------------------------------- /Video09/game.c: -------------------------------------------------------------------------------- 1 | #include "game.h" 2 | #include "init_sdl.h" 3 | #include "load_media.h" 4 | 5 | void game_render_color(struct Game *g); 6 | void game_toggle_music(void); 7 | void game_events(struct Game *g); 8 | void game_update(struct Game *g); 9 | void game_draw(const struct Game *g); 10 | 11 | bool game_new(struct Game **game) { 12 | *game = calloc(1, sizeof(struct Game)); 13 | if (*game == NULL) { 14 | fprintf(stderr, "Error Calloc of New Game.\n"); 15 | return false; 16 | } 17 | struct Game *g = *game; 18 | 19 | if (!game_init_sdl(g)) { 20 | return false; 21 | } 22 | if (!game_load_media(g)) { 23 | return false; 24 | } 25 | 26 | if (!text_new(&g->text, g->renderer)) { 27 | return false; 28 | } 29 | if (!player_new(&g->player, g->renderer)) { 30 | return false; 31 | } 32 | 33 | g->is_running = true; 34 | 35 | srand((unsigned)time(NULL)); 36 | 37 | return true; 38 | } 39 | 40 | void game_free(struct Game **game) { 41 | if (*game) { 42 | struct Game *g = *game; 43 | 44 | Mix_HaltMusic(); 45 | Mix_HaltChannel(-1); 46 | 47 | if (g->music) { 48 | Mix_FreeMusic(g->music); 49 | g->music = NULL; 50 | } 51 | if (g->sdl_sound) { 52 | Mix_FreeChunk(g->sdl_sound); 53 | g->sdl_sound = NULL; 54 | } 55 | if (g->c_sound) { 56 | Mix_FreeChunk(g->c_sound); 57 | g->c_sound = NULL; 58 | } 59 | 60 | if (g->player) { 61 | player_free(&g->player); 62 | } 63 | if (g->text) { 64 | text_free(&g->text); 65 | } 66 | 67 | if (g->background) { 68 | SDL_DestroyTexture(g->background); 69 | g->background = NULL; 70 | } 71 | 72 | if (g->renderer) { 73 | SDL_DestroyRenderer(g->renderer); 74 | g->renderer = NULL; 75 | } 76 | if (g->window) { 77 | SDL_DestroyWindow(g->window); 78 | g->window = NULL; 79 | } 80 | 81 | Mix_CloseAudio(); 82 | 83 | Mix_Quit(); 84 | TTF_Quit(); 85 | SDL_Quit(); 86 | 87 | free(g); 88 | 89 | g = NULL; 90 | *game = NULL; 91 | 92 | printf("All Clean!\n"); 93 | } 94 | } 95 | 96 | void game_render_color(struct Game *g) { 97 | SDL_SetRenderDrawColor(g->renderer, (Uint8)rand(), (Uint8)rand(), 98 | (Uint8)rand(), 255); 99 | Mix_PlayChannel(-1, g->c_sound, 0); 100 | } 101 | 102 | void game_toggle_music(void) { 103 | if (Mix_PausedMusic()) { 104 | Mix_ResumeMusic(); 105 | } else { 106 | Mix_PauseMusic(); 107 | } 108 | } 109 | 110 | void game_events(struct Game *g) { 111 | while (SDL_PollEvent(&g->event)) { 112 | switch (g->event.type) { 113 | case SDL_EVENT_QUIT: 114 | g->is_running = false; 115 | break; 116 | case SDL_EVENT_KEY_DOWN: 117 | switch (g->event.key.scancode) { 118 | case SDL_SCANCODE_ESCAPE: 119 | g->is_running = false; 120 | break; 121 | case SDL_SCANCODE_SPACE: 122 | game_render_color(g); 123 | break; 124 | case SDL_SCANCODE_M: 125 | game_toggle_music(); 126 | break; 127 | default: 128 | break; 129 | } 130 | break; 131 | default: 132 | break; 133 | } 134 | } 135 | } 136 | 137 | void game_update(struct Game *g) { 138 | text_update(g->text, g->sdl_sound); 139 | player_update(g->player); 140 | } 141 | 142 | void game_draw(const struct Game *g) { 143 | SDL_RenderClear(g->renderer); 144 | 145 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 146 | text_draw(g->text); 147 | player_draw(g->player); 148 | 149 | SDL_RenderPresent(g->renderer); 150 | } 151 | 152 | bool game_run(struct Game *g) { 153 | if (!Mix_PlayMusic(g->music, -1)) { 154 | fprintf(stderr, "Error playing Music: %s\n", SDL_GetError()); 155 | return false; 156 | } 157 | 158 | while (g->is_running) { 159 | game_events(g); 160 | 161 | game_update(g); 162 | 163 | game_draw(g); 164 | 165 | SDL_Delay(16); 166 | } 167 | 168 | return true; 169 | } 170 | -------------------------------------------------------------------------------- /Video03/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define SDL_FLAGS SDL_INIT_VIDEO 9 | 10 | #define WINDOW_TITLE "Background and Icon" 11 | #define WINDOW_WIDTH 800 12 | #define WINDOW_HEIGHT 600 13 | 14 | struct Game { 15 | SDL_Window *window; 16 | SDL_Renderer *renderer; 17 | SDL_Texture *background; 18 | SDL_Event event; 19 | bool is_running; 20 | }; 21 | 22 | bool game_init_sdl(struct Game *g); 23 | bool game_new(struct Game **game); 24 | void game_free(struct Game **game); 25 | void game_events(struct Game *g); 26 | void game_draw(struct Game *g); 27 | void game_run(struct Game *g); 28 | 29 | bool game_init_sdl(struct Game *g) { 30 | if (!SDL_Init(SDL_FLAGS)) { 31 | fprintf(stderr, "Error initializing SDL3: %s\n", SDL_GetError()); 32 | return false; 33 | } 34 | 35 | g->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_WIDTH, WINDOW_HEIGHT, 0); 36 | if (!g->window) { 37 | fprintf(stderr, "Error creating Window: %s\n", SDL_GetError()); 38 | return false; 39 | } 40 | 41 | g->renderer = SDL_CreateRenderer(g->window, NULL); 42 | if (!g->renderer) { 43 | fprintf(stderr, "Error creating Renderer: %s\n", SDL_GetError()); 44 | return false; 45 | } 46 | 47 | SDL_Surface *icon_surf = IMG_Load("images/C-logo.png"); 48 | if (!icon_surf) { 49 | fprintf(stderr, "Error loading Surface: %s\n", SDL_GetError()); 50 | return false; 51 | } 52 | 53 | if (!SDL_SetWindowIcon(g->window, icon_surf)) { 54 | fprintf(stderr, "Error setting Window Icond: %s\n", SDL_GetError()); 55 | SDL_DestroySurface(icon_surf); 56 | return false; 57 | } 58 | SDL_DestroySurface(icon_surf); 59 | 60 | return true; 61 | } 62 | 63 | bool game_load_media(struct Game *g) { 64 | g->background = IMG_LoadTexture(g->renderer, "images/background.png"); 65 | if (!g->background) { 66 | fprintf(stderr, "Error loading Texture: %s\n", SDL_GetError()); 67 | return false; 68 | } 69 | 70 | return true; 71 | } 72 | 73 | bool game_new(struct Game **game) { 74 | *game = calloc(1, sizeof(struct Game)); 75 | if (*game == NULL) { 76 | fprintf(stderr, "Error Calloc of New Game.\n"); 77 | return false; 78 | } 79 | struct Game *g = *game; 80 | 81 | if (!game_init_sdl(g)) { 82 | return false; 83 | } 84 | 85 | if (!game_load_media(g)) { 86 | return false; 87 | } 88 | 89 | g->is_running = true; 90 | 91 | return true; 92 | } 93 | 94 | void game_free(struct Game **game) { 95 | if (*game) { 96 | struct Game *g = *game; 97 | 98 | if (g->background) { 99 | SDL_DestroyTexture(g->background); 100 | g->background = NULL; 101 | } 102 | 103 | if (g->renderer) { 104 | SDL_DestroyRenderer(g->renderer); 105 | g->renderer = NULL; 106 | } 107 | if (g->window) { 108 | SDL_DestroyWindow(g->window); 109 | g->window = NULL; 110 | } 111 | 112 | SDL_Quit(); 113 | 114 | free(g); 115 | 116 | g = NULL; 117 | *game = NULL; 118 | 119 | printf("All Clean!\n"); 120 | } 121 | } 122 | 123 | void game_events(struct Game *g) { 124 | while (SDL_PollEvent(&g->event)) { 125 | switch (g->event.type) { 126 | case SDL_EVENT_QUIT: 127 | g->is_running = false; 128 | break; 129 | case SDL_EVENT_KEY_DOWN: 130 | switch (g->event.key.scancode) { 131 | case SDL_SCANCODE_ESCAPE: 132 | g->is_running = false; 133 | break; 134 | default: 135 | break; 136 | } 137 | break; 138 | default: 139 | break; 140 | } 141 | } 142 | } 143 | 144 | void game_draw(struct Game *g) { 145 | SDL_RenderClear(g->renderer); 146 | 147 | SDL_RenderTexture(g->renderer, g->background, NULL, NULL); 148 | 149 | SDL_RenderPresent(g->renderer); 150 | } 151 | 152 | void game_run(struct Game *g) { 153 | while (g->is_running) { 154 | game_events(g); 155 | 156 | game_draw(g); 157 | 158 | SDL_Delay(16); 159 | } 160 | } 161 | 162 | int main(void) { 163 | bool exit_status = EXIT_FAILURE; 164 | 165 | struct Game *game = NULL; 166 | 167 | if (game_new(&game)) { 168 | game_run(game); 169 | 170 | exit_status = EXIT_SUCCESS; 171 | } 172 | 173 | game_free(&game); 174 | 175 | return exit_status; 176 | } 177 | -------------------------------------------------------------------------------- /src/bubble.c: -------------------------------------------------------------------------------- 1 | #include "bubble.h" 2 | 3 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 4 | int radius, int x, int y); 5 | SDL_Surface *solid_color_surface(SDL_Surface *src_surf, SDL_Color color); 6 | 7 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 8 | int radius, int x, int y) { 9 | SDL_BlitSurface( 10 | src_surf, NULL, target_surf, 11 | &(SDL_Rect){radius + x, radius + y, src_surf->w, src_surf->h}); 12 | SDL_BlitSurface( 13 | src_surf, NULL, target_surf, 14 | &(SDL_Rect){radius + x, radius - y, src_surf->w, src_surf->h}); 15 | SDL_BlitSurface( 16 | src_surf, NULL, target_surf, 17 | &(SDL_Rect){radius - x, radius + y, src_surf->w, src_surf->h}); 18 | SDL_BlitSurface( 19 | src_surf, NULL, target_surf, 20 | &(SDL_Rect){radius - x, radius - y, src_surf->w, src_surf->h}); 21 | SDL_BlitSurface( 22 | src_surf, NULL, target_surf, 23 | &(SDL_Rect){radius + y, radius + x, src_surf->w, src_surf->h}); 24 | SDL_BlitSurface( 25 | src_surf, NULL, target_surf, 26 | &(SDL_Rect){radius + y, radius - x, src_surf->w, src_surf->h}); 27 | SDL_BlitSurface( 28 | src_surf, NULL, target_surf, 29 | &(SDL_Rect){radius - y, radius + x, src_surf->w, src_surf->h}); 30 | SDL_BlitSurface( 31 | src_surf, NULL, target_surf, 32 | &(SDL_Rect){radius - y, radius - x, src_surf->w, src_surf->h}); 33 | } 34 | 35 | SDL_Surface *solid_color_surface(SDL_Surface *src_surf, SDL_Color color) { 36 | if (!src_surf) { 37 | fprintf(stderr, "Error: Surface is NULL.\n"); 38 | return NULL; 39 | } 40 | 41 | SDL_Surface *color_surf = SDL_DuplicateSurface(src_surf); 42 | if (!color_surf) { 43 | fprintf(stderr, "Error copying Surface: %s\n", SDL_GetError()); 44 | return NULL; 45 | } 46 | 47 | if (!SDL_LockSurface(color_surf)) { 48 | fprintf(stderr, "Error locking Surface: %s\n", SDL_GetError()); 49 | SDL_DestroySurface(color_surf); 50 | return NULL; 51 | } 52 | 53 | int width = color_surf->w; 54 | int height = color_surf->h; 55 | 56 | const SDL_PixelFormatDetails *format_details = 57 | SDL_GetPixelFormatDetails(color_surf->format); 58 | if (!format_details) { 59 | fprintf(stderr, "Error getting format details: %s\n", SDL_GetError()); 60 | SDL_DestroySurface(color_surf); 61 | return NULL; 62 | } 63 | 64 | if (format_details->bits_per_pixel != 32) { 65 | fprintf(stderr, "Error not a 32bit Surface.\n"); 66 | SDL_DestroySurface(color_surf); 67 | return NULL; 68 | } 69 | 70 | Uint32 *pixels = (Uint32 *)color_surf->pixels; 71 | SDL_Palette *palette = SDL_GetSurfacePalette(color_surf); 72 | 73 | for (int y = 0; y < height; y++) { 74 | for (int x = 0; x < width; x++) { 75 | Uint32 pixel = pixels[width * y + x]; 76 | Uint8 r, g, b, a; 77 | SDL_GetRGBA(pixel, format_details, palette, &r, &g, &b, &a); 78 | if (a > 0) { 79 | pixel = SDL_MapRGBA(format_details, palette, color.r, color.g, 80 | color.b, a); 81 | pixels[width * y + x] = pixel; 82 | } 83 | } 84 | } 85 | 86 | SDL_UnlockSurface(color_surf); 87 | 88 | return color_surf; 89 | } 90 | 91 | SDL_Surface *bubble_surface(SDL_Surface *src_surf, int radius, 92 | SDL_Color outer_color) { 93 | if (!src_surf) { 94 | fprintf(stderr, "Error: Surface is NULL.\n"); 95 | return NULL; 96 | } 97 | 98 | int width = src_surf->w + radius * 2; 99 | int height = src_surf->h + radius * 2; 100 | 101 | SDL_Surface *target_surf = 102 | SDL_CreateSurface(width, height, src_surf->format); 103 | if (!target_surf) { 104 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 105 | return NULL; 106 | } 107 | 108 | SDL_Surface *outer_surf = solid_color_surface(src_surf, outer_color); 109 | if (!outer_surf) { 110 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 111 | SDL_DestroySurface(target_surf); 112 | return NULL; 113 | } 114 | 115 | // // Polar Coordinates Trigonometry Algorithm 116 | // for (int index = 0; index < (2 * M_PI * radius); index++) { 117 | // double rad = (double)index / radius; 118 | // int x = (int)(cos(rad) * radius) + radius; 119 | // int y = (int)(sin(rad) * radius) + radius; 120 | // 121 | // SDL_BlitSurface(outer_surf, NULL, target_surf, 122 | // &(SDL_Rect){x, y, outer_surf->w, outer_surf->h}); 123 | // } 124 | 125 | // Bresenham's Circle Drawing Algorithm 126 | // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm 127 | int x = 0; 128 | int y = radius; 129 | int d = 3 - 2 * radius; 130 | blit_symmetric_points(outer_surf, target_surf, radius, x, y); 131 | while (y >= x) { 132 | x++; 133 | if (d > 0) { 134 | y--; 135 | d = d + 4 * (x - y) + 10; 136 | } else { 137 | d = d + 4 * x + 6; 138 | } 139 | blit_symmetric_points(outer_surf, target_surf, radius, x, y); 140 | } 141 | 142 | SDL_BlitSurface(src_surf, NULL, target_surf, 143 | &(SDL_Rect){radius, radius, src_surf->w, src_surf->h}); 144 | 145 | SDL_DestroySurface(outer_surf); 146 | 147 | return target_surf; 148 | } 149 | 150 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 151 | SDL_Color inner_color, SDL_Color outer_color) { 152 | TTF_Font *font = TTF_OpenFont("fonts/freesansbold.ttf", size); 153 | if (!font) { 154 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 155 | return NULL; 156 | } 157 | 158 | SDL_Surface *text_surf = TTF_RenderText_Blended(font, str, 0, inner_color); 159 | TTF_CloseFont(font); 160 | font = NULL; 161 | if (!text_surf) { 162 | fprintf(stderr, "Error rendering text to Surface: %s\n", 163 | SDL_GetError()); 164 | 165 | return NULL; 166 | } 167 | 168 | SDL_Surface *bubble_surf = bubble_surface(text_surf, radius, outer_color); 169 | SDL_DestroySurface(text_surf); 170 | text_surf = NULL; 171 | if (!bubble_surf) { 172 | return NULL; 173 | } 174 | 175 | return bubble_surf; 176 | } 177 | -------------------------------------------------------------------------------- /Video08/bubble.c: -------------------------------------------------------------------------------- 1 | #include "bubble.h" 2 | 3 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 4 | int radius, int x, int y); 5 | SDL_Surface *solid_color_surface(SDL_Surface *src_surf, SDL_Color color); 6 | 7 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 8 | int radius, int x, int y) { 9 | SDL_BlitSurface( 10 | src_surf, NULL, target_surf, 11 | &(SDL_Rect){radius + x, radius + y, src_surf->w, src_surf->h}); 12 | SDL_BlitSurface( 13 | src_surf, NULL, target_surf, 14 | &(SDL_Rect){radius + x, radius - y, src_surf->w, src_surf->h}); 15 | SDL_BlitSurface( 16 | src_surf, NULL, target_surf, 17 | &(SDL_Rect){radius - x, radius + y, src_surf->w, src_surf->h}); 18 | SDL_BlitSurface( 19 | src_surf, NULL, target_surf, 20 | &(SDL_Rect){radius - x, radius - y, src_surf->w, src_surf->h}); 21 | SDL_BlitSurface( 22 | src_surf, NULL, target_surf, 23 | &(SDL_Rect){radius + y, radius + x, src_surf->w, src_surf->h}); 24 | SDL_BlitSurface( 25 | src_surf, NULL, target_surf, 26 | &(SDL_Rect){radius + y, radius - x, src_surf->w, src_surf->h}); 27 | SDL_BlitSurface( 28 | src_surf, NULL, target_surf, 29 | &(SDL_Rect){radius - y, radius + x, src_surf->w, src_surf->h}); 30 | SDL_BlitSurface( 31 | src_surf, NULL, target_surf, 32 | &(SDL_Rect){radius - y, radius - x, src_surf->w, src_surf->h}); 33 | } 34 | 35 | SDL_Surface *solid_color_surface(SDL_Surface *src_surf, SDL_Color color) { 36 | if (!src_surf) { 37 | fprintf(stderr, "Error: Surface is NULL.\n"); 38 | return NULL; 39 | } 40 | 41 | SDL_Surface *color_surf = SDL_DuplicateSurface(src_surf); 42 | if (!color_surf) { 43 | fprintf(stderr, "Error copying Surface: %s\n", SDL_GetError()); 44 | return NULL; 45 | } 46 | 47 | if (!SDL_LockSurface(color_surf)) { 48 | fprintf(stderr, "Error locking Surface: %s\n", SDL_GetError()); 49 | SDL_DestroySurface(color_surf); 50 | return NULL; 51 | } 52 | 53 | int width = color_surf->w; 54 | int height = color_surf->h; 55 | 56 | const SDL_PixelFormatDetails *format_details = 57 | SDL_GetPixelFormatDetails(color_surf->format); 58 | if (!format_details) { 59 | fprintf(stderr, "Error getting format details: %s\n", SDL_GetError()); 60 | SDL_DestroySurface(color_surf); 61 | return NULL; 62 | } 63 | 64 | if (format_details->bits_per_pixel != 32) { 65 | fprintf(stderr, "Error not a 32bit Surface.\n"); 66 | SDL_DestroySurface(color_surf); 67 | return NULL; 68 | } 69 | 70 | Uint32 *pixels = (Uint32 *)color_surf->pixels; 71 | SDL_Palette *palette = SDL_GetSurfacePalette(color_surf); 72 | 73 | for (int y = 0; y < height; y++) { 74 | for (int x = 0; x < width; x++) { 75 | Uint32 pixel = pixels[width * y + x]; 76 | Uint8 r, g, b, a; 77 | SDL_GetRGBA(pixel, format_details, palette, &r, &g, &b, &a); 78 | if (a > 0) { 79 | pixel = SDL_MapRGBA(format_details, palette, color.r, color.g, 80 | color.b, a); 81 | pixels[width * y + x] = pixel; 82 | } 83 | } 84 | } 85 | 86 | SDL_UnlockSurface(color_surf); 87 | 88 | return color_surf; 89 | } 90 | 91 | SDL_Surface *bubble_surface(SDL_Surface *src_surf, int radius, 92 | SDL_Color outer_color) { 93 | if (!src_surf) { 94 | fprintf(stderr, "Error: Surface is NULL.\n"); 95 | return NULL; 96 | } 97 | 98 | int width = src_surf->w + radius * 2; 99 | int height = src_surf->h + radius * 2; 100 | 101 | SDL_Surface *target_surf = 102 | SDL_CreateSurface(width, height, src_surf->format); 103 | if (!target_surf) { 104 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 105 | return NULL; 106 | } 107 | 108 | SDL_Surface *outer_surf = solid_color_surface(src_surf, outer_color); 109 | if (!outer_surf) { 110 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 111 | SDL_DestroySurface(target_surf); 112 | return NULL; 113 | } 114 | 115 | // // Polar Coordinates Trigonometry Algorithm 116 | // for (int index = 0; index < (2 * M_PI * radius); index++) { 117 | // double rad = (double)index / radius; 118 | // int x = (int)(cos(rad) * radius) + radius; 119 | // int y = (int)(sin(rad) * radius) + radius; 120 | // 121 | // SDL_BlitSurface(outer_surf, NULL, target_surf, 122 | // &(SDL_Rect){x, y, outer_surf->w, outer_surf->h}); 123 | // } 124 | 125 | // Bresenham's Circle Drawing Algorithm 126 | // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm 127 | int x = 0; 128 | int y = radius; 129 | int d = 3 - 2 * radius; 130 | blit_symmetric_points(outer_surf, target_surf, radius, x, y); 131 | while (y >= x) { 132 | x++; 133 | if (d > 0) { 134 | y--; 135 | d = d + 4 * (x - y) + 10; 136 | } else { 137 | d = d + 4 * x + 6; 138 | } 139 | blit_symmetric_points(outer_surf, target_surf, radius, x, y); 140 | } 141 | 142 | SDL_BlitSurface(src_surf, NULL, target_surf, 143 | &(SDL_Rect){radius, radius, src_surf->w, src_surf->h}); 144 | 145 | SDL_DestroySurface(outer_surf); 146 | 147 | return target_surf; 148 | } 149 | 150 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 151 | SDL_Color inner_color, SDL_Color outer_color) { 152 | TTF_Font *font = TTF_OpenFont("fonts/freesansbold.ttf", size); 153 | if (!font) { 154 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 155 | return NULL; 156 | } 157 | 158 | SDL_Surface *text_surf = TTF_RenderText_Blended(font, str, 0, inner_color); 159 | TTF_CloseFont(font); 160 | font = NULL; 161 | if (!text_surf) { 162 | fprintf(stderr, "Error rendering text to Surface: %s\n", 163 | SDL_GetError()); 164 | 165 | return NULL; 166 | } 167 | 168 | SDL_Surface *bubble_surf = bubble_surface(text_surf, radius, outer_color); 169 | SDL_DestroySurface(text_surf); 170 | text_surf = NULL; 171 | if (!bubble_surf) { 172 | return NULL; 173 | } 174 | 175 | return bubble_surf; 176 | } 177 | -------------------------------------------------------------------------------- /Video09/bubble.c: -------------------------------------------------------------------------------- 1 | #include "bubble.h" 2 | 3 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 4 | int radius, int x, int y); 5 | SDL_Surface *solid_color_surface(SDL_Surface *src_surf, SDL_Color color); 6 | 7 | void blit_symmetric_points(SDL_Surface *src_surf, SDL_Surface *target_surf, 8 | int radius, int x, int y) { 9 | SDL_BlitSurface( 10 | src_surf, NULL, target_surf, 11 | &(SDL_Rect){radius + x, radius + y, src_surf->w, src_surf->h}); 12 | SDL_BlitSurface( 13 | src_surf, NULL, target_surf, 14 | &(SDL_Rect){radius + x, radius - y, src_surf->w, src_surf->h}); 15 | SDL_BlitSurface( 16 | src_surf, NULL, target_surf, 17 | &(SDL_Rect){radius - x, radius + y, src_surf->w, src_surf->h}); 18 | SDL_BlitSurface( 19 | src_surf, NULL, target_surf, 20 | &(SDL_Rect){radius - x, radius - y, src_surf->w, src_surf->h}); 21 | SDL_BlitSurface( 22 | src_surf, NULL, target_surf, 23 | &(SDL_Rect){radius + y, radius + x, src_surf->w, src_surf->h}); 24 | SDL_BlitSurface( 25 | src_surf, NULL, target_surf, 26 | &(SDL_Rect){radius + y, radius - x, src_surf->w, src_surf->h}); 27 | SDL_BlitSurface( 28 | src_surf, NULL, target_surf, 29 | &(SDL_Rect){radius - y, radius + x, src_surf->w, src_surf->h}); 30 | SDL_BlitSurface( 31 | src_surf, NULL, target_surf, 32 | &(SDL_Rect){radius - y, radius - x, src_surf->w, src_surf->h}); 33 | } 34 | 35 | SDL_Surface *solid_color_surface(SDL_Surface *src_surf, SDL_Color color) { 36 | if (!src_surf) { 37 | fprintf(stderr, "Error: Surface is NULL.\n"); 38 | return NULL; 39 | } 40 | 41 | SDL_Surface *color_surf = SDL_DuplicateSurface(src_surf); 42 | if (!color_surf) { 43 | fprintf(stderr, "Error copying Surface: %s\n", SDL_GetError()); 44 | return NULL; 45 | } 46 | 47 | if (!SDL_LockSurface(color_surf)) { 48 | fprintf(stderr, "Error locking Surface: %s\n", SDL_GetError()); 49 | SDL_DestroySurface(color_surf); 50 | return NULL; 51 | } 52 | 53 | int width = color_surf->w; 54 | int height = color_surf->h; 55 | 56 | const SDL_PixelFormatDetails *format_details = 57 | SDL_GetPixelFormatDetails(color_surf->format); 58 | if (!format_details) { 59 | fprintf(stderr, "Error getting format details: %s\n", SDL_GetError()); 60 | SDL_DestroySurface(color_surf); 61 | return NULL; 62 | } 63 | 64 | if (format_details->bits_per_pixel != 32) { 65 | fprintf(stderr, "Error not a 32bit Surface.\n"); 66 | SDL_DestroySurface(color_surf); 67 | return NULL; 68 | } 69 | 70 | Uint32 *pixels = (Uint32 *)color_surf->pixels; 71 | SDL_Palette *palette = SDL_GetSurfacePalette(color_surf); 72 | 73 | for (int y = 0; y < height; y++) { 74 | for (int x = 0; x < width; x++) { 75 | Uint32 pixel = pixels[width * y + x]; 76 | Uint8 r, g, b, a; 77 | SDL_GetRGBA(pixel, format_details, palette, &r, &g, &b, &a); 78 | if (a > 0) { 79 | pixel = SDL_MapRGBA(format_details, palette, color.r, color.g, 80 | color.b, a); 81 | pixels[width * y + x] = pixel; 82 | } 83 | } 84 | } 85 | 86 | SDL_UnlockSurface(color_surf); 87 | 88 | return color_surf; 89 | } 90 | 91 | SDL_Surface *bubble_surface(SDL_Surface *src_surf, int radius, 92 | SDL_Color outer_color) { 93 | if (!src_surf) { 94 | fprintf(stderr, "Error: Surface is NULL.\n"); 95 | return NULL; 96 | } 97 | 98 | int width = src_surf->w + radius * 2; 99 | int height = src_surf->h + radius * 2; 100 | 101 | SDL_Surface *target_surf = 102 | SDL_CreateSurface(width, height, src_surf->format); 103 | if (!target_surf) { 104 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 105 | return NULL; 106 | } 107 | 108 | SDL_Surface *outer_surf = solid_color_surface(src_surf, outer_color); 109 | if (!outer_surf) { 110 | fprintf(stderr, "Error creating new Surface: %s\n", SDL_GetError()); 111 | SDL_DestroySurface(target_surf); 112 | return NULL; 113 | } 114 | 115 | // // Polar Coordinates Trigonometry Algorithm 116 | // for (int index = 0; index < (2 * M_PI * radius); index++) { 117 | // double rad = (double)index / radius; 118 | // int x = (int)(cos(rad) * radius) + radius; 119 | // int y = (int)(sin(rad) * radius) + radius; 120 | // 121 | // SDL_BlitSurface(outer_surf, NULL, target_surf, 122 | // &(SDL_Rect){x, y, outer_surf->w, outer_surf->h}); 123 | // } 124 | 125 | // Bresenham's Circle Drawing Algorithm 126 | // https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm 127 | int x = 0; 128 | int y = radius; 129 | int d = 3 - 2 * radius; 130 | blit_symmetric_points(outer_surf, target_surf, radius, x, y); 131 | while (y >= x) { 132 | x++; 133 | if (d > 0) { 134 | y--; 135 | d = d + 4 * (x - y) + 10; 136 | } else { 137 | d = d + 4 * x + 6; 138 | } 139 | blit_symmetric_points(outer_surf, target_surf, radius, x, y); 140 | } 141 | 142 | SDL_BlitSurface(src_surf, NULL, target_surf, 143 | &(SDL_Rect){radius, radius, src_surf->w, src_surf->h}); 144 | 145 | SDL_DestroySurface(outer_surf); 146 | 147 | return target_surf; 148 | } 149 | 150 | SDL_Surface *bubble_create_text(const char *str, float size, int radius, 151 | SDL_Color inner_color, SDL_Color outer_color) { 152 | TTF_Font *font = TTF_OpenFont("fonts/freesansbold.ttf", size); 153 | if (!font) { 154 | fprintf(stderr, "Error Opening Font: %s\n", SDL_GetError()); 155 | return NULL; 156 | } 157 | 158 | SDL_Surface *text_surf = TTF_RenderText_Blended(font, str, 0, inner_color); 159 | TTF_CloseFont(font); 160 | font = NULL; 161 | if (!text_surf) { 162 | fprintf(stderr, "Error rendering text to Surface: %s\n", 163 | SDL_GetError()); 164 | 165 | return NULL; 166 | } 167 | 168 | SDL_Surface *bubble_surf = bubble_surface(text_surf, radius, outer_color); 169 | SDL_DestroySurface(text_surf); 170 | text_surf = NULL; 171 | if (!bubble_surf) { 172 | return NULL; 173 | } 174 | 175 | return bubble_surf; 176 | } 177 | --------------------------------------------------------------------------------