[Armadeus-commitlog] SF.net SVN: armadeus: [556] trunk/target/demos/armanoid
Brought to you by:
sszy
|
From: <ar...@us...> - 2007-01-27 15:47:14
|
Revision: 556
http://armadeus.svn.sourceforge.net/armadeus/?rev=556&view=rev
Author: artemys
Date: 2007-01-27 07:47:09 -0800 (Sat, 27 Jan 2007)
Log Message:
-----------
[DEMOS] First working version (with sound) of Armanoid game (SDL Demonstration)
This game will be used in the article for Linux Magazine France
Modified Paths:
--------------
trunk/target/demos/armanoid/Makefile
trunk/target/demos/armanoid/armanoid.c
trunk/target/demos/armanoid/bar.bmp
Added Paths:
-----------
trunk/target/demos/armanoid/buzzer.c
trunk/target/demos/armanoid/buzzer.h
trunk/target/demos/armanoid/collide.c
trunk/target/demos/armanoid/collide.h
Modified: trunk/target/demos/armanoid/Makefile
===================================================================
--- trunk/target/demos/armanoid/Makefile 2007-01-26 13:49:18 UTC (rev 555)
+++ trunk/target/demos/armanoid/Makefile 2007-01-27 15:47:09 UTC (rev 556)
@@ -1,24 +1,46 @@
+ifeq ($(TARGET),arm)
INCLUDE_PATH="../../../buildroot/build_arm_nofpu/SDL-1.2.9/include/"
LIBRARY_PATH="../../../buildroot/build_arm_nofpu/root/usr/lib/"
INSTALL_DIR="../../../buildroot/build_arm_nofpu/root/usr/bin/"
+CC=arm-linux-gcc
+DEFINES=TARGET
+else
+INCLUDE_PATH="/usr/include/SDL"
+LIBRARY_PATH="/usr/lib/"
+INSTALL_DIR="."
+CC=gcc
+DEFINES=HOST
+endif
+CFLAGS="-g"
+
default: armanoid
-all: armanoid armanoidpc
+all: armanoid
-armanoid: armanoid.c
- arm-linux-g++ -I$(INCLUDE_PATH) -L$(LIBRARY_PATH) -o $@ $^ -lSDL
-armanoidpc: armanoid.c
- g++ -I/usr/include/SDL -o $@ $^ -lSDL
+armanoid.o: armanoid.c
+ $(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $^
+collide.o: collide.c
+ $(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $^
+
+#timer.o: timer.cpp
+# $(CC) -I$(INCLUDE_PATH) $(CFLAGS) -c -o $@ $^
+
+buzzer.o: buzzer.c
+ $(CC) -I$(INCLUDE_PATH) $(CFLAGS) -D$(DEFINES) -c -o $@ $^
+
+armanoid: armanoid.o collide.o buzzer.o
+ $(CC) -I$(INCLUDE_PATH) -L$(LIBRARY_PATH) -o $@ $^ -lSDL
+
install: armanoid
- cp armanoid $INSTALL_DIR
- cp ball.bmp $INSTALL_DIR
+ cp armanoid $INSTALL_DIR
+ cp ball.bmp $INSTALL_DIR
cp block.bmp $INSTALL_DIR
- cp bar.bmp $INSTALL_DIR
+ cp bar.bmp $INSTALL_DIR
clean:
- rm -rf armanoid armanoidpc
- rm -rf *.o
\ No newline at end of file
+ rm -rf armanoid
+ rm -rf *.o
Modified: trunk/target/demos/armanoid/armanoid.c
===================================================================
--- trunk/target/demos/armanoid/armanoid.c 2007-01-26 13:49:18 UTC (rev 555)
+++ trunk/target/demos/armanoid/armanoid.c 2007-01-27 15:47:09 UTC (rev 556)
@@ -1,3 +1,23 @@
+/*
+ *
+ * Small game to demonstrate how to use (or not use ;-) ) SDL library
+ * for the Armadeus project. www.armadeus.og
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // for sleep()
@@ -3,11 +23,26 @@
#include "SDL.h"
+// For collision detection:
+#include "collide.h"
+// For timer handling (g++ only)
+//#include "timer.h"
+// To play sound:
+#include "buzzer.h"
+
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
+#ifdef DEBUG
+#define debug( args...) printf( ## args )
+#else
+#define debug( args...) do {;} while(0);
+#endif
+
+#define bool unsigned int
+#define false 0
+#define true 1
+
SDL_Surface *back;
-//SDL_Surface *image;
-SDL_Surface* bar;
SDL_Surface* block;
SDL_Surface *screen;
@@ -30,12 +65,13 @@
};
static struct sprite ball;
-//int xpos=0,ypos=0;
-int barxpos=SCREEN_WIDTH/2, barypos= SCREEN_HEIGHT-32;
+static struct sprite bar;
+
+static bool ball_isfree = false;
int remainingBlocks = 0;
-#define BLOCK_HORI_SIZE 32
-#define BLOCK_VERT_SIZE 24
+static int BLOCK_HORI_SIZE = 32;
+static int BLOCK_VERT_SIZE = 24;
#define BLOCK_SPACING 4
#define YOFFUP 24
@@ -44,19 +80,46 @@
#define MAX_HORI_BLOCKS ((SCREEN_WIDTH-XOFF*2)/(BLOCK_HORI_SIZE+BLOCK_SPACING))
#define MAX_VERT_BLOCKS ((SCREEN_HEIGHT-YOFFUP*2-YOFFDOWN)/(BLOCK_VERT_SIZE+BLOCK_SPACING))
+const int NB_FRAMES_PER_SECOND = 50;
-char blocks[MAX_HORI_BLOCKS][MAX_VERT_BLOCKS];
+char blocks[32][32];
-int loadImages()
+// Load an image from a filename to a sprite surface
+static int loadImage( struct sprite* aSprite, char* afilename )
{
int result = 0;
-
- //back = SDL_LoadBMP("./background.bmp");
- ball.pSurface = SDL_LoadBMP("./ball.bmp");
- bar = SDL_LoadBMP("./bar.bmp");
+ SDL_Surface* loadedImage = NULL;
+
+ loadedImage= SDL_LoadBMP( afilename );
+ if( loadedImage == NULL )
+ {
+ printf("Error while loading image: %s\n", afilename);
+ result = -1;
+ }
+ else
+ {
+ aSprite->pSurface = SDL_DisplayFormat( loadedImage );
+ SDL_FreeSurface( loadedImage );
+ aSprite->width = aSprite->pSurface->w;
+ aSprite->height = aSprite->pSurface->h;
+ }
+ return( result );
+}
+
+// Load all images needed by the game (from .bmp files)
+static int loadImages()
+{
+ int result = 0;
+
+ loadImage( &ball, "./ball.bmp");
+ loadImage( &bar, "./bar.bmp");
+
block = SDL_LoadBMP("./block.bmp");
- if( ball.pSurface == NULL || bar == NULL || block ==NULL )
+ BLOCK_HORI_SIZE = block->w;
+ BLOCK_VERT_SIZE = block->h;
+ // Check if we got all images
+ if( ball.pSurface == NULL || bar.pSurface == NULL || block ==NULL )
{
printf("Unable to load image files !\n");
result = -1;
@@ -72,37 +135,45 @@
{
printf("Error while setting transparent color\n");
}
+
+ bar.xpos=SCREEN_WIDTH/2; bar.ypos= SCREEN_HEIGHT-(bar.height*2);
}
return(result);
}
+static void freeRessources()
+{
+ SDL_FreeSurface( screen );
+ SDL_FreeSurface( ball.pSurface );
+ SDL_FreeSurface( bar.pSurface );
+ SDL_FreeSurface( block );
+}
+
void DrawIMG(SDL_Surface *img, int x, int y)
{
- SDL_Rect dest;
- dest.x = x;
- dest.y = y;
- SDL_BlitSurface(img, NULL, screen, &dest);
+ SDL_Rect dest;
+ dest.x = x;
+ dest.y = y;
+ SDL_BlitSurface(img, NULL, screen, &dest);
}
-void DrawIMG(SDL_Surface *img, int x, int y,
+void DrawIMGRect(SDL_Surface *img, int x, int y,
int w, int h, int x2, int y2)
{
- SDL_Rect dest;
- dest.x = x;
- dest.y = y;
- SDL_Rect dest2;
- dest2.x = x2;
- dest2.y = y2;
- dest2.w = w;
- dest2.h = h;
- SDL_BlitSurface(img, &dest2, screen, &dest);
+ SDL_Rect dest;
+ dest.x = x;
+ dest.y = y;
+ SDL_Rect dest2;
+ dest2.x = x2;
+ dest2.y = y2;
+ dest2.w = w;
+ dest2.h = h;
+ SDL_BlitSurface(img, &dest2, screen, &dest);
}
-void DrawBG()
+void drawBackground()
{
- //DrawIMG(back, 0, 0);
-
SDL_Rect dest;
dest.x = 0; dest.y = 0; dest.w = SCREEN_WIDTH; dest.h = SCREEN_HEIGHT;
// Fill background
@@ -139,13 +210,12 @@
}
}
-void DrawScene()
+void drawScene()
{
- //DrawIMG(back, xpos-2, ypos-2, 132, 132, xpos-2, ypos-2);
- DrawBG();
+ drawBackground();
drawBlocks();
DrawIMG(ball.pSurface, ball.xpos, ball.ypos);
- DrawIMG(bar, barxpos, barypos);
+ DrawIMG(bar.pSurface, bar.xpos, bar.ypos);
SDL_Flip(screen);
}
@@ -154,76 +224,121 @@
{
bool result = false;
- // Test pad collision
- Uint32 distance=0;
-/* distance = (ypos - barypos) * (ypos - barypos) + (xpos - barxpos) * (xpos - barxpos);
-
- if( distance <= 32 )
- result = true;
-*/
+// SDL_CollideBoundingBox(&ball , ball.xpos , ball.ypos ,
+// SDL_Surface *sb , int bx , int by)
+
Uint32 Xind, Yind;
- if( (ball.xpos + ball.xhot > XOFF) && (ball.ypos + ball.yhot > YOFFUP) )
+ if( (ball.xpos + ball.width > XOFF) && (ball.ypos + ball.height > YOFFUP) )
{
- if( (ball.xpos + ball.xhot < SCREEN_WIDTH - XOFF) && (ball.ypos + ball.yhot < SCREEN_HEIGHT - YOFFDOWN) )
+ if( (ball.xpos + ball.width < SCREEN_WIDTH - XOFF) && (ball.ypos + ball.height < SCREEN_HEIGHT - YOFFDOWN) )
{
Xind = (ball.xpos-XOFF) / (BLOCK_HORI_SIZE + BLOCK_SPACING);
Yind = (ball.ypos-YOFFUP) / (BLOCK_VERT_SIZE + BLOCK_SPACING);
if( (Xind < MAX_HORI_BLOCKS) && (Yind < MAX_VERT_BLOCKS) && (blocks[Xind][Yind] == 1) )
{
result = true;
- printf("Xpos: %d, Xind: %d, YPos %d, Yind %d \n", ball.xpos, Xind, ball.ypos, Yind);
+ debug("Xpos: %d, Xind: %d, YPos %d, Yind %d \n", ball.xpos, Xind, ball.ypos, Yind);
blocks[Xind][Yind] = 0;
+ if( (ball.xpos + ball.width / 2) < (XOFF + (Xind) * (BLOCK_HORI_SIZE + BLOCK_SPACING)) )
+ {
+ ball.xspeed = -(ball.xspeed);
+ debug("SideG coll\n");
+ }
+ else if( (ball.xpos + ball.width / 2) > (XOFF + (Xind+1) * (BLOCK_HORI_SIZE + BLOCK_SPACING)) )
+ {
+ ball.xspeed = -(ball.xspeed);
+ debug("SideD coll\n");
+ } else
+ ball.yspeed = -(ball.yspeed);
remainingBlocks--;
}
}
}
-// printf("Dist: %i\r", distance);
- return(result);
+
+ return( result );
}
bool hasBallCollidedBar(void)
{
bool result = false;
- if( (ball.xpos + ball.xhot >= barxpos) && (ball.xpos + ball.xhot <= (barxpos+64)) )
- if( (ball.ypos + ball.yhot >= barypos) && (ball.ypos + ball.yhot <= (barypos+16)) )
- result = true;
+// if( (ball.xpos + ball.xhot >= barxpos) && (ball.xpos + ball.xhot <= (barxpos+64)) )
+// if( (ball.ypos + ball.yhot >= barypos) && (ball.ypos + ball.yhot <= (barypos+16)) )
+// result = true;
+ if( SDL_CollideBoundingBox(ball.pSurface , ball.xpos , ball.ypos , bar.pSurface, bar.xpos , bar.ypos) )
+ result = true;
return(result);
}
+bool hasBallCollidedBarOnSide(void)
+{
+ bool result = false;
+
+ if( (ball.ypos > bar.ypos) && ( SDL_CollideBoundingBox(ball.pSurface , ball.xpos , ball.ypos , bar.pSurface, bar.xpos , bar.ypos) ) )
+ result = true;
+
+ return(result);
+}
+
+#define MAX_BAR_SPEED 10
int main(int argc, char *argv[])
{
Uint8* keys;
-
+ int nbFrames = 0;
+ //Timer fps, update;
//Sint8 xspeed = 1, yspeed =1;
- if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )
+ // Initialize SDL
+ if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER /*| SDL_INIT_EVENTTHREAD |SDL_INIT_NOPARACHUTE*/) < 0 )
{
printf("Unable to init SDL: %s\n", SDL_GetError());
exit(1);
}
+ if (SDL_InitSubSystem(SDL_INIT_TIMER) == -1)
+ {
+ fprintf(stderr, "SDL timer failed to initialize! Error: %s\n", SDL_GetError());
+ exit(1);
+ }
+ else
+ {
+ fprintf(stdout, "SDL timer initialized properly!\n");
+ }
+ // Ask SDL to cleanup when exiting
atexit(SDL_Quit);
- screen=SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0/*SDL_HWSURFACE|SDL_DOUBLEBUF*/ );
- if ( screen == NULL )
+ // Get a screen to display our game
+ screen=SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0/*SDL_HWPALETTE*//*SDL_HWSURFACE|| SDL_DOUBLEBUF*/ );
+ if( screen == NULL )
{
printf("Unable to set %dx%dvideo mode: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_GetError());
exit(1);
}
+ // Load our graphics
if( loadImages() )
{
return(1);
}
- DrawBG();
+ drawBackground();
initBlocks();
+ // Initialize sound
+ if( initBuzzer() )
+ {
+ printf("Unable to find PWM on your system, sound won't be activated\n");
+ }
+
int done=0;
- printf("Calculated blocks number: Hori: %d, Vert: %d\n", MAX_HORI_BLOCKS, MAX_VERT_BLOCKS);
+ debug("Calculated blocks number: Hori: %d, Vert: %d\n", MAX_HORI_BLOCKS, MAX_VERT_BLOCKS);
- sleep(1);
+ // Hide mouse
SDL_ShowCursor(0);
+
+ /* // Start timer for Frame Rate calculation
+ update.start();
+ fps.start();*/
+
// Main loop
while(done == 0)
{
@@ -237,32 +352,79 @@
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
}
}
- // Check user actions
+
+ bar.xpos += 1*(bar.xspeed/2);
+ if( bar.xspeed < 0 ) bar.xspeed++; else if( bar.xspeed > 0 ) bar.xspeed--;
+ if(bar.xpos < 0) bar.xpos = 0;
+ if( bar.xpos > (SCREEN_WIDTH-bar.width) ) bar.xpos = (SCREEN_WIDTH-bar.width);
+
+ // Check user actions and move pad
keys = SDL_GetKeyState(NULL);
/*if ( keys[SDLK_UP] ) { ball.ypos -= 1; }
if ( keys[SDLK_DOWN] ) { ball.ypos += 1; }*/
- if ( keys[SDLK_LEFT] ) { barxpos -= 2; if(barxpos < 0) barxpos = 0;}
- if ( keys[SDLK_RIGHT] ) { barxpos += 2; if( barxpos > (SCREEN_WIDTH-64) ) barxpos = (SCREEN_WIDTH-64);}
+ if ( keys[SDLK_LEFT] )
+ {
+ bar.xspeed -= 2; if( bar.xspeed <= -MAX_BAR_SPEED ) bar.xspeed = -MAX_BAR_SPEED;
+ }
+ if ( keys[SDLK_RIGHT] )
+ {
+ bar.xspeed += 2; if( bar.xspeed >= MAX_BAR_SPEED ) bar.xspeed = MAX_BAR_SPEED;
+ }
+ if ( keys[SDLK_SPACE] ) { ball_isfree = true; ball.yspeed = -1; }
+
// Move ball depending on speed
- ball.ypos += ball.yspeed;
- ball.xpos += ball.xspeed;
+ if( ball_isfree )
+ {
+ ball.ypos += ball.yspeed;
+ ball.xpos += ball.xspeed;
+ } else // or from the pad if captured
+ {
+ ball.ypos = bar.ypos - ball.height;
+ ball.xpos = bar.xpos + bar.width/2 - ball.width/2;
+ if( bar.xspeed > 0 )
+ ball.xspeed = 1;
+ else if( bar.xspeed < 0 )
+ ball.xspeed = -1;
+ }
// Check if ball will go out of playing area
- if( ball.xpos+ball.xhot >= SCREEN_WIDTH ) { ball.xspeed = -(ball.xspeed); printf("Xx: %i\n", ball.xspeed); ball.xhot = 0;}
- if( ball.ypos+ball.yhot >= SCREEN_HEIGHT ) { /*ball.yspeed = -(ball.yspeed); ball.yhot = 0;*/ printf("PERDU !\n"); done=1;}
- if ( ball.xpos+ball.xhot <= 0 ) { ball.xspeed = -(ball.xspeed); ball.xhot = ball.width; printf("Xx: %i\n", ball.xspeed); }
- if ( ball.ypos+ball.yhot <= 0 ) { ball.yspeed = -(ball.yspeed); ball.yhot = ball.height; printf("Yy: %i\n", ball.yspeed);}
+ if( ball.xpos + ball.width >= SCREEN_WIDTH ) { ball.xspeed = -(ball.xspeed); debug("Xx: %i\n", ball.xspeed); ball.xhot = 0;}
+ if( ball.ypos + ball.height >= SCREEN_HEIGHT ) { printf("PERDU !\n"); done=1;}
+ if( ball.xpos <= 0 ) { ball.xspeed = -(ball.xspeed); ball.xhot = ball.width; debug("Xx: %i\n", ball.xspeed); }
+ if( ball.ypos <= 0 ) { ball.yspeed = -(ball.yspeed); ball.yhot = ball.height; debug("Yy: %i\n", ball.yspeed);}
// Check if ball has collided with an other object
- if( hasBallCollidedBar() ) { ball.yspeed = -(ball.yspeed); ball.yhot = abs(ball.yhot-ball.width);};
- if( hasBallCollidedBlock() ) { ball.yspeed = -(ball.yspeed); /*ball.xspeed = -(ball.xspeed);*/ ball.yhot = abs(ball.yhot-ball.width);};
+ if( hasBallCollidedBar() && ball_isfree ) { ball.yspeed = -(ball.yspeed); ball.yhot = abs(ball.yhot-ball.width); playSound(1000,100);};
+ if( hasBallCollidedBarOnSide() ) { ball.xspeed = -(ball.xspeed); playSound(1000,100);};
+ if( hasBallCollidedBlock() ) { playSound(500,100); };
if( remainingBlocks <= 0 ) { printf("GAGNE !!\n"); done=1;}
// Update screen
- DrawScene();
+ drawScene();
+ nbFrames++;
+
+ // Calculate and stabilize Frame Rate
+/* if( update.getTicks() > 1000 )
+ {
+ printf("FPS: %f\n", (float)nbFrames );
+ update.start();
+ nbFrames = 0;
+ }
+ while( fps.getTicks() < (1000 / NB_FRAMES_PER_SECOND) )
+ {
+ ;
+ }
+ fps.start();*/
+ SDL_Delay(20);
}
+ // Cleanup what we used
+ releaseBuzzer();
+ freeRessources();
+ SDL_QuitSubSystem( SDL_INIT_TIMER );
+ SDL_Quit();
+
return 0;
}
Modified: trunk/target/demos/armanoid/bar.bmp
===================================================================
(Binary files differ)
Added: trunk/target/demos/armanoid/buzzer.c
===================================================================
--- trunk/target/demos/armanoid/buzzer.c (rev 0)
+++ trunk/target/demos/armanoid/buzzer.c 2007-01-27 15:47:09 UTC (rev 556)
@@ -0,0 +1,100 @@
+#include "SDL.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "buzzer.h"
+
+int playing, initialized = 0;
+FILE* fd;
+FILE* fda;
+
+#ifdef TARGET
+#define FREQ_SYS_FILE "/sys/class/pwm/pwm0/frequency"
+#define ACTIVE_SYS_FILE "/sys/class/pwm/pwm0/active"
+#else
+#define FREQ_SYS_FILE "./frequency"
+#define ACTIVE_SYS_FILE "./active"
+#endif // TARGET
+
+SDL_TimerID myTimerID;
+
+/*
+ * Initialize the buzzer "sound" system
+ *
+ */
+int initBuzzer()
+{
+ int result = -1;
+
+ if( !initialized )
+ {
+ playing = 0;
+ fd = fopen( FREQ_SYS_FILE, "w" );
+ fda = fopen( ACTIVE_SYS_FILE, "w" );
+
+ if( (fd != NULL) && (fda != NULL) )
+ {
+ result = 0;
+ initialized = 1;
+ } else
+ printf("Buzzer: can't open /sys interface\n");
+ }
+ return( result );
+}
+
+static Uint32 timerExpired(Uint32 interval, void* param)
+{
+ playing = 0;
+ // Stop PWM
+ fwrite( "0", 1, 1, fda );
+ fflush( fda );
+ //printf("Timer expired\n");
+
+ return(0);
+}
+
+/*
+ * Free ressources allocated by the sound system
+ *
+ */
+void releaseBuzzer()
+{
+ if( initialized )
+ {
+ playing = 0;
+ SDL_RemoveTimer( myTimerID );
+ timerExpired(0, 0);
+ fclose( fd );
+ fclose( fda );
+ initialized = 0;
+ }
+}
+
+/*
+ * Play a sound at given frequency during given time
+ *
+ * Frequency should be in Hertz
+ * Time in milliseconds
+ */
+void playSound( int aFreq, int aTime )
+{
+ if( (!playing) && (initialized) )
+ {
+ char freq[16]; int nchar;
+
+ // Limit frequency to [50,15k] Herz
+ if( aFreq < 50 ) aFreq = 50;
+ if( aFreq > 15000 ) aFreq = 15000;
+ // Launch PWM
+ fwrite( "1", 1, 1, fda );
+ fflush( fda );
+ // Program PWM with given frequency
+ nchar = sprintf( freq, "%d", aFreq);
+ fwrite( freq, nchar, nchar, fd );
+ fflush( fd );
+ // Launch a timer that will stop sound when desired value is reached
+ myTimerID = SDL_AddTimer( (Uint32) aTime, timerExpired , 0);
+ playing = 1;
+ }
+}
+
Added: trunk/target/demos/armanoid/buzzer.h
===================================================================
--- trunk/target/demos/armanoid/buzzer.h (rev 0)
+++ trunk/target/demos/armanoid/buzzer.h 2007-01-27 15:47:09 UTC (rev 556)
@@ -0,0 +1,13 @@
+#ifndef H_BUZZER_INCLUDE
+#define H_BUZZER_INCLUDE
+
+
+// Initialize the buzzer "sound" system
+int initBuzzer( void );
+// Play a sound on buzzer at given frequency (Hz) and during given time (ms)
+void playSound( int aFreq, int aTime );
+// Free ressources allocated by the sound system
+void releaseBuzzer( void );
+
+
+#endif //H_BUZZER_INCLUDE
Added: trunk/target/demos/armanoid/collide.c
===================================================================
--- trunk/target/demos/armanoid/collide.c (rev 0)
+++ trunk/target/demos/armanoid/collide.c 2007-01-27 15:47:09 UTC (rev 556)
@@ -0,0 +1,208 @@
+#include "collide.h"
+
+/*if this header is not supported on your system comment out
+the assert function call in SDL_TransparentPixel*/
+#include "assert.h"
+
+/*returns maximum or minimum of number*/
+#define SDL_COLLIDE_MAX(a,b) ((a > b) ? a : b)
+#define SDL_COLLIDE_MIN(a,b) ((a < b) ? a : b)
+
+/*
+ SDL surface test if offset (u,v) is a transparent pixel
+*/
+int SDL_CollideTransparentPixelTest(SDL_Surface *surface , int u , int v)
+{
+ /*assert that (u,v) offsets lie within surface*/
+ assert( !((u < surface->w) || (v < surface->h)) );
+
+ int bpp = surface->format->BytesPerPixel;
+ /*here p is the address to the pixel we want to retrieve*/
+ Uint8 *p = (Uint8 *)surface->pixels + v * surface->pitch + u * bpp;
+
+ Uint32 pixelcolor;
+
+ switch(bpp)
+ {
+ case(1):
+ pixelcolor = *p;
+ break;
+
+ case(2):
+ pixelcolor = *(Uint16 *)p;
+ break;
+
+ case(3):
+ if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
+ pixelcolor = p[0] << 16 | p[1] << 8 | p[2];
+ else
+ pixelcolor = p[0] | p[1] << 8 | p[2] << 16;
+ break;
+
+ case(4):
+ pixelcolor = *(Uint32 *)p;
+ break;
+ }
+
+ /*test whether pixels color == color of transparent pixels for that surface*/
+ return (pixelcolor == surface->format->colorkey);
+}
+
+/*
+ SDL pixel perfect collision test
+*/
+int SDL_CollidePixel(SDL_Surface *as , int ax , int ay ,
+ SDL_Surface *bs , int bx , int by)
+{
+ /*Box A;
+ Box B;*/
+
+ /*a - bottom right co-ordinates*/
+ int ax1 = ax + as->w - 1;
+ int ay1 = ay + as->h - 1;
+
+ /*b - bottom right co-ordinates*/
+ int bx1 = bx + bs->w - 1;
+ int by1 = by + bs->h - 1;
+
+ /*check if bounding boxes intersect*/
+ if((bx1 < ax) || (ax1 < bx))
+ return 0;
+ if((by1 < ay) || (ay1 < by))
+ return 0;
+
+
+/*Now lets make the bouding box for which we check for a pixel collision*/
+
+ /*To get the bounding box we do
+ Ax1,Ay1_____________
+ | |
+ | |
+ | |
+ | Bx1,By1_____________
+ | | | |
+ | | | |
+ |_______|_______| |
+ | Ax2,Ay2 |
+ | |
+ | |
+ |____________Bx2,By2
+
+ To find that overlap we find the biggest left hand cordinate
+ AND the smallest right hand co-ordinate
+
+ To find it for y we do the biggest top y value
+ AND the smallest bottom y value
+
+ Therefore the overlap here is Bx1,By1 --> Ax2,Ay2
+
+ Remember Ax2 = Ax1 + SA->w
+ Bx2 = Bx1 + SB->w
+
+ Ay2 = Ay1 + SA->h
+ By2 = By1 + SB->h
+ */
+
+ /*now we loop round every pixel in area of
+ intersection
+ if 2 pixels alpha values on 2 surfaces at the
+ same place != 0 then we have a collision*/
+ int inter_x0 = SDL_COLLIDE_MAX(ax,bx);
+ int inter_x1 = SDL_COLLIDE_MIN(ax1,bx1);
+
+ int inter_y0 = SDL_COLLIDE_MAX(ay,by);
+ int inter_y1 = SDL_COLLIDE_MIN(ay1,by1);
+
+ int y;
+ for(y = inter_y0 ; y <= inter_y1 ; y++)
+ {
+ int x;
+ for(x = inter_x0 ; x <= inter_x1 ; x++)
+ {
+ /*compute offsets for surface
+ before pass to TransparentPixel test*/
+ if((SDL_CollideTransparentPixelTest(as , x-ax , y-ay))
+ && (SDL_CollideTransparentPixelTest(bs , x-bx , y-by)))
+ return 1;
+ }
+ }
+}
+
+/*
+ SDL bounding box collision test
+*/
+int SDL_CollideBoundingBox(SDL_Surface *sa , int ax , int ay ,
+ SDL_Surface *sb , int bx , int by)
+{
+ if(bx + sb->w < ax) return 0; //just checking if their
+ if(bx > ax + sa->w) return 0; //bounding boxes even touch
+
+ if(by + sb->h < ay) return 0;
+ if(by > ay + sa->h) return 0;
+
+ return 1; //bounding boxes intersect
+}
+
+/*
+ SDL bounding box collision tests (works on SDL_Rect's)
+*/
+int SDL_CollideBoundingBoxRect(SDL_Rect a , SDL_Rect b)
+{
+ if(b.x + b.w < a.x) return 0; //just checking if their
+ if(b.x > a.x + a.w) return 0; //bounding boxes even touch
+
+ if(b.y + b.h < a.y) return 0;
+ if(b.y > a.y + a.h) return 0;
+
+ return 1; //bounding boxes intersect
+}
+
+/*
+ tests whether 2 circles intersect
+
+ circle1 : centre (x1,y1) with radius r1
+ circle2 : centre (x2,y2) with radius r2
+
+ (allow distance between circles of offset)
+*/
+int SDL_CollideBoundingCircle(int x1 , int y1 , int r1 ,
+ int x2 , int y2 , int r2 , int offset)
+{
+ int xdiff = x2 - x1; // x plane difference
+ int ydiff = y2 - y1; // y plane difference
+
+ /* distance between the circles centres squared */
+ int dcentre_sq = (ydiff*ydiff) + (xdiff*xdiff);
+
+ /* calculate sum of radiuses squared */
+ int r_sum_sq = r1 + r2; // square on seperate line, so
+ r_sum_sq *= r_sum_sq; // dont recompute r1 + r2
+
+ return (dcentre_sq - r_sum_sq <= (offset*offset));
+}
+
+/*
+ a circle intersection detection algorithm that will use
+ the position of the centre of the surface as the centre of
+ the circle and approximate the radius using the width and height
+ of the surface (for example a rect of 4x6 would have r = 2.5).
+*/
+int SDL_SurfaceCollideBoundingCircle(SDL_Surface *a , int x1 , int y1 ,
+ SDL_Surface *b , int x2 , int y2 ,
+ int offset)
+{
+ int r1,r2;
+ /* if radius is not specified
+ we approximate them using SDL_Surface's
+ width and height average and divide by 2*/
+ r1 = (a->w + a->h) / 4; // same as / 2) / 2;
+ r2 = (b->w + b->h) / 4;
+
+ x1 += a->w / 2; // offset x and y
+ y1 += a->h / 2; // co-ordinates into
+ // centre of image
+ x2 += b->w / 2;
+ y2 += b->h / 2;
+
+ return SDL_CollideBoundingCircle(x1,y1,r1,x2,y2,r2,offset);
+}
Added: trunk/target/demos/armanoid/collide.h
===================================================================
--- trunk/target/demos/armanoid/collide.h (rev 0)
+++ trunk/target/demos/armanoid/collide.h 2007-01-27 15:47:09 UTC (rev 556)
@@ -0,0 +1,86 @@
+/*
+ SDL_collide: A 2D collision detection library for use with SDL
+ Copyright (C) 2005 Amir Taaki
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Amir Taaki
+ ge...@gm...
+
+ Rob Loach
+ http://robloach.net
+*/
+
+/* A simple library for collision detection using SDL */
+
+#ifndef _SDL_COLLIDE_h
+#define _SDL_COLLIDE_h
+
+/* Set up for C function definitions, even when using C++ */
+// #ifdef __cplusplus
+//extern "C" {
+// #endif
+
+#include "SDL.h"
+/*
+ SDL surface test if offset (u,v) is a transparent pixel
+*/
+int SDL_CollideTransparentPixelTest(SDL_Surface *surface , int u , int v);
+
+/*
+ SDL pixel perfect collision test
+*/
+int SDL_CollidePixel(SDL_Surface *as , int ax , int ay ,
+ SDL_Surface *bs , int bx , int by);
+
+/*
+ SDL bounding box collision test
+*/
+int SDL_CollideBoundingBox(SDL_Surface *sa , int ax , int ay ,
+ SDL_Surface *sb , int bx , int by);
+
+/*
+ SDL bounding box collision tests (works on SDL_Rect's)
+*/
+int SDL_CollideBoundingBoxRect(SDL_Rect a , SDL_Rect b);
+
+/*
+ tests whether 2 circles intersect
+
+ circle1 : centre (x1,y1) with radius r1
+ circle2 : centre (x2,y2) with radius r2
+
+ (allow distance between circles of offset)
+*/
+int SDL_CollideBoundingCircle(int x1 , int y1 , int r1 ,
+ int x2 , int y2 , int r2 , int offset);
+
+/*
+ a circle intersection detection algorithm that will use
+ the position of the centre of the surface as the centre of
+ the circle and approximate the radius using the width and height
+ of the surface (for example a rect of 4x6 would have r = 2.5).
+*/
+int SDL_SurfaceCollideBoundingCircle(SDL_Surface *a , int x1 , int y1 ,
+ SDL_Surface *b , int x2 , int y2 ,
+ int offset);
+
+
+/* Ends C function definitions when using C++ */
+// #ifdef __cplusplus
+// }
+// #endif
+
+#endif /* _SDL_COLLIDE_h */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|