clean up and added own TTF file so we are independent from eff-content-fonts
[mancala] / src / play.c
1 /*
2 *  for Maemo renamed to play.c and some bugfixes (2009, Reto Zingg)
3 *
4 *  Main Mancala Program Module Source -- main.c 
5 *  $Id: main.c,v 1.7.2.25 2004/01/17 06:56:23 sparrow_hawk Exp $
6 *
7 *  Copyright (C) 2003 Kevin Riggle 
8 *  http://cmancala.sourcefoge.net
9 *  Copyright (C) 2009 Reto Zingg
10 *
11 *  This program is free software; you can redistribute it and/or modify it
12 *  under the terms of the GNU General Public License as published by the
13 *  Free Software Foundation; either version 2, or (at your option) any
14 *  later version.
15 *
16 *  This program is distributed in the hope that it will be useful, but
17 *  WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 *  General Public License for more details, a copy of which may be found in
20 *  the file COPYING provided in the main directory of this release.
21 *
22 */
23
24 #include <hildon/hildon.h>
25
26 #include "SDL_mixer.h"
27 #include "SDL.h"
28 #include "SDL_image.h"
29 #include "SDL_ttf.h"
30
31 #include "graphics.h"
32 #include "mancala.h"
33 #include "ai.h"
34 #include "sounds.h"
35 #include "play.h"
36
37 // the surfaces
38 SDL_Surface *screen, *board, *title_text, *tile, *stone[STONE_MAX+1], *exit_text;
39 // the fonts
40 TTF_Font *title_font, *home_font, *board_font;
41 // The sound effects that will be used
42 Mix_Chunk *pick = NULL;
43
44
45 void sdl_clean_up(){
46         
47         int i = 0;
48         
49         SDL_FreeSurface(board);
50         SDL_FreeSurface(tile);
51         SDL_FreeSurface(exit_text);
52         SDL_FreeSurface(title_text);
53         for(i=0; i<=STONE_MAX; i++)
54                 SDL_FreeSurface(stone[i]);
55         SDL_FreeSurface(screen);
56         TTF_CloseFont(title_font);
57         TTF_CloseFont(board_font);
58         TTF_CloseFont(home_font);
59         Mix_FreeChunk(pick);
60         /* Make sure we clean up after ourselves */
61         TTF_Quit();
62         Mix_CloseAudio();
63         SDL_Quit();
64         return;
65 }
66
67 int play() {
68         
69         SDL_Rect board_rect, title_rect, exit_rect;
70         SDL_Color font_color;
71         SDL_Event event;
72         SDL_Color font_color_exit;
73         
74         char tile_path[STRING_MAX], stone_path[STRING_MAX];
75         char icon_path[STRING_MAX], title_path[STRING_MAX];
76         char home_path[STRING_MAX], board_path[STRING_MAX];
77         char pick_path[STRING_MAX];
78         int aiBoard[BOARD_MAX+1], humanBoard[BOARD_MAX+1];
79         int i, redraw_board, highlight, old_highlight, active;
80         int current_move, ai_last_move, human_last_move, state;
81         
82         /* Set up the game board and game variables. */
83         gameInit(aiBoard, humanBoard);
84         current_move = 0;
85         ai_last_move = human_last_move = -99;
86         
87         /* initialize our libraries */
88         //if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0) {
89        if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
90                fprintf(stderr, "Unable to initialize SDL: %s\n", 
91                         SDL_GetError());
92                         sdl_clean_up();
93                         return 1;
94        }
95        
96        if (TTF_Init() < 0) {
97                fprintf(stderr, "Unable to initialize SDL_ttf: %s\n", 
98                         SDL_GetError());
99                         sdl_clean_up();
100                         return 1;
101        }
102        
103        //Initialize SDL_mixer 
104        
105        if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) 
106        {
107                fprintf(stderr, "Unable to initialize Mix_OpenAudio: %s\n",
108                         SDL_GetError());
109                         sdl_clean_up();
110                         return 1;
111        }
112        
113        
114        /* Load our images... PNGs now, maybe XPMs later */
115        sprintf(tile_path, "%s/tile.png", RES_PATH);
116        if ((tile = LoadRes(tile_path)) == NULL) {
117                fprintf(stderr, "Unable to load resource: %s\n", 
118                         SDL_GetError());
119                         sdl_clean_up();
120                         return 1;
121        }
122        
123        for (i=0; i<=STONE_MAX; i++) {
124                if (sprintf(stone_path, "%s/stone%02d.png", RES_PATH, i) == 0)
125                        fprintf(stderr, "Problems assembling path.\n");
126                if (!(stone[i] = LoadRes(stone_path))) {
127                        fprintf(stderr, "Unable to load resource: %s\n",
128                                 SDL_GetError());
129                                 sdl_clean_up();
130                                 return 1;
131                }
132        }
133        
134        /* Load our font(s) */
135        if (sprintf(title_path, "%s/luxisr.ttf", FONT_PATH) == 0)
136                fprintf(stderr, "Problems assembling path.\n");
137        if (!(title_font = TTF_OpenFont(title_path, TITLE_SIZE))) {
138                fprintf(stderr, "Could not load font: %s\n", TTF_GetError());
139                sdl_clean_up();
140                return 1;
141        }
142        
143        if (sprintf(board_path, "%s/luxisr.ttf", FONT_PATH) == 0)
144                fprintf(stderr, "Problems assembling path.\n");
145        if (!(board_font = TTF_OpenFont(board_path, BOARD_SIZE))) {
146                fprintf(stderr, "Could not load font: %s\n", TTF_GetError());
147                sdl_clean_up();
148                return 1;
149        }
150        
151        if (sprintf(home_path, "%s/luxisr.ttf", FONT_PATH) == 0)
152                fprintf(stderr, "Problems assembling path.\n");
153        if (!(home_font = TTF_OpenFont(home_path, HOME_SIZE))) {
154                fprintf(stderr, "Could not load font: %s\n", TTF_GetError());
155                sdl_clean_up();
156                return 1;
157        }
158        
159        /* Load sound effects */ 
160        sprintf(pick_path, "%s/pick.wav", RES_PATH); 
161        if ((pick = Mix_LoadWAV(pick_path)) == NULL) { 
162                fprintf(stderr, "Unable to load sound: %s\n", 
163                         SDL_GetError());
164                         sdl_clean_up();
165                         return 1; 
166        }
167        
168        /* store the font's color */
169        font_color.r = 255;
170        font_color.b = 255;
171        font_color.g = 255;
172        
173        /* render the title text 
174        if (!(title_text = TTF_RenderText_Solid(title_font, 
175                "Mancala", font_color))) 
176                fprintf(stderr, "TTF: %s\n", TTF_GetError());
177        */
178        title_text = NULL;
179        
180        
181        /* define the position of the board in the screen */
182        board_rect.x = 0;
183        board_rect.y = Y_OFFSET;
184        board_rect.w = 0;
185        board_rect.h = 0;
186        
187        /* set window properties and create it */
188        SDL_WM_SetCaption("Mancala", "Mancala");
189        if (sprintf(icon_path, "%s/icon.png", RES_PATH) == 0)
190                fprintf(stderr, "Problems assembling icon path.\n");
191        SDL_WM_SetIcon(LoadRes(icon_path), NULL);
192        if ((screen = SDL_SetVideoMode(tile->w*8, (tile->h*2) + Y_OFFSET, 16, SDL_FULLSCREEN))
193                == NULL) {
194                fprintf(stderr, "Unable to set %dx%d video: %s", tile->w*8,
195                         tile->h*2, SDL_GetError());
196                         sdl_clean_up();
197                         return 1;
198        }
199        
200        
201        /* define the font color fot the exit text */
202        font_color_exit.r = 255;
203        font_color_exit.r = 255;
204        font_color_exit.r = 255;
205        
206        
207        
208        if (!(exit_text = TTF_RenderText_Blended(home_font, "EXIT", 
209              font_color_exit))) {
210                      fprintf(stderr, "SDL_ttf: %s\n", TTF_GetError());
211                      return 1;
212         }
213        
214         exit_rect.x = 400;
215         exit_rect.y = 0;
216         exit_rect.w = 0;
217         exit_rect.h = 0;
218         
219         SDL_BlitSurface(exit_text, NULL, screen, &exit_rect);
220         
221        state = HMN_WAIT;
222        redraw_board = 1;
223        old_highlight = 0;      
224        highlight = 0;
225        active = 0;
226        
227        /* GAME LOOP */
228        while (state != GAME_WON) {
229                
230                /* check for GTK events... */
231                /* otherwise hildon thinks the app hangs... */
232                while (gtk_events_pending ())
233                        gtk_main_iteration ();
234                
235                /* figure out if anything important happened */
236                old_highlight = highlight;
237                while (SDL_PollEvent(&event)) {
238                        /* BAIL OUT! BAIL OUT! */
239                        if (event.type == SDL_KEYDOWN){
240                                fprintf(stderr, "event SDL_KEYDOWN found....\n");
241                                if ( event.key.keysym.sym == SDLK_q )
242                                {
243                                        fprintf(stderr, "event SDLK_q found....\n");
244                                        SDL_Event quit_event;
245                                        quit_event.type = SDL_QUIT;
246                                        SDL_PushEvent(&quit_event);
247                                }
248                        }
249                        
250                        if (event.type == SDL_MOUSEBUTTONDOWN) {
251                                if ((event.button.button = 1) &&
252                                    (event.button.y < Y_OFFSET)) {
253                                        fprintf(stderr, "clicked out side the board in exit area...\n");
254                                        SDL_Event quit_event;
255                                        quit_event.type = SDL_QUIT;
256                                        SDL_PushEvent(&quit_event);
257                                }
258                        }
259                        
260                        if (event.type == SDL_QUIT) {
261                                fprintf(stderr, "event SDL_QUIT found....\n");
262                                sdl_clean_up();
263                                return 0;
264                        }
265                        
266                        /* get events */
267                        if (state == HMN_WAIT) {
268                                switch (event.type) {
269                                        case SDL_MOUSEBUTTONDOWN:
270                                                if ((event.button.button = 1) &&
271                                                    (event.button.y < tile->h) &&
272                                                    (event.button.y > Y_OFFSET)) {
273
274                                                        int pitch=0;
275                                                        pitch = event.button.x / tile->w;
276
277                                                         // pitch 0 and 7 are the homebases which you can't play
278                                                         if ( pitch == 0 || pitch == 7 ){
279                                                                  fprintf(stderr, "clicked out side the board...\n");
280                                                         }
281                                                         else{
282                                                                 current_move = pitch;
283                                                                 state = HMN_MOVE;
284                                                         }
285                                                }
286                                                break;
287                                        case SDL_MOUSEMOTION:
288                                                if (event.motion.y < tile->h) {
289                                                        highlight = event.motion.x / tile->w;
290                                                }
291                                                else
292                                                        highlight = 0;
293                                                break;
294                                        case SDL_ACTIVEEVENT:
295                                                if (event.active.gain == 0)
296                                                        highlight = 0;
297                                                break;
298                                }
299                        }
300                }
301                SDL_Delay(DELAY_MAX);
302                
303                /* GAME LOGIC */
304                if (gameWon(aiBoard, humanBoard) == 1)
305                        state = GAME_WON;
306                
307                /* happy happy state machine */
308                switch(state) {
309                        case HMN_WAIT:
310                                active = 0;
311                                if (highlight != old_highlight)
312                                        redraw_board = 1;
313                                break;
314                        case HMN_MOVE:
315                                human_last_move = move(humanBoard,aiBoard,current_move);
316                                play_sound(pick);
317                                redraw_board = 1;
318                                if (human_last_move == 0)
319                                        state = HMN_WAIT;
320                                else 
321                                        state = CMP_WAIT;
322                                printf("Human moving from %d to %d, now %d\n", current_move, human_last_move, state);
323                                break;
324                        case CMP_WAIT:
325                                SDL_Delay(DELAY_AI);
326                                active = 1;
327                                current_move = aiMove(aiBoard, humanBoard);
328                                state = CMP_MOVE;
329                                break;
330                        case CMP_MOVE:
331                                printf("Computer moving\n");
332                                ai_last_move = move(aiBoard,humanBoard,current_move);
333                                play_sound(pick);
334                                redraw_board = 1;
335                                if (ai_last_move == 0)
336                                        state = CMP_WAIT;
337                                else
338                                        state = HMN_WAIT;
339                                break;
340                        case GAME_WON:
341                                if (aiBoard[0] > humanBoard[0]) {
342                                        if (!(title_text = TTF_RenderText_Blended(title_font, 
343                                                "Computer Wins!", font_color)))
344                                                fprintf(stderr, "TTF: %s\n", TTF_GetError());
345                                }
346                                else {
347                                        if (!(title_text = TTF_RenderText_Blended(title_font, 
348                                                "Human Wins!", font_color))) 
349                                                fprintf(stderr, "TTF: %s\n", TTF_GetError());
350                                }
351                                redraw_board = 1;
352                                break;
353                }
354                
355                /* redraw the board if needed */
356                if (redraw_board == 1) {
357                        /*printf("redrawing board\n");*/
358                        
359                        /* draw and blit the board */
360                        board = DrawBoard(aiBoard, humanBoard, board_font, 
361                                           home_font, tile, stone, active, 
362                                           highlight);
363                                           if (!board) {
364                                                   fprintf(stderr, "Could not draw the board.\n");
365                                           }
366                                           else {
367                                                   // board_rect = SurfaceToRect(board);
368                                                   SDL_BlitSurface(board, NULL, screen, 
369                                                                    &board_rect);
370                                           }
371                                           
372                                           /* draw, center, and blit the title */
373                                           if (title_text) {
374                                                   title_rect = SurfaceToRect(title_text);
375                                                   title_rect.x = ((screen->w - title_rect.w)/2);
376                                                   title_rect.y = ((screen->h - title_rect.h)/2);
377                                                   SDL_BlitSurface(title_text, NULL, screen, 
378                                                                    &title_rect);
379                                           }
380                                           
381                                           SDL_UpdateRect(screen, 0,0,0,0);
382                                           
383                                           redraw_board = 0;
384                }
385                
386        }
387        
388        SDL_Delay(DELAY_AI);
389        
390        sdl_clean_up();
391        return 0;
392        
393 }
394