refraction 3
[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 #include <hgw/hgw.h>
26 #include <unistd.h>
27
28 #include "SDL_mixer.h"
29 #include "SDL.h"
30 #include "SDL_image.h"
31 #include "SDL_ttf.h"
32
33 #include "graphics.h"
34 #include "mancala.h"
35 #include "ai.h"
36 #include "sounds.h"
37 #include "play.h"
38
39 #include "callbacks.h"
40
41 // the surfaces
42 SDL_Surface *screen, *board, *title_text, *tile, *stone[STONE_MAX+1], *exit_text;
43 // the fonts
44 TTF_Font *title_font, *home_font, *board_font;
45 // The sound effects that will be used
46 Mix_Chunk *pick = NULL;
47 // the hildon-game-wrapper context
48 HgwContext *hgw_context = NULL;
49
50 void sdl_clean_up(){
51         
52         int i = 0;
53         
54         SDL_FreeSurface(board);
55         SDL_FreeSurface(tile);
56         SDL_FreeSurface(exit_text);
57         SDL_FreeSurface(title_text);
58         for(i=0; i<=STONE_MAX; i++)
59                 SDL_FreeSurface(stone[i]);
60         SDL_FreeSurface(screen);
61         TTF_CloseFont(title_font);
62         TTF_CloseFont(board_font);
63         TTF_CloseFont(home_font);
64         Mix_FreeChunk(pick);
65         /* Make sure we clean up after ourselves */
66         TTF_Quit();
67         Mix_CloseAudio();
68         SDL_Quit();
69         return;
70 }
71
72 int play() {
73         
74         SDL_Rect board_rect, title_rect, exit_rect;
75         SDL_Color font_color;
76         SDL_Event event;
77         SDL_Color font_color_exit;
78         
79         char tile_path[STRING_MAX], stone_path[STRING_MAX];
80         char icon_path[STRING_MAX], title_path[STRING_MAX];
81         char home_path[STRING_MAX], board_path[STRING_MAX];
82         char pick_path[STRING_MAX];
83         int aiBoard[BOARD_MAX+1], humanBoard[BOARD_MAX+1];
84         int i, redraw_board, highlight, old_highlight, active;
85         int current_move, ai_last_move, human_last_move, state;
86         
87         /* Set up the game board and game variables. */
88         gameInit(aiBoard, humanBoard);
89         current_move = 0;
90         ai_last_move = human_last_move = -99;
91         
92         /* initialize our libraries */
93         //if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0) {
94        if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
95                fprintf(stderr, "Unable to initialize SDL: %s\n", 
96                         SDL_GetError());
97                         sdl_clean_up();
98                         return 1;
99        }
100        
101        if (TTF_Init() < 0) {
102                fprintf(stderr, "Unable to initialize SDL_ttf: %s\n", 
103                         SDL_GetError());
104                         sdl_clean_up();
105                         return 1;
106        }
107        
108        //Initialize SDL_mixer 
109        
110        if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ) 
111        {
112                fprintf(stderr, "Unable to initialize Mix_OpenAudio: %s\n",
113                         SDL_GetError());
114                         sdl_clean_up();
115                         return 1;
116        }
117        
118        
119        /* Load our images... PNGs now, maybe XPMs later */
120        sprintf(tile_path, "%s/tile.png", RES_PATH);
121        if ((tile = LoadRes(tile_path)) == NULL) {
122                fprintf(stderr, "Unable to load resource: %s\n", 
123                         SDL_GetError());
124                         sdl_clean_up();
125                         return 1;
126        }
127        
128        for (i=0; i<=STONE_MAX; i++) {
129                if (sprintf(stone_path, "%s/stone%02d.png", RES_PATH, i) == 0)
130                        fprintf(stderr, "Problems assembling path.\n");
131                if (!(stone[i] = LoadRes(stone_path))) {
132                        fprintf(stderr, "Unable to load resource: %s\n",
133                                 SDL_GetError());
134                                 sdl_clean_up();
135                                 return 1;
136                }
137        }
138        
139        /* Load our font(s) */
140        if (sprintf(title_path, "%s/luxisr.ttf", FONT_PATH) == 0)
141                fprintf(stderr, "Problems assembling path.\n");
142        if (!(title_font = TTF_OpenFont(title_path, TITLE_SIZE))) {
143                fprintf(stderr, "Could not load font: %s\n", TTF_GetError());
144                sdl_clean_up();
145                return 1;
146        }
147        
148        if (sprintf(board_path, "%s/luxisr.ttf", FONT_PATH) == 0)
149                fprintf(stderr, "Problems assembling path.\n");
150        if (!(board_font = TTF_OpenFont(board_path, BOARD_SIZE))) {
151                fprintf(stderr, "Could not load font: %s\n", TTF_GetError());
152                sdl_clean_up();
153                return 1;
154        }
155        
156        if (sprintf(home_path, "%s/luxisr.ttf", FONT_PATH) == 0)
157                fprintf(stderr, "Problems assembling path.\n");
158        if (!(home_font = TTF_OpenFont(home_path, HOME_SIZE))) {
159                fprintf(stderr, "Could not load font: %s\n", TTF_GetError());
160                sdl_clean_up();
161                return 1;
162        }
163        
164        /* Load sound effects */ 
165        sprintf(pick_path, "%s/pick.wav", RES_PATH); 
166        if ((pick = Mix_LoadWAV(pick_path)) == NULL) { 
167                fprintf(stderr, "Unable to load sound: %s\n", 
168                         SDL_GetError());
169                         sdl_clean_up();
170                         return 1; 
171        }
172        
173        /* store the font's color */
174        font_color.r = 255;
175        font_color.b = 255;
176        font_color.g = 255;
177        
178        /* render the title text 
179        if (!(title_text = TTF_RenderText_Solid(title_font, 
180                "Mancala", font_color))) 
181                fprintf(stderr, "TTF: %s\n", TTF_GetError());
182        */
183        title_text = NULL;
184        
185        
186        /* define the position of the board in the screen */
187        board_rect.x = 0;
188        board_rect.y = Y_OFFSET;
189        board_rect.w = 0;
190        board_rect.h = 0;
191        
192        /* set window properties and create it */
193        SDL_WM_SetCaption("Mancala", "Mancala");
194        if (sprintf(icon_path, "%s/icon.png", RES_PATH) == 0)
195                fprintf(stderr, "Problems assembling icon path.\n");
196        SDL_WM_SetIcon(LoadRes(icon_path), NULL);
197        if ((screen = SDL_SetVideoMode(tile->w*8, (tile->h*2) + Y_OFFSET, 16, SDL_FULLSCREEN))
198                == NULL) {
199                fprintf(stderr, "Unable to set %dx%d video: %s", tile->w*8,
200                         tile->h*2, SDL_GetError());
201                         sdl_clean_up();
202                         return 1;
203        }
204        
205        
206        /* define the font color fot the exit text */
207        font_color_exit.r = 255;
208        font_color_exit.r = 255;
209        font_color_exit.r = 255;
210        
211        
212        
213        if (!(exit_text = TTF_RenderText_Blended(home_font, "EXIT", 
214              font_color_exit))) {
215                      fprintf(stderr, "SDL_ttf: %s\n", TTF_GetError());
216                      return 1;
217         }
218        
219         exit_rect.x = 400;
220         exit_rect.y = 0;
221         exit_rect.w = 0;
222         exit_rect.h = 0;
223         
224         SDL_BlitSurface(exit_text, NULL, screen, &exit_rect);
225         
226        state = HMN_WAIT;
227        redraw_board = 1;
228        old_highlight = 0;      
229        highlight = 0;
230        active = 0;
231        
232        /* GAME LOOP */
233        while (state != GAME_WON) {
234                
235                /* check for GTK events... */
236                /* otherwise hildon thinks the app hangs... */
237                while (gtk_events_pending ())
238                        gtk_main_iteration ();
239                
240                /* figure out if anything important happened */
241                old_highlight = highlight;
242                while (SDL_PollEvent(&event)) {
243                        /* BAIL OUT! BAIL OUT! */
244                        if (event.type == SDL_KEYDOWN){
245                                fprintf(stderr, "event SDL_KEYDOWN found....\n");
246                                if ( event.key.keysym.sym == SDLK_q )
247                                {
248                                        fprintf(stderr, "event SDLK_q found....\n");
249                                        SDL_Event quit_event;
250                                        quit_event.type = SDL_QUIT;
251                                        SDL_PushEvent(&quit_event);
252                                }
253                        }
254                        
255                        if (event.type == SDL_MOUSEBUTTONDOWN) {
256                                if ((event.button.button = 1) &&
257                                    (event.button.y < Y_OFFSET)) {
258                                        fprintf(stderr, "clicked out side the board in exit area...\n");
259                                        SDL_Event quit_event;
260                                        quit_event.type = SDL_QUIT;
261                                        SDL_PushEvent(&quit_event);
262                                }
263                        }
264                        
265                        if (event.type == SDL_QUIT) {
266                                fprintf(stderr, "event SDL_QUIT found....\n");
267                                sdl_clean_up();
268                                return 0;
269                        }
270                        
271                        /* get events */
272                        if (state == HMN_WAIT) {
273                                switch (event.type) {
274                                        case SDL_MOUSEBUTTONDOWN:
275                                                if ((event.button.button = 1) &&
276                                                    (event.button.y < tile->h) &&
277                                                    (event.button.y > Y_OFFSET)) {
278
279                                                        int pitch=0;
280                                                        pitch = event.button.x / tile->w;
281
282                                                         // pitch 0 and 7 are the homebases which you can't play
283                                                         if ( pitch == 0 || pitch == 7 ){
284                                                                  fprintf(stderr, "clicked out side the board...\n");
285                                                         }
286                                                         else{
287                                                                 current_move = pitch;
288                                                                 state = HMN_MOVE;
289                                                         }
290                                                }
291                                                break;
292                                        case SDL_MOUSEMOTION:
293                                                if (event.motion.y < tile->h) {
294                                                        highlight = event.motion.x / tile->w;
295                                                }
296                                                else
297                                                        highlight = 0;
298                                                break;
299                                        case SDL_ACTIVEEVENT:
300                                                if (event.active.gain == 0)
301                                                        highlight = 0;
302                                                break;
303                                }
304                        }
305                }
306                SDL_Delay(DELAY_MAX);
307                
308                /* GAME LOGIC */
309                if (gameWon(aiBoard, humanBoard) == 1)
310                        state = GAME_WON;
311                
312                /* happy happy state machine */
313                switch(state) {
314                        case HMN_WAIT:
315                                active = 0;
316                                if (highlight != old_highlight)
317                                        redraw_board = 1;
318                                break;
319                        case HMN_MOVE:
320                                human_last_move = move(humanBoard,aiBoard,current_move);
321                                play_sound(pick);
322                                redraw_board = 1;
323                                if (human_last_move == 0)
324                                        state = HMN_WAIT;
325                                else 
326                                        state = CMP_WAIT;
327                                printf("Human moving from %d to %d, now %d\n", current_move, human_last_move, state);
328                                break;
329                        case CMP_WAIT:
330                                SDL_Delay(DELAY_AI);
331                                active = 1;
332                                current_move = aiMove(aiBoard, humanBoard);
333                                state = CMP_MOVE;
334                                break;
335                        case CMP_MOVE:
336                                printf("Computer moving\n");
337                                ai_last_move = move(aiBoard,humanBoard,current_move);
338                                play_sound(pick);
339                                redraw_board = 1;
340                                if (ai_last_move == 0)
341                                        state = CMP_WAIT;
342                                else
343                                        state = HMN_WAIT;
344                                break;
345                        case GAME_WON:
346                                if (aiBoard[0] > humanBoard[0]) {
347                                        if (!(title_text = TTF_RenderText_Blended(title_font, 
348                                                "Computer Wins!", font_color)))
349                                                fprintf(stderr, "TTF: %s\n", TTF_GetError());
350                                }
351                                else {
352                                        if (!(title_text = TTF_RenderText_Blended(title_font, 
353                                                "Human Wins!", font_color))) 
354                                                fprintf(stderr, "TTF: %s\n", TTF_GetError());
355                                }
356                                redraw_board = 1;
357                                break;
358                }
359                
360                /* redraw the board if needed */
361                if (redraw_board == 1) {
362                        /*printf("redrawing board\n");*/
363                        
364                        /* draw and blit the board */
365                        board = DrawBoard(aiBoard, humanBoard, board_font, 
366                                           home_font, tile, stone, active, 
367                                           highlight);
368                                           if (!board) {
369                                                   fprintf(stderr, "Could not draw the board.\n");
370                                           }
371                                           else {
372                                                   // board_rect = SurfaceToRect(board);
373                                                   SDL_BlitSurface(board, NULL, screen, 
374                                                                    &board_rect);
375                                           }
376                                           
377                                           /* draw, center, and blit the title */
378                                           if (title_text) {
379                                                   title_rect = SurfaceToRect(title_text);
380                                                   title_rect.x = ((screen->w - title_rect.w)/2);
381                                                   title_rect.y = ((screen->h - title_rect.h)/2);
382                                                   SDL_BlitSurface(title_text, NULL, screen, 
383                                                                    &title_rect);
384                                           }
385                                           
386                                           SDL_UpdateRect(screen, 0,0,0,0);
387                                           
388                                           redraw_board = 0;
389                }
390                
391        }
392        
393        SDL_Delay(DELAY_AI);
394        
395        sdl_clean_up();
396        return 0;
397        
398 }
399
400
401 int main(int argc, char **argv) {
402     
403     fprintf(stderr, "mancala main loop\n");
404 //     #if HGW_FUNC
405     hgw_context = hgw_context_compat_init(argc, argv);
406     if (!hgw_context) {
407         fprintf(stderr, "Cannot init hildon-games-startup!\n");
408         return 0;
409     }
410     hgw_compat_set_cb_exit(hgw_context, exit_callback);
411     hgw_compat_set_cb_quit(hgw_context, quit_callback);
412     hgw_compat_set_cb_flush(hgw_context, flush_callback);
413     if(!hgw_context_compat_check(hgw_context)) return 0;
414     
415     /* hildon-games-wrapper part */
416     hgw_msg_compat_receive(hgw_context, 0);
417     usleep(100);
418 //     #endif
419     // Main game
420     play();
421     
422 //     #if HGW_FUNC
423     hgw_context_compat_destroy_deinit(hgw_context);
424 //     #endif
425     
426     return 0;
427 }
428