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