summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--20x20.pngbin0 -> 966 bytes
-rw-r--r--DejaVuSans.ttfbin0 -> 348652 bytes
-rw-r--r--Makefile26
-rw-r--r--README.txt10
-rw-r--r--ball.c31
-rw-r--r--ball.h20
-rw-r--r--color.c24
-rw-r--r--color.h15
-rw-r--r--icon.pngbin0 -> 1771 bytes
-rw-r--r--paddle.c170
-rw-r--r--paddle.h20
-rw-r--r--paddle.pngbin0 -> 552 bytes
-rw-r--r--pong.c359
-rw-r--r--pong.h44
-rw-r--r--text.c30
-rw-r--r--text.h16
16 files changed, 765 insertions, 0 deletions
diff --git a/20x20.png b/20x20.png
new file mode 100644
index 0000000..2856981
--- /dev/null
+++ b/20x20.png
Binary files differ
diff --git a/DejaVuSans.ttf b/DejaVuSans.ttf
new file mode 100644
index 0000000..467265e
--- /dev/null
+++ b/DejaVuSans.ttf
Binary files differ
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c6abdc8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+CC=gcc
+STRIP=strip
+WARN=-Wall -W -ansi -pedantic
+CFLAGS=-Os -march=pentium3 -fomit-frame-pointer -pipe ${WARN}
+LDFLAGS=-Wl,-O1,-s
+INCLUDES=`sdl-config --cflags`
+LIBRARIES=`sdl-config --libs` -lSDL_ttf -lSDL_image
+EXT=.exe
+
+EXE=pong${EXT}
+
+OBJS=pong.o color.o text.o ball.o paddle.o
+
+all: ${OBJS}
+ ${CC} ${LDFLAGS} ${OBJS} -o ${EXE} ${LIBRARIES}
+
+clean:
+ rm -f ${OBJS}
+ rm -f ${EXE}
+
+rebuild: clean all
+remake: rebuild
+
+%.o: %.c
+ ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
+ \ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..bb57e9e
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,10 @@
+Building:
+-- Edit Makefile
+ -- "EXT=" controls the output file's extension. This should be .exe on Windows, .app on SkyOS, and blank on Linux.
+
+Controls:
+Left Paddle Up: s
+Left Paddle Down: x
+Right Paddle Up: k
+Right Paddle Down:
+Pause Game: p
diff --git a/ball.c b/ball.c
new file mode 100644
index 0000000..6470f68
--- /dev/null
+++ b/ball.c
@@ -0,0 +1,31 @@
+#include "SDL.h"
+#include "SDL_image.h"
+#include <stdlib.h>
+#include "ball.h"
+
+Ball_t * CreateBall(const char * image) {
+ SDL_Surface * Temp = NULL;
+ Ball_t * newball;
+ newball = malloc(sizeof(Ball_t));
+ Temp = IMG_Load(image);
+ if (!Temp) {
+ fprintf(stderr, "Unable to load image: %s\n", SDL_GetError());
+ exit (-1);
+ }
+ newball->Surface = SDL_DisplayFormatAlpha(Temp);
+ newball->Rect.w = newball->Surface->w;
+ newball->Rect.h = newball->Surface->h;
+ SDL_FreeSurface(Temp);
+ return newball;
+}
+
+void DrawBall(Ball_t * Ball) {
+ SDL_BlitSurface(Ball->Surface, NULL, SDL_GetVideoSurface(), &Ball->Rect);
+ SDL_UpdateRect(SDL_GetVideoSurface(), Ball->Rect.x, Ball->Rect.y, Ball->Rect.w, Ball->Rect.h);
+}
+
+void DeleteBall(Ball_t * Ball) {
+ SDL_FreeSurface(Ball->Surface);
+ free(Ball);
+}
+
diff --git a/ball.h b/ball.h
new file mode 100644
index 0000000..8a97e54
--- /dev/null
+++ b/ball.h
@@ -0,0 +1,20 @@
+#ifndef BALL_H
+#define BALL_H
+
+#include "SDL.h"
+#include "SDL_image.h"
+
+typedef struct {
+ SDL_Surface * Surface;
+ SDL_Rect Rect;
+ Sint8 xv;
+ Sint8 yv;
+ Uint8 absolute;
+ Uint8 counter;
+} Ball_t;
+
+Ball_t * CreateBall(const char * image);
+void DrawBall(Ball_t * Ball);
+void DeleteBall(Ball_t * Ball);
+
+#endif
diff --git a/color.c b/color.c
new file mode 100644
index 0000000..3a3fc88
--- /dev/null
+++ b/color.c
@@ -0,0 +1,24 @@
+#include "SDL.h"
+#include <stdlib.h>
+#include "color.h"
+
+Color_t * CreateColor(Uint8 r, Uint8 g, Uint8 b) {
+ Color_t * newcolor;
+ newcolor = malloc(sizeof(Color_t));
+ newcolor->components.r = r;
+ newcolor->components.g = g;
+ newcolor->components.b = b;
+ newcolor->color = SDL_MapRGB(SDL_GetVideoSurface()->format, r, g, b);
+ return newcolor;
+}
+
+Color_t * CreateColorAlpha(Uint8 r, Uint8 g, Uint8 b, Uint8 a) {
+ Color_t * newcolor;
+ newcolor = malloc(sizeof(Color_t));
+ newcolor->components.r = r;
+ newcolor->components.g = g;
+ newcolor->components.b = b;
+ newcolor->alpha = a;
+ newcolor->color = SDL_MapRGBA(SDL_GetVideoSurface()->format, r, g, b, a);
+ return newcolor;
+}
diff --git a/color.h b/color.h
new file mode 100644
index 0000000..1297d69
--- /dev/null
+++ b/color.h
@@ -0,0 +1,15 @@
+#ifndef COLOR_H
+#define COLOR_H
+
+#include "SDL.h"
+
+typedef struct {
+ Uint32 color;
+ Uint8 alpha;
+ SDL_Color components;
+} Color_t;
+
+Color_t * CreateColor(Uint8 r, Uint8 g, Uint8 b);
+Color_t * CreateColorAlpha(Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+
+#endif
diff --git a/icon.png b/icon.png
new file mode 100644
index 0000000..9acdfd9
--- /dev/null
+++ b/icon.png
Binary files differ
diff --git a/paddle.c b/paddle.c
new file mode 100644
index 0000000..081678b
--- /dev/null
+++ b/paddle.c
@@ -0,0 +1,170 @@
+#include "SDL.h"
+#include "SDL_image.h"
+#include <stdlib.h>
+#include "pong.h"
+#include "paddle.h"
+
+Paddle_t * CreatePaddle(const char * image) {
+ SDL_Surface * Temp = NULL;
+ Paddle_t * newpaddle;
+ newpaddle = malloc(sizeof(Paddle_t));
+ Temp = IMG_Load(image);
+ if (!Temp) {
+ fprintf(stderr, "Unable to load image: %s\n", SDL_GetError());
+ exit (-1);
+ }
+ newpaddle->Score = 0;
+ newpaddle->Surface = SDL_DisplayFormatAlpha(Temp);
+ newpaddle->Paddle.w = newpaddle->Surface->w;
+ newpaddle->Paddle.h = newpaddle->Surface->h;
+ newpaddle->Top.w = newpaddle->Paddle.w;
+ newpaddle->Top.h = 1;
+ newpaddle->Bottom.w = newpaddle->Paddle.w;
+ newpaddle->Bottom.h = 1;
+ SDL_FreeSurface(Temp);
+ return newpaddle;
+}
+
+void DrawPaddle(Paddle_t * Paddle) {
+ SDL_BlitSurface(Paddle->Surface, NULL, SDL_GetVideoSurface(), &Paddle->Paddle);
+ SDL_UpdateRect(SDL_GetVideoSurface(), Paddle->Paddle.x, Paddle->Paddle.y, Paddle->Paddle.w, Paddle->Paddle.h);
+}
+
+void DeletePaddle(Paddle_t * Paddle) {
+ SDL_FreeSurface(Paddle->Surface);
+ free(Paddle);
+}
+
+void MovePaddleUp(Paddle_t * Paddle, SDLKey Key) {
+ if ( Game.keystate[Key] ) {
+ if ( Paddle->Paddle.y != 0 ) {
+ DrawRect(&Paddle->Paddle, black->color);
+ Paddle->Paddle.y -= Game.Speed;
+ if ( Paddle->Paddle.y <= 0 ) {
+ Paddle->Paddle.y = 0;
+ }
+ Paddle->Top.y = Paddle->Paddle.y - 1l;
+ Paddle->Bottom.y = Paddle->Paddle.y + Paddle->Paddle.h + 1;
+ if ( Collide(&Paddle->Top, &Ball->Rect) ) {
+ DrawRect(&Ball->Rect, black->color);
+ Ball->Rect.y = Paddle->Top.y - Ball->Rect.h - 2;
+ if ( Ball->Rect.y <= 0 ) {
+ Paddle->Score++;
+ UpdateScore(P1Score, Paddle->Score);
+ if ( (Left->Score > Game.Score_Limit) && (Left->Score > Right->Score + 1) ) {
+ Game.done = 1;
+ } else {
+ Reset();
+ }
+ }
+ Ball->yv = -Ball->yv;
+ DrawBall(Ball);
+ }
+ DrawPaddle(Paddle);
+ }
+ }
+}
+
+void MovePaddleDown(Paddle_t * Paddle, SDLKey Key) {
+ if ( Game.keystate[Key] ) {
+ if ( Paddle->Paddle.y != Game.height - Paddle->Paddle.h ) {
+ DrawRect(&Paddle->Paddle, black->color);
+ Paddle->Paddle.y += Game.Speed;
+ if ( Paddle->Paddle.y >= Game.height - Paddle->Paddle.h ) {
+ Paddle->Paddle.y = Game.height - Paddle->Paddle.h;
+ }
+ Paddle->Top.y = Paddle->Paddle.y - 1;
+ Paddle->Bottom.y = Paddle->Paddle.y + Paddle->Paddle.h + 1;
+ if ( Collide(&Paddle->Bottom, &Ball->Rect) ) {
+ DrawRect(&Ball->Rect, black->color);
+ Ball->Rect.y = Paddle->Bottom.y + 2;
+ if ( Ball->Rect.y > Game.height - Ball->Rect.h ) {
+ Paddle->Score++;
+ UpdateScore(P1Score, Paddle->Score);
+ if ( (Left->Score > Game.Score_Limit) && (Left->Score > Right->Score + 1) ) {
+ Game.done = 1;
+ } else {
+ Reset();
+ }
+ }
+ Ball->yv = -Ball->yv;
+ DrawBall(Ball);
+ }
+ DrawPaddle(Paddle);
+ }
+ }
+}
+
+ /* if ( Game.keystate[SDLK_j] ) {
+ if ( Right->Paddle.x > Game.width - 70 ) {
+ DrawRect(&Right->Paddle, black->color);
+ Right->Paddle.x -= 2;
+ Right->Bottom.x -= 2;
+ Right->Top.x -= 2;
+ DrawPaddle(Right);
+ if ( Collide(Ball->Rect, Right->Paddle) ) {
+ Ball->yv = 0;
+ Ball->xv = -Ball->xv;
+ if ( Ball->xv > 0 ) {
+ Ball->xv++;
+ } else if ( Ball->xv < 0 ) {
+ Ball->xv--;
+ }
+ }
+ }
+ }
+ if ( Game.keystate[SDLK_l] ) {
+ if ( Right->Paddle.x + Right->Paddle.w < Game.width ) {
+ DrawRect(&Right->Paddle, black->color);
+ Right->Paddle.x += 2;
+ Right->Bottom.x += 2;
+ Right->Top.x += 2;
+ DrawPaddle(Right);
+ if ( Collide(Ball->Rect, Right->Paddle) ) {
+ Ball->yv = 0;
+ Ball->xv = -Ball->xv;
+ if ( Ball->xv > 0 ) {
+ Ball->xv++;
+ } else if ( Ball->xv < 0 ) {
+ Ball->xv--;
+ }
+ }
+ }
+ }
+ if ( Game.keystate[SDLK_a] ) {
+ if ( Left->Paddle.x > 0 ) {
+ DrawRect(&Left->Paddle, black->color);
+ Left->Paddle.x -= 2;
+ Left->Bottom.x -= 2;
+ Left->Top.x -= 2;
+ DrawPaddle(Left);
+ if ( Collide(Ball->Rect, Left->Paddle) ) {
+ Ball->yv = 0;
+ Ball->xv = -Ball->xv;
+ if ( Ball->xv > 0 ) {
+ Ball->xv++;
+ } else if ( Ball->xv < 0 ) {
+ Ball->xv--;
+ }
+ }
+ }
+ }
+ if ( Game.keystate[SDLK_d] ) {
+ if ( Left->Paddle.x + Left->Paddle.w < 70 ) {
+ DrawRect(&Left->Paddle, black->color);
+ Left->Paddle.x += 2;
+ Left->Bottom.x += 2;
+ Left->Top.x += 2;
+ DrawPaddle(Left);
+ if ( Collide(Ball->Rect, Left->Paddle) ) {
+ Ball->yv = 0;
+ Ball->xv = -Ball->xv;
+ if ( Ball->xv > 0 ) {
+ Ball->xv++;
+ } else if ( Ball->xv < 0 ) {
+ Ball->xv--;
+ }
+ }
+ }
+ }*/
+
diff --git a/paddle.h b/paddle.h
new file mode 100644
index 0000000..c963434
--- /dev/null
+++ b/paddle.h
@@ -0,0 +1,20 @@
+#ifndef PADDLE_H
+#define PADDLE_H
+
+#include "SDL.h"
+
+typedef struct {
+ Uint8 Score;
+ SDL_Surface * Surface;
+ SDL_Rect Paddle;
+ SDL_Rect Top;
+ SDL_Rect Bottom;
+} Paddle_t;
+
+Paddle_t * CreatePaddle(const char * image);
+void DrawPaddle(Paddle_t * Paddle);
+void DeletePaddle(Paddle_t * Paddle);
+void MovePaddleUp(Paddle_t * Paddle, SDLKey Key);
+void MovePaddleDown(Paddle_t * Paddle, SDLKey Key);
+
+#endif
diff --git a/paddle.png b/paddle.png
new file mode 100644
index 0000000..9ef4efd
--- /dev/null
+++ b/paddle.png
Binary files differ
diff --git a/pong.c b/pong.c
new file mode 100644
index 0000000..0d77e97
--- /dev/null
+++ b/pong.c
@@ -0,0 +1,359 @@
+#include "SDL.h"
+#include "SDL_image.h"
+#include "SDL_ttf.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+
+#include "pong.h"
+#include "text.h"
+#include "color.h"
+#include "ball.h"
+#include "paddle.h"
+
+TTF_Font * DejaVu = NULL;
+
+int main(int argc, char *argv[]) {
+ SDL_Event Event;
+ SDL_Surface * Surface = NULL;
+ SDL_Surface * Temp = NULL;
+ Game.height = 480; /* Modify Window Height */
+ Game.width = 640; /* Modify Window Width */
+ Game.depth = 0;
+ Game.done = 0;
+ Game.play = 1;
+ Game.Score_Limit = 2;
+ Game.Speed = Game.height / 75; /* Modify Paddle Speeds */
+ Event.type = SDL_NOEVENT;
+
+ if ( argc ) {
+ if ( argv ) {}
+ }
+
+ srand(time(NULL));
+
+ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+ fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
+ exit(-1);
+ }
+ atexit(SDL_Quit);
+ if ( TTF_Init() < 0 ) {
+ fprintf(stderr, "Unable to init SDL_ttf: %s\n", TTF_GetError());
+ exit(-1);
+ }
+ atexit(TTF_Quit);
+
+ DejaVu = TTF_OpenFont(
+#ifdef SKYOS
+ "/boot/system/fonts/DejaVuSans.ttf",
+#else
+ "DejaVuSans.ttf",
+#endif
+ 18);
+ if ( !DejaVu ) {
+ fprintf(stderr, "TTF_OpenFont: %s\n", TTF_GetError());
+ exit(-1);
+ }
+
+ Surface = SDL_SetVideoMode(Game.width, Game.height, Game.depth, SDL_HWSURFACE);
+ if ( !Surface ) {
+ fprintf(stderr, "Unable to create main surface: %s\n", SDL_GetError());
+ exit(-1);
+ }
+
+ black = CreateColor(0, 0, 0);
+ white = CreateColor(255, 255, 255);
+
+ Temp = IMG_Load("icon.png");
+ if ( !Temp ) {
+ fprintf(stderr, "%s\n", SDL_GetError());
+ exit (-1);
+ }
+ SDL_SetColorKey(Temp, SDL_SRCCOLORKEY, black->color);
+ SDL_WM_SetIcon(Temp, NULL);
+ SDL_FreeSurface(Temp);
+ SDL_WM_SetCaption("SDL Pong", "SDL Pong");
+ SDL_ShowCursor(SDL_DISABLE);
+
+ Ball = CreateBall("20x20.png");
+ Left = CreatePaddle("paddle.png");
+ Right = CreatePaddle("paddle.png");
+
+ Start = CreateText(DejaVu, "Press Space to start.", &white->components);
+ Again = CreateText(DejaVu, "Play Again? [y/n]", &white->components);
+ Player = CreateText(DejaVu, "Player ", &white->components);
+ P1Score = CreateText(DejaVu, "0", &white->components);
+ P2Score = CreateText(DejaVu, "0", &white->components);
+ Wins = CreateText(DejaVu, " Wins!", &white->components);
+ One = CreateText(DejaVu, "1", &white->components);
+ Two = CreateText(DejaVu, "2", &white->components);
+
+ Start->Rect.x = (Game.width / 2) - (Start->Rect.w / 2);
+ Start->Rect.y = (Game.height / 2) + 200;
+ Again->Rect.x = (Game.width / 2) - (Again->Rect.w / 2);
+ Again->Rect.y = (Game.height / 2) - (Again->Rect.h / 2);
+ Player->Rect.x = (Game.width / 2) - (Wins->Rect.w / 2) - (Player->Rect.w / 2);
+ Player->Rect.y = (Game.height / 2) - 100;
+ One->Rect.x = Player->Rect.x + Player->Rect.w;
+ One->Rect.y = Player->Rect.y;
+ Two->Rect.x = Player->Rect.x + Player->Rect.w;
+ Two->Rect.y = Player->Rect.y;
+ Wins->Rect.x = Two->Rect.x + Two->Rect.w;
+ Wins->Rect.y = Player->Rect.y;
+ P1Score->Rect.w = P1Score->Surface->w;
+ P1Score->Rect.h = P1Score->Surface->h;
+ P1Score->Rect.x = 70;
+ P1Score->Rect.y = 1;
+ P2Score->Rect.w = P2Score->Surface->w;
+ P2Score->Rect.h = P2Score->Surface->h;
+ P2Score->Rect.x = Game.width - P2Score->Rect.w - 70;
+ P2Score->Rect.y = 1;
+
+ Left->Paddle.x = 25;
+ Left->Top.x = Left->Paddle.x;
+ Left->Bottom.x = Left->Paddle.x;
+ Right->Paddle.x = Game.width - Right->Paddle.w - 25;
+ Right->Top.x = Right->Paddle.x;
+ Right->Bottom.x = Right->Paddle.x;
+ /* Set Y values to prevent DrawRect from screwing us over
+ * Padding SDL_Rects with NULL y values with throw mess up the h value
+ */
+ Left->Paddle.y = 0;
+ Right->Paddle.y = 0;
+
+ while ( Game.play == 1 ) {
+ SDL_BlitSurface(Start->Surface, NULL, Surface, &Start->Rect);
+ SDL_UpdateRect(Surface, Start->Rect.x, Start->Rect.y, Start->Rect.w, Start->Rect.h);
+ UpdateScore(P1Score, Left->Score);
+ UpdateScore(P2Score, Right->Score);
+ Reset();
+
+ for (;;) {
+ if ( Event.type == SDL_QUIT ) {
+ goto cleanup;
+ }
+ if ( SDL_PollEvent(&Event) != 0 ) {
+ if ( Event.type == SDL_KEYDOWN ) {
+ if ( Event.key.keysym.sym == SDLK_SPACE ) {
+ DrawRect(&Start->Rect, black->color);
+ break;
+ } else if ( Event.key.keysym.sym == SDLK_ESCAPE ) {
+ goto cleanup;
+ }
+ }
+ }
+ SDL_Delay(10);
+ }
+
+ while ( Game.done == 0 ) {
+ if ( SDL_PollEvent(&Event) != 0 ) {
+ if ( Event.type == SDL_QUIT ) {
+ goto cleanup;
+ }
+ if ( Event.type == SDL_KEYDOWN ) {
+ if ( Event.key.keysym.sym == SDLK_ESCAPE ) {
+ goto cleanup;
+ }
+ if ( Event.key.keysym.sym == SDLK_p ) {
+ for (;;) {
+ if ( SDL_PollEvent(&Event) != 0 ) {
+ if ( Event.type == SDL_QUIT ) {
+ goto cleanup;
+ }
+ if ( Event.type == SDL_KEYDOWN ) {
+ if ( Event.key.keysym.sym == SDLK_ESCAPE ) {
+ goto cleanup;
+ }
+ if ( Event.key.keysym.sym == SDLK_p ) {
+ break;
+ }
+ }
+ }
+ SDL_Delay(10);
+ }
+ }
+ }
+ }
+ Game.keystate = SDL_GetKeyState(NULL);
+ MovePaddleUp(Right, SDLK_k);
+ MovePaddleDown(Right, SDLK_m);
+ MovePaddleUp(Left, SDLK_s);
+ MovePaddleDown(Left, SDLK_x);
+
+ if ( Ball->Rect.x <= 0 ) {
+ Right->Score++;
+ UpdateScore(P2Score, Right->Score);
+ if ( (Right->Score > Game.Score_Limit) && ( Right->Score > Left->Score + 1) ) {
+ Game.done = 1;
+ } else {
+ Reset();
+ }
+ } else if ( Ball->Rect.x >= (Game.width - Ball->Rect.w) ) {
+ Left->Score++;
+ UpdateScore(P1Score, Left->Score);
+ if ( (Left->Score > Game.Score_Limit) && (Left->Score > Right->Score + 1) ) {
+ Game.done = 1;
+ } else {
+ Reset();
+ }
+ }
+
+ DrawRect(&Ball->Rect, black->color);
+ Ball->absolute = abs(Ball->xv);
+ for (Ball->counter = 0; Ball->counter < Ball->absolute; Ball->counter++) {
+ if ( Collide(&Right->Paddle, &Ball->Rect) ) {
+ DrawRect(&Right->Paddle, black->color);
+ DrawPaddle(Right);
+ if ( Ball->Rect.y < Right->Paddle.y + (Right->Paddle.h / 4) ){
+ Ball->yv -= 1;
+ } else if ( Ball->Rect.y > Right->Paddle.y + Right->Paddle.h - (Right->Paddle.h / 4) ) {
+ Ball->yv += 1;
+ }
+ Ball->xv = -Ball->xv;
+ } else if ( Collide(&Left->Paddle, &Ball->Rect) ) {
+ DrawRect(&Left->Paddle, black->color);
+ DrawPaddle(Left);
+ if ( Ball->Rect.y < Left->Paddle.y + (Left->Paddle.h / 4) ){
+ Ball->yv -= 1;
+ } else if ( Ball->Rect.y > Left->Paddle.y + Left->Paddle.h - (Left->Paddle.h / 4) ) {
+ Ball->yv += 1;
+ }
+ Ball->xv = -Ball->xv;
+ }
+ if ( Collide(&P1Score->Rect, &Ball->Rect) ) {
+ UpdateScore(P1Score, Left->Score);
+ } else if ( Collide(&P2Score->Rect, &Ball->Rect) ) {
+ UpdateScore(P2Score, Right->Score);
+ }
+ Ball->Rect.x += Ball->xv;
+ }
+ Ball->absolute = abs(Ball->yv);
+ for (Ball->counter = 0; Ball->counter < Ball->absolute; Ball->counter++) {
+ if ( ( Collide(&Left->Top, &Ball->Rect)
+ || Collide(&Right->Top, &Ball->Rect) )
+ && Ball->yv > 0 ) {
+ Ball->yv = -Ball->yv;
+ } else if ( ( Collide(&Left->Bottom, &Ball->Rect)
+ || Collide(&Right->Bottom, &Ball->Rect) )
+ && Ball->yv < 0 ) {
+ Ball->yv = -Ball->yv;
+ }
+ if ( Ball->Rect.y <= 0 ) {
+ Ball->yv = -Ball->yv;
+ Ball->Rect.y = 0;
+ } else if ( Ball->Rect.y >= Game.height - Ball->Rect.h ) {
+ Ball->yv = -Ball->yv;
+ Ball->Rect.y = Game.height - Ball->Rect.h;
+ }
+ Ball->Rect.y += Ball->yv;
+ }
+ SDL_BlitSurface(Ball->Surface, NULL, Surface, &Ball->Rect);
+ SDL_UpdateRect(Surface, Ball->Rect.x, Ball->Rect.y, Ball->Rect.w, Ball->Rect.h);
+ SDL_Delay(10);
+
+ if ( Game.done == 1 ) {
+ DrawRect(&Ball->Rect, black->color);
+ DrawRect(&Left->Paddle, black->color);
+
+ DrawRect(&Right->Paddle, black->color);
+ SDL_BlitSurface(Again->Surface, NULL, Surface, &Again->Rect);
+ SDL_BlitSurface(Player->Surface, NULL, Surface, &Player->Rect);
+ if ( Left->Score > Right->Score ) {
+ SDL_BlitSurface(One->Surface, NULL, Surface, &One->Rect);
+ } else {
+ SDL_BlitSurface(Two->Surface, NULL, Surface, &Two->Rect);
+ }
+ SDL_BlitSurface(Wins->Surface, NULL, Surface, &Wins->Rect);
+ SDL_UpdateRect(Surface, Again->Rect.x, Again->Rect.y, Again->Rect.w, Again->Rect.h);
+ SDL_UpdateRect(Surface, Player->Rect.x, Player->Rect.y, Player->Rect.w + Two->Rect.w + Wins->Rect.w, Player->Rect.h);
+
+ for (;;) {
+ if ( SDL_PollEvent(&Event) != 0 ) {
+ if ( Event.type == SDL_QUIT ) {
+ goto cleanup;
+ }
+ if ( Event.type == SDL_KEYDOWN ) {
+ if ( (Event.key.keysym.sym == SDLK_n) || (Event.key.keysym.sym == SDLK_ESCAPE) ) {
+ goto cleanup;
+ } else if ( Event.key.keysym.sym == SDLK_y ) {
+ Game.done = 0;
+ Left->Score = 0;
+ Right->Score = 0;
+ DrawRect(&Again->Rect, black->color);
+ SDL_FillRect(Surface, &Player->Rect, black->color);
+ SDL_FillRect(Surface, &Two->Rect, black->color);
+ SDL_FillRect(Surface, &Wins->Rect, black->color);
+ SDL_UpdateRect(Surface, Player->Rect.x, Player->Rect.y, Player->Rect.w + Two->Rect.w + Wins->Rect.w, Player->Rect.h);
+ UpdateScore(P1Score, Left->Score);
+ UpdateScore(P2Score, Right->Score);
+ Reset();
+ break;
+ }
+ }
+ }
+ SDL_Delay(10);
+ }
+ }
+ }
+ }
+cleanup:
+ free(black);
+ free(white);
+ DeleteBall(Ball);
+ DeletePaddle(Right);
+ DeletePaddle(Left);
+ DeleteText(Start);
+ DeleteText(Again);
+ DeleteText(Player);
+ DeleteText(Wins);
+ DeleteText(P1Score);
+ DeleteText(P2Score);
+ DeleteText(One);
+ DeleteText(Two);
+ return 0;
+}
+
+void Reset() {
+ DrawRect(&Ball->Rect, black->color);
+ DrawRect(&Left->Paddle, black->color);
+ DrawRect(&Right->Paddle, black->color);
+ Left->Paddle.y = (Game.height / 2) - (Left->Paddle.h / 2);
+ Left->Top.y = Left->Paddle.y - 1;
+ Left->Bottom.y = Left->Paddle.y + Left->Paddle.h + 1;
+ Right->Paddle.y = (Game.height / 2) - (Right->Paddle.h / 2);
+ Right->Top.y = Right->Paddle.y - 1;
+ Right->Bottom.y = Right->Paddle.y + Right->Paddle.h + 1;
+ Ball->Rect.x = (Game.width / 2) - (Ball->Rect.w / 2);
+ Ball->Rect.y = 1;
+ Ball->xv = (rand() % 2) ? 2 : -2;
+ Ball->yv = (rand() % 2) ? 2 : -2;
+ DrawBall(Ball);
+ DrawPaddle(Left);
+ DrawPaddle(Right);
+ SDL_Delay(500);
+}
+
+void DrawRect(SDL_Rect * rect, Uint32 color) {
+ SDL_FillRect(SDL_GetVideoSurface(), rect, color);
+ SDL_UpdateRect(SDL_GetVideoSurface(), rect->x, rect->y, rect->w, rect->h);
+}
+
+void UpdateScore(Text_t * Text, Uint8 score) {
+ char buffer[4];
+ DrawRect(&Text->Rect, black->color);
+ sprintf(buffer, "%u", score);
+ UpdateText(Text, DejaVu, buffer, &white->components);
+ Text->Rect.w = Text->Surface->w;
+ Text->Rect.h = Text->Surface->h;
+ SDL_BlitSurface(Text->Surface, NULL, SDL_GetVideoSurface(), &Text->Rect);
+ SDL_UpdateRect(SDL_GetVideoSurface(), Text->Rect.x, Text->Rect.y, Text->Rect.w, Text->Rect.h);
+}
+
+int Collide(SDL_Rect * a, SDL_Rect * b) {
+ if ( b->x + b->w < a->x ) return 0;
+ if ( b->x > a->x + a->w ) return 0;
+ if ( b->y + b->h < a->y ) return 0;
+ if ( b->y > a->y + a->h ) return 0;
+ return 1;
+}
diff --git a/pong.h b/pong.h
new file mode 100644
index 0000000..cc381bc
--- /dev/null
+++ b/pong.h
@@ -0,0 +1,44 @@
+
+#ifndef PONG_H
+#define PONG_H
+
+#include "SDL.h"
+
+#include "text.h"
+#include "paddle.h"
+#include "ball.h"
+#include "color.h"
+
+void Reset();
+void DrawRect(SDL_Rect * rect, Uint32 color);
+void UpdateScore(Text_t * Text, Uint8 score);
+int Collide(SDL_Rect * a, SDL_Rect * b);
+
+Color_t * white;
+Color_t * black;
+Ball_t * Ball;
+Paddle_t * Left;
+Paddle_t * Right;
+
+struct Game {
+ Uint16 height;
+ Uint16 width;
+ Uint8 depth;
+ Uint8 Speed;
+ Uint8 Score_Limit;
+ Sint8 done;
+ Sint8 play;
+ Uint8 * keystate;
+ Uint8 counter;
+} Game;
+
+Text_t * Start;
+Text_t * Again;
+Text_t * Player;
+Text_t * Wins;
+Text_t * P1Score;
+Text_t * P2Score;
+Text_t * One;
+Text_t * Two;
+
+#endif
diff --git a/text.c b/text.c
new file mode 100644
index 0000000..f221f3d
--- /dev/null
+++ b/text.c
@@ -0,0 +1,30 @@
+#include "SDL.h"
+#include "SDL_ttf.h"
+#include <stdlib.h>
+#include "text.h"
+
+Text_t * CreateText(TTF_Font * Font, const char * text, SDL_Color * components) {
+ Text_t * newtext;
+ newtext = malloc(sizeof(Text_t));
+ newtext->Surface = NULL;
+ UpdateText(newtext, Font, text, components);
+ return newtext;
+}
+
+void UpdateText(Text_t * tobeupdated, TTF_Font * Font, const char * text, SDL_Color * components) {
+ SDL_Surface * Temp = NULL;
+ Temp = TTF_RenderText_Blended(Font, text, *components);
+ if (tobeupdated->Surface) {
+ SDL_FreeSurface(tobeupdated->Surface);
+ }
+ tobeupdated->Surface = SDL_DisplayFormatAlpha(Temp);
+ SDL_FreeSurface(Temp);
+ tobeupdated->Rect.w = tobeupdated->Surface->w;
+ tobeupdated->Rect.h = tobeupdated->Surface->h;
+}
+
+void DeleteText(Text_t * Text) {
+ SDL_FreeSurface(Text->Surface);
+ free(Text);
+}
+
diff --git a/text.h b/text.h
new file mode 100644
index 0000000..f4f7b55
--- /dev/null
+++ b/text.h
@@ -0,0 +1,16 @@
+#include "SDL.h"
+#include "SDL_ttf.h"
+
+#ifndef TEXT_H
+#define TEXT_H
+
+typedef struct {
+ SDL_Surface * Surface;
+ SDL_Rect Rect;
+} Text_t;
+
+Text_t * CreateText(TTF_Font * Font, const char * text, SDL_Color * components);
+void UpdateText(Text_t * tobeupdated, TTF_Font * Font, const char * text, SDL_Color * components);
+void DeleteText(Text_t * Text);
+
+#endif