12 Weston Terrace, West Kilbride, KA23 9JX. Scotland.
*/
+
+/***********************************************************
+Contributors
+
+Colm Gallagher : Concept and initial programming
+Alan Grier : Graphics
+THomas Plunkett : Audio
+Shard : BEOS Port and bugfixes
+Adolfo : Bugfix for Linux Red-Hat version 7.3
+
+************************************************************
+version who changes
+-------------------------------------------------------------------
+0.1 Colm initial Linux & Windows revisions
+
+0.2 Shard Bugfix: buffer overrun in clearWord
+ function corrupted memory. Strange
+ thing is it crashed BEOS, but not
+ Linux or Windows - guess they handle
+ memory differently or BEOS is much
+ better at detecting exceptions
+
+0.3 Shard added BEOS port (new makefile)
+
+0.4 Adolfo Bugfix: oops! in the checkGuess
+ function, I tried to initialise
+ test[] using a variable as if I was
+ using vb6 ! Have changed this to a
+ static buffer and all is now well.
+
+0.5 Colm Added keyboard input
+
+***********************************************************/
+
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int solvePuzzle = 0;
int shuffleRemaining = 0;
int clearGuess = 0;
-//int winGame = 0;
int gameStart = 0;
int gameTime = 0;
// audio vars
Uint32 audio_len;
Uint8 *audio_pos;
-
struct sound{
char* name;
Mix_Chunk *audio_chunk;
struct sound* next;
};
-
struct sound* soundCache = NULL;
-/*******************************************************************************/
+
+
+
+
+/***********************************************************
+synopsis: walk the module level soundCache until the required
+ name is found. when found, return the audio data
+ if name is not found, return NULL instead.
+
+inputs: name - the unique id string of the required sound
+
+outputs: returns a chunk of audio or NULL if not found
+***********************************************************/
Mix_Chunk* getSound(char* name){
struct sound* currentSound = soundCache;
return NULL;
}
-/*******************************************************************************/
+
+
+
+/***********************************************************
+synopsis: push a sound onto the soundCache
+
+inputs: soundCache - pointer to the head of the soundCache
+ name - unique id string for the sound, this is used
+ to later play the sound
+ filename - the filename of the WAV file
+
+outputs: n/a
+***********************************************************/
void pushSound(struct sound** soundCache, char* name, char* filename){
struct sound* thisSound = NULL;
*soundCache = thisSound;
}
-/*******************************************************************************/
+
+
+
+/***********************************************************
+synopsis: push all the game sounds onto the soundCache
+ linked list. Not that soundCache is passed into
+ pushSound by reference, so that the head pointer
+ can be updated
+
+inputs: pointer to the soundCache
+
+outputs: n/a
+***********************************************************/
void bufferSounds(struct sound** soundCache){
pushSound(&(*soundCache),"click-answer", "audio/click-answer.wav");
}
-/*******************************************************************************/
+
+
+
+/***********************************************************
+synopsis: free all of the data in the audio buffer
+ the audio buffer is a module variable
+
+inputs: n/a
+
+outputs: n/a
+***********************************************************/
void clearSoundBuffer(){
struct sound* currentSound = soundCache, *previousSound = NULL;
}
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: determine the next blank space in a string
+ blanks are indicated by pound £ not space
+
+inputs: pointer the string to check
+
+outputs: returns position of next blank (1 is first character)
+ or 0 if no blanks found
+***********************************************************/
int nextBlank(char* string){
-// determine the next blank space in a string - blanks are indicated by pound £ not space
int i;
int found=0;
}
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: shift a string of characters 1 character to the left
+ truncating the leftmost character
+
+inputs: pointer to string to shift
+
+outputs: pointer to the shifted string
+***********************************************************/
char* shiftLeftKill(char* string){
-// shift a string of characters 1 character to the left
int i;
char start;
free(newString);
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: shift a string of characters 1 character to the left
+ move the first character to the end of the string
+ so it wraps around
+
+inputs: pointer to string to shift
+
+outputs: pointer to the shifted string
+***********************************************************/
char* shiftLeft(char* string){
-// shift a string of characters 1 character to the left
-// move the first character to the end of the string
int i;
char start;
free(newString);
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: Generate all possible combinations of the root word
+ the initial letter is fixed, so to work out all
+ anagrams of a word, prefix with space.
+
+inputs: head - pointer to the answers list
+ dlbHead - pointer to the dictionary
+ guess - pointer to the current guess
+ remain - pointer to the remaining letters
+
+outputs: all parameters are in/out
+***********************************************************/
void ag(struct node** head, struct dlb_node* dlbHead, char** guess, char** remain){
-// generate all possible combinations of the root word
-// the initial letter is fixed (hence the space character
-// at the end of the possible list)
char* newGuess;
char* newRemain;
newGuess[guessLen+1] = '\0';
newRemain[remainLen-1] = '\0';
-// printf("%s\n", newGuess);
-
if(strlen(newGuess) > 3){
if (dlb_lookup(dlbHead,shiftLeftKill(newGuess))){
push(&(*head), shiftLeftKill(newGuess));
free(newRemain);
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: update all of the answers to "found"
+
+inputs: head - pointer to the answers linked list
+
+outputs: n/a
+***********************************************************/
void solveIt(struct node* head){
struct node* current = head;
}
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: load the named image to position x,y onto the
+ required surface
+
+inputs: file - the filename to load (.BMP)
+ screen - the SDL_Surface to display the image
+ x,y - the top left postion
+
+outputs: n/a
+***********************************************************/
void ShowBMP(char *file, SDL_Surface *screen, int x, int y){
SDL_Surface *image;
SDL_Rect dest;
SDL_BlitSurface(image, NULL, screen, &dest);
/* Update the changed portion of the screen */
- //SDL_UpdateRects(screen, 1, &dest);
SDL_FreeSurface(image);
}
-/***********************************************************/
-/*void displayAnswerBoxes(struct node* head, SDL_Surface* screen){
-// for each letter to each answer in the nodelist,
-// display a neat little box to fill in later
-struct node* current = head;
-SDL_Rect outerrect, innerrect;
-int i;
-char imagePath[] = "images/small-£.bmp";
-int twoOnALine = 0;
- // width and height are always the same
- outerrect.w = 17;
- outerrect.h = 17;
- outerrect.x = 70;
- outerrect.y = 380;
+/***********************************************************
+synopsis: for each letter to each answer in the nodelist,
+ display a neat little box. If the answer has
+ been found display the letter for each box.
+ if the answer was guessed (as opposed to set found
+ by solveIt), display a white background, otherwise
+ display a blue background.
- while (current != NULL){
+inputs: head - pointer to the answers linked list
+ screen - pointer to the SDL_Surface to update
- // update the x for each letter
- for (i=0;i<current->length;i++){
- SDL_FillRect(screen, &outerrect,0);
- innerrect.w = outerrect.w - 2;
- innerrect.h = outerrect.h - 2;
- innerrect.x = outerrect.x + 1;
- innerrect.y = outerrect.y + 1;
-
- if (current->guessed){
- SDL_FillRect(screen, &innerrect,SDL_MapRGB(screen->format,255,255,255));
- }
- else{
- SDL_FillRect(screen, &innerrect,SDL_MapRGB(screen->format,217,220,255));
- }
-
- if (current->found){
- imagePath[13] = current->anagram[i];
- ShowBMP(imagePath, screen, innerrect.x+2, innerrect.y );
- }
-
- outerrect.x += 18;
- }
-
- if ( twoOnALine<4 ){
- // shift x along to show the next word
- outerrect.x += (8-current->length) * 18;
- twoOnALine++;
- }
- else{
- // reset the x, ready for the next line
- outerrect.x = 70;
- twoOnALine = 0;
- // update the y for each word
- outerrect.y += 19;
- }
- current=current->next;
- }
- SDL_Flip(screen);
-}
-*/
-/***********************************************************/
+outputs: n/a
+***********************************************************/
void displayAnswerBoxes(struct node* head, SDL_Surface* screen){
-// for each letter to each answer in the nodelist,
-// display a neat little box to fill in later
struct node* current = head;
SDL_Rect outerrect, innerrect, letterBankRect;
int acrossOffset = 70;
int numLetters = 0;
int listLetters = 0;
-//char imagePath[] = "images/small-£.bmp";
// width and height are always the same
outerrect.w = 16;
if (current->found){
innerrect.x+=2;
-// innerrect.y-=1;
letterBankRect.x = 10 * ((int)current->anagram[i] - 97);
- //imagePath[13] = current->anagram[i];
- //ShowBMP(imagePath, screen, innerrect.x+2, innerrect.y );
SDL_SetColorKey(smallLetterBank, SDL_SRCCOLORKEY, SDL_MapRGB(smallLetterBank->format,255,0,255));
SDL_BlitSurface(smallLetterBank, &letterBankRect, screen, &innerrect);
}
current=current->next;
}
-// SDL_Flip(screen);
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: walk the linked list of answers checking
+ for our guess. If the guess exists, mark it as
+ found and guessed.
+ if it's the longest word play the foundbig
+ sound otherwise play the got word sound.
+ If the word has already been found, play the
+ duplicate sound.
+ If it cannot be found, play the badword sound
+
+inputs: answer - the string that we're checking
+ head - pointer to the linked list of answers
+
+outputs: n/a
+***********************************************************/
void checkGuess(char* answer, struct node* head){
// check the guess against the answers
struct node* current = head;
int i, len;
int foundWord = 0;
+char test[7];
len = nextBlank(answer) -1;
if (len<0) len=7;
- char test[len];
+// char test[len]; //bugfix by Adolfo - what was I thinking! and why does it only fail on RH 7.3??
for (i=0; i<len; i++){
test[i] = answer[i];
}
}
}
-/***********************************************************/
+/***********************************************************
+synopsis: determine the next blank space in a string
+ blanks are indicated by pound £ not space.
+ When a blank is found, move the chosen letter
+ from one box to the other.
+ i.e. If we're using the ANSWER box,
+ move the chosen letter from the SHUFFLE box
+ to the ANSWER box and move a SPACE back to the
+ SHUFFLE box. and if we're using the SHUFFLE box
+ move the chosen letter from ANSWER to SHUFFLE
+ and move a SPACE into ANSWER.
+
+inputs: box - the ANSWER or SHUFFLE box
+ *index - pointer to the letter we're interested in
+
+outputs: retval : the coords of the next blank position
+ *index : pointer to the new position were interested in
+***********************************************************/
int nextBlankPosition(int box, int* index){
-// determine the next blank space in a string - blanks are indicated by pound £ not space
-int i;
+int i=0;
switch(box){
case ANSWER:
return i * (GAME_LETTER_WIDTH+GAME_LETTER_SPACE)+BOX_START_X;
}
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: handle the keyboard events
+ BACKSPACE & ESCAPE - clear letters
+ RETURN - check guess
+ SPACE - shuffle
+ a-z - select the first instance of that letter
+ in the shuffle box and move to the answer box
+
+inputs: event - the key that has been pressed
+ node - the top of the answers list
+ letters - the letter sprites
+
+outputs: n/a
+***********************************************************/
+void handleKeyboardEvent(SDL_Event *event, struct node* head, struct sprite** letters){
+
+struct sprite* current = *letters;
+char keyedLetter;
+
+ keyedLetter = event->key.keysym.sym;
+
+ if (!gamePaused){
+
+ switch(keyedLetter){
+
+ case SDLK_BACKSPACE: case SDLK_ESCAPE:
+ // clear has been pressed
+ clearGuess = 1;
+ break;
+
+ case SDLK_RETURN:
+ //enter has been pressed
+ checkGuess(answer, head);
+ break;
+ case ' ':
+ // shuffle has been pressed
+ shuffleRemaining = 1;
+ Mix_PlayChannel(-1, getSound("shuffle"),0);
+ break;
+ default:
+ // loop round until we find the first instance of the selected letter in SHUFFLE
+ while (current!=NULL&¤t->box!=CONTROLS){
+ if (current->box == SHUFFLE){
+ if (current->letter == keyedLetter){
+ current->toX = nextBlankPosition(ANSWER, ¤t->index);
+ current->toY = ANSWER_BOX_Y;
+ current->box = ANSWER;
+ Mix_PlayChannel(-1, getSound("click-shuffle"), 0);
+ break; //while
+ }
+ }
+ current=current->next;
+ }
+
+ }
+
+ }
+}
+
+
+
+
+/***********************************************************
+synopsis: checks where the mouse click occurred - if it's in
+ a defined hotspot then perform the appropriate action
+
+ Hotspot Action
+ -----------------------------------------------------
+ A letter set the new x,y of the letter
+ and play the appropriate sound
+
+ ClearGuess set the clearGuess flag
+
+ checkGuess pass the current answer to the
+ checkGuess routine
+
+ solvePuzzle set the solvePuzzle flag
+
+ shuffle set the shuffle flag and
+ play the appropriate sound
+
+ newGame set the newGame flag
+
+ quitGame set the quitGame flag
+
+inputs: button - mouse button that has ben clicked
+ x, y - the x,y coords of the mouse
+ screen - the SDL_Surface to display the image
+ head - pointer to the top of the answers list
+ letters - pointer to the letters sprites
+
+outputs: n/a
+***********************************************************/
void clickDetect(int button, int x, int y, SDL_Surface *screen, struct node* head, struct sprite** letters){
struct sprite* current = *letters;
}
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: move all letters from answer to shuffle
+
+inputs: letters - the letter sprites
+
+outputs: n/a
+***********************************************************/
int clearWord(struct sprite** letters){
struct sprite* current = *letters;
int i;
int count = 0;
- for (i=0;i<=7;i++){
+ //for (i=0;i<=7;i++){ // bug fixed by Shard - killed BEOSr, but not linux or windows!
+ for (i=0;i<7;i++){
orderedLetters[i] = NULL;
}
current=current->next;
}
- for (i=0;i<=7;i++){
+ for (i=0;i<7;i++){
if(orderedLetters[i] != NULL)
orderedLetters[i]->toX = nextBlankPosition(SHUFFLE, &orderedLetters[i]->index);
}
return count;
}
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: display the score graphic
+
+inputs: screen - the SDL_Surface to display the image
+
+outputs: n/a
+***********************************************************/
void updateScore(SDL_Surface* screen){
// we'll display the total Score, this is the game score
SDL_BlitSurface(numberBank, &fromrect, scoreSprite->sprite, &torect);
}
}
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: displays the graphical representation of time
+
+inputs: screen - the SDL_Surface to display the image
+
+outputs: n/a
+***********************************************************/
void updateTime(SDL_Surface* screen){
// the time is x seconds minus the number of seconds of game time
Mix_PlayChannel(-1, getSound("clock-tick"), 0);
}
}
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: spin the word file to a random location and then
+ loop until a 7 or 8 letter word is found
+ this is quite a weak way to get a random word
+ considering we've got a nice dbl Dictionary to
+ hand - but it works for now.
+
+inputs: n/a
+
+outputs: a random word
+***********************************************************/
char* getRandomWord(){
-// spin the word file to a random location and then
-// loop until a 7 or 8 letter word is found
FILE* wordlist;
int filelocation;
int i;
char* wordFromList = malloc(sizeof(char) * 50);
-int len;
+int len=0;
int done = 0;
filelocation = rand()%10000;
wordFromList[len+1] = '\0';
return wordFromList;
- free(wordFromList);
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: swap 2 characters in a string
+
+inputs: from, to - the characters to swap
+
+outputs: the swapped string
+***********************************************************/
char* swapChars(int from, int to, char* string){
-// swap 2 characters in a string
char swap;
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: working backwards in the string,
+ find the first non space character
+
+inputs: a string to check
+
+outputs: the position of the character
+***********************************************************/
int revFirstNonSpace(char* thisWord){
-// working backwards in the string,
-// find the first non space character
int i;
for (i = strlen(thisWord) ; i>0; i--){
return 0;
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: replace characters randomly
+
+inputs: string to randomise (in/out)
+
+outputs: n/a
+***********************************************************/
void shuffleWord(char** thisWord){
-// replace characters randomly
int numSwaps;
int from, to;
strcpy(*thisWord, swapChars(from, to, *thisWord));
}
- // move all the spaces to the end
-// strcpy(buffer, *thisWord);
-// for (i=0;i<strlen(buffer);i++){
-// if(buffer[i] == SPACE_CHAR){
-// from = i;
-// to = revFirstNonSpace(buffer);
-// if (to == 0) break; // no spaces
-// to--;
-// if (from < to){
-// letter = buffer[i+1];
-// buffer[i+1] = buffer[i];
-// buffer[i] = letter;
-// }
-// }
-// }
-// strcpy(*thisWord, buffer);
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: returns the index of a specific letter in a string
+
+inputs: string - the string to check
+ letter - the letter to return
+
+outputs: the index of the letter
+***********************************************************/
int whereinstr(char* string, char letter){
-// returns the index of a specific letter in a string
int i, len;
len=strlen(string);
return 0;
}
-
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: same as shuffle word, but also tell the letter
+ sprites where to move to
+
+inputs: thisWord - the string to shuffle (in/out)
+ letters - the letter sprites
+
+outputs: n/a
+***********************************************************/
void shuffleAvailableLetters(char** thisWord, struct sprite** letters){
-// same as shuffle word, but also tell the letter sprites where
-// to move to
struct sprite *thisLetter = *letters;
int from, to;
free(shuffleChars);
free(shufflePos);
}
-/***********************************************************/
-/*void* updateClock(void *arg){
-int timeNow;
- while((gameTime < AVAILABLE_TIME) && !stopTheClock){
- timeNow = time(0) - gameStart;
- if (timeNow!=gameTime){
- gameTime = timeNow;
- updateTimeDisplay = 1;
- //sleep(1);
- }
- }
- stopTheClock = 1;
- solvePuzzle = 1;
- return NULL;
-}
-*/
-/********************************************************************/
+
+
+
+/***********************************************************
+synopsis: build letter string into linked list of letter graphics
+
+inputs: letters - letter sprites head node (in/out)
+ screen - the SDL_Surface to display the image
+
+outputs: n/a
+***********************************************************/
void buildLetters(struct sprite** letters, SDL_Surface* screen){
-// build letter string into linked list of letter graphics
struct sprite *thisLetter = NULL, *previousLetter = NULL;
int i;
SDL_BlitSurface(letterBank, &blankRect, thisLetter->replace, NULL);
thisLetter->x = rand()%799;//i * (GAME_LETTER_WIDTH + GAME_LETTER_SPACE) + BOX_START_X;
thisLetter->y = rand()%599;//SHUFFLE_BOX_Y;
+ thisLetter->letter = shuffle[i];
thisLetter->h = thisLetter->sprite->h;
thisLetter->w = thisLetter->sprite->w;
thisLetter->toX = i * (GAME_LETTER_WIDTH + GAME_LETTER_SPACE) + BOX_START_X;
}
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: add the clock to the sprites
+ keep a module reference to it for quick and easy update
+ this sets the clock to a fixed 5:00 start
+
+inputs: letters - letter sprites head node (in/out)
+ screen - the SDL_Surface to display the image
+
+outputs: n/a
+***********************************************************/
void addClock(struct sprite** letters, SDL_Surface* screen){
-// add the clock to the sprites
-// keep a module reference to it for quick and easy update
struct sprite *thisLetter = NULL, *previousLetter = NULL, *current = *letters;
int i;
clockSprite = thisLetter;
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: add the Score to the sprites
+ keep a module reference to it for quick and easy update
+
+inputs: letters - letter sprites head node (in/out)
+ screen - the SDL_Surface to display the image
+
+outputs: n/a
+***********************************************************/
void addScore(struct sprite** letters, SDL_Surface* screen){
-// add the Score to the sprites
-// keep a module reference to it for quick and easy update
struct sprite *thisLetter = NULL, *previousLetter = NULL, *current = *letters;
SDL_Rect fromrect, torect, blankRect;
previousLetter->next = thisLetter;
scoreSprite = thisLetter;
}
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: do all of the initialisation for a new game:
+ build the screen
+ get a random word and generate anagrams
+ (must get less than 66 anagrams to display on screen)
+ initialise all the game control flags
+
+inputs: head - first node in the answers list (in/out)
+ dblHead - first node in the dictionary list
+ screen - the SDL_Surface to display the image
+ letters - first node in the letter sprites (in/out)
+
+outputs: n/a
+***********************************************************/
void newGame(struct node** head, struct dlb_node* dlbHead, SDL_Surface* screen, struct sprite** letters){
char* guess;
char* remain;
-//pthread_t clock;
int happy = 0; // we don't want any more than ones with 66 answers - that's all we can show...
int i;
remain[7] = '\0';
-// printf("%s,%i\n", remain, bigWordLen);
remain[bigWordLen]='\0';
shuffleWord(&remain);
strcpy(shuffle, remain);
-// printf("shuffle:%s\n", shuffle);
free(guess);
free(remain);
gameTime = 0;
stopTheClock = 0;
- // create the clock loop on a new thread
- //pthread_create(&clock, NULL, updateClock, NULL);
}
-/***********************************************************/
+
+
+
+
+/***********************************************************
+synopsis: a big while loop that runs the full length of the
+ game, checks the game events and responds
+ accordingly
+
+ event action
+ -------------------------------------------------
+ winGame stop the clock and solve puzzle
+ timeRemaining update the clock tick
+ timeUp stop the clock and solve puzzle
+ solvePuzzle trigger solve puzzle and stop clock
+ updateAnswers trigger update answers
+ startNew trigger start new
+ updateScore trigger update score
+ shuffle trigger shuffle
+ clear trigger clear answer
+ quit end loop
+ poll events check for keyboard/mouse and quit
+
+ finally, move the sprites -this is always called
+ so the sprites are always considered to be moving
+ no "move sprites" event exists - sprites x&y just
+ needs to be updated and they will always be moved
+
+inputs: head - first node in the answers list (in/out)
+ dblHead - first node in the dictionary list
+ screen - the SDL_Surface to display the image
+ letters - first node in the letter sprites (in/out)
+
+outputs: n/a
+***********************************************************/
void gameLoop(struct node** head, struct dlb_node* dlbHead, SDL_Surface* screen, struct sprite** letters){
int done=0;
{
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
-// printf("shuffle: %s\n", shuffle);
-// printf("guess: %s\n", answer);
clickDetect(event.button.button, event.button.x, event.button.y, screen, *head, &(*letters));
break;
- case SDL_QUIT:
+
+ case SDL_KEYUP:
+ handleKeyboardEvent(&event, *head, &(*letters));
+ break;
+ case SDL_QUIT:
done=1;
}
- }
+ }
moveSprites(&screen, &(*letters), letterSpeed);
- }
+ }
}
-/***********************************************************/
+
+
+
+/***********************************************************
+synopsis: initialise graphics and sound, build the dictionary
+ cache the images and start the game loop
+ when the game is done tidy up
+
+inputs: argc - argument count
+ argv - arguments
+
+outputs: retval 0 = success 1 = failure
+***********************************************************/
int main(int argc, char *argv[]){
struct node* head = NULL;
bufferSounds(&soundCache);
- // create the audio handler on a new thread
- //pthread_create(&audio, NULL, handleSounds, NULL);
-
// create dictionary
createDLBTree(&dlbHead);
+++ /dev/null
-/*
-Anagramarama - A word game. Like anagrams? You'll love anagramarama!
-Copyright (C) 2003 Colm Gallagher
-
-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
-
-Contact Details: colm@coralquest.com
- 12 Weston Terrace, West Kilbride, KA23 9JX. Scotland.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <SDL/SDL.h>
-#include <pthread.h>
-
-struct sound{
- char* name;
- SDL_AudioSpec spec;
- Uint8 *audio_chunk;
- Uint32 audio_len;
- Uint8 *audio_pos;
- struct sound* next;
-};
-
-struct soundQueue{
- char* name;
- struct soundQueue* next;
-};
-
-//Uint32 audio_len;
-//Uint8 *audio_pos;
-
-//struct sound* soundCache = NULL;
-//struct soundQueue* sounds = NULL;
-
-/*******************************************************************************/
-//void fill_audio(void *udata, Uint8 *stream, int len){
-// The audio function callback takes the following parameters:
-// stream: A pointer to the audio buffer to be filled
-// len: The length (in bytes) of the audio buffer
-
- /* Only play if we have data left */
-// if ( audio_len == 0 )
-// return;
-
- /* Mix as much data as possible */
-// len = ( len > audio_len ? audio_len : len );
-// SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);
-// audio_pos += len;
-// audio_len -= len;
-//}
-
-/*******************************************************************************/
-void pushSound(struct sound** soundCache, char* name, char* filename){
-
-struct sound* thisSound = NULL;
-
- thisSound = malloc(sizeof(struct sound));
- thisSound->name = malloc(sizeof(name)*strlen(name));
- strcpy(thisSound->name, name);
- /* Set the audio format */
- thisSound->spec.freq = 22050;
- thisSound->spec.format = AUDIO_S16;
- thisSound->spec.channels = 2; /* 1 = mono, 2 = stereo */
- thisSound->spec.samples = 1024; /* Good low-latency value for callback */
- thisSound->spec.callback = NULL; // null for now - we'll set the local ref in the play routine
- thisSound->spec.userdata = NULL;
- thisSound->next = *soundCache;
-
- if (!strcmp(name, "playArea")){
- // create a big area to mix and play the audio in
-// thisSound->audio_len = malloc(sizeof(Uint32));
- thisSound->audio_len = 8152;
- thisSound->audio_chunk = malloc(sizeof(Uint8)*thisSound->audio_len);
- }
- else{
- // Attempt to load a sample
- if (!SDL_LoadWAV(filename, &thisSound->spec, &thisSound->audio_chunk, &thisSound->audio_len)){
- SDL_CloseAudio();
- fprintf(stderr, "Error: %s", SDL_GetError());
- return;
- }
- }
-
- *soundCache = thisSound;
-}
-
-/*******************************************************************************/
-void bufferSounds(struct sound** soundCache){
-
- pushSound(&(*soundCache),"click", "audio/click.wav");
- pushSound(&(*soundCache),"click2", "audio/click2.wav");
- pushSound(&(*soundCache),"found", "audio/found.wav");
- pushSound(&(*soundCache),"playArea", "");
-}
-
-/*******************************************************************************/
-void clearSoundBuffer(struct sound** soundCache){
-
-struct sound* currentSound = *soundCache, *previousSound = NULL;
-
- printf("top\n");
-
- while (currentSound!=NULL){
-
- printf("in top\n");
-
- SDL_FreeWAV(currentSound->audio_chunk);
- free(currentSound->name);
- previousSound = currentSound;
- currentSound = currentSound->next;
- free(previousSound);
-
- printf("in botton\n");
- }
-
- printf("bottom\n");
-}
-
-/*******************************************************************************/
-//void playSound(struct sound* soundCache, char* name){
-
-//struct sound* currentSound = soundCache;
-
-// while (currentSound!=NULL){
-// if (!strcmp(currentSound->name, name)){
-// printf("current sound is : %s\n", currentSound->name);
-// audio_pos = currentSound->audio_chunk;
-// audio_len = currentSound->audio_len;
- /* Open the audio device, forcing the desired format */
-// currentSound->spec.callback = fill_audio;
-// if ( SDL_OpenAudio(¤tSound->spec, NULL) < 0 ) {
-// fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
-// return;
-// }
-
- // Unpause the audio
-// SDL_PauseAudio(0);
-
- /* Wait for sound to complete */
-// while ( audio_len > 0 ) {
-// SDL_Delay(100); /* Sleep 1/10 second */
-// }
-
-// SDL_CloseAudio();
-// break;
-
-// }
-// currentSound = currentSound->next;
-// }
-//}
-
-/*******************************************************************************/
-void pushSoundQueue(struct soundQueue** sounds, char* name){
-
-struct soundQueue* current = *sounds;
-struct soundQueue* previous = NULL;
-
-
- // get the tail - won't ever be very many, so not too lossy
- // and saves handling a tail pointer
- while (current != NULL){
- previous = current;
- current = current->next;
- }
-
- current = NULL;
- // OK a bit nasty - i'm reusing current here, i only
- // used it above for running through the list
-
- current = malloc(sizeof(struct soundQueue));
- current->name = malloc(sizeof(char)*strlen(name));
- strcpy(current->name,name);
- current->next = NULL;
-
-
- // join up the queue
- if (previous == NULL)
- // first time only, the head is previous
- *sounds = current;
- else
- previous->next = current;
-
-}
-
-/*******************************************************************************/
-void popSoundQueue(struct soundQueue** sounds, char* name){
-
-struct soundQueue* oldHead = *sounds;
-
- *sounds = oldHead->next;
-
- free(oldHead->name);
- free(oldHead);
-}
-
-/*******************************************************************************/
-//int doneSounds = 0;
-//int audioThreadOpen = 0;
-//void* handleSounds(void *arg){
-
-//char* name;
-
-// audioThreadOpen = 1;
-
- // if we're currently playing a sound or have none to handle - just leave
-// while(!doneSounds){
-
-// if(SDL_GetAudioStatus() == SDL_AUDIO_STOPPED && sounds != NULL){
- // get next sound off the queue and then pop it
-// name = malloc(sizeof(char)*strlen(sounds->name));
-// strcpy(name, sounds->name);
-// popSoundQueue(&sounds, name);
-// printf("sound: %s\n", name);
-// playSound(soundCache, name);
-
-// free(name);
-// }
-// }
-// audioThreadOpen = 0;
-// return 0;
-//}
-
-/*******************************************************************************/
-/*int main(int argc, char** argv){
-
-SDL_Surface* screen = NULL;
-SDL_Event event;
-Uint8* key;
-
-pthread_t audio;
-
- if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0){
- fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
- exit(1);
- }
-
- screen=SDL_SetVideoMode(640,480,8,0);
-
- atexit(SDL_Quit);
-
- soundCache=NULL;
- soundCache = malloc(sizeof(struct sound));
- bufferSounds(&soundCache);
-
- //sounds = malloc(sizeof(struct soundQueue));
- pushSoundQueue(&sounds, "click");
- pushSoundQueue(&sounds, "click2");
- pushSoundQueue(&sounds, "click");
- pushSoundQueue(&sounds, "click2");
- pushSoundQueue(&sounds, "click2");
- pushSoundQueue(&sounds, "found");
-
- // create the audio handler on a new thread
- pthread_create(&audio, NULL, handleSounds, NULL);
-
-// playSound(soundCache, "click");
-// playSound(soundCache, "click2");
-// playSound(soundCache, "found");
-
- do{
- key = SDL_GetKeyState(NULL);
- if(SDL_PollEvent(&event))
- if(event.type == SDL_QUIT)
- break;
- }
- while (!key[SDLK_ESCAPE]);
-
- doneSounds=1;
- while (audioThreadOpen){
- SDL_Delay(500);
- }
-
- clearSoundBuffer(&soundCache);
- return 0;
-}*/