1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16 #include <string.h>
17 #include <gtk/gtk.h>
18 #include <glib/gi18n.h>
19 #include <gdk/gdkkeysyms.h>
20 #include "load.h"
21 #include "free.h"
22 #include "alloc.h"
23 #include "draw.h"
24 #include "throw.h"
25 #include "game.h"
26 #include "position.h"
27 #include "select.h"
28 #include "set.h"
29 #include "get.h"
30 #include "callback.h"
31 #include "find.h"
32 #include "clear.h"
33 #include "list.h"
34 #include "def.h"
35
36 #include "config.h"
37
event_blink(gpointer data)38 gboolean event_blink(gpointer data)
39 {
40 struct _prog *prog_data = (struct _prog*) data;
41
42 struct _card *tmp;
43
44 GList *lst;
45
46 struct _card *card = NULL;
47
48
49 for(lst = prog_data->waiting; lst; lst = lst->next)
50 {
51 tmp = lst->data;
52
53 if(tmp->blink == TRUE)
54 {
55 tmp->draw = !tmp->draw;
56 card = tmp;
57 }
58 }
59
60
61 if(card && prog_data->copy)
62 {
63 GdkGC *gc = prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)];
64
65 if(card->draw == TRUE)
66 {
67 draw_card_pixmap(card->pixmap, card->pixmask,
68 prog_data->target, card->dim.x, card->dim.y, gc);
69 /*gdk_gc_set_clip_mask(gc,
70 prog_data->cardmask);
71
72 gdk_gc_set_clip_origin(gc,
73 card->dim.x,
74 card->dim.y);
75
76 gdk_draw_pixbuf( prog_data->target,
77 gc,
78 card->img, 0, 0,
79 card->dim.x, card->dim.y, card->dim.w, card->dim.h,
80 GDK_RGB_DITHER_NONE, 0, 0);
81
82 gdk_gc_set_clip_mask(gc, NULL);*/
83 }
84 else
85 gdk_draw_drawable(prog_data->target,
86 gc,
87 prog_data->copy,
88 card->dim.x, card->dim.y, card->dim.x, card->dim.y,
89 card->dim.w, card->dim.h);
90
91
92 gdk_draw_drawable( prog_data->area->window,
93 gc, prog_data->target,
94 card->dim.x, card->dim.y, card->dim.x, card->dim.y,
95 card->dim.w, card->dim.h);
96
97 }
98
99 return(TRUE);
100 }
101
key_down(GtkWidget * widget,GdkEventKey * event,gpointer user_data)102 gboolean key_down(GtkWidget *widget,
103 GdkEventKey *event,
104 gpointer user_data)
105 {
106 struct _prog *prog_data = user_data;
107
108 if(event->type == GDK_KEY_PRESS)
109 {
110 /*int family = 0;
111
112 if(prog_data->waiting)
113 family = ((struct _card*)prog_data->waiting->data)->family ;
114 if(prog_data->state == EGS_SECOND)
115 {
116 int j = -1;
117 switch(event->keyval)
118 {
119 case GDK_1:
120 case GDK_KP_1:
121 j = 0;
122 case GDK_2:
123 case GDK_KP_2:
124 if(j==-1)
125 j = 1;
126 case GDK_3:
127 case GDK_KP_3:
128 if(j==-1)
129 j = 2;
130 case GDK_4:
131 case GDK_KP_4:
132 if(j==-1)
133 j = 3;
134 if( j != family )
135 {
136 int i;
137 for(i = 0; i<4; i++)
138 gtk_widget_set_sensitive(
139 prog_data->allwidgets[10+i],
140 FALSE);
141 }
142 break;
143 }
144 if(j != -1 && j != family )
145 click_selectmaster(prog_data, prog_data->player, j);
146 }
147 else if(prog_data->state == READY_DISTRIB2
148 && is_player_next(prog_data, 2) )
149 {
150 int j= g_list_length(prog_data->players[2]);
151 switch(event->keyval)
152 {
153 case GDK_1: j = j-1;
154 break;
155 case GDK_2: j = j-2;
156 break;
157 case GDK_3: j = j-3;
158 break;
159 case GDK_4: j = j-4;
160 break;
161 case GDK_5: j = j-5;
162 break;
163 case GDK_6: j = j-6;
164 break;
165 case GDK_7: j = j-7;
166 break;
167 case GDK_8: j = j-8;
168 break;
169
170 }
171
172 if(j >= 0)
173 {
174 game_turn(prog_data, g_list_nth_data(prog_data->players[2], j) );
175 game_play_ia(prog_data);
176 }
177 }*/
178
179 switch(event->keyval)
180 {
181 case GDK_Escape:
182 if(prog_data->movecard)
183 {
184 if(prog_data->copy)
185 g_object_unref(prog_data->copy);
186
187 prog_data->copy = NULL;
188
189 prog_data->movecard->card->draw = TRUE;
190
191 g_free(prog_data->movecard);
192 prog_data->movecard = NULL;
193
194 draw_container(prog_data);
195 }
196 break;
197 /*
198 case GDK_space:
199 if(prog_data->state == READY_DISTRIB1
200 || prog_data->state == EGS_SECOND)
201 dowhatever_click(prog_data);
202 else
203 action_click(prog_data);
204
205 break;
206
207 case GDK_Return:
208 if(prog_data->state == READY_DISTRIB1)
209 {
210 int i;
211 for(i = 0; i<4; i++)
212 gtk_widget_set_sensitive(
213 prog_data->allwidgets[10+i],
214 FALSE);
215 click_selectmaster(prog_data,
216 prog_data->player, family);
217 }
218 break;
219
220 */
221 }
222 }
223 }
224
225
226 /* click_givecard : takes care of distributing
227 * the first batch of cards to the players
228 * (5 cards each) and show one more card. This
229 * final card will be proposed to each player
230 * one at a time. If anyone decide to take it,
231 * then the family of this card will become the
232 * master family of the round (trump).
233 *
234 * struct _prog *prog_data: see file def.h
235 *
236 * What is needed in struct _prog :
237 *
238 * prog_data->state : the status of the game
239 * right now. Are we playing yet ?
240 * This is an enum egstate (see file def.h
241 * for more details about it)
242 *
243 * prog_data->allwidgets[4] : allwidgets is
244 * an array composed by many GtkWidget* each.
245 * The Fifth ([4]) is a spinbutton; which will
246 * be suppressed in the future.
247 */
click_givecard(struct _prog * prog_data)248 void click_givecard(struct _prog *prog_data)
249 {
250 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[6]), NULL);
251 gtk_button_set_label(GTK_BUTTON(prog_data->allwidgets[2]),
252 _("Pass") );
253
254 prog_data->state = DISTRIBUTING;
255
256 game_distribute_phase1(prog_data);
257
258 game_finish_phase1(prog_data);
259
260 prog_data->player = prog_data->distributer;
261
262 select_player_next(&prog_data->player);
263
264 prog_data->menext = prog_data->player;
265
266 prog_data->state = READY_DISTRIB1;
267
268 if(prog_data->output != NULL)
269 {
270 fprintf(prog_data->output,
271 _("Ready, distribution phase 1 done.\n") );
272 }
273
274 game_choose_trump(prog_data);
275 }
276
play_next_turn(struct _prog * prog_data)277 gboolean play_next_turn(struct _prog* prog_data)
278 {
279 return (
280 prog_data->player != 2
281 && prog_data->player == prog_data->menext
282 && prog_data->players[prog_data->player]
283 );
284 }
285
286 /* click_selectmaster : Start the first turn of this round.
287 * This means many things has to be done. First of all
288 * when calling this function it means a player decided
289 * which master family is the trump of this round.
290 * We need to set this, to send the remaining cards
291 * to each player (3 each, except the so called master
292 * of the game, he will get 2 from the pile and one
293 * which was the card proposed to the players as the
294 * trump). Then we needs to set new points for all
295 * cards from the trump family. They are now more
296 * powerful then they were initialised.
297 * Then the computer will play he has to.
298 *
299 * struct _prog *prog_data: see file def.h
300 *
301 * What is needed in struct _prog:
302 *
303 * prog_data->state : an enum egstate, see
304 * file def.h for more details
305 *
306 * prog_data->master : who takes the proposed
307 * card.
308 *
309 * prog_data->player : who has to drop a card
310 * right now. It's not exactly always this.
311 * When each players has dropped one card,
312 * the player is not the player who needs to
313 * drop a card next.
314 *
315 * prog_data->hashand : who is in charge
316 * of deciding the first of each four cards
317 * to be dropped on the table at each turn.
318 * This is the player who has the hand
319 * before anyone drops a more powerful card.
320 * Note: it's not chaning when someone do
321 * this (dropping a more powerful card).
322 * That is why it's called "hashand" and not
323 * "havehand". See menext for the player who
324 * have the hand right now.
325 *
326 * prog_data->menext : the player which
327 * win this turn at the moment. It can
328 * be changed at any card drop except the
329 * first. When you win a turn, you are
330 * the first to drop the first card next.
331 * This is exactly when menext should
332 * not be changed. You can't change menext
333 * at this time because you are the one
334 * to drop the card. You are then already
335 * the menext player.
336 *
337 * prog_data->distributer : which player
338 * takes care of distributing the cards.
339 * Note: you don't have to do it with
340 * the mouse or something like this. This
341 * is all virtual dude. Anyway it's needed
342 * to know who is the first to play on the
343 * first turn.
344 * Note: each round it's incremented by
345 * turning round the clock.
346 *
347 * prog_data->family : the trump color.
348 *
349 * prog_data->allwidgets[4] : allwidgets is an
350 * array composed by many GtkWidget*.
351 * The fifth is the spinbutton, which will
352 * be suppressed in the future.
353 *
354 * prog_data->waiting : a GList representing
355 * the table. This is where you drop your cards.
356 * Each element of this list is a struct _card,
357 * defined in the def.h file.
358 *
359 * prog_data->allwidgets[5] : a GtkImage
360 * containing nothing at first. This is where
361 * we put the icon of the trump family
362 * (diamond, spade, heart or club)
363 *
364 * prog_data->icons : an array of 4 GtkImage,
365 * each of the family icons.
366 *
367 * prog_data->output : the stream to print
368 * messages to. Default is stdout.
369 */
click_selectmaster(struct _prog * prog_data,int master,int trump)370 void click_selectmaster(struct _prog *prog_data, int master, int trump)
371 {
372 char str[10];
373
374 prog_data->state = DISTRIBUTING;
375
376 prog_data->master = master;
377
378 switch(master)
379 {
380 case 0:
381 g_stpcpy(str, _("Top") );
382 break;
383 case 1:
384 g_stpcpy(str, _("Right") );
385 break;
386 case 2:
387 g_stpcpy(str, _("You") );
388 break;
389 case 3:
390 g_stpcpy(str, _("Left") );
391 break;
392 }
393
394 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[7]), str);
395
396 prog_data->family = trump;
397
398 prog_data->player = prog_data->menext;
399 prog_data->hashand = prog_data->menext;
400
401 gtk_image_set_from_pixbuf(GTK_IMAGE(prog_data->allwidgets[5]),
402 prog_data->icons[prog_data->family]);
403
404 if(prog_data->output != NULL)
405 {
406 fprintf(prog_data->output, _("Trump: ") );
407 game_print_family(prog_data->output, prog_data->family);
408 fprintf(prog_data->output, "\n");
409 }
410
411 game_distribute_phase2(prog_data);
412
413 set_points(prog_data);
414
415 prog_data->players[2] = g_list_sort(prog_data->players[2],
416 list_sort);
417
418 if(prog_data->withdeclaration == TRUE)
419 {
420 game_check_declarations(prog_data);
421 }
422
423 gtk_label_set_text(GTK_LABEL(prog_data->allwidgets[8]),
424 "1/8" );
425
426 gtk_button_set_label(GTK_BUTTON(prog_data->allwidgets[2]),
427 _("Next") );
428 gtk_widget_set_sensitive(prog_data->allwidgets[2], FALSE);
429
430 if(prog_data->player == 2)
431 {
432 set_moveable(prog_data->players[2], TRUE);
433 }
434 else
435 {
436 set_moveable(prog_data->players[2], FALSE);
437 }
438
439 prog_data->state = READY_DISTRIB2;
440
441 game_hand_position(prog_data, -1);
442
443
444 draw_container(prog_data);
445
446 if( play_next_turn(prog_data) )
447 {
448 game_turn(prog_data, NULL);
449 }
450 game_play_ia(prog_data);
451
452 }
453
454 /* click_play : a mouse click on the
455 * game area means something should be
456 * done. The action here can be a card
457 * drop, a distributing process, or
458 * an end of a round.
459 * In all case it should be related to
460 * the computer doing something.
461 */
click_play(struct _prog * prog_data)462 void click_play(struct _prog *prog_data)
463 {
464
465 game_turn(prog_data, NULL);
466
467 game_play_ia(prog_data);
468 }
469
470 /* action_click : the user clicked
471 * on something. And we need to know
472 * what he means. This is depending
473 * on the game state.
474 *
475 * struct _prog *prog_data: see file def.h
476 *
477 * What is used in the struct _prog:
478 *
479 * prog_data->state : enum egstate,
480 * see file def.h for more details.
481 *
482 *
483 */
action_click(struct _prog * prog_data)484 void action_click(struct _prog *prog_data)
485 {
486 if(prog_data->state == READY_PILE)
487 {
488 if(prog_data->output != NULL)
489 {
490 fprintf(prog_data->output,
491 _("Distribute phase 1 please!\n") );
492 }
493
494 if((prog_data->points[0] > 100 || prog_data->points[1] > 100 )
495 && (prog_data->points[0] != prog_data->points[1]) )
496 {
497
498 free_cell_list(&prog_data->cells);
499
500
501 prog_data->report = 0;
502
503 prog_data->points[0] = 0;
504 prog_data->points[1] = 0;
505
506 prog_data->row = 0;
507
508 gtk_table_resize(GTK_TABLE(prog_data->allwidgets[9]),
509 1, 2);
510
511 }
512
513
514 click_givecard(prog_data);
515 }
516 else
517 if(prog_data->state == READY_DISTRIB2)
518 {
519 /*if(prog_data->output != NULL)
520 fprintf(prog_data->output,
521 _("Play !\n") );*/
522
523 click_play(prog_data);
524 }
525
526 draw_container(prog_data);
527 }
528
529 /* event_start : user clicked on the Start
530 * labelled button. In the future this will
531 * be replaced by something else.
532 *
533 * struct _prog *prog_data: see file def.h
534 *
535 */
event_start(GtkButton * button,gpointer data)536 void event_start(GtkButton *button, gpointer data)
537 {
538 struct _prog *prog_data = (struct _prog*)data;
539
540 dowhatever_click(prog_data);
541
542 }
543
dowhatever_click(struct _prog * prog_data)544 void dowhatever_click(struct _prog * prog_data)
545 {
546
547 if(prog_data->output != NULL)
548 {
549 fprintf(prog_data->output,
550 _("Click on Button\n") );
551 }
552
553 if(prog_data->state == READY_DISTRIB1)
554 {
555 gtk_widget_set_sensitive(prog_data->allwidgets[10+
556 ((struct _card*)prog_data->waiting->data)->family],
557 FALSE);
558
559 if(prog_data->output != NULL)
560 {
561 fprintf(prog_data->output,
562 _("You don't want this card. Ok!\n") );
563 }
564
565 game_choose_trump_next(prog_data);
566
567 }
568 else if(prog_data->state == EGS_SECOND)
569 {
570 int i;
571 for(i=0; i<4; i++)
572 {
573 if(i != ((struct _card*)prog_data->waiting->data)->family )
574 gtk_widget_set_sensitive(prog_data->allwidgets[10+i], FALSE);
575 }
576
577 if(prog_data->output)
578 {
579 fprintf(prog_data->output,
580 _("Player decided to pass a second time.\n") );
581 }
582
583 game_choose_trump_next(prog_data);
584 }
585 else
586 action_click(prog_data);
587
588 }
589
590 /* motion_notify_event : the user drag the mouse.
591 * This means a mouse button is pressed and the
592 * cursor is moving.
593 *
594 * struct _prog *prog_data: see fil def.h
595 *
596 * What is needed in struct _prog:
597 *
598 * prog_data->movecard : this is a pointer
599 * to a struct _movingcard defined in the
600 * def.h file. It will be NULL if there are
601 * no moving card at the moment. A moving
602 * card is a card which the user is dragging
603 * around on the game area.
604 * The struct contains informations about
605 * this card, like a pointer to the
606 * struct _card of this particular card.
607 * Also a separate struct _dim for the
608 * position of the dragged card exists
609 * because we need to recover the orginal
610 * position of the card if it can't be
611 * dropped. It's preferable to keep
612 * the original data in the struct _card,
613 * not in the newly allocated movecard _dim.
614 *
615 */
motion_notify_event(GtkWidget * widget,GdkEventMotion * event,gpointer data)616 gint motion_notify_event (GtkWidget *widget, GdkEventMotion *event,
617 gpointer data)
618 {
619 struct _prog *prog_data = (struct _prog*)data;
620
621 struct _target *zone = NULL;
622
623 GdkPixmap *source;
624
625 int x, y, w, h, toph, leftw,
626 ax, ay, aw, ah,
627 bx, by, bw, bh;
628
629 if(prog_data->movecard)
630 {
631 if(!prog_data->copy)
632 {
633 prog_data->movecard->card->draw = FALSE;
634
635 draw_copy(prog_data);
636
637 prog_data->movecard->card->draw = TRUE;
638 }
639
640 if(prog_data->copy)
641 {
642 x = prog_data->movecard->dim.x;
643 y = prog_data->movecard->dim.y;
644
645 w = prog_data->movecard->card->dim.w;
646 h = prog_data->movecard->card->dim.h;
647
648 gdk_draw_drawable(prog_data->target,
649 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
650 prog_data->copy,
651 x-1, y-1, x-1, y-1, w+2, h+2);
652
653 if(prog_data->dropping)
654 {
655 zone = draw_dropping_zone(prog_data,
656 prog_data->target);
657
658 }
659
660 prog_data->movecard->dim.x =
661 (gint)event->x -prog_data->movecard->dim.w;
662
663 prog_data->movecard->dim.y =
664 (gint)event->y -prog_data->movecard->dim.h;
665 if(zone)
666 {
667 if(zone->active == FALSE)
668 source = prog_data->copy;
669 else
670 source = prog_data->target;
671
672
673 gdk_draw_drawable(prog_data->area->window,
674 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
675 source,
676 zone->dim.x, zone->dim.y,
677 zone->dim.x, zone->dim.y,
678 zone->dim.w, 1);
679
680
681 gdk_draw_drawable(prog_data->area->window,
682 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
683 source,
684 zone->dim.x+zone->dim.w,
685 zone->dim.y,
686 zone->dim.x+zone->dim.w,
687 zone->dim.y,
688 1, zone->dim.h);
689
690 gdk_draw_drawable(prog_data->area->window,
691 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
692 source,
693 zone->dim.x,
694 zone->dim.y+zone->dim.h,
695 zone->dim.x,
696 zone->dim.y+zone->dim.h,
697 zone->dim.w+1, 1);
698
699 gdk_draw_drawable(prog_data->area->window,
700 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
701 source,
702 zone->dim.x,
703 zone->dim.y,
704 zone->dim.x,
705 zone->dim.y,
706 1, zone->dim.h);
707
708 }
709
710 draw_moving_card(prog_data, prog_data->target);
711
712 gdk_draw_drawable(prog_data->area->window,
713 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
714 prog_data->target,
715 prog_data->movecard->dim.x,
716 prog_data->movecard->dim.y,
717 prog_data->movecard->dim.x,
718 prog_data->movecard->dim.y,
719 w, h);
720
721
722 /*----Refreshing area optimization----
723 * try this on an old XXX Mhz, and
724 * see how fast it is when you drag
725 * a card around. */
726 if(x <= prog_data->movecard->dim.x)
727 {
728 leftw = prog_data->movecard->dim.x -x;
729 bx = x-1;
730
731 bw = leftw+2;
732 }
733 else
734 {
735 leftw = w-x+prog_data->movecard->dim.x;
736 bx = x+leftw-1;
737
738 bw = w-leftw+2;
739 }
740
741 if(y <= prog_data->movecard->dim.y)
742 {
743 ax = x-1;
744 ay = y-1;
745 toph = prog_data->movecard->dim.y -y;
746 ah = toph+1;
747 aw = w+2;
748
749 by = y+toph;
750 bh = h - toph +1;
751 }
752 else
753 {
754 toph = h-(y-prog_data->movecard->dim.y);
755 ax = x -1;
756 ay = y+toph;
757 ah = h - toph +1;
758 aw = w +2;
759
760 by = y-1;
761 bh = toph+1;
762 }
763
764
765 gdk_draw_drawable(
766 prog_data->area->window,
767 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
768 prog_data->target,
769 ax, ay, ax, ay,
770 aw, ah);
771
772 gdk_draw_drawable(
773 prog_data->area->window,
774 prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)],
775 prog_data->target,
776 bx, by, bx, by,
777 bw, bh);
778
779 }
780
781 }
782
783 return TRUE;
784 }
785
786
787
788 /* button_press_event : user did press a mouse button.
789 *
790 * prog_data->waiting: GList containing cards dropped
791 * on the table.
792 *
793 * prog_data->players[2] : GList containing the user
794 * hand. The player corresponding to the human
795 * player is the third of the players array ([2])
796 * and is represented at the bottom of the screen.
797 *
798 */
button_press_event(GtkWidget * widget,GdkEventButton * event,gpointer data)799 void button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer data)
800 {
801 struct _prog *prog_data = (struct _prog*)data;
802
803 gboolean found = FALSE;
804
805 if(event->button == 1)
806 {
807 found = find_moveable_card(prog_data->waiting, event, prog_data);
808
809 if(found == FALSE)
810 found = find_moveable_card(prog_data->players[2], event, prog_data);
811
812 if(found == TRUE)
813 clear_blink(prog_data);
814 }
815 }
816
is_player_next(struct _prog * prog_data,int n)817 gboolean is_player_next(struct _prog *prog_data, int n)
818 {
819 return (
820 (
821 (prog_data->player == n
822 && prog_data->player != prog_data->hashand )
823 || ( prog_data->player == prog_data->hashand
824 && prog_data->menext == n)
825 )
826 && prog_data->players[n] != NULL
827 );
828 }
829
game_drop_enable(struct _prog * prog_data)830 gboolean game_drop_enable(struct _prog *prog_data)
831 {
832 struct _target *zone = get_active_targetzone(prog_data->dropping);
833
834 return (
835 prog_data->no_drag == TRUE
836 || ( zone
837 && zone->active == TRUE
838 && (prog_data->state == READY_DISTRIB2
839 || prog_data->state == READY_DISTRIB1)
840 )
841 );
842 }
843
844 /* button_release_event : user released a pressed
845 * mouse button. This means we need to check if
846 * a card was selected. If true, then we want
847 * to check if it can be dropped here.
848 *
849 * See file def.h for more details about
850 * structs and their fields.
851 */
button_release_event(GtkWidget * widget,GdkEventButton * event,gpointer data)852 void button_release_event (GtkWidget *widget,
853 GdkEventButton *event, gpointer data)
854 {
855 struct _prog *prog_data = (struct _prog*)data;
856
857 struct _card *drop = NULL;
858
859 if(event->button == 1)
860 {
861 if(prog_data->movecard)
862 {
863 if(prog_data->copy)
864 g_object_unref(prog_data->copy);
865
866 prog_data->copy = NULL;
867
868 prog_data->movecard->card->draw = TRUE;
869
870 if( is_player_next(prog_data, 2) )
871 {
872 if(prog_data->output != NULL)
873 fprintf(prog_data->output,
874 _("Click on a moveable card!\n") );
875
876 if( game_drop_enable(prog_data) )
877 drop = prog_data->movecard->card;
878 }
879
880 g_free(prog_data->movecard);
881 prog_data->movecard = NULL;
882
883 if(drop != NULL)
884 {
885 if(prog_data->state == READY_DISTRIB1)
886 {
887 if(prog_data->output != NULL)
888 {
889 fprintf(prog_data->output,
890 _("You selected the card!\n") );
891 }
892
893 gtk_widget_set_sensitive(
894 prog_data->allwidgets[10+((struct _card*)
895 prog_data->waiting->data)->family], FALSE);
896
897 click_selectmaster(prog_data, 2,
898 ((struct _card*)prog_data->waiting->data)->family);
899 }
900 else if(prog_data->state != EGS_SECOND)
901 {
902 if(prog_data->hide == TRUE)
903 {
904 int i;
905
906 prog_data->hide = FALSE;
907
908 for(i = 0; i < 4; i++)
909 {
910 if(i != 2)
911 set_draw_face(prog_data->players[i], FALSE);
912 }
913 }
914
915 gtk_label_set_text(
916 GTK_LABEL(prog_data->allwidgets[6]),
917 NULL);
918
919 game_turn(prog_data, drop);
920
921 game_play_ia(prog_data);
922 }
923 }
924
925 draw_container(prog_data);
926 }
927 else
928 {
929 /*if(prog_data->output != NULL)
930 fprintf(prog_data->output,
931 _("Click on game area occured\n") );*/
932
933 action_click(prog_data);
934 }
935 }
936 }
937
938 /* realisation : the game area has been
939 * initilialised by Gtk, we now needs to
940 * draw it. This means allocating a
941 * GtkPixmap to draw to, then loading
942 * cards (because we need to know the window
943 * depth before loading any images).
944 *
945 * Then we can set the position of the
946 * dropping zone area, because we need
947 * to know the size of the area before
948 * positioning it. At least it's true
949 * for the middle area of the table.
950 * At the moment it's the only dropping
951 * area created.
952 *
953 * Then we can start the game, that means
954 * preparing everything for the game to
955 * be played. As an example there is the
956 * prog_data->pile GList that needs to be
957 * mixed.
958 *
959 * See game_start() function for more details
960 * about what needs to be done. (file game.c)
961 *
962 * return gboolean: see Gtk documentation
963 * about realize event of a gdk-drawing area.
964 */
realisation(GtkWidget * aire_de_dessin,gpointer data)965 gboolean realisation( GtkWidget *aire_de_dessin, gpointer data )
966 {
967 struct _prog *prog_data = (struct _prog*) data;
968
969 alloc_prog(prog_data);
970
971 if(prog_data->target)
972 draw_background(prog_data, prog_data->target);
973
974 if( load_cards(DATA_DIR,
975 prog_data,
976 aire_de_dessin) == FALSE)
977 {
978 int i;
979 for(i =0; i< 4; i++)
980 {
981 if(prog_data->icons[i])
982 gtk_image_set_from_pixbuf(
983 GTK_IMAGE(prog_data->allwidgets[14+i]),
984 prog_data->icons[i]);
985 }
986
987
988 if(!prog_data->card_stretch)
989 resize_cards(prog_data, 80, 108);
990 else
991 {
992 int w, h;
993 gdk_drawable_get_size(prog_data->target, &w, &h);
994 resize_cards(prog_data,
995 w/6,
996 h/5);
997 }
998
999 position_targetzone(prog_data);
1000
1001 game_start(prog_data);
1002 }
1003 else
1004 {
1005 GtkWidget *dialog;
1006
1007 dialog = gtk_message_dialog_new(
1008 GTK_WINDOW(prog_data->allwidgets[0]),
1009 GTK_DIALOG_MODAL,
1010 GTK_MESSAGE_ERROR,
1011 GTK_BUTTONS_CLOSE,
1012 _("An error occured while loading cards pictures.\nPlease reinstall.") , NULL);
1013
1014 g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(error_event), prog_data);
1015
1016 gtk_widget_show_all(dialog);
1017 }
1018
1019 return TRUE;
1020 }
1021
1022 /* rafraichissement : refresh the game area.
1023 *
1024 * return gboolean: see Gtk documentation
1025 * about expose-event
1026 */
rafraichissement(GtkWidget * aire_de_dessin,GdkEventExpose * event,gpointer data)1027 gboolean rafraichissement( GtkWidget *aire_de_dessin, GdkEventExpose *event, gpointer data)
1028 {
1029 draw_container((struct _prog*)data );
1030
1031 return FALSE;
1032 }
1033
1034 /*
1035 * return gboolean: see Gtk documentation
1036 * about destroy event
1037 */
quit(GtkWidget * window,gpointer data)1038 gboolean quit(GtkWidget *window, gpointer data)
1039 {
1040 gtk_main_quit();
1041
1042 return TRUE;
1043 }
1044
resize_cards(struct _prog * prog_data,int w,int h)1045 void resize_cards(struct _prog* prog_data, int w, int h)
1046 {
1047 GdkPixbuf *src, *scaled = NULL;
1048 int original_w, original_h;
1049
1050 if(prog_data->back_original)
1051 {
1052 original_w = gdk_pixbuf_get_width(prog_data->back_original);
1053 original_h = gdk_pixbuf_get_height(prog_data->back_original);
1054
1055 if(prog_data->card_ratio)
1056 {
1057 float ratio;
1058
1059 ratio = original_w/(float)original_h;
1060
1061 w = h*ratio;
1062 }
1063 }
1064
1065 GList *ptr;
1066
1067 struct _card * data_card;
1068
1069 for(ptr = prog_data->all; ptr; ptr = ptr->next)
1070 {
1071 data_card = ptr->data;
1072
1073 /*if(data_card->dim.w != w || data_card->dim.h != h)*/
1074 {
1075 scaled = gdk_pixbuf_scale_simple(data_card->original,
1076 w, h, GDK_INTERP_BILINEAR);
1077
1078 }
1079 /*else
1080 scaled = NULL;*/
1081
1082 if(scaled)
1083 {
1084 src = scaled;
1085 }
1086 else
1087 src = data_card->original;
1088
1089 if(data_card->pixmap)
1090 g_object_unref(data_card->pixmap);
1091
1092 if(data_card->pixmask)
1093 g_object_unref(data_card->pixmask);
1094
1095 gdk_pixbuf_render_pixmap_and_mask(src,
1096 &data_card->pixmap,
1097 &data_card->pixmask, 150);
1098
1099 gdk_drawable_get_size(data_card->pixmap,
1100 &data_card->dim.w, &data_card->dim.h);
1101 /*
1102 data_card->dim.w = gdk_pixbuf_get_width(data_card->img);
1103 data_card->dim.h = gdk_pixbuf_get_height(data_card->img);
1104 */
1105
1106 if(scaled)
1107 {
1108 g_object_unref(scaled);
1109 scaled = NULL;
1110 }
1111
1112 }
1113
1114 if(prog_data->back)
1115 {
1116 gdk_drawable_get_size(prog_data->back,
1117 &original_w, &original_h);
1118 }
1119
1120 /*if( original_w != w || original_h != h)*/
1121 {
1122 if(prog_data->output)
1123 fprintf(prog_data->output,
1124 "Resizing img to %d %d\n",
1125 w, h);
1126 scaled = gdk_pixbuf_scale_simple(prog_data->back_original,
1127 w, h, GDK_INTERP_BILINEAR);
1128 }
1129 /*else
1130 {
1131 if(prog_data->output)
1132 fprintf(prog_data->output,
1133 "Copying the original %d %d\n",
1134 w, h);
1135 scaled = NULL;
1136 }*/
1137
1138 if(scaled)
1139 src = scaled;
1140 else
1141 src = prog_data->back_original;
1142
1143 if(prog_data->back)
1144 g_object_unref(prog_data->back);
1145
1146 if(prog_data->backmask)
1147 g_object_unref(prog_data->backmask);
1148
1149 gdk_pixbuf_render_pixmap_and_mask(src,
1150 &prog_data->back,
1151 &prog_data->backmask, 170);
1152
1153 gdk_draw_pixbuf(prog_data->back, NULL, src,
1154 0, 0, 0, 0,
1155 -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
1156
1157 if(scaled)
1158 {
1159 gdk_drawable_get_size(prog_data->back, &w, &h);
1160
1161 if(prog_data->output)
1162 fprintf(prog_data->output,
1163 "Back img is %d %d\n",
1164 w, h);
1165 g_object_unref(scaled);
1166 }
1167 }
1168
1169 /* resize: the window size has changed.
1170 * We need to draw and position everything
1171 * again.
1172 *
1173 * see Gtk documentation about check-resize
1174 * event for more informations.
1175 */
resize(GtkContainer * container,gpointer data)1176 void resize(GtkContainer *container, gpointer data)
1177 {
1178 struct _prog *prog_data = (struct _prog*) data;
1179
1180 gboolean animation;
1181 int w,h;
1182
1183 if(prog_data->target
1184 && prog_data->area &&
1185 prog_data->area->window )
1186 {
1187 gdk_drawable_get_size(prog_data->target, &w, &h);
1188
1189 if(prog_data->area->allocation.width != w
1190 || prog_data->area->allocation.height != h)
1191 {
1192 clear_blink(prog_data);
1193
1194 alloc_pixmap(prog_data);
1195
1196 if(prog_data->card_stretch)
1197 {
1198 gdk_drawable_get_size(prog_data->target, &w, &h);
1199
1200 if(prog_data->output)
1201 fprintf(prog_data->output, "resize %d %d\n",
1202 w, h);
1203
1204 resize_cards(prog_data,
1205 w/6, h/5);
1206 }
1207
1208 animation = prog_data->animation;
1209 if(animation == TRUE)
1210 prog_data->animation = FALSE;
1211
1212 game_middle_position(prog_data);
1213
1214 game_hand_position(prog_data, -1);
1215
1216 position_targetzone(prog_data);
1217
1218 draw_container(prog_data);
1219
1220 if(animation == TRUE)
1221 prog_data->animation = TRUE;
1222 }
1223 }
1224 }
1225
error_event(GtkDialog * dialog,gint rid,gpointer data)1226 void error_event(GtkDialog *dialog, gint rid, gpointer data)
1227 {
1228 struct _prog *prog_data = (struct _prog *) data;
1229
1230 gtk_widget_destroy(GTK_WIDGET(dialog));
1231
1232 gtk_widget_destroy(GTK_WIDGET(prog_data->allwidgets[0]));
1233 }
1234
1235
dialog_response_event(GtkDialog * dialog,gint rid,gpointer data)1236 void dialog_response_event(GtkDialog *dialog, gint rid, gpointer data)
1237 {
1238 /*if(rid == GTK_RESPONSE_CLOSE)*/
1239 gtk_widget_destroy(GTK_WIDGET(dialog));
1240 }
1241
click_diamond(GtkButton * button,gpointer data)1242 void click_diamond(GtkButton *button, gpointer data)
1243 {
1244 struct _prog *prog_data = (struct _prog *) data;
1245 int i=0;
1246 for(i = 0; i<4; i++)
1247 gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1248 FALSE);
1249
1250 click_selectmaster(prog_data, prog_data->player, 0);
1251 }
1252
click_heart(GtkButton * button,gpointer data)1253 void click_heart(GtkButton *button, gpointer data)
1254 {
1255 struct _prog *prog_data = (struct _prog *) data;
1256 int i=0;
1257 for(i = 0; i<4; i++)
1258 gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1259 FALSE);
1260
1261 click_selectmaster(prog_data, prog_data->player, 2);
1262 }
1263
click_club(GtkButton * button,gpointer data)1264 void click_club(GtkButton *button, gpointer data)
1265 {
1266 struct _prog *prog_data = (struct _prog *) data;
1267 int i=0;
1268 for(i = 0; i<4; i++)
1269 gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1270 FALSE);
1271
1272 click_selectmaster(prog_data, prog_data->player, 3);
1273 }
1274
click_spade(GtkButton * button,gpointer data)1275 void click_spade(GtkButton *button, gpointer data)
1276 {
1277 struct _prog *prog_data = (struct _prog *) data;
1278 int i=0;
1279 for(i = 0; i<4; i++)
1280 gtk_widget_set_sensitive(prog_data->allwidgets[10+i],
1281 FALSE);
1282
1283 click_selectmaster(prog_data, prog_data->player, 1);
1284 }
1285