void Whack_a_Skunk_Loop::draw(void)
{
	al_clear_to_color(al_map_rgb(0x00, 0x00, 0x00));

	al_draw_bitmap(
		bg_bitmap->bitmap,
		top_offset.x,
		top_offset.y,
		0
	);

	float scales[3] = { 0.83f, 0.9f, 1.0f };
	Wrap::Bitmap *hole_bmps[3] = {
		mask_back,
		mask_middle,
		mask_front
	};
	int hole_yoffs[3] = { 6, 8, 10 };
	Wrap::Bitmap *highlight_bmps[3] = {
		highlight_back,
		highlight_middle,
		highlight_front
	};
	int highlight_yoffs[3] = { 5, 6, 8 };
	Wrap::Bitmap *maskhighlight_bmps[3] = {
		mask_backhighlight,
		mask_middlehighlight,
		mask_fronthighlight
	};
	
	for (int i = 0; i < 9; i++) {
		int row = i / 3;

		if (i == curr_hole) {
			Wrap::Bitmap *highlight = highlight_bmps[row];
			int highlight_w = al_get_bitmap_width(highlight->bitmap);
			int highlight_h = al_get_bitmap_height(highlight->bitmap);
			al_draw_bitmap(
				highlight->bitmap,
				holes[i].x-highlight_w/2+top_offset.x,
				holes[i].y-highlight_h+highlight_yoffs[row]+top_offset.y,
				0
			);
		}
		
		Animation_Set *anim_set;
		bool done = get_skunk_info(i, &anim_set);

		int x = holes[i].x - skunk_size.w/2 + top_offset.x;
		int y = holes[i].y - skunk_size.h + top_offset.y;
		float scale = scales[row];
		int ox = (skunk_size.w * (1.0f-scale)) / 2;
		int oy = 10;
		oy += (skunk_size.h * (1.0f-scale)) / 2;
		int len = anim_set->get_length(anim_set->get_sub_animation_name());
		if (holes[i].count > len/2) {
			oy += ((float)(holes[i].count-(len/2)) / (len/2)) * 60 /* 60 = base skunk height */;
		}
		else {
			oy += (1.0 - ((float)holes[i].count / (len/2))) * 60;
		}

		if (!done) {
			int cx, cy, cw, ch;
			al_get_clipping_rectangle(&cx, &cy, &cw, &ch);
			General::set_clipping_rectangle(x, y, skunk_size.w, skunk_size.h);

			if (holes[i].status == ALIVE || holes[i].status == TAUNTING || holes[i].status == GOING_DOWN) {
				anim_set->get_current_animation()->draw_scaled(
					0, 0, skunk_size.w, skunk_size.h,
					x+ox, y+oy, skunk_size.w*scale, skunk_size.h*scale,
					0
				);
			}
			else if (holes[i].status == DYING) {
				std::string name = anim_set->get_sub_animation_name();
				int frame = anim_set->get_current_animation()->get_current_frame_num();
				anim_set->set_sub_animation("popup");
				anim_set->set_frame(holes[i].type == FAKE ? 0 : 3);
				anim_set->get_current_animation()->draw_scaled(
					0, 0, skunk_size.w, skunk_size.h,
					x+ox, y+oy, skunk_size.w*scale, skunk_size.h*scale,
					0
				);
				anim_set->set_sub_animation(name);
				anim_set->set_frame(frame);
			}

			al_set_clipping_rectangle(cx, cy, cw, ch);
		}

		Wrap::Bitmap *mask = i == curr_hole ? maskhighlight_bmps[row] : hole_bmps[row];
		int mask_w = al_get_bitmap_width(mask->bitmap);
		int mask_h = al_get_bitmap_height(mask->bitmap);
		al_draw_bitmap(
			mask->bitmap,
			holes[i].x-mask_w/2+top_offset.x,
			holes[i].y-mask_h+hole_yoffs[row]+top_offset.y,
			0
		);
		
		if (!done) {
			if (holes[i].status == DYING) {
				anim_set->get_current_animation()->draw_scaled(
					0, 0, skunk_size.w, skunk_size.h,
					x+ox, y+oy, skunk_size.w*scale, skunk_size.h*scale,
					0
				);
			}
		}
	}

	// Draw timer
	int digits;
	if (timer/1000 >= 10) {
		digits = 2;
	}
	else {
		digits = 1;
	}
	
	int font_w = font->get_current_animation()->get_current_frame()->get_width();
	float xx = (cfg.screen_w-font_w*(digits+1))/2;
	float yy = 5;
	int tmp = timer;
	for (int i = 0; i < digits; i++) {
		int p = powf(10, (digits-i)+2);
		int frame = tmp / p;
		font->set_sub_animation(General::itos(frame));
		font->get_current_animation()->draw(
			xx, yy, 0
		);
		tmp -= frame * p;
		xx += font_w;
	}
	font->set_sub_animation("s");
	font->get_current_animation()->draw(
		xx, yy, 0
	);

	// Draw score/hitx
	if (hits < 0) {
		hits = 0;
	}
	char buf[100];
	snprintf(buf, 100, "%d", hits);
	draw_centered_text(font, al_map_rgb(0x00, 0xff, 0x00), buf, cfg.screen_w/4-30, 5);

	int hitx;
	if (hits_in_a_row >= 7) {
		hitx = 3;
	}
	else if (hits_in_a_row >= 3) {
		hitx = 2;
	}
	else {
		hitx = 1;
	}
	snprintf(buf, 100, "x%d", hitx);
	draw_centered_text(font, al_map_rgb(0xff, 0xd7, 0x00), buf, cfg.screen_w*3/4+15, 5);

	std::list<Pow>::iterator pow_it;
	for (pow_it = pows.begin(); pow_it != pows.end(); pow_it++) {
		Pow &p = *pow_it;
		ALLEGRO_COLOR tint;
		float a;
		if (p.count < POW_LIFETIME/2) {
			a = 1.0;
		}
		else {
			a = ((float)p.count-POW_LIFETIME/2) / (POW_LIFETIME/2);
			if (a > 1.0) a = 1.0;
			a = 1.0 - a;
		}
		tint = al_map_rgba_f(1.0, 1.0, 1.0, a);
		int r = (cfg.screen_w / 120) * 2 + 1;
		al_draw_tinted_bitmap(
			p.kratch ? kratch_bmp->bitmap : pow_bmp->bitmap,
			tint,
			p.x-al_get_bitmap_width(pow_bmp->bitmap)/2+General::rand()%r-(r/2)+top_offset.x,
			p.y-al_get_bitmap_height(pow_bmp->bitmap)/2+General::rand()%r-(r/2)+top_offset.y,
			0
		);
	}
	std::list<Star>::iterator star_it;
	for (star_it = stars.begin(); star_it != stars.end(); star_it++) {
		Star &s = *star_it;
		ALLEGRO_COLOR tint;
		float b = (float)s.count / STAR_LIFETIME;
		if (b > 1.0) b = 1.0;
		tint = al_map_rgb_f(1.0, 1.0, b);
		al_draw_tinted_rotated_bitmap(
			star_bmp->bitmap,
			tint,
			al_get_bitmap_width(star_bmp->bitmap)/2,
			al_get_bitmap_height(star_bmp->bitmap)/2,
			s.x+top_offset.x, s.y+top_offset.y,
			s.angle,
			0
		);
	}

	if (bashing) {
		float xx = holes[curr_hole].x;
		float yy = holes[curr_hole].y - hand_size.h;
		xx += top_offset.x;
		yy += top_offset.y;

		xx += 90; // trial and error
		yy += 110;

		if  (curr_hole == 0 || curr_hole == 3 || curr_hole == 6) {
			hand->set_sub_animation("left");
		}
		else if (curr_hole == 1 || curr_hole == 4 || curr_hole == 7) {
			hand->set_sub_animation("middle");
			xx -= 68;
		}
		else {
			hand->set_sub_animation("right");
			xx -= 68*2;
		}

		hand->get_current_animation()->draw(
			xx-hand_size.w/2,
			yy,
			0
		);
	}
}
Exemple #2
0
static void 
draw_ping_graph (Netinfo *netinfo)
{
	cairo_t *cr;
	GtkStyle *style;
	GtkWidget *widget;
	PangoLayout *layout;
	gint ntodisplay = 5;
	gint rangemin, rangemax;
	PingGraphBarData *bar_data;
	gdouble max;
	gint width, height;
	gint font_height, offset;
	gint bar_height, separator_height;
	gdouble scale_factor;
	gint line1h, line2h;
	gint index;
	gint step, x, h;
	gchar *tmpstr;

	widget = netinfo->graph;
	cr = gdk_cairo_create (gtk_widget_get_window(widget));
	style = gtk_widget_get_style(widget);

	rangemax = packets_transmitted;
	rangemin = MAX (0, rangemax - ntodisplay);

	bar_data = g_newa (PingGraphBarData, ntodisplay);
	max = get_bar_data (netinfo, bar_data, ntodisplay, rangemin,
			    rangemax);

	/* Created up here so we can get the geometry info. */
	layout = gtk_widget_create_pango_layout (widget, _("Time (ms):"));
	/* We guess that the first label is representative. */
	pango_layout_get_pixel_size (layout, NULL, &font_height);
	width = gtk_widget_get_allocated_width (widget);
	height = gtk_widget_get_allocated_height (widget);

	offset = 0.05*height;
	bar_height = height - 2.5*font_height - offset;
	scale_factor = bar_height / max;
	separator_height = bar_height + offset;
	line1h = bar_height + 0.125*font_height + offset;
	line2h = bar_height + 1.25*font_height + offset;

	gtk_paint_box (style, cr, GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_IN, 
		       widget, NULL, 0, 0, width, height);

	gtk_paint_layout (style, cr, GTK_STATE_NORMAL, TRUE, 
			  widget, NULL, 0.02*width, line1h,
			  layout);
	g_object_unref (layout);

	layout = gtk_widget_create_pango_layout (widget, _("Seq. No.:"));
	gtk_paint_layout (style, cr, GTK_STATE_NORMAL, TRUE, 
			  widget, NULL, 0.02*width, line2h,
			  layout);
	g_object_unref (layout);

	gtk_paint_hline (style, cr, GTK_STATE_NORMAL, widget, NULL,
			 0.02*width, 0.98*width, separator_height);

	index = 0;
	step = width / (ntodisplay + 1.0);
	for (x = 1.5*step; x < width; x += step) {
		if (bar_data[index].valid) {
			h = scale_factor*bar_data[index].value;
			gtk_paint_flat_box (style, cr, GTK_STATE_SELECTED,
					    GTK_SHADOW_ETCHED_IN, widget,
					    NULL, x - 0.4*step,
					    offset + bar_height - h,
					    0.8*step, h);
			tmpstr = g_strdup_printf ("%.2f", bar_data[index].value);
		} else {
			tmpstr = g_strdup ("-");
		}
		draw_centered_text (widget, cr, x, line1h, tmpstr);
		g_free (tmpstr);
		if (index + rangemin + 1 <= rangemax) {
			tmpstr = g_strdup_printf ("%d", index + rangemin + 1);
		} else {
			tmpstr = g_strdup ("-");
		}
		draw_centered_text (widget, cr, x, line2h, tmpstr);
		g_free (tmpstr);
		index++;
	}

	cairo_destroy (cr);
}