Compare commits
30 Commits
23009a78f1
...
5600a7359a
Author | SHA1 | Date | |
---|---|---|---|
5600a7359a | |||
134592d9f6 | |||
267e6f7d5d | |||
54ecb1f828 | |||
d0166b0802 | |||
f893c57598 | |||
2ebcf624de | |||
9a069cfa84 | |||
b9df2a3cf0 | |||
c8bd082866 | |||
46e9265365 | |||
bb6d81c99d | |||
54c5f78370 | |||
45df3ec812 | |||
4ac1d84ef6 | |||
ebdcba9afb | |||
5b18911111 | |||
5ced7d7ade | |||
20a2065f47 | |||
40a904e100 | |||
30fc668684 | |||
0462b187b4 | |||
b0d7f5cc48 | |||
c5e8473d79 | |||
05addb3baa | |||
039149a745 | |||
a70d61ca52 | |||
c56480a33b | |||
0d522fb521 | |||
145fbfd02e |
3
README
3
README
@ -3,3 +3,6 @@ A game of Pong.
|
||||
Requirements
|
||||
===========
|
||||
* sdl2
|
||||
* sdl2-ttf
|
||||
* fontconfig
|
||||
* Liberation Mono fonts
|
4
configure
vendored
4
configure
vendored
@ -4225,8 +4225,6 @@ else
|
||||
fi
|
||||
|
||||
|
||||
#AC_PROG_LIBTOOL
|
||||
#AC_CONFIG_HEADERS([config.h])
|
||||
ac_config_files="$ac_config_files Makefile src/Makefile"
|
||||
|
||||
|
||||
@ -4397,7 +4395,7 @@ fi
|
||||
|
||||
|
||||
|
||||
min_sdl_version=2.0
|
||||
min_sdl_version=2.0.0
|
||||
|
||||
if test "x$sdl_prefix$sdl_exec_prefix" = x ; then
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
AC_INIT([pong], [0.1-alpha], [paumars@courrier.dev])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
||||
AC_PROG_CC
|
||||
#AC_PROG_LIBTOOL
|
||||
#AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
])
|
||||
AM_PATH_SDL2(2.0)
|
||||
AM_PATH_SDL2
|
||||
|
||||
AC_OUTPUT
|
||||
|
@ -7,6 +7,10 @@ pong_SOURCES = \
|
||||
ball.c \
|
||||
ball.h \
|
||||
racket.c \
|
||||
racket.h
|
||||
pong_CFLAGS = $(SDL_CFLAGS)
|
||||
pong_LDFLAGS = $(SDL_LIBS)
|
||||
racket.h \
|
||||
score.c \
|
||||
score.h \
|
||||
text.c \
|
||||
text.h
|
||||
pong_CFLAGS = $(SDL_CFLAGS) `pkg-config --cflags SDL2_ttf fontconfig`
|
||||
pong_LDFLAGS = $(SDL_LIBS) `pkg-config --libs SDL2_ttf fontconfig` -lm
|
||||
|
38
src/ball.c
38
src/ball.c
@ -1,13 +1,15 @@
|
||||
#include <stdlib.h> // srand, rand
|
||||
#include <time.h> // time
|
||||
#include <math.h> // sin, cos, M_PI
|
||||
#include "ball.h"
|
||||
#include "racket.h"
|
||||
|
||||
Ball*
|
||||
Ball_init(int screen_width, int screen_height)
|
||||
Ball_init(int screen_width, int screen_height, int posX_start)
|
||||
{
|
||||
srand(time(NULL));
|
||||
Ball *b = malloc(sizeof(Ball));
|
||||
*(int *)&b->BALL_WIDTH = 20;
|
||||
*(int *)&b->BALL_HEIGHT = 20;
|
||||
*(int *)&b->BALL_VELOCITY = 10;
|
||||
*(int *)&b->BALL_POSX_START = posX_start;
|
||||
*(int *)&b->SCREEN_WIDTH = screen_width;
|
||||
*(int *)&b->SCREEN_HEIGHT = screen_height;
|
||||
Ball_reset(b, 1);
|
||||
@ -16,10 +18,20 @@ Ball_init(int screen_width, int screen_height)
|
||||
|
||||
void
|
||||
Ball_reset(Ball *b, int direction) {
|
||||
b->posX = 100;
|
||||
b->posY = 100;
|
||||
b->velX = direction * 7;
|
||||
b->velY = 5;
|
||||
// 120 deg angle with norm horizontal vector
|
||||
int angle;
|
||||
do {
|
||||
angle = rand() % BALL_ANGLE_MAX_OFFSET*2 + BALL_ANGLE_MAX_OFFSET/2 - 90;
|
||||
} while (-BALL_ANGLE_MIN_OFFSET <= angle && angle <= BALL_ANGLE_MIN_OFFSET);
|
||||
if (direction < 0) {
|
||||
b->posX = b->BALL_POSX_START;
|
||||
}
|
||||
else {
|
||||
b->posX = b->SCREEN_WIDTH - b->BALL_POSX_START;
|
||||
}
|
||||
b->posY = b->SCREEN_HEIGHT/2;
|
||||
b->velX = -direction * BALL_VELOCITY * cos(angle * M_PI / 180);
|
||||
b->velY = BALL_VELOCITY * sin(angle * M_PI / 180);
|
||||
}
|
||||
|
||||
void
|
||||
@ -31,14 +43,14 @@ Ball_free(Ball *b)
|
||||
int
|
||||
Ball_collision(const Ball *b, const Racket *r) {
|
||||
const int leftB = b->posX;
|
||||
const int rightB = leftB + b->BALL_WIDTH;
|
||||
const int rightB = leftB + BALL_WIDTH;
|
||||
const int upB = b->posY;
|
||||
const int downB = upB + b->BALL_HEIGHT;
|
||||
const int downB = upB + BALL_HEIGHT;
|
||||
|
||||
const int leftR = r->posX;
|
||||
const int rightR = leftR + r->RACKET_WIDTH;
|
||||
const int rightR = leftR + RACKET_WIDTH;
|
||||
const int upR = r->posY;
|
||||
const int downR = upR + r->RACKET_HEIGHT;
|
||||
const int downR = upR + RACKET_HEIGHT;
|
||||
|
||||
if(downB <= upR
|
||||
|| upB >= downR
|
||||
@ -52,7 +64,7 @@ Ball_collision(const Ball *b, const Racket *r) {
|
||||
|
||||
int
|
||||
Ball_render(const Ball *b, SDL_Renderer *renderer) {
|
||||
SDL_Rect rect = { b->posX, b->posY, b->BALL_WIDTH, b->BALL_HEIGHT };
|
||||
SDL_Rect rect = { b->posX, b->posY, BALL_WIDTH, BALL_HEIGHT };
|
||||
if (SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) < 0) {
|
||||
printf("SDL_SetRenderDrawColor failed! SDL_Error: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
|
12
src/ball.h
12
src/ball.h
@ -6,19 +6,23 @@
|
||||
|
||||
#include "racket.h"
|
||||
|
||||
static const int BALL_WIDTH = 20;
|
||||
static const int BALL_HEIGHT = 20;
|
||||
static const int BALL_VELOCITY = 7;
|
||||
static const int BALL_ANGLE_MIN_OFFSET = 10;
|
||||
static const int BALL_ANGLE_MAX_OFFSET = 60;
|
||||
|
||||
typedef struct Ball {
|
||||
const int BALL_WIDTH;
|
||||
const int BALL_HEIGHT;
|
||||
const int BALL_VELOCITY;
|
||||
const int SCREEN_WIDTH;
|
||||
const int SCREEN_HEIGHT;
|
||||
const int BALL_POSX_START;
|
||||
int posX;
|
||||
int posY;
|
||||
int velX;
|
||||
int velY;
|
||||
} Ball;
|
||||
|
||||
Ball* Ball_init(int screen_width, int screen_height);
|
||||
Ball* Ball_init(int screen_width, int screen_height, int posX_start);
|
||||
void Ball_reset(Ball *b, int direction);
|
||||
void Ball_free(Ball *b);
|
||||
//void Ball_handle_event(Ball *b, SDL_Event *e);
|
||||
|
25
src/main.c
25
src/main.c
@ -1,4 +1,5 @@
|
||||
#include <SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pong.h"
|
||||
@ -6,30 +7,28 @@
|
||||
int main (int argc, char* args[])
|
||||
{
|
||||
Pong *p = NULL;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||
{
|
||||
printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
|
||||
return 1;
|
||||
}
|
||||
if (TTF_Init() < 0)
|
||||
{
|
||||
printf( "TTF could not initialize! TTF_Error: %s\n", TTF_GetError() );
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = Pong_init();
|
||||
Pong_render(p);
|
||||
|
||||
int start = false;
|
||||
while (!start) {
|
||||
printf("Press any key to start...\r");
|
||||
fflush(stdout);
|
||||
while( SDL_PollEvent( &(p->e) ) != 0 )
|
||||
{
|
||||
if( p->e.type == SDL_KEYDOWN) start = true;
|
||||
if (p == NULL) {
|
||||
printf("Pong failed to initialise!\n");
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
putc('\n', stdout);
|
||||
|
||||
Pong_run(p);
|
||||
Pong_free(p);
|
||||
|
||||
TTF_Quit();
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
|
96
src/pong.c
96
src/pong.c
@ -6,21 +6,29 @@ Pong*
|
||||
Pong_init() {
|
||||
Pong *p = malloc(sizeof(Pong));
|
||||
|
||||
// Cast away the const
|
||||
*(int *)&p->SCREEN_WIDTH = 640;
|
||||
*(int *)&p->SCREEN_HEIGHT = 480;
|
||||
p->ball = Ball_init(PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, PONG_BALL_POSX);
|
||||
p->racketL = Racket_init(PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, PONG_RACKET_POSX, PONG_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(PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, PONG_SCREEN_WIDTH - PONG_RACKET_POSX - RACKET_WIDTH, PONG_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->ball = Ball_init(p->SCREEN_WIDTH, p->SCREEN_HEIGHT);
|
||||
p->racketL = Racket_init(p->SCREEN_WIDTH, p->SCREEN_HEIGHT, 50, 50, SDL_SCANCODE_E, SDL_SCANCODE_D);
|
||||
p->racketR = Racket_init(p->SCREEN_WIDTH, p->SCREEN_HEIGHT, p->SCREEN_WIDTH - 50, 50, SDL_SCANCODE_I, SDL_SCANCODE_K);
|
||||
|
||||
p->window = SDL_CreateWindow( "Pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, p->SCREEN_WIDTH, p->SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
|
||||
p->window = SDL_CreateWindow( "Pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, PONG_SCREEN_WIDTH, PONG_SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
|
||||
if( p->window == NULL )
|
||||
{
|
||||
printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
|
||||
Pong_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->renderer = SDL_CreateRenderer(p->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
p->screenSurface = SDL_GetWindowSurface( p->window );
|
||||
|
||||
@ -34,6 +42,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);
|
||||
@ -47,14 +56,33 @@ Pong_clear(Pong *p) {
|
||||
SDL_RenderClear( p->renderer );
|
||||
}
|
||||
|
||||
void
|
||||
Pong_render(Pong *p) {
|
||||
int
|
||||
Pong_render(Pong *p, int start) {
|
||||
Pong_clear(p);
|
||||
Ball_render(p->ball, p->renderer);
|
||||
Racket_render(p->racketL, p->renderer);
|
||||
Racket_render(p->racketR, p->renderer);
|
||||
int error = Ball_render(p->ball, p->renderer)
|
||||
+ Racket_render(p->racketL, p->renderer)
|
||||
+ Racket_render(p->racketR, p->renderer);
|
||||
|
||||
if (!start) {
|
||||
Text *start_text;
|
||||
const char *start_text_str = "Press any key to begin...";
|
||||
const int start_text_posX = 50;
|
||||
const int start_text_posY = 400;
|
||||
const int start_text_width = 500;
|
||||
const int start_text_height = 40;
|
||||
const char *start_text_style = "Regular";
|
||||
const int start_text_ptsize = 8;
|
||||
|
||||
start_text = Text_init(start_text_posX, start_text_posY, start_text_style, start_text_ptsize);
|
||||
error += Text_render(start_text, p->renderer, start_text_str, start_text_width, start_text_height);
|
||||
Text_free(start_text);
|
||||
}
|
||||
if (error > 0) {
|
||||
return error;
|
||||
}
|
||||
|
||||
SDL_RenderPresent(p->renderer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -70,18 +98,18 @@ 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)
|
||||
else if(b->posX + BALL_WIDTH > b->SCREEN_WIDTH)
|
||||
{
|
||||
p->racketL->score++;
|
||||
p->racketL->score->score++;
|
||||
Ball_reset(b, 1);
|
||||
}
|
||||
|
||||
b->posY += b->velY;
|
||||
if ((b->posY < 0) || (b->posY + b->BALL_HEIGHT > b->SCREEN_HEIGHT))
|
||||
if ((b->posY < 0) || (b->posY + BALL_HEIGHT > b->SCREEN_HEIGHT))
|
||||
{
|
||||
b->posY -= b->velY;
|
||||
b->velY = -b->velY;
|
||||
@ -90,7 +118,18 @@ Ball_move(Ball *b, Pong *p)
|
||||
|
||||
void
|
||||
Pong_run(Pong *p) {
|
||||
int start = false;
|
||||
int quit = false;
|
||||
Pong_render(p, start);
|
||||
while (!start) {
|
||||
fflush(stdout);
|
||||
while( SDL_PollEvent( &(p->e) ) != 0 )
|
||||
{
|
||||
if( p->e.type == SDL_KEYDOWN) start = true;
|
||||
}
|
||||
}
|
||||
putc('\n', stdout);
|
||||
|
||||
while (!quit) {
|
||||
|
||||
while( SDL_PollEvent( &(p->e) ) != 0 )
|
||||
@ -106,25 +145,18 @@ Pong_run(Pong *p) {
|
||||
Ball_move(p->ball, p);
|
||||
Racket_move(p->racketL);
|
||||
Racket_move(p->racketR);
|
||||
Pong_render(p);
|
||||
Pong_score_run(p);
|
||||
if (Pong_render(p, start) > 0) quit = true;
|
||||
Pong_status(p, quit);
|
||||
}
|
||||
Pong_score_end(p);
|
||||
}
|
||||
|
||||
void
|
||||
Pong_score(const Pong *p, char c) {
|
||||
printf("SCORE: L %i | R %i", p->racketL->score, p->racketR->score);
|
||||
putc(c, stdout);
|
||||
Pong_status(const Pong *p, int quit) {
|
||||
printf("[STATUS] SCORE: L %i | R %i", p->racketL->score->score, p->racketR->score->score);
|
||||
if (quit) {
|
||||
putc('\n', stdout);
|
||||
}
|
||||
|
||||
void
|
||||
Pong_score_run(const Pong *p) {
|
||||
Pong_score(p, '\r');
|
||||
fflush(stdout);
|
||||
else {
|
||||
putc('\r', stdout);
|
||||
}
|
||||
|
||||
void
|
||||
Pong_score_end(const Pong *p) {
|
||||
Pong_score(p, '\n');
|
||||
}
|
||||
|
14
src/pong.h
14
src/pong.h
@ -5,13 +5,15 @@
|
||||
|
||||
#include "ball.h"
|
||||
|
||||
static const int PONG_SCREEN_WIDTH = 640;
|
||||
static const int PONG_SCREEN_HEIGHT = 480;
|
||||
static const int PONG_BALL_POSX = 100;
|
||||
static const int PONG_RACKET_POSX = 50;
|
||||
|
||||
typedef struct Pong {
|
||||
const int SCREEN_WIDTH;
|
||||
const int SCREEN_HEIGHT;
|
||||
SDL_Window* window;
|
||||
SDL_Surface* screenSurface;
|
||||
SDL_Renderer* renderer;
|
||||
//SDL_Texture* texture;
|
||||
SDL_Event e;
|
||||
Ball *ball;
|
||||
Racket *racketL;
|
||||
@ -21,11 +23,9 @@ 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, int start);
|
||||
void Ball_move(Ball *b, Pong *p);
|
||||
void Pong_run(Pong *p);
|
||||
void Pong_score(const Pong *p, char c);
|
||||
void Pong_score_run(const Pong *p);
|
||||
void Pong_score_end(const Pong *p);
|
||||
void Pong_status(const Pong *p, int quit);
|
||||
|
||||
#endif
|
||||
|
22
src/racket.c
22
src/racket.c
@ -4,15 +4,15 @@ Racket*
|
||||
Racket_init(int screen_width, int screen_height, int posX, int posY, SDL_Keycode up, SDL_Keycode down)
|
||||
{
|
||||
Racket *r = malloc(sizeof(Racket));
|
||||
*(int *)&r->RACKET_WIDTH = 20;
|
||||
*(int *)&r->RACKET_HEIGHT = 100;
|
||||
*(int *)&r->RACKET_VELOCITY = 10;
|
||||
*(int *)&r->SCREEN_WIDTH = screen_width;
|
||||
*(int *)&r->SCREEN_HEIGHT = screen_height;
|
||||
*(int *)&r->posX = posX;
|
||||
r->posY = posY;
|
||||
*(int *)&r->vel = 5;
|
||||
r->score = 0;
|
||||
r->score = Score_init(r->posX - SCORE_WIDTH/2 + RACKET_WIDTH/2, RACKET_WIDTH);
|
||||
if (r->score == NULL) {
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
*(SDL_Keycode *)&r->up = up;
|
||||
*(SDL_Keycode *)&r->down = down;
|
||||
r->updown = 0;
|
||||
@ -22,17 +22,21 @@ 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);
|
||||
}
|
||||
|
||||
int
|
||||
Racket_render(const Racket *r, SDL_Renderer *renderer) {
|
||||
SDL_Rect rect = { r->posX, r->posY, r->RACKET_WIDTH, r->RACKET_HEIGHT };
|
||||
SDL_Rect rect = { r->posX, r->posY, RACKET_WIDTH, RACKET_HEIGHT };
|
||||
if (SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) < 0) {
|
||||
printf("SDL_SetRenderDrawColor failed! SDL_Error: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
SDL_RenderFillRect(renderer, &rect);
|
||||
if (Score_render(r->score, renderer) > 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -45,10 +49,10 @@ Racket_handle_event(Racket *r, const Uint8 *keystate) {
|
||||
|
||||
void
|
||||
Racket_move(Racket *r) {
|
||||
r->posY += r->updown * r->vel;
|
||||
if ((r->posY < 0) || (r->posY + r->RACKET_HEIGHT > r->SCREEN_HEIGHT))
|
||||
r->posY += r->updown * RACKET_VELOCITY;
|
||||
if ((r->posY < 0) || (r->posY + RACKET_HEIGHT > r->SCREEN_HEIGHT))
|
||||
{
|
||||
r->posY -= r->updown * r->vel;
|
||||
r->posY -= r->updown * RACKET_VELOCITY;
|
||||
}
|
||||
r->updown = 0;
|
||||
}
|
||||
|
14
src/racket.h
14
src/racket.h
@ -3,18 +3,20 @@
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "score.h"
|
||||
|
||||
static const int RACKET_WIDTH = 20;
|
||||
static const int RACKET_HEIGHT = 100;
|
||||
static const int RACKET_VELOCITY = 5;
|
||||
|
||||
typedef struct Racket {
|
||||
const int RACKET_WIDTH;
|
||||
const int RACKET_HEIGHT;
|
||||
const int RACKET_VELOCITY;
|
||||
const int SCREEN_WIDTH;
|
||||
const int SCREEN_HEIGHT;
|
||||
const int posX;
|
||||
int posY;
|
||||
const int vel;
|
||||
int score;
|
||||
const SDL_Keycode up;
|
||||
const SDL_Keycode down;
|
||||
int posY;
|
||||
Score* score;
|
||||
int updown;
|
||||
} Racket;
|
||||
|
||||
|
24
src/score.c
Normal file
24
src/score.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "score.h"
|
||||
|
||||
Score*
|
||||
Score_init(int posX, int posY) {
|
||||
Score *s = malloc(sizeof(Score));
|
||||
s->score = 0;
|
||||
s->text = Text_init(posX, posY, SCORE_FONT_STYLE, SCORE_FONT_PTSIZE);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
Score_free(Score *s) {
|
||||
Text_free(s->text);
|
||||
free(s);
|
||||
}
|
||||
|
||||
int
|
||||
Score_render(const Score *s, SDL_Renderer *renderer) {
|
||||
char score_str[3];
|
||||
sprintf(score_str, "%i", s->score);
|
||||
Text_render(s->text, renderer, score_str, SCORE_WIDTH, SCORE_HEIGHT);
|
||||
return 0;
|
||||
}
|
20
src/score.h
Normal file
20
src/score.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef SCORE_H
|
||||
#define SCORE_H
|
||||
|
||||
#include "text.h"
|
||||
|
||||
static const int SCORE_WIDTH = 50;
|
||||
static const int SCORE_HEIGHT = 50;
|
||||
static const FcChar8 *SCORE_FONT_STYLE = "Bold";
|
||||
static const int SCORE_FONT_PTSIZE = 16;
|
||||
|
||||
typedef struct Score {
|
||||
int score;
|
||||
Text *text;
|
||||
} Score;
|
||||
|
||||
Score* Score_init(int posX, int posY);
|
||||
void Score_free(Score* score);
|
||||
int Score_render(const Score* score, SDL_Renderer *renderer);
|
||||
|
||||
#endif
|
67
src/text.c
Normal file
67
src/text.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include "text.h"
|
||||
|
||||
Text*
|
||||
Text_init(int posX, int posY, const FcChar8 *TEXT_FONT_STYLE, int TEXT_FONT_PTSIZE) {
|
||||
Text *t = malloc(sizeof(Text));
|
||||
*(int *)&t->POSX = posX;
|
||||
*(int *)&t->POSY = posY;
|
||||
|
||||
FcConfig *config = FcInitLoadConfigAndFonts();
|
||||
FcPattern *pat = FcPatternCreate();
|
||||
|
||||
FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, (char *) 0);
|
||||
FcFontSet* fs = FcFontList(config, pat, os);
|
||||
|
||||
FcChar8 *style, *family;
|
||||
for (int i=0; fs && i < fs->nfont; ++i) {
|
||||
FcPattern* font = fs->fonts[i];
|
||||
if (FcPatternGetString(font, FC_FILE, 0, &(t->TEXT_FONT_FILE)) == FcResultMatch
|
||||
&& FcPatternGetString(font, FC_FAMILY, 0, &family) == FcResultMatch
|
||||
&& FcPatternGetString(font, FC_STYLE, 0, &style) == FcResultMatch
|
||||
&& strcmp(TEXT_FONT_FAMILY, family) == 0
|
||||
&& strcmp(TEXT_FONT_STYLE, style) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
t->TEXT_FONT = TTF_OpenFont(t->TEXT_FONT_FILE, TEXT_FONT_PTSIZE);
|
||||
FcFontSetDestroy(fs);
|
||||
FcObjectSetDestroy(os);
|
||||
FcPatternDestroy(pat);
|
||||
FcConfigDestroy(config);
|
||||
if (t->TEXT_FONT == NULL) {
|
||||
printf("TTF_OpenFont fail with path '%s'. TTF_Error: %s\n", t->TEXT_FONT_FILE, TTF_GetError());
|
||||
free(t);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
Text_free(Text *t) {
|
||||
TTF_CloseFont(t->TEXT_FONT);
|
||||
free(t);
|
||||
}
|
||||
|
||||
int
|
||||
Text_render(const Text* t, SDL_Renderer *renderer, const char *str, int width, int height) {
|
||||
SDL_Rect textRect = { t->POSX , t->POSY, width, height };
|
||||
|
||||
SDL_Surface *textSurface = TTF_RenderText_Solid(t->TEXT_FONT, str, TEXT_FONT_COLOR);
|
||||
if (textSurface == NULL) {
|
||||
printf("Text rendering failed. TTF_Error: %s\n", TTF_GetError());
|
||||
return 1;
|
||||
}
|
||||
SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
|
||||
if (textTexture == NULL) {
|
||||
printf("Texture rendering failed. SDL_Error: %s\n", SDL_GetError());
|
||||
SDL_FreeSurface(textSurface);
|
||||
return 1;
|
||||
}
|
||||
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
|
||||
|
||||
SDL_FreeSurface(textSurface);
|
||||
SDL_DestroyTexture(textTexture);
|
||||
|
||||
return 0;
|
||||
}
|
22
src/text.h
Normal file
22
src/text.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef TEXT_H
|
||||
#define TEXT_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_ttf.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
||||
static const FcChar8 *TEXT_FONT_FAMILY = "Liberation Mono";
|
||||
static const SDL_Color TEXT_FONT_COLOR = { 255, 255, 255 };
|
||||
|
||||
typedef struct Text {
|
||||
const int POSX;
|
||||
const int POSY;
|
||||
TTF_Font *TEXT_FONT;
|
||||
FcChar8 *TEXT_FONT_FILE;
|
||||
} Text;
|
||||
|
||||
Text* Text_init(int posX, int posY, const FcChar8 *font_style, int font_ptsize);
|
||||
void Text_free(Text* text);
|
||||
int Text_render(const Text* text, SDL_Renderer *renderer, const char *str, int width, int height);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user