/* * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "draw.h" #include "def.h" #include "game.h" /* draw_moving_card : draw the card which is * dragged around by the player right now. * * Why this is particular ? * * There is a position (x,y) for the card, * which is not used here. Instead we use * the struct _movingcard dim position. */ void draw_moving_card(struct _prog *prog_data, GdkPixmap *target) { GdkGC *gc; GdkPixmap *img; GtkStateType state = GTK_WIDGET_STATE(prog_data->area); gc = prog_data->area->style->fg_gc[state]; if(prog_data->movecard->card->draw_face == TRUE) { img = prog_data->movecard->card->img; gdk_gc_set_clip_mask(gc, prog_data->cardmask); } else { img = prog_data->back; gdk_gc_set_clip_mask(gc, prog_data->backmask); } gdk_gc_set_clip_origin(gc, prog_data->movecard->dim.x, prog_data->movecard->dim.y); gdk_draw_drawable( target, prog_data->area->style->fg_gc[state], img, 0, 0, prog_data->movecard->dim.x, prog_data->movecard->dim.y, -1, -1); gdk_gc_set_clip_mask(gc, NULL); } /* draw_cards : takes care to draw a list of * cards contained on a GList. Of course * we check the draw flag in each card * before drawing them, and if draw_face * is activated. If true, then the value * of the card is revealed to the user. * If not we use the back image of cards. * * Note: the list is scanned from the * last to the first, because the order * is important here. The first becomes * the nearest, and the last the farest * (hided by others) */ void draw_cards(struct _prog *prog_data, GList *list, GdkPixmap *target) { GList *ptr; struct _card *data_ptr; GdkPixmap *img; GdkGC *gc; GtkStateType state = GTK_WIDGET_STATE(prog_data->area); gc = prog_data->area->style->fg_gc[state]; for(ptr = g_list_last(list); ptr; ptr = ptr->prev) { data_ptr = ptr->data; if(data_ptr->draw == TRUE || data_ptr->blink == TRUE) { if(data_ptr->draw_face == FALSE) { img = prog_data->back; gdk_gc_set_clip_mask(gc, prog_data->backmask); } else if(data_ptr->draw == TRUE) { img = data_ptr->img; gdk_gc_set_clip_mask(gc, prog_data->cardmask); } else img = NULL; if(img != NULL) { gdk_gc_set_clip_origin(gc, data_ptr->dim.x, data_ptr->dim.y); gdk_draw_drawable( target, prog_data->area->style->fg_gc[state], img, 0, 0, data_ptr->dim.x, data_ptr->dim.y, -1, -1); gdk_gc_set_clip_mask(gc, NULL); } } } } gboolean player_can_drop(struct _prog *prog_data) { return ( ( (prog_data->player == 2 && prog_data->player != prog_data->hashand ) || ( prog_data->player == prog_data->hashand && prog_data->menext == 2) ) && prog_data->players[2] != NULL ); } gboolean card_touch_dropzone(struct _movingcard *movecard, struct _target *zone) { return ( movecard->dim.x > zone->dim.x - movecard->card->dim.w && movecard->dim.x < zone->dim.x + zone->dim.w && movecard->dim.y > zone->dim.y - movecard->card->dim.h && movecard->dim.y < zone->dim.y + zone->dim.h ); } /* draw_dropping_zone : draw a white * rectangle corresponding to a target * zone (where the player can drop a * card). * * We should draw the rectangle only * if : * - the player is moving a card around * right now * * - the center of the card is in the * so called rectangle. */ struct _target* draw_dropping_zone(struct _prog *prog_data, GdkPixmap *target) { GList *lst; struct _target *zone = NULL; for(lst = prog_data->dropping; lst; lst = lst->next) { zone = (struct _target *)lst->data; zone->active = FALSE; if(prog_data->movecard && player_can_drop(prog_data) ) { if( card_touch_dropzone(prog_data->movecard, zone) ) { gdk_draw_rectangle(target, prog_data->area->style->light_gc[GTK_WIDGET_STATE(prog_data->area)], FALSE, zone->dim.x, zone->dim.y, zone->dim.w, zone->dim.h); zone->active = TRUE; } } } return(zone); } void draw_copy(struct _prog *prog_data) { if(!prog_data->copy) { prog_data->copy = gdk_pixmap_new( prog_data->area->window, prog_data->area->allocation.width, prog_data->area->allocation.height, -1); } if(prog_data->copy) { draw_to(prog_data, prog_data->copy); } } /* draw_container : takes care of drawing * everything on the screen. In the right * order, so the player can grab cards * that he see. */ void draw_container(struct _prog *prog_data) { if(prog_data->target != NULL) { /* Paint it black */ gdk_draw_rectangle( prog_data->target, prog_data->area->style->black_gc, TRUE, 0, 0, prog_data->area->allocation.width, prog_data->area->allocation.height ); draw_cards(prog_data, prog_data->pile, prog_data->target); draw_cards(prog_data, prog_data->waiting, prog_data->target); if(prog_data->players != NULL) { int i; for(i=0; i<4; i++) draw_cards(prog_data, prog_data->players[i], prog_data->target); } if(prog_data->dropping) { draw_dropping_zone(prog_data, prog_data->target); } if(prog_data->movecard) draw_moving_card(prog_data, prog_data->target); /* Blit */ gdk_draw_drawable( prog_data->area->window, prog_data->area->style->fg_gc[GTK_WIDGET_STATE(prog_data->area)], prog_data->target, 0, 0, 0, 0, -1, -1 ); } } void draw_to(struct _prog *prog_data, GdkPixmap *target) { if(target != NULL) { /* Paint it black */ gdk_draw_rectangle( target, prog_data->area->style->black_gc, TRUE, 0, 0, prog_data->area->allocation.width, prog_data->area->allocation.height ); draw_cards(prog_data, prog_data->pile, target); draw_cards(prog_data, prog_data->waiting, target); if(prog_data->players != NULL) { int i; for(i=0; i< 4; i++) draw_cards(prog_data, prog_data->players[i], target); } } }