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