diff --git a/src/Makefile.am b/src/Makefile.am index 8cf198a..c6c59b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,8 @@ pong_SOURCES = \ ball.c \ ball.h \ racket.c \ - racket.h + racket.h \ + score.c \ + score.h pong_CFLAGS = $(SDL_CFLAGS) `pkg-config --cflags SDL2_ttf` pong_LDFLAGS = $(SDL_LIBS) `pkg-config --libs SDL2_ttf` -lm diff --git a/src/assets/LiberationMono-Bold.ttf b/src/assets/LiberationMono-Bold.ttf new file mode 100644 index 0000000..9997cda Binary files /dev/null and b/src/assets/LiberationMono-Bold.ttf differ diff --git a/src/pong.c b/src/pong.c index 9964da3..342c1cd 100644 --- a/src/pong.c +++ b/src/pong.c @@ -14,7 +14,18 @@ Pong_init() { p->ball = Ball_init(p->SCREEN_WIDTH, p->SCREEN_HEIGHT, p->BALL_POSX); p->racketL = Racket_init(p->SCREEN_WIDTH, p->SCREEN_HEIGHT, p->RACKET_POSX, p->SCREEN_HEIGHT/2, SDL_SCANCODE_E, SDL_SCANCODE_D); + if (p->racketL == NULL) { + Ball_free(p->ball); + free(p); + return NULL; + } p->racketR = Racket_init(p->SCREEN_WIDTH, p->SCREEN_HEIGHT, p->SCREEN_WIDTH - p->RACKET_POSX, p->SCREEN_HEIGHT/2, SDL_SCANCODE_I, SDL_SCANCODE_K); + if (p->racketR == NULL) { + Ball_free(p->ball); + Racket_free(p->racketL); + free(p); + return NULL; + } p->window = SDL_CreateWindow( "Pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, p->SCREEN_WIDTH, p->SCREEN_HEIGHT, SDL_WINDOW_SHOWN ); if( p->window == NULL ) @@ -23,6 +34,7 @@ Pong_init() { Pong_free(p); return NULL; } + p->renderer = SDL_CreateRenderer(p->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); p->screenSurface = SDL_GetWindowSurface( p->window ); @@ -36,6 +48,7 @@ Pong_init() { void Pong_free(Pong *p) { SDL_DestroyRenderer(p->renderer); + SDL_FreeSurface(p->screenSurface); SDL_DestroyWindow(p->window); Ball_free(p->ball); Racket_free(p->racketL); @@ -49,14 +62,17 @@ Pong_clear(Pong *p) { SDL_RenderClear( p->renderer ); } -void +int Pong_render(Pong *p) { Pong_clear(p); - Ball_render(p->ball, p->renderer); - Racket_render(p->racketL, p->renderer); - Racket_render(p->racketR, p->renderer); - - SDL_RenderPresent(p->renderer); + const int error = Ball_render(p->ball, p->renderer) + + Racket_render(p->racketL, p->renderer) + + Racket_render(p->racketR, p->renderer); + if (error > 0) { + return error; + } + SDL_RenderPresent(p->renderer); + return 0; } @@ -72,13 +88,13 @@ Ball_move(Ball *b, Pong *p) } if (b->posX < 0) { - p->racketR->score++; + p->racketR->score->score++; Ball_reset(b, -1); } else if(b->posX + b->BALL_WIDTH > b->SCREEN_WIDTH) { - p->racketL->score++; + p->racketL->score->score++; Ball_reset(b, 1); } @@ -108,7 +124,7 @@ Pong_run(Pong *p) { Ball_move(p->ball, p); Racket_move(p->racketL); Racket_move(p->racketR); - Pong_render(p); + if (Pong_render(p) > 0) quit = true; Pong_score_run(p); } Pong_score_end(p); @@ -116,7 +132,7 @@ Pong_run(Pong *p) { void Pong_score(const Pong *p, char c) { - printf("SCORE: L %i | R %i", p->racketL->score, p->racketR->score); + printf("SCORE: L %i | R %i", p->racketL->score->score, p->racketR->score->score); putc(c, stdout); } diff --git a/src/pong.h b/src/pong.h index 7c9cc74..b4f3932 100644 --- a/src/pong.h +++ b/src/pong.h @@ -11,7 +11,6 @@ typedef struct Pong { SDL_Window* window; SDL_Surface* screenSurface; SDL_Renderer* renderer; - //SDL_Texture* texture; SDL_Event e; Ball *ball; const int BALL_POSX; @@ -23,7 +22,7 @@ typedef struct Pong { Pong* Pong_init(); void Pong_free(Pong *p); void Pong_clear(Pong *p); -void Pong_render(Pong *p); +int Pong_render(Pong *p); void Ball_move(Ball *b, Pong *p); void Pong_run(Pong *p); void Pong_score(const Pong *p, char c); diff --git a/src/racket.c b/src/racket.c index dcc02ec..620979b 100644 --- a/src/racket.c +++ b/src/racket.c @@ -12,7 +12,11 @@ Racket_init(int screen_width, int screen_height, int posX, int posY, SDL_Keycode *(int *)&r->posX = posX; r->posY = posY; *(int *)&r->vel = 5; - r->score = 0; + r->score = Score_init(r->posX, 20); + if (r->score == NULL) { + free(r); + return NULL; + } *(SDL_Keycode *)&r->up = up; *(SDL_Keycode *)&r->down = down; r->updown = 0; @@ -22,6 +26,7 @@ Racket_init(int screen_width, int screen_height, int posX, int posY, SDL_Keycode void Racket_free(Racket *r) { + Score_free(r->score); free(r); } @@ -33,6 +38,9 @@ Racket_render(const Racket *r, SDL_Renderer *renderer) { return 1; } SDL_RenderFillRect(renderer, &rect); + if (Score_render(r->score, renderer) > 0) { + return 1; + } return 0; } diff --git a/src/racket.h b/src/racket.h index 9b3c165..ea516d9 100644 --- a/src/racket.h +++ b/src/racket.h @@ -3,6 +3,8 @@ #include +#include "score.h" + typedef struct Racket { const int RACKET_WIDTH; const int RACKET_HEIGHT; @@ -12,7 +14,7 @@ typedef struct Racket { const int posX; int posY; const int vel; - int score; + Score* score; const SDL_Keycode up; const SDL_Keycode down; int updown; diff --git a/src/score.c b/src/score.c new file mode 100644 index 0000000..f3544ca --- /dev/null +++ b/src/score.c @@ -0,0 +1,50 @@ +#include "score.h" + +static const char font_path[] = "assets/LiberationMono-Bold.ttf"; + +Score* +Score_init(int posX, int posY) { + Score *s = malloc(sizeof(Score)); + *(int *)&s->POSX = posX; + *(int *)&s->POSY = posY; + s->score = 0; + s->font = TTF_OpenFont(font_path, 16); + if (s->font == NULL) { + printf("TTF_OpenFont fail with path '%s'. TTF_Error: %s\n", font_path, TTF_GetError()); + free(s); + return NULL; + } + s->textColor = (SDL_Color) { 255, 255, 255 }; + return s; +} + +void +Score_free(Score *s) { + TTF_CloseFont(s->font); + free(s); +} + +int +Score_render(const Score *s, SDL_Renderer *renderer) { + char score_str[3]; + SDL_Rect scoreRect = { s->POSX , s->POSY, 50, 50 }; + + sprintf(score_str, "%i", s->score); + SDL_Surface *scoreSurface = TTF_RenderText_Solid(s->font, score_str, s->textColor); + if (scoreSurface == NULL) { + printf("Text rendering failed. TTF_Error: %s\n", TTF_GetError()); + return 1; + } + SDL_Texture *scoreTexture = SDL_CreateTextureFromSurface(renderer, scoreSurface); + if (scoreTexture == NULL) { + printf("Texture rendering failed. SDL_Error: %s\n", SDL_GetError()); + SDL_FreeSurface(scoreSurface); + return 1; + } + SDL_RenderCopy(renderer, scoreTexture, NULL, &scoreRect); + + SDL_FreeSurface(scoreSurface); + SDL_DestroyTexture(scoreTexture); + + return 0; +} diff --git a/src/score.h b/src/score.h new file mode 100644 index 0000000..e7a372b --- /dev/null +++ b/src/score.h @@ -0,0 +1,19 @@ +#ifndef SCORE_H +#define SCORE_H + +#include +#include + +typedef struct Score { + const int POSX; + const int POSY; + int score; + TTF_Font *font; + SDL_Color textColor; +} Score; + +Score* Score_init(int posX, int posY); +void Score_free(Score* score); +int Score_render(const Score* score, SDL_Renderer *renderer); + +#endif