1 /*                                   */
2 /* xemeraldia   ---- init-graphics.c */
3 /*                                   */
4 
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8 
9 #include <gdk/gdkkeysyms.h>
10 
11 #include "graphics.h"
12 #include "bitmaps.h"
13 
14 static void  createBWPixmaps(GdkDrawable *w, int depth), createColoredPixmaps(GdkDrawable *w, int depth);
15 static void  createGCs(GdkDrawable *), createCrushAnimePixmaps(GdkDrawable *w, int depth);
16 
17 GtkWidget  *board_w, *nextItem_w, *quit, *start, *scores, *score_disp, *level_disp, *about;
18 GtkWidget  *score_frame, *score_text, *high_sc_w, *topLevel;
19 GdkGC *draw_gc, *delete_gc;
20 GdkPixmap  *block[BLOCK_VARIETY * 2 + 1], *crush[CRUSH_ANIME_FRAMES];
21 GdkPixmap  *board_pix, *star, *saved_screen, *background;
22 GdkColor     black, white;
23 int     colored;
24 
createBackground(void)25 static void createBackground(void)
26 {
27 	cairo_t *cr = gdk_cairo_create(background);
28 	cairo_pattern_t *p = cairo_pattern_create_radial(
29 		WIN_WIDTH * .2, WIN_HEIGHT * .1, 0,
30 		WIN_WIDTH * .2, WIN_HEIGHT * .1, WIN_WIDTH * 1.2
31 		);
32 	cairo_pattern_add_color_stop_rgb(p, 0,
33 		0, 0, .7
34 		);
35 
36 	cairo_pattern_add_color_stop_rgb(p, 1,
37 		0, 0, 0
38 		);
39 	cairo_set_source(cr, p);
40 	cairo_paint(cr);
41 	cairo_destroy(cr);
42 }
43 
initXlib()44 void  initXlib ()
45 {
46 	int     depth;
47 	GdkVisual *vi;
48 
49 	gdk_color_black(gdk_colormap_get_system(), &black);
50 	gdk_color_white(gdk_colormap_get_system(), &white);
51 
52 	vi = gdk_visual_get_system();
53 	depth = vi->depth;
54 	colored = ((depth != 1) && (vi->type != GDK_VISUAL_GRAYSCALE));
55 
56 	createGCs (board_pix);
57 	createCrushAnimePixmaps (board_pix, depth);
58 	if (colored)
59 	  createColoredPixmaps (board_pix, depth);
60 	else
61 	  createBWPixmaps (board_pix, depth);
62 	createBackground();
63 	clearNextItem ();
64 	clearScreen();
65 
66 
67 	animated_score_font = pango_font_description_from_string("sans-serif 20");
68 	pause_font = pango_font_description_from_string("sans-serif Bold Italic 22");
69 	game_over_font = pango_font_description_from_string("sans-serif Bold 10");
70 }
71 
keyPressed(GtkWidget * widget G_GNUC_UNUSED,GdkEventKey * event G_GNUC_UNUSED,gpointer user_data G_GNUC_UNUSED)72 static gboolean keyPressed(GtkWidget *widget G_GNUC_UNUSED,
73 	GdkEventKey *event G_GNUC_UNUSED,
74 	gpointer user_data G_GNUC_UNUSED)
75 {
76 	switch(event->keyval)
77 	{
78 		case GDK_K:
79 		case GDK_k:
80 		case GDK_I:
81 		case GDK_i:
82 		case GDK_Down:
83 		case GDK_Begin:
84 			Rotation();
85 			return TRUE;
86 		case GDK_Up:
87 		case GDK_J:
88 		case GDK_j:
89 			CCRotation();
90 			return TRUE;
91 		case GDK_Left:
92 		case GDK_H:
93 		case GDK_h:
94 		case GDK_U:
95 		case GDK_u:
96 			MoveLeft();
97 			return TRUE;
98 		case GDK_Right:
99 		case GDK_L:
100 		case GDK_l:
101 			MoveRight();
102 			return TRUE;
103 		case GDK_space:
104 			MoveDown();
105 			return TRUE;
106 		case GDK_S:
107 		case GDK_s:
108 		case GDK_P:
109 		case GDK_p:
110 		case GDK_Pause:
111 			StartGame();
112 			return TRUE;
113 		case GDK_Q:
114 		case GDK_q:
115 			Quit();
116 			return TRUE;
117 	}
118 	return FALSE;
119 }
120 
initGTK(GtkWidget * w)121 void initGTK(GtkWidget *w)
122 {
123 	GtkWidget  *nextBox, *Score, *Level, *Next, *hbox, *vbox, *vbox2, *frame, *framevbox, *x;
124 
125 	g_signal_connect(G_OBJECT(w), "key-press-event", G_CALLBACK(keyPressed), NULL);
126 
127 	hbox = gtk_hbox_new(FALSE, 2);
128 	gtk_container_add(GTK_CONTAINER(w), hbox);
129 
130 	board_w = gtk_drawing_area_new();
131 	gtk_widget_set_size_request(board_w, WIN_WIDTH, WIN_HEIGHT);
132 	gtk_widget_set_app_paintable(board_w, TRUE);
133 	gtk_widget_set_double_buffered(board_w, FALSE);
134 	g_signal_connect(G_OBJECT (board_w), "expose_event",
135 		G_CALLBACK (expose_board), NULL);
136 
137 	gtk_box_pack_start(GTK_BOX(hbox), board_w, TRUE, TRUE, 3);
138 
139 	vbox = gtk_vbox_new(FALSE, 6);
140 	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 3);
141 
142 	x = gtk_label_new(NULL);
143 	gtk_box_pack_start(GTK_BOX(vbox), x, FALSE, FALSE, 0);
144 
145 	nextBox = gtk_frame_new(NULL);
146 	gtk_box_pack_start(GTK_BOX(vbox), nextBox, FALSE, FALSE, 0);
147 
148 	vbox2 = gtk_vbox_new(FALSE, 1);
149 	gtk_container_add(GTK_CONTAINER(nextBox), vbox2);
150 
151 	Next = gtk_label_new(NULL);
152 	gtk_label_set_markup(GTK_LABEL(Next), _("<b>NEXT</b>"));
153 	gtk_box_pack_start(GTK_BOX(vbox2), Next, TRUE, TRUE, 0);
154 
155 	nextItem_w = gtk_drawing_area_new();
156 	gtk_widget_set_size_request(nextItem_w, BLOCK_WIDTH * 3, BLOCK_HEIGHT * 3);
157 	g_signal_connect (G_OBJECT (nextItem_w), "expose_event",
158 		G_CALLBACK (RedrawNextItem), NULL);
159 	gtk_box_pack_start(GTK_BOX(vbox2), nextItem_w, TRUE, TRUE, 0);
160 
161 	frame = gtk_frame_new(NULL);
162 	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
163 
164 	framevbox = gtk_vbox_new(FALSE, 2);
165 	gtk_container_add(GTK_CONTAINER(frame), framevbox);
166 
167 	Score = gtk_label_new(NULL);
168 	gtk_label_set_markup(GTK_LABEL(Score), _("<b>SCORE</b>"));
169 	gtk_box_pack_start(GTK_BOX(framevbox), Score, TRUE, TRUE, 0);
170 
171 	score_disp = gtk_label_new("0");
172 	gtk_box_pack_start(GTK_BOX(framevbox), score_disp, TRUE, TRUE, 0);
173 
174 	x = gtk_label_new(NULL);
175 	gtk_box_pack_start(GTK_BOX(framevbox), x, TRUE, TRUE, 0);
176 
177 	Level = gtk_label_new(NULL);
178 	gtk_label_set_markup(GTK_LABEL(Level), _("<b>LEVEL</b>"));
179 	gtk_box_pack_start(GTK_BOX(framevbox), Level, TRUE, TRUE, 0);
180 
181 	level_disp = gtk_label_new("0");
182 	gtk_box_pack_start(GTK_BOX(framevbox), level_disp, TRUE, TRUE, 0);
183 
184 
185 	frame = gtk_alignment_new(.5,0.2,.9,.15);
186 	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
187 
188 	framevbox = gtk_vbutton_box_new();
189 	gtk_container_add(GTK_CONTAINER(frame), framevbox);
190 
191 	start = gtk_button_new_with_label(_("Start"));
192 /*  GTK_WIDGET_SET_FLAGS(start, GTK_CAN_DEFAULT); */
193 	gtk_box_pack_start(GTK_BOX(framevbox), start, TRUE, FALSE, 0);
194 
195 	if(app_data.usescorefile)
196 	{
197 		scores = gtk_button_new_with_label(_("Scores"));
198 		gtk_box_pack_start(GTK_BOX(framevbox), scores, TRUE, FALSE, 0);
199 	}
200 
201 #ifdef GTK_STOCK_ABOUT
202 	about = gtk_button_new_from_stock(GTK_STOCK_ABOUT);
203 #else
204 	about = gtk_button_new_with_label(_("About..."));
205 #endif
206 	gtk_box_pack_start(GTK_BOX(framevbox), about, TRUE, FALSE, 0);
207 
208 	quit = gtk_button_new_from_stock(GTK_STOCK_QUIT);
209 	gtk_box_pack_start(GTK_BOX(framevbox), quit, TRUE, FALSE, 0);
210 
211 /*
212 	frame = gtk_label_new(NULL);
213 	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 0);
214 */
215 }
216 
217 
createGCs(GdkDrawable * w)218 static void  createGCs (GdkDrawable *w)
219 {
220   GdkGCValues values;
221 
222   values.foreground  = white;
223   values.background  = black;
224   draw_gc = gdk_gc_new_with_values(w, &values, GDK_GC_FOREGROUND | GDK_GC_BACKGROUND);
225   values.foreground  = black;
226   values.background  = black;
227   delete_gc = gdk_gc_new_with_values(w, &values, GDK_GC_FOREGROUND | GDK_GC_BACKGROUND);
228 }
229 
230 
createBWPixmaps(GdkDrawable * w,int depth)231 static void  createBWPixmaps (GdkDrawable *w, int depth)
232 {
233   int   i;
234   const char *block_bits[BLOCK_VARIETY * 2 + 1];
235 
236   star = gdk_pixmap_create_from_data(w, star_bits, BLOCK_WIDTH, BLOCK_HEIGHT, depth, &white, &black);
237   block_bits[1] = block1_bits;
238   block_bits[2] = block2_bits;
239   block_bits[3] = block3_bits;
240   block_bits[4] = block4_bits;
241   block_bits[5] = block5_bits;
242   block_bits[6] = block6_bits;
243   block_bits[7] = block1cr_bits;
244   block_bits[8] = block2cr_bits;
245   block_bits[9] = block3cr_bits;
246   block_bits[10] = block4cr_bits;
247   block_bits[11] = block5cr_bits;
248   block_bits[12] = block6cr_bits;
249   for (i = 1; i <= BLOCK_VARIETY * 2; i++)
250     {
251       block[i] = gdk_pixmap_create_from_data(w, block_bits[i],
252                           BLOCK_WIDTH, BLOCK_HEIGHT, depth, &white, &black);
253     }
254 }
255 
256 
createColoredPixmaps(GdkDrawable * w,int depth)257 static void  createColoredPixmaps (GdkDrawable *w, int depth)
258 {
259   int   i;
260   GdkColor block_pixel[BLOCK_VARIETY + 1];
261 
262   star = gdk_pixmap_create_from_data(w, star_bits, BLOCK_WIDTH, BLOCK_HEIGHT, depth, &app_data.starpixel, &black);
263   block_pixel[1] = app_data.block1pixel;
264   block_pixel[2] = app_data.block2pixel;
265   block_pixel[3] = app_data.block3pixel;
266   block_pixel[4] = app_data.block4pixel;
267   block_pixel[5] = app_data.block5pixel;
268   block_pixel[6] = app_data.block6pixel;
269   for (i = 1; i <= BLOCK_VARIETY; i++)
270   {
271 		cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_RGB24, BLOCK_WIDTH, BLOCK_HEIGHT);
272 		cairo_t *c = cairo_create(s);
273 		gdk_cairo_set_source_color(c, &block_pixel[i]);
274 		cairo_move_to(c, 0, 0);
275 		cairo_set_line_width(c, BLOCK_HEIGHT * .0625);
276 		cairo_line_to(c, BLOCK_WIDTH, BLOCK_HEIGHT);
277 		cairo_stroke(c);
278 
279 		cairo_rectangle(c, BLOCK_WIDTH * .1, BLOCK_HEIGHT * .1, BLOCK_WIDTH * .9, BLOCK_HEIGHT * .9);
280 
281 		cairo_pattern_t *p = cairo_pattern_create_radial(BLOCK_WIDTH / 2, BLOCK_HEIGHT / 2, 0,
282 			BLOCK_WIDTH / 2, BLOCK_HEIGHT / 2, BLOCK_WIDTH / 2);
283 		cairo_pattern_add_color_stop_rgb(p, 0,
284 			block_pixel[i].red / 65535.0,
285 			block_pixel[i].green / 65535.0,
286 			block_pixel[i].blue / 65535.0
287 			);
288 
289 		cairo_pattern_add_color_stop_rgb(p, 1,
290 			(block_pixel[i].red / 65535.0) * .7,
291 			(block_pixel[i].green / 65535.0) * .7,
292 			(block_pixel[i].blue / 65535.0) * .7
293 			);
294 		cairo_set_source(c, p);
295 		cairo_fill(c);
296 
297 		cairo_move_to(c, 0, 0);
298 		cairo_line_to(c, BLOCK_WIDTH, 0);
299 		cairo_line_to(c, BLOCK_WIDTH, BLOCK_HEIGHT * .55);
300 		cairo_curve_to(c, BLOCK_WIDTH / 2, BLOCK_HEIGHT * .16,
301 			BLOCK_WIDTH / 2, BLOCK_HEIGHT * .78,
302 			0, BLOCK_HEIGHT * .44);
303 		cairo_close_path(c);
304 		//p = cairo_pattern_create_linear(16, 16, 16, 0);
305 		p = cairo_pattern_create_radial(BLOCK_WIDTH * .2, BLOCK_HEIGHT * .2, 1,
306 			BLOCK_WIDTH * .2, BLOCK_HEIGHT * .2, 28);
307 		cairo_pattern_add_color_stop_rgba(p, 0, 1, 1, 1, .9);
308 		cairo_pattern_add_color_stop_rgba(p, 1, 1, 1, 1, .2);
309 		cairo_set_source(c, p);
310 		cairo_fill(c);
311 
312 		block[i] = gdk_pixmap_new(w,BLOCK_WIDTH,BLOCK_HEIGHT,-1);
313 		cairo_t *cr_pixmap = gdk_cairo_create(block[i]);
314 		cairo_set_source_surface (cr_pixmap, s, 0, 0);
315 		cairo_paint(cr_pixmap);
316 		cairo_destroy(cr_pixmap);
317 
318 		/* the "crack" */
319 		cairo_set_line_width(c, BLOCK_HEIGHT * .09);
320 		cairo_set_source_rgba(c, 0, 0, 0, .8);
321 		cairo_move_to(c, 0, BLOCK_HEIGHT * .1);
322 		cairo_line_to(c, BLOCK_WIDTH * .6, BLOCK_HEIGHT * .6);
323 		cairo_line_to(c, BLOCK_WIDTH, BLOCK_HEIGHT * .2);
324 		cairo_stroke(c);
325 		cairo_move_to(c, BLOCK_WIDTH * .6, BLOCK_HEIGHT * .6);
326 		cairo_line_to(c, BLOCK_WIDTH * .4, BLOCK_HEIGHT);
327 		cairo_stroke(c);
328 
329 		block[i +  BLOCK_VARIETY] = gdk_pixmap_new(w,BLOCK_WIDTH,BLOCK_HEIGHT,-1);
330 		cr_pixmap = gdk_cairo_create(block[i + BLOCK_VARIETY]);
331 		cairo_set_source_surface (cr_pixmap, s, 0, 0);
332 		cairo_paint(cr_pixmap);
333 		cairo_destroy(cr_pixmap);
334 
335 		cairo_destroy(c);
336 		cairo_surface_destroy(s);
337 
338 //      block[i] = gdk_pixmap_create_from_data(w, colorblock_bits,
339 //                          BLOCK_WIDTH, BLOCK_HEIGHT, depth, &block_pixel[i], &black);
340   }
341 //  for (i = BLOCK_VARIETY + 1; i <= BLOCK_VARIETY * 2; i++)
342 //      block[i] = gdk_pixmap_create_from_data(w, colorblockcr_bits,
343 //                          BLOCK_WIDTH, BLOCK_HEIGHT, depth, &block_pixel[i - BLOCK_VARIETY], &black);
344 }
345 
346 
createCrushAnimePixmaps(GdkDrawable * w,int depth)347 static void  createCrushAnimePixmaps (GdkDrawable *w, int depth)
348 {
349   int   i;
350   const unsigned char *crush_bits[CRUSH_ANIME_FRAMES];
351 
352   crush_bits[0] = crush0_bits;
353   crush_bits[1] = crush1_bits;
354   crush_bits[2] = crush2_bits;
355   crush_bits[3] = crush3_bits;
356   crush_bits[4] = crush4_bits;
357   for (i = 0; i < CRUSH_ANIME_FRAMES; i++)
358     crush[i] = gdk_pixmap_create_from_data(w, (char*)crush_bits[i],
359                           BLOCK_WIDTH, BLOCK_HEIGHT, depth, &white, &black);
360 }
361