From d680d25c6a10678f0c999ade1041e363b0df7e91 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Thu, 3 Aug 2006 22:55:17 +0000 Subject: Code Import git-svn-id: svn://mattst88.com/svn/glpong/trunk@2 449aeecc-241a-0410-943f-e2f883e2d7a2 --- Makefile | 26 ++++++ ball.c | 51 ++++++++++++ ball.h | 19 +++++ ball.png | Bin 0 -> 1771 bytes glpong.c | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ glpong.h | 30 +++++++ paddle.c | 23 ++++++ paddle.h | 14 ++++ 8 files changed, 439 insertions(+) create mode 100644 Makefile create mode 100644 ball.c create mode 100644 ball.h create mode 100644 ball.png create mode 100644 glpong.c create mode 100644 glpong.h create mode 100644 paddle.c create mode 100644 paddle.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..de596c5 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +CC=gcc +STRIP=strip +WARN=-Wall -W -ansi -pedantic +CFLAGS=-Os -pipe -std=c99 ${WARN} +LDFLAGS=-Wl,-O1,-s +INCLUDES=`sdl-config --cflags` +LIBRARIES=`sdl-config --libs` -lSDL_image -lGL +EXT=.exe + +EXE=glpong${EXT} + +OBJS=glpong.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/ball.c b/ball.c new file mode 100644 index 0000000..5728e9f --- /dev/null +++ b/ball.c @@ -0,0 +1,51 @@ +#include + +#include "SDL.h" +#include "SDL_opengl.h" + +#include "glpong.h" +#include "ball.h" + +void GLPong_BallAdd() { + Uint8 i; + int added = 0; + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) { + if (GLPong.Balls[i] == NULL) { + GLPong.Balls[i] = malloc(sizeof(Ball_t)); + added = 1; + break; + } + } + + if (added) { + GLPong.Balls[i]->w = GLPong.w / (GLfloat)40; + GLPong.Balls[i]->h = GLPong.h / (GLfloat)30; + GLPong.Balls[i]->x = 40.0f; + GLPong.Balls[i]->y = 40.0f; + GLPong.Balls[i]->r = (float)rand() / RAND_MAX; + GLPong.Balls[i]->g = (float)rand() / RAND_MAX; + GLPong.Balls[i]->b = (float)rand() / RAND_MAX; + GLPong.Balls[i]->a = SDL_ALPHA_OPAQUE; + GLPong.Balls[i]->xv = GLPong.w / (GLfloat)320; + GLPong.Balls[i]->yv = GLPong.h / (GLfloat)240; + } +} + +void GLPong_BallDelete() { + Uint8 i; + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i--) { + if (GLPong.Balls[i] != NULL) { + free(GLPong.Balls[i]); + GLPong.Balls[i] = NULL; + break; + } + } +} + +int GLPong_BallCollide(const Ball_t * a, const Ball_t * 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/ball.h b/ball.h new file mode 100644 index 0000000..6707ebb --- /dev/null +++ b/ball.h @@ -0,0 +1,19 @@ +#ifndef BALL_H +#define BALL_H + +#include "SDL.h" +#include "SDL_opengl.h" + +GLuint ball_texture; + +typedef struct { + GLfloat w, h, x, y; + GLfloat r, g, b, a; + GLfloat xv, yv; +} Ball_t; + +void GLPong_BallAdd(); +void GLPong_BallDelete(); +int GLPong_BallCollide(const Ball_t * a, const Ball_t * b); + +#endif diff --git a/ball.png b/ball.png new file mode 100644 index 0000000..9acdfd9 Binary files /dev/null and b/ball.png differ diff --git a/glpong.c b/glpong.c new file mode 100644 index 0000000..6779a79 --- /dev/null +++ b/glpong.c @@ -0,0 +1,276 @@ +#include +#include +#include + +#include "SDL.h" +#include "SDL_opengl.h" +#include "SDL_image.h" + +#include "glpong.h" + +int main(int argc, char * argv[]) { + if (argc) { + if (argv) {} + } + + GLPong_Init(); + + GLPong_PaddlesCreate(); + + GLPong_BallAdd(); + + while ( !GLPong.done ) { + GLPong_HandleEvents(); + GLPong_Move(); + GLPong_Draw(); + SDL_Delay(10); + } + GLPong_CleanUp(); + + return 0; +} + +void GLPong_Init() { + SDL_Surface * temp = NULL; + Uint8 i; + GLPong.done = 0; + + GLPong.w = 800; + GLPong.h = 600; + + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) { + GLPong.Balls[i] = NULL; + } + + srand(time(NULL)); + + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); + atexit(SDL_Quit); + + SDL_WM_SetCaption("glPong", "glPong"); + temp = IMG_Load("ball.png"); + SDL_WM_SetIcon(temp, NULL); + SDL_ShowCursor(SDL_DISABLE); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + GLPong.Surface = SDL_SetVideoMode(GLPong.w, GLPong.h, 32, SDL_OPENGL); + glViewport(0, 0, GLPong.w, GLPong.h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0.0f, GLPong.w, GLPong.h, 0.0f, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glShadeModel(GL_SMOOTH); + glClearDepth(2.0f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + GLPong.Event.type = SDL_NOEVENT; + + printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR)); + printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER)); + printf("OpenGL Version: %s\n", glGetString(GL_VERSION)); + printf("OpenGL Extensions: %s\n", glGetString(GL_EXTENSIONS)); + + ball_texture = SDL_GL_SurfaceToTexture(temp); + SDL_FreeSurface(temp); +} + +void GLPong_HandleEvents() { + if (SDL_PollEvent(&GLPong.Event) != 0) { + if (GLPong.Event.type == SDL_QUIT) { + GLPong.done = 1; + return; + } + if (GLPong.Event.type == SDL_KEYDOWN) { + if (GLPong.Event.key.keysym.sym == SDLK_ESCAPE) { + GLPong.done = 1; + return; + } else if (GLPong.Event.key.keysym.sym == SDLK_SPACE) { + GLPong_BallAdd(); + } else if (GLPong.Event.key.keysym.sym == SDLK_p) { + for (;;) { + SDL_Delay(10); + if (SDL_PollEvent(&GLPong.Event) != 0) { + if (GLPong.Event.type == SDL_QUIT) { + GLPong.done = 1; + return; + } else if (GLPong.Event.type == SDL_KEYDOWN){ + if (GLPong.Event.key.keysym.sym == SDLK_ESCAPE) { + GLPong.done = 1; + return; + } else if (GLPong.Event.key.keysym.sym == SDLK_p) { + break; + } + } + } + } + } + } + } +} + +void GLPong_Draw() { + Uint8 i; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, ball_texture); + glEnable(GL_TEXTURE_2D); + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) { + if (GLPong.Balls[i] != NULL) { + glLoadIdentity(); + glTranslatef(GLPong.Balls[i]->x, GLPong.Balls[i]->y, 0); + glColor4f(GLPong.Balls[i]->r, GLPong.Balls[i]->g, GLPong.Balls[i]->b, GLPong.Balls[i]->a); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 1.0f); glVertex2f(GLPong.Balls[i]->w, GLPong.Balls[i]->h); /* Lower Left */ + glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, GLPong.Balls[i]->h); /* Lower Right */ + glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 0.0f); /* Upper Right */ + glTexCoord2f(0.0f, 0.0f); glVertex2f(GLPong.Balls[i]->w, 0.0f); /* Upper Left */ + glEnd(); + } + } + glDisable(GL_TEXTURE_2D); + + SDL_GL_SwapBuffers(); +} + +void GLPong_CleanUp() { + Uint8 i; + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) { + if (GLPong.Balls[i] != NULL) { + free(GLPong.Balls[i]); + GLPong.Balls[i] = NULL; + } + } +} + +void GLPong_Move() { + Uint8 i; + Uint8 j; + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) { + if (GLPong.Balls[i] != NULL) { + GLPong.Balls[i]->x += GLPong.Balls[i]->xv; + GLPong.Balls[i]->y += GLPong.Balls[i]->yv; + if ( GLPong.Balls[i]->y > (GLPong.h - GLPong.Balls[i]->h) || GLPong.Balls[i]->y < 0.0f ) { + GLPong.Balls[i]->yv = -GLPong.Balls[i]->yv; + } + if ( GLPong.Balls[i]->x > (GLPong.w - GLPong.Balls[i]->w) || GLPong.Balls[i]->x < 0.0f ) { + GLPong.Balls[i]->xv = -GLPong.Balls[i]->xv; + } + } + } + /*if (GLPong.Balls[1] != NULL) { + if (GLPong_BallCollide(GLPong.Balls[0], GLPong.Balls[1])) { + GLPong.Balls[0]->xv = -GLPong.Balls[0]->xv; + GLPong.Balls[0]->yv = -GLPong.Balls[0]->yv; + GLPong.Balls[1]->xv = -GLPong.Balls[1]->xv; + GLPong.Balls[1]->yv = -GLPong.Balls[1]->yv; + } + }*/ + + /* + for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *) - 1; i++) { + if (GLPong.Balls[i] != NULL) { + for (j = i + i; j < sizeof(GLPong.Balls) / sizeof(void *); j++) { + if (j != i && GLPong.Balls[j] != NULL) { + if (GLPong_BallCollide(GLPong.Balls[i], GLPong.Balls[j])) { + printf("%d - %d\n", i, j); + GLPong.Balls[i]->xv *= -1; + GLPong.Balls[i]->yv *= -1; + GLPong.Balls[j]->xv *= -1; + GLPong.Balls[j]->yv *= -1; + } + } + } + } + }*/ + /*for (i = 0; i < sizeof(GLPong.Balls) / sizeof(void *); i++) { + if (GLPong.Balls[i] != NULL) { + for (j = 0; j < sizeof(GLPong.Balls) / sizeof(void *); i++) { + if (GLPong.Balls[j] != NULL && i != j) { + if (GLPong_BallCollide(GLPong.Balls[i], GLPong.Balls[j])) { + GLPong.Balls[i]->xv *= -1; + GLPong.Balls[i]->yv *= -1; + } + } + } + } + }*/ +} + +GLuint SDL_GL_SurfaceToTexture(SDL_Surface * surface) { + Uint32 rmask, gmask, bmask, amask; + SDL_Surface * temp = NULL; + SDL_Surface * tempalpha = NULL; + GLuint texture; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + tempalpha = SDL_DisplayFormatAlpha(surface); + SDL_SetAlpha(tempalpha, 0, SDL_ALPHA_TRANSPARENT); + temp = SDL_CreateRGBSurface(SDL_SWSURFACE, surface->w, surface->h, 32, bmask, gmask, rmask, amask); + SDL_FreeSurface(surface); + SDL_BlitSurface(tempalpha, NULL, temp, NULL); + + SDL_FreeSurface(tempalpha); + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + SDL_LockSurface(temp); + glTexImage2D(GL_TEXTURE_2D, 0, 4, temp->w, temp->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, temp->pixels); + SDL_UnlockSurface(temp); + SDL_FreeSurface(temp); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + return texture; +} + +GLuint SDL_GL_NPOTSurfaceToTexture(SDL_Surface * surface, GLfloat * wratio, GLfloat * hratio) { + SDL_Surface * pow2 = NULL; + unsigned int w = NextPow2(surface->w); + unsigned int h = NextPow2(surface->h); + if (wratio) { + *wratio = (GLfloat)surface->w / (GLfloat)h; + } + if (hratio) { + *hratio = (GLfloat)surface->h/(GLfloat)h; + } + + pow2 = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask); + SDL_BlitSurface(surface, NULL, pow2, NULL); + SDL_FreeSurface(surface); + + return SDL_GL_SurfaceToTexture(pow2); +} + +__inline__ unsigned int NextPow2(unsigned int value) { + unsigned int x; + __asm("dec %1\n\t" + "movl $2,%0\n\t" + "bsr %1,%1\n\t" + "shl %b1,%0\n\t" + : "=r" (x) + : "c" (value) + ); + return x; +} diff --git a/glpong.h b/glpong.h new file mode 100644 index 0000000..d48b3fe --- /dev/null +++ b/glpong.h @@ -0,0 +1,30 @@ +#ifndef GLPONG_H +#define GLPONG_H + +#include "SDL.h" +#include "SDL_opengl.h" + +#include "ball.h" +#include "paddle.h" + +struct { + SDL_Event Event; + SDL_Surface * Surface; + Ball_t * Balls[4]; + Paddle_t Left, Right; + Uint16 w; + Uint16 h; + Uint16 done; +} GLPong; + +void GLPong_Init(); +void GLPong_HandleEvents(); +void GLPong_Draw(); +void GLPong_CleanUp(); +void GLPong_Move(); + +GLuint SDL_GL_SurfaceToTexture(SDL_Surface * surface); +GLuint SDL_GL_NPOTSurfaceToTexture(SDL_Surface * surface, GLfloat * wratio, GLfloat * hratio); +__inline__ unsigned int NextPow2(unsigned int value); + +#endif diff --git a/paddle.c b/paddle.c new file mode 100644 index 0000000..be1ba87 --- /dev/null +++ b/paddle.c @@ -0,0 +1,23 @@ +#include + +#include "SDL.h" +#include "SDL_opengl.h" + +#include "paddle.h" +#include "glpong.h" +#include "ball.h" + +void GLPong_PaddlesCreate() { + GLPong.Left.w = 8; + GLPong.Left.h = 64; + GLPong.Left.x = 0; + GLPong.Left.y = (GLPong.h / 2) - (GLPong.h / 2); + GLPong.Left.r = 1.0; + GLPong.Left.g = 1.0; + GLPong.Left.b = 1.0; + GLPong.Left.a = 0.0; + GLPong.Left.Top.w = GLPong.Left.w; + GLPong.Left.Top.h = 1; + GLPong.Left.Top.x = GLPong.Left.x; + GLPong.Left.Top.y = GLPong.Left.y - 1; +} diff --git a/paddle.h b/paddle.h new file mode 100644 index 0000000..6ec3893 --- /dev/null +++ b/paddle.h @@ -0,0 +1,14 @@ +#ifndef PADDLE_H +#define PADDLE_H + +typedef struct { + GLfloat w, h, x, y; + GLfloat r, g, b, a; + struct { + GLfloat w, h, x, y; + } Top, Bottom; +} Paddle_t; + +void GLPong_PaddlesCreate(); + +#endif -- cgit v1.2.3