1 /*======================================================================
2 xrot
3 Copyright (C) 1997,1998 Masao Shiraishi
4 e-mail:msiro@cs.meiji.ac.jp
5 ========================================================================*/
6
7 #include <X11/Xlib.h>
8 #include <X11/Xutil.h>
9 #include <X11/keysym.h>
10 #include <X11/xpm.h>
11 #include <sys/types.h>
12 #include <memory.h>
13 #include <stdlib.h>
14 #include <math.h>
15 #include <stdio.h>
16
17 #include "xrot.h"
18 #include "pixmap.h"
19 #include "xwin.h"
20 #include "record.h"
21
22 #include "c1.h"
23 #include "c2.h"
24 #include "c3.h"
25 #include "c4.h"
26 #include "c5.h"
27 #include "c6.h"
28 #include "c7.h"
29
30 #ifdef MITSHM
31 #include <sys/ipc.h>
32 #include <sys/shm.h>
33 #include <X11/extensions/XShm.h>
34 XShmSegmentInfo shminfo[2];
35 int shm = 1;
36 #endif
37
38 #define PROG_NAME "xrot"
39
40 int vwidth, vheight;
41 int RWIDTH, RHEIGHT;
42
43 Display *dp = NULL;
44 Colormap cmap;
45 XColor colors;
46 unsigned long gpixel, b3pixel, otpixel, cs_pixel;
47 unsigned long tipix[4];
48 char g_pixel;
49 unsigned short grad[64];
50 int redc;
51 int owncmap;
52
53 #define FONT "-*-new century schoolbook-medium-i-*--18-*-*-*-p-*-*-*"
54 #define FONT_CS "-*-new century schoolbook-medium-r-*--18-*-*-*-p-*-*-*"
55 #define FONT2 "-*-times-bold-r-*--14-*-*-*-p-*-*-*"
56
57 Pixel *bg_col;
58 unsigned int bg_num;
59
60 Window win, root;
61 GC copyGC, clearGC, blackGC, goalGC;
62 GC textGC, text_csGC[2], titleGC, keysGC, fadeGC;
63 int sc;
64 XImage *ximage[2];
65 int dbl_buf;
66 XEvent ev;
67 XFontStruct *fn, *fn2, *fn_cs;
68 int ascent, ascent2, ascent_cs;
69
70 static int cs_width, cs_x, cs_text_x;
71 static int cs_num;
72 static int cs_state[COURSE];
73
74 /* pixmap */
75 Pixmap p_frame, p_titlem;
76 Pixmap num[5];
77 int num_state;
78 Pixmap back_pix;
79 char **bg_data[4];
80 XImage *back_image;
81 Pixmap p_wall[21];
82 int wall_width[21], wall_height[21];
83 char **p_wall_data[21];
84 Pixmap point_ball;
85
86 Pixmap p_ball[2], mask[2];
87 GC ballGC[2][2];
88 XpmAttributes xpatt;
89 int ball_x, ball_y, ball_w, ball_h;
90 int ball_x_bg, ball_y_bg;
91 int view_x, view_y;
92 Pixmap p_course;
93
94 Pixmap fade[25];
95
96 char *image[2];
97 unsigned char *temp;
98
99 int key_right, key_left;
100 int key_space, jump_key, soft_key;
101 int escape;
102 int restart; /* RET key */
103
104 unsigned long black_pixel, white_pixel;
105
106 struct course_d *cs_d[COURSE];
107 int lx[COURSE];
108 int ly[COURSE];
109 int sdeg[COURSE];
110 int gx[COURSE];
111 int gy[COURSE];
112 int gw[COURSE];
113 int gh[COURSE];
114
115 /* course data */
116 unsigned int bw, bh;
117 XImage *bimage;
118 char *bdata;
119
120 int width, height;
121
122 #define TCOL1 "white"
123 #define TCOL2 "orange"
124 #define TCOL3 "yellow"
125
init_X()126 void init_X()
127 {
128 XSizeHints size;
129 XWMHints hints;
130 Visual *visual;
131 XColor set_pixel, rgb;
132 int i;
133 unsigned long bpixel, wpixel;
134 unsigned long plane_mask, pixel[64];
135
136 if( (dp = XOpenDisplay( NULL )) == NULL ){
137 fprintf( stderr, "Can't connect X server\n" );
138 exit(1);
139 }
140 sc = DefaultScreen( dp );
141 root = RootWindow( dp, sc );
142 visual = DefaultVisual( dp, sc );
143 win = XCreateSimpleWindow( dp, root, 0, 0, WWIDTH, WHEIGHT,
144 0, 0, 0);
145 bpixel = BlackPixel( dp, sc );
146 wpixel = WhitePixel( dp, sc );
147 cmap = DefaultColormap( dp, sc );
148 if( XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 80 ) == 0 )
149 owncmap = 1;
150 else
151 XFreeColors( dp, cmap, pixel, 80, 0 );
152 if( visual->class != PseudoColor || DefaultDepth(dp, sc) != 8 )
153 owncmap = 1;
154 if( owncmap )
155 create_cmap( &bpixel, &wpixel );
156 XSetWindowBackground( dp, win, bpixel );
157
158 copyGC = XCreateGC( dp, root, 0, NULL );
159 XSetGraphicsExposures( dp, copyGC, False );
160 clearGC = XCreateGC( dp, root, 0, NULL );
161 XSetForeground( dp, clearGC, 0 );
162 blackGC = XCreateGC( dp, root, 0, NULL );
163 XSetForeground( dp, blackGC, bpixel );
164 black_pixel = bpixel;
165 white_pixel = wpixel;
166
167 XAllocNamedColor( dp, cmap, "yellow", &set_pixel, &rgb );
168 b3pixel = set_pixel.pixel;
169 XAllocNamedColor( dp, cmap, "red", &set_pixel, &rgb );
170 otpixel = set_pixel.pixel;
171 XAllocNamedColor( dp, cmap, "orange", &set_pixel, &rgb );
172 cs_pixel = set_pixel.pixel;
173
174 set_fade();
175
176 /* font */
177 textGC = XCreateGC( dp, root, 0, NULL );
178 if( (fn = XLoadQueryFont( dp, FONT )) == NULL )
179 p_err("Unable to load font");
180 XSetFont( dp, textGC, fn->fid );
181 ascent = fn->max_bounds.ascent;
182 XSetForeground( dp, textGC, wpixel );
183
184 text_csGC[0] = XCreateGC( dp, root, 0, NULL );
185 if( (fn_cs = XLoadQueryFont( dp, FONT_CS )) == NULL )
186 p_err("Unable to load font");
187 XSetFont( dp, text_csGC[0], fn_cs->fid );
188 ascent_cs = fn_cs->max_bounds.ascent;
189 XSetForeground( dp, text_csGC[0], wpixel );
190
191 text_csGC[1] = XCreateGC( dp, root, 0, NULL );
192 XSetFont( dp, text_csGC[1], fn_cs->fid );
193 ascent_cs = fn_cs->max_bounds.ascent;
194 XSetForeground( dp, text_csGC[1], cs_pixel );
195
196 titleGC = XCreateGC( dp, root, 0, NULL );
197 if( (fn2 = XLoadQueryFont( dp, FONT2 )) == NULL )
198 p_err("Unable to load font");
199 XSetFont( dp, titleGC, fn2->fid );
200 keysGC = XCreateGC( dp, root, 0, NULL );
201 XSetFont( dp, keysGC, fn2->fid );
202 ascent2 = fn2->max_bounds.ascent;
203 XAllocNamedColor( dp, cmap, TCOL2, &set_pixel, &rgb );
204 tipix[1] = set_pixel.pixel;
205 XAllocNamedColor( dp, cmap, TCOL3, &set_pixel, &rgb );
206 tipix[2] = set_pixel.pixel;
207
208 for( i = 0; i < 64; i++ )
209 grad[i] = (unsigned short) (sin(M_PI/64.0*i) * 65535.0);
210 redc = 0;
211
212 XSelectInput( dp, win, ExposureMask | KeyPressMask | KeyReleaseMask );
213
214 size.flags = PMinSize | PMaxSize;
215 size.min_width = WWIDTH;
216 size.min_height = WHEIGHT;
217 size.max_width = WWIDTH;
218 size.max_height = WHEIGHT;
219 XSetNormalHints( dp, win, &size );
220
221 hints.flags = InputHint;
222 #ifdef HINT_TRUE
223 hints.input = True;
224 #else
225 hints.input = False;
226 #endif
227 XSetWMHints( dp, win, &hints );
228
229 XStoreName( dp, win, PROG_NAME );
230
231 key_left = key_right = 0;
232 key_space = 0;
233 jump_key = 0;
234 XMapWindow( dp, win );
235 XFlush( dp );
236 ev_loop1:
237 XNextEvent( dp, &ev );
238 if( ev.type != Expose )
239 goto ev_loop1;
240
241 #ifdef MITSHM
242 if( XShmQueryExtension( dp ) != True )
243 shm = 0;
244 if( shm ){
245 ximage[0] = XShmCreateImage( dp, DefaultVisual( dp, sc ),
246 8, ZPixmap, NULL, &shminfo[0], vwidth, vheight );
247 ximage[1] = XShmCreateImage( dp, DefaultVisual( dp, sc ),
248 8, ZPixmap, NULL, &shminfo[1], vwidth, vheight );
249 RWIDTH = ximage[0]->bytes_per_line;
250 RHEIGHT = ximage[0]->height;
251 shminfo[0].shmid = shmget( IPC_PRIVATE,
252 ximage[0]->bytes_per_line * ximage[0]->height, IPC_CREAT | 0777 );
253 shminfo[0].shmaddr = ximage[0]->data = image[0]
254 = (char *)shmat( shminfo[0].shmid, 0, 0 );
255 shminfo[0].readOnly = True;
256 if( !XShmAttach( dp, &shminfo[0] ) )
257 p_err("MIT-SHM error\n");
258 shminfo[1].shmid = shmget( IPC_PRIVATE,
259 ximage[1]->bytes_per_line * ximage[1]->height, IPC_CREAT | 0777 );
260 shminfo[1].shmaddr = ximage[1]->data = image[1]
261 = (char *)shmat( shminfo[1].shmid, 0, 0 );
262 shminfo[1].readOnly = True;
263 if( !XShmAttach( dp, &shminfo[1] ) )
264 p_err("MIT-SHM error\n");
265 }else
266 #endif
267 {
268 image[0] = (char *)malloc(vwidth * vheight);
269 image[1] = (char *)malloc(vwidth * vheight);
270 ximage[0] = XCreateImage( dp, DefaultVisual( dp, sc ),
271 8, ZPixmap, 0, image[0], vwidth, vheight, 8, 0 );
272 ximage[1] = XCreateImage( dp, DefaultVisual( dp, sc ),
273 8, ZPixmap, 0, image[1], vwidth, vheight, 8, 0 );
274 RWIDTH = ximage[0]->bytes_per_line;
275 RHEIGHT = ximage[0]->height;
276 }
277 dbl_buf = 0;
278 XSync(dp, True);
279
280 view_x = (225-vwidth)/2;
281 view_y = (225-vheight)/2;
282 ballGC[0][0] = XCreateGC( dp, root, 0, NULL );
283 ballGC[1][0] = XCreateGC( dp, root, 0, NULL );
284 ballGC[0][1] = XCreateGC( dp, root, 0, NULL );
285 ballGC[1][1] = XCreateGC( dp, root, 0, NULL );
286 xpatt.valuemask = XpmColormap;
287 xpatt.colormap = cmap;
288 XpmCreatePixmapFromData(
289 dp, root, ball_xpm, &p_ball[0], &mask[0], &xpatt );
290 xpatt.valuemask = XpmColormap;
291 xpatt.colormap = cmap;
292 XpmCreatePixmapFromData(
293 dp, root, ball2_xpm, &p_ball[1], &mask[1], &xpatt );
294 XSetFillStyle( dp, ballGC[0][0], FillTiled );
295 XSetClipMask( dp, ballGC[0][0], mask[0] );
296 XSetFillStyle( dp, ballGC[1][0], FillTiled );
297 XSetClipMask( dp, ballGC[1][0], mask[1] );
298 XSetFillStyle( dp, ballGC[0][1], FillTiled );
299 XSetClipMask( dp, ballGC[0][1], mask[0] );
300 XSetFillStyle( dp, ballGC[1][1], FillTiled );
301 XSetClipMask( dp, ballGC[1][1], mask[1] );
302 ball_w = xpatt.width;
303 ball_h = xpatt.height;
304 ball_x_bg = (200-xpatt.width)/2;
305 ball_y_bg = (200-xpatt.height)/2;
306 XSetClipOrigin( dp, ballGC[0][0], ball_x_bg, ball_y_bg );
307 XSetTSOrigin( dp, ballGC[0][0], ball_x_bg, ball_y_bg );
308 XSetTile( dp, ballGC[0][0], p_ball[0] );
309 XSetClipOrigin( dp, ballGC[0][1], ball_x_bg, ball_y_bg );
310 XSetTSOrigin( dp, ballGC[0][1], ball_x_bg, ball_y_bg );
311 XSetTile( dp, ballGC[0][1], p_ball[1] );
312 ball_x = (vwidth-xpatt.width)/2 + view_x;
313 ball_y = (vheight-xpatt.height)/2 + view_y;
314 XSetClipOrigin( dp, ballGC[1][0], ball_x, ball_y );
315 XSetTSOrigin( dp, ballGC[1][0], ball_x, ball_y );
316 XSetTile( dp, ballGC[1][0], p_ball[0] );
317 XSetClipOrigin( dp, ballGC[1][1], ball_x, ball_y );
318 XSetTSOrigin( dp, ballGC[1][1], ball_x, ball_y );
319 XSetTile( dp, ballGC[1][1], p_ball[1] );
320
321 p_wall_data[0] = wall1_xpm;
322 p_wall_data[1] = wall2_xpm;
323 p_wall_data[2] = wall3_xpm;
324 p_wall_data[3] = wall4_xpm;
325 p_wall_data[4] = wall5_xpm;
326 p_wall_data[5] = wall6_xpm;
327 p_wall_data[6] = wall7_xpm;
328 p_wall_data[7] = wall8_xpm;
329 p_wall_data[8] = wall9_xpm;
330 p_wall_data[9] = wall10_xpm;
331 p_wall_data[10] = down_xpm;
332 p_wall_data[11] = left_xpm;
333 p_wall_data[12] = right_xpm;
334 p_wall_data[13] = up_xpm;
335 p_wall_data[14] = down1_xpm;
336 p_wall_data[15] = left1_xpm;
337 p_wall_data[16] = right1_xpm;
338 p_wall_data[17] = up1_xpm;
339 p_wall_data[18] = left2_xpm;
340 p_wall_data[19] = right2_xpm;
341 p_wall_data[20] = pin_xpm;
342 read_pixmap();
343 bg_data[0] = bg1_xpm;
344 bg_data[1] = bg2_xpm;
345 bg_data[2] = bg3_xpm;
346 bg_data[3] = bg4_xpm;
347
348 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
349 tipix[0] = pixel[0];
350 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
351 tipix[3] = pixel[0];
352 XSetForeground( dp, keysGC, tipix[3] );
353 if( XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 ) ){
354 gpixel = pixel[0];
355 g_pixel = (char) gpixel;
356 goalGC = XCreateGC( dp, root, 0, NULL );
357 XSetForeground( dp, goalGC, gpixel );
358 colors.pixel = gpixel;
359 colors.flags = DoRed | DoGreen | DoBlue;
360 colors.green = 0;
361 colors.blue = 0;
362 colors.red = 0;
363 XStoreColor( dp, cmap, &colors );
364 }else
365 if( owncmap == 0 )
366 goalGC = XCreateGC( dp, root, 0, NULL );
367 else
368 p_err("Color Allocation Error");
369
370 /* course parameter set */
371 cs_d[0] = c1;
372 cs_d[1] = c2;
373 cs_d[2] = c3;
374 cs_d[3] = c4;
375 cs_d[4] = c5;
376 cs_d[5] = c6;
377 /* cs_d[6] = c7; */
378
379 lx[0] = c1_x;
380 ly[0] = c1_y;
381 sdeg[0] = c1_deg;
382 gx[0] = g1x;
383 gy[0] = g1y;
384 gw[0] = g1w;
385 gh[0] = g1h;
386 lx[1] = c2_x;
387 ly[1] = c2_y;
388 sdeg[1] = c2_deg;
389 gx[1] = g2x;
390 gy[1] = g2y;
391 gw[1] = g2w;
392 gh[1] = g2h;
393 lx[2] = c3_x;
394 ly[2] = c3_y;
395 sdeg[2] = c3_deg;
396 gx[2] = g3x;
397 gy[2] = g3y;
398 gw[2] = g3w;
399 gh[2] = g3h;
400 lx[3] = c4_x;
401 ly[3] = c4_y;
402 sdeg[3] = c4_deg;
403 gx[3] = g4x;
404 gy[3] = g4y;
405 gw[3] = g4w;
406 gh[3] = g4h;
407 lx[4] = c5_x;
408 ly[4] = c5_y;
409 sdeg[4] = c5_deg;
410 gx[4] = g5x;
411 gy[4] = g5y;
412 gw[4] = g5w;
413 gh[4] = g5h;
414 gx[5] = g6x;
415 gy[5] = g6y;
416 gw[5] = g6w;
417 gh[5] = g6h;
418 lx[6] = c7_x;
419 ly[6] = c7_y;
420 sdeg[6] = c7_deg;
421 XAutoRepeatOff( dp );
422 cs_num = 0;
423 }
424
read_pixmap()425 read_pixmap()
426 {
427 int i;
428
429 xpatt.valuemask = XpmColormap;
430 xpatt.colormap = cmap;
431 for( i = 0; i < 21; i++ ){
432 XpmCreatePixmapFromData( dp, root,
433 p_wall_data[i], &p_wall[i], NULL, &xpatt );
434 wall_width[i] = xpatt.width;
435 wall_height[i] = xpatt.height;
436 }
437 XpmCreatePixmapFromData( dp, root, frame_xpm, &p_frame, NULL, &xpatt );
438 XpmCreatePixmapFromData( dp, root, titlem_xpm, &p_titlem, NULL, &xpatt );
439 XpmCreatePixmapFromData( dp, root, ball3_xpm, &point_ball, NULL, &xpatt );
440
441 XpmCreatePixmapFromData( dp, root, one_xpm, &num[0], NULL, &xpatt );
442 XpmCreatePixmapFromData( dp, root, two_xpm, &num[1], NULL, &xpatt );
443 XpmCreatePixmapFromData( dp, root, three_xpm, &num[2], NULL, &xpatt );
444 XpmCreatePixmapFromData( dp, root, go_xpm, &num[3], NULL, &xpatt );
445 XpmCreatePixmapFromData( dp, root, goal_xpm, &num[4], NULL, &xpatt );
446 }
447
change_cmap()448 void change_cmap()
449 {
450 int i;
451 unsigned long bpixel, wpixel;
452 unsigned long plane_mask, pixel[1];
453 XColor set_pixel, rgb;
454
455 /* free pixmap */
456 free_pix( p_ball[0] );
457 free_pix( p_ball[1] );
458 free_pix( mask[0] );
459 free_pix( mask[1] );
460 for( i = 0; i < 20; i++ )
461 free_pix( p_wall[i] );
462 free_pix( p_frame );
463 free_pix( p_titlem );
464 free_pix( point_ball );
465 for( i = 0; i < 5; i++ )
466 free_pix( num[i] );
467
468 owncmap = 1;
469 create_cmap( &bpixel, &wpixel );
470
471 XSetForeground( dp, textGC, wpixel );
472 XSetForeground( dp, text_csGC[0], wpixel );
473 XSetForeground( dp, text_csGC[1], cs_pixel );
474 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
475 tipix[0] = pixel[0];
476 XAllocNamedColor( dp, cmap, TCOL2, &set_pixel, &rgb );
477 tipix[1] = set_pixel.pixel;
478 XAllocNamedColor( dp, cmap, TCOL3, &set_pixel, &rgb );
479 tipix[2] = set_pixel.pixel;
480 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
481 tipix[3] = pixel[0];
482 XSetForeground( dp, keysGC, tipix[3] );
483
484 XSetForeground( dp, blackGC, bpixel );
485 black_pixel = bpixel;
486 XSetWindowBackground( dp, win, bpixel );
487
488 /* ball */
489 xpatt.valuemask = XpmColormap;
490 xpatt.colormap = cmap;
491 XpmCreatePixmapFromData(
492 dp, root, ball_xpm, &p_ball[0], &mask[0], &xpatt );
493 XpmCreatePixmapFromData(
494 dp, root, ball2_xpm, &p_ball[1], &mask[1], &xpatt );
495 XSetClipMask( dp, ballGC[0][0], mask[0] );
496 XSetClipMask( dp, ballGC[0][1], mask[1] );
497 XSetTile( dp, ballGC[0][0], p_ball[0] );
498 XSetTile( dp, ballGC[0][1], p_ball[1] );
499 XSetClipMask( dp, ballGC[1][0], mask[0] );
500 XSetClipMask( dp, ballGC[1][1], mask[1] );
501 XSetTile( dp, ballGC[1][0], p_ball[0] );
502 XSetTile( dp, ballGC[1][1], p_ball[1] );
503
504 /* misc */
505 read_pixmap();
506
507 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
508 tipix[0] = pixel[0];
509 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
510 tipix[3] = pixel[0];
511 XSetForeground( dp, keysGC, tipix[3] );
512 XAllocColorCells( dp, cmap, False, &plane_mask, 0, pixel, 1 );
513 gpixel = pixel[0];
514 g_pixel = (char) gpixel;
515 XSetForeground( dp, goalGC, gpixel );
516 colors.pixel = gpixel;
517 colors.flags = DoRed | DoGreen | DoBlue;
518 colors.green = 0;
519 colors.blue = 0;
520 colors.red = 0;
521 XStoreColor( dp, cmap, &colors );
522 }
523
set_fade()524 set_fade()
525 {
526 GC fgc,bgc;
527 int i,j;
528 struct {
529 int x;
530 int y;
531 } maskd[25] = {
532 {0,0},{2,2},{0,2},{2,0},{1,1},{3,3},{1,3},{3,1},
533 {0,4},{2,4},{4,2},{4,0},{4,4},{0,1},{2,3},{3,0},
534 {1,2},{4,3},{2,1},{1,4},{3,2},{1,0},{3,4},{4,1},{0,3}
535 };
536
537 for( i = 0; i < 25; i++ )
538 fade[i] = XCreatePixmap( dp, root, 5, 5, 1 );
539 fgc = XCreateGC( dp, fade[0], 0, NULL );
540 bgc = XCreateGC( dp, fade[0], 0, NULL );
541 XSetForeground( dp, fgc, 1 );
542 XSetForeground( dp, bgc, 0 );
543 for( i = 0; i < 25; i++ ){
544 XFillRectangle( dp, fade[i], bgc, 0, 0, 5, 5 );
545 for( j = 0; j <= i; j++ )
546 XDrawPoint( dp, fade[i], fgc, maskd[j].x, maskd[j].y );
547 }
548 fadeGC = XCreateGC( dp, root, 0, NULL );
549 XSetFillStyle( dp, fadeGC, FillStippled );
550 XFreeGC( dp, fgc );
551 XFreeGC( dp, bgc );
552 }
553
free_pix(fpix)554 free_pix( fpix )
555 Pixmap fpix;
556 {
557 if( fpix )
558 XFreePixmap( dp, fpix );
559 }
560
create_cmap(bpixel,wpixel)561 create_cmap( bpixel, wpixel )
562 unsigned long *bpixel, *wpixel;
563 {
564 Colormap new_cmap;
565 XColor set_pixel, rgb;
566 XVisualInfo v_info;
567
568 if( XMatchVisualInfo( dp, sc, 8, PseudoColor, &v_info ) == 0 )
569 p_err("This X server doesn't support PseudoColor (256 colors)");
570 new_cmap = XCreateColormap( dp, root, v_info.visual, AllocNone );
571 XInstallColormap( dp, new_cmap );
572 XSetWindowColormap( dp, win, new_cmap );
573 XAllocNamedColor( dp, new_cmap, "black", &set_pixel, &rgb );
574 *bpixel = set_pixel.pixel;
575 XAllocNamedColor( dp, new_cmap, "white", &set_pixel, &rgb );
576 *wpixel = set_pixel.pixel;
577 XAllocNamedColor( dp, new_cmap, "yellow", &set_pixel, &rgb );
578 b3pixel = set_pixel.pixel;
579 XAllocNamedColor( dp, new_cmap, "red", &set_pixel, &rgb );
580 otpixel = set_pixel.pixel;
581 XAllocNamedColor( dp, new_cmap, "orange", &set_pixel, &rgb );
582 cs_pixel = set_pixel.pixel;
583 white_pixel = *wpixel;
584 black_pixel = *bpixel;
585
586 cmap = new_cmap;
587 }
588
589 /*
590 goal
591 */
592
clear_screen()593 void clear_screen()
594 {
595 int i;
596
597 XSetForeground( dp, fadeGC, black_pixel );
598 for( i = 0; i < 25; i++ ){
599 XSetStipple( dp, fadeGC, fade[i] );
600 XFillRectangle( dp, win, fadeGC, 0, 0, WWIDTH, WHEIGHT );
601 XFlush( dp );
602 u_sleep(20000);
603 }
604 XSync( dp, True );
605 u_sleep(300000);
606 }
607
draw_result(high,res_time)608 void draw_result( high, res_time )
609 int high;
610 int res_time;
611 {
612 XCharStruct overall;
613 int dir;
614 int ascent_i;
615 int descent;
616 int s_width;
617 int i;
618 int x, rec_x[3], min_x;
619 char form[20];
620
621 char buf[20], n_buf[3][20+NAME_MAX], buf_t[10];
622
623 XClearWindow( dp, win );
624 sprintf(buf, "COURSE %d", select_course);
625 XTextExtents( fn, buf, strlen(buf), &dir, &ascent_i, &descent, &overall );
626 s_width = overall.rbearing - overall.lbearing;
627 x = (WWIDTH - s_width) / 2 - overall.lbearing;
628 XDrawString( dp, win, textGC, x, 30+ascent, buf, strlen(buf) );
629
630 for( i = 0; i < 3; i++ ){
631 conv_time( record[select_course-1][i], buf_t );
632 sprintf(form, "%%d %%s %%-%ds", NAME_MAX );
633 sprintf(n_buf[i], form, i+1, buf_t, name[select_course-1][i] );
634 XTextExtents( fn, n_buf[i], strlen(n_buf[i]),
635 &dir, &ascent_i, &descent, &overall );
636 s_width = overall.rbearing - overall.lbearing;
637 rec_x[i] = (WWIDTH - s_width) / 2 - overall.lbearing;
638 }
639 min_x = rec_x[0];
640 if( rec_x[1] < min_x )
641 min_x = rec_x[1];
642 if( rec_x[2] < min_x )
643 min_x = rec_x[2];
644 for( i = 0; i < 3; i++ )
645 XDrawString( dp, win, textGC, min_x,
646 65+ascent+i*30, n_buf[i], strlen(n_buf[i]) );
647
648 if( high > 0 )
649 XCopyArea( dp, point_ball, win, copyGC, 0, 0, 14, 14,
650 min_x-20+(overall.lbearing), 68+(high-1)*30 );
651 conv_time( res_time, buf_t );
652 sprintf(buf, "Results : %s",buf_t);
653 XTextExtents( fn, buf, strlen(buf), &dir, &ascent_i, &descent, &overall );
654 s_width = overall.rbearing - overall.lbearing;
655 x = (WWIDTH - s_width) / 2 - overall.lbearing;
656 if( high > 0 ){
657 XSetForeground( dp, textGC, b3pixel );
658 XDrawString( dp, win, textGC, x, 180, buf, strlen(buf) );
659 XSetForeground( dp, textGC, white_pixel );
660 }else if( over_time > (res_time/6) ){
661 XSetForeground( dp, textGC, otpixel );
662 XDrawString( dp, win, textGC, x, 180, buf, strlen(buf) );
663 XSetForeground( dp, textGC, white_pixel );
664 }else
665 XDrawString( dp, win, textGC, x, 180, buf, strlen(buf) );
666
667 XFlush( dp );
668 }
669
conv_time(tm,buf)670 void conv_time( tm, buf )
671 int tm;
672 char *buf;
673 {
674 int min, sec, msec;
675
676 msec = tm % 100;
677 sec = tm / 100;
678 min = sec / 60;
679 sec = sec % 60;
680
681 sprintf(buf, "%01d\'%02d\"%02d", min, sec, msec);
682 }
683
684 /*
685 course select
686 */
687
course_select()688 int course_select()
689 {
690 int sc;
691
692 set_cs_state();
693 draw_cst();
694 sc = cs_ev();
695 cs_num = sc - 1;
696 set_cs_state();
697 draw_cst_sub();
698
699 if( sc != 1 )
700 XFillRectangle( dp, win, blackGC, cs_x, 45, cs_width, 23 );
701 if( sc != 2 )
702 XFillRectangle( dp, win, blackGC, cs_x, 70, cs_width, 23 );
703 if( sc != 3 )
704 XFillRectangle( dp, win, blackGC, cs_x, 95, cs_width, 23 );
705 if( sc != 4 )
706 XFillRectangle( dp, win, blackGC, cs_x, 120, cs_width, 23 );
707 if( sc != 5 )
708 XFillRectangle( dp, win, blackGC, cs_x, 145, cs_width, 23 );
709 if( sc != 6 )
710 XFillRectangle( dp, win, blackGC, cs_x, 170, cs_width, 23 );
711 if( sc != 7 )
712 XFillRectangle( dp, win, blackGC, cs_x, 195, cs_width, 23 );
713 XFlush(dp);
714
715 return sc;
716 }
717
cs_ev()718 int cs_ev()
719 {
720 int a;
721 while(1){
722 XNextEvent( dp, &ev );
723 if( ev.type == Expose )
724 draw_cst();
725 if( ev.type == KeyPress )
726 if( (a = keycheck3(ev)) )
727 return a;
728 }
729 }
730
keycheck3(ev)731 keycheck3(ev)
732 XKeyEvent ev;
733 {
734 char ch;
735 KeySym ksym;
736
737 XLookupString( &ev, &ch, 1, &ksym, NULL );
738 switch(ksym){
739 case XK_Up:
740 cs_num--;
741 cs_num = (cs_num + COURSE) % COURSE;
742 set_cs_state();
743 draw_cst_sub();
744 return 0;
745 case XK_Down:
746 cs_num++;
747 cs_num %= COURSE;
748 set_cs_state();
749 draw_cst_sub();
750 return 0;
751 case XK_space:
752 return (cs_num+1);
753 case XK_1:
754 return 1;
755 case XK_2:
756 return 2;
757 case XK_3:
758 return 3;
759 case XK_4:
760 return 4;
761 case XK_5:
762 return 5;
763 case XK_6:
764 return 6;
765 case XK_7:
766 return 7;
767 case XK_q:
768 end_prog();
769 }
770 return 0;
771 }
772
set_cs_state()773 set_cs_state()
774 {
775 int i;
776
777 for( i = 0; i < COURSE; i++ )
778 cs_state[i] = 0;
779 cs_state[cs_num] = 1;
780 }
781
draw_cst()782 draw_cst()
783 {
784 XCharStruct overall;
785 int dir;
786 int ascent_i;
787 int descent;
788 int s_width;
789 int x;
790
791 char buf[20];
792
793 XClearWindow( dp, win );
794 sprintf(buf, "COURSE SELECT");
795 XTextExtents( fn_cs, buf, strlen(buf),
796 &dir, &ascent_i, &descent, &overall );
797 s_width = overall.rbearing - overall.lbearing;
798 x = (WWIDTH - s_width) / 2 - overall.lbearing;
799 XDrawString( dp, win, text_csGC[0], x, 15+ascent_cs, buf, strlen(buf) );
800
801 sprintf(buf, "5. Professional");
802 XTextExtents( fn_cs, buf, strlen(buf),
803 &dir, &ascent_i, &descent, &overall );
804 s_width = overall.rbearing - overall.lbearing;
805 cs_text_x = (WWIDTH - s_width) / 2 - overall.lbearing;
806 cs_width = s_width;
807 cs_x = cs_text_x + overall.lbearing;
808
809 draw_cst_sub();
810 }
811
draw_cst_sub()812 draw_cst_sub()
813 {
814 char buf[20];
815
816 XFillRectangle( dp, win, blackGC, cs_x, 45, cs_width, 175 );
817 sprintf(buf, "1. Novice");
818 XDrawString( dp, win, text_csGC[cs_state[0]],
819 cs_text_x, 45+ascent_cs, buf, strlen(buf) );
820 sprintf(buf, "2. Average");
821 XDrawString( dp, win, text_csGC[cs_state[1]],
822 cs_text_x, 70+ascent_cs, buf, strlen(buf) );
823 sprintf(buf, "3. Master");
824 XDrawString( dp, win, text_csGC[cs_state[2]],
825 cs_text_x, 95+ascent_cs, buf, strlen(buf) );
826 sprintf(buf, "4. Expert");
827 XDrawString( dp, win, text_csGC[cs_state[3]],
828 cs_text_x, 120+ascent_cs, buf, strlen(buf) );
829 sprintf(buf, "5. Professional");
830 XDrawString( dp, win, text_csGC[cs_state[4]],
831 cs_text_x, 145+ascent_cs, buf, strlen(buf) );
832 sprintf(buf, "6. Special 1");
833 XDrawString( dp, win, text_csGC[cs_state[5]],
834 cs_text_x, 170+ascent_cs, buf, strlen(buf) );
835 sprintf(buf, "7. Special 2");
836 XDrawString( dp, win, text_csGC[cs_state[6]],
837 cs_text_x, 195+ascent_cs, buf, strlen(buf) );
838 XFlush( dp );
839 }
840
841
create_course()842 void create_course()
843 {
844 int x, y, pix;
845 struct course_d *cd;
846
847
848 p_course = XCreatePixmap( dp, root, MWIDTH, MHEIGHT,
849 DefaultDepth( dp, sc ) );
850 XFillRectangle( dp, p_course, clearGC, 0, 0, MWIDTH, MHEIGHT );
851 init_course();
852
853 if( select_course != 7 ){
854 cd = cs_d[select_course-1];
855 while(1){
856 x = cd->x;
857 y = cd->y;
858 pix = (cd++)->pix;
859 if( pix == '@' )
860 break;
861 if( pix == 20 )
862 XCopyArea( dp, p_wall[20], p_course, copyGC, 0, 0,
863 wall_width[20], wall_height[20], x * 5, y * 5 );
864 else
865 XCopyArea( dp, p_wall[pix], p_course, copyGC, 0, 0,
866 wall_width[pix], wall_height[pix], x * 25, y * 25 );
867 }
868 }else
869 c7_make();
870
871 bimage = XGetImage( dp, p_course, 0, 0,
872 MWIDTH, MHEIGHT, AllPlanes, ZPixmap );
873 bw = MWIDTH; bh = MHEIGHT;
874 bdata = bimage->data;
875 }
876
init_course()877 init_course()
878 {
879 int a;
880
881 a = select_course-1;
882 if( select_course != 7 )
883 XFillRectangle( dp, p_course, goalGC, gx[a], gy[a], gw[a], gh[a] );
884 else{
885 XFillRectangle( dp, p_course, goalGC, g7x[0], g7y[0], g7w[0], g7h[0] );
886 XFillRectangle( dp, p_course, goalGC, g7x[1], g7y[1], g7w[1], g7h[1] );
887 }
888 }
889
890 /* course 7 */
c7_make()891 c7_make()
892 {
893 int w[29][29], w2[29][29], *p;
894 int dx[] = {0,1,0,-1}, dy[] = {-1,0,1,0};
895 int x, y;
896 int a, i;
897
898 for( x = 0; x < 29; x++ )
899 for( y = 0; y < 29; y++ )
900 w[x][y] = 0;
901 for( x = 2; x < 28; x += 2 )
902 for( y = 2; y < 28; y += 2 ){
903 l1:
904 if( x == 2 )
905 a = (rand() & 0x30) >> 4;
906 else
907 a = rand() % 3;
908 p = &w[x+dx[a]][y+dy[a]];
909 if( *p ){
910 if( (rand() & 0xff) > 0x80 )
911 goto l1;
912 } else
913 *p = 1;
914 }
915 a = rand() & 0x3;
916 switch( a ){
917 case 0:
918 for( x = 0; x < 29; x++ )
919 for( y = 0; y < 29; y++ )
920 w2[x][y] = w[x][y];
921 break;
922 case 1:
923 for( x = 0; x < 29; x++ )
924 for( y = 0; y < 29; y++ )
925 w2[28-y][x] = w[x][y];
926 break;
927 case 2:
928 for( x = 0; x < 29; x++ )
929 for( y = 0; y < 29; y++ )
930 w2[28-x][28-y] = w[x][y];
931 break;
932 case 3:
933 for( x = 0; x < 29; x++ )
934 for( y = 0; y < 29; y++ )
935 w2[y][28-x] = w[x][y];
936 }
937 for( x = 0; x < 29; x++ )
938 for( y = 0; y < 29; y++ )
939 if( w2[x][y] )
940 if( y & 1 )
941 draw_c7(x,y,1);
942 else
943 draw_c7(x,y,0);
944
945 for( i = 0; i < 950; i += 50 ){
946 XCopyArea( dp, p_wall[2], p_course, copyGC, 0, 0,
947 wall_width[2], wall_height[2], i, 995 );
948 XCopyArea( dp, p_wall[3], p_course, copyGC, 0, 0,
949 wall_width[3], wall_height[3], 0, i );
950 }
951 XCopyArea( dp, p_wall[2], p_course, copyGC, 0, 0,
952 wall_width[2]-5, wall_height[2], 950, 995 );
953 XCopyArea( dp, p_wall[3], p_course, copyGC, 0, 0,
954 wall_width[3], wall_height[3]-5, 0, 950 );
955 for( i = 970; i > 25; i -= 50 ){
956 XCopyArea( dp, p_wall[2], p_course, copyGC, 0, 0,
957 wall_width[2], wall_height[2], i, 0 );
958 XCopyArea( dp, p_wall[3], p_course, copyGC, 0, 0,
959 wall_width[3], wall_height[3], 995, i );
960 }
961 XCopyArea( dp, p_wall[2], p_course, copyGC, 5, 0,
962 wall_width[2]-5, wall_height[2], 25, 0 );
963 XCopyArea( dp, p_wall[3], p_course, copyGC, 0, 5,
964 wall_width[3], wall_height[3]-5, 995, 25 );
965
966 }
967
draw_c7(x,y,ty)968 draw_c7( x, y, ty )
969 int x, y, ty;
970 {
971 int i;
972
973 if( ty )
974 for( i = 0; i < 8; i++ )
975 XCopyArea( dp, p_wall[20], p_course, copyGC,
976 0, 0, 10, 10, x*35+15, (y-1)*35+i*10+15);
977 else
978 for( i = 0; i < 8; i++ )
979 XCopyArea( dp, p_wall[20], p_course, copyGC,
980 0, 0, 10, 10, (x-1)*35+i*10+15, y*35+15);
981 }
982
set_background(scn)983 void set_background(scn)
984 int scn;
985 {
986 int bx, by;
987 int y;
988 int p_status;
989 int wid;
990
991 retry:
992 xpatt.valuemask = XpmReturnPixels | XpmColormap;
993 xpatt.colormap = cmap;
994 if( (p_status = XpmCreatePixmapFromData(
995 dp, win, bg_data[scn], &back_pix, NULL, &xpatt )) != XpmSuccess ){
996 if( owncmap == 0 ){
997 change_cmap();
998 goto retry;
999 }
1000 p_err(XpmGetErrorString(p_status));
1001 }
1002 bg_col = xpatt.pixels;
1003 bg_num = xpatt.npixels;
1004 XFillRectangle(dp, back_pix,
1005 ballGC[0][ball_type], ball_x_bg, ball_y_bg, ball_w, ball_h);
1006 back_image = XGetImage( dp, back_pix, 0, 0, 200, 200, AllPlanes, ZPixmap );
1007 wid = RWIDTH;
1008 if( wid > 200 )
1009 wid = 200;
1010 back_data = (char *)malloc(wid * vheight);
1011 bx = (200-wid)/2;
1012 by = (200-vheight)/2;
1013 for( y = 0; y < vheight; y++ )
1014 memcpy( back_data+y*wid, (back_image->data)+bx+(by+y)*200, wid );
1015 }
1016
free_xres()1017 void free_xres()
1018 {
1019 XFreePixmap( dp, p_course );
1020 XDestroyImage( bimage );
1021
1022 XFreeColors( dp, cmap, bg_col, bg_num, 0 );
1023 XDestroyImage( back_image );
1024 XFreePixmap( dp, back_pix );
1025 free( back_data );
1026 XFlush(dp);
1027 }
1028
draw_win()1029 void draw_win()
1030 {
1031 XClearWindow( dp, win );
1032 XCopyArea( dp, p_frame, win, copyGC, 0, 0, 225, 225, 0, 0 );
1033 XCopyArea( dp, p_titlem, win, copyGC, 0, 0, 70, 35,
1034 (WWIDTH-225-75)/2+225, 10 );
1035 }
1036
draw_mesg()1037 void draw_mesg()
1038 {
1039 XFillRectangle( dp, win, blackGC, (WWIDTH-225-70)/2+225, 150, 70, 60 );
1040 if( num_state < 3 )
1041 XCopyArea( dp, num[num_state], win, copyGC, 0, 0, 60, 60,
1042 (WWIDTH-225-60)/2+225, 150 );
1043 else if( num_state < 5 )
1044 XCopyArea( dp, num[num_state], win, copyGC, 0, 0, 70, 60,
1045 (WWIDTH-225-70)/2+225, 150 );
1046
1047 XFlush(dp);
1048 }
1049
pre_ev()1050 int pre_ev()
1051 {
1052 while( XEventsQueued( dp, QueuedAfterReading ) ){
1053 XNextEvent( dp, &ev );
1054 switch( ev.type ){
1055 case Expose:
1056 draw_win();
1057 screen();
1058 break;
1059 case KeyPress:
1060 case KeyRelease:
1061 key_check( ev );
1062 if( escape == 1 )
1063 return 1;
1064 restart = 0;
1065 }
1066 }
1067 return 0;
1068 }
1069
pre_event()1070 void pre_event()
1071 {
1072 while( XCheckWindowEvent( dp, win, KeyPressMask, &ev ) )
1073 ;
1074 }
1075
goal_event(h,t)1076 void goal_event( h, t )
1077 int h, t;
1078 {
1079 while(1){
1080 XNextEvent( dp, &ev );
1081 if( ev.type == Expose )
1082 draw_result( h, t );
1083 if( ev.type == KeyPress )
1084 if( keycheck2(ev) )
1085 return;
1086 }
1087 }
1088
keycheck2(ev)1089 keycheck2(ev)
1090 XKeyEvent ev;
1091 {
1092 char ch;
1093 KeySym ksym;
1094
1095 XLookupString( &ev, &ch, 1, &ksym, NULL );
1096 if( ksym == XK_space )
1097 return 1;
1098 if( ksym == XK_q ){
1099 end_prog();
1100 }
1101 return 0;
1102 }
1103
check_ev()1104 void check_ev()
1105 {
1106 redc++;
1107 redc &= 0x3f;
1108 colors.red = grad[redc];
1109 XStoreColor( dp, cmap, &colors );
1110
1111 while( XEventsQueued( dp, QueuedAfterReading ) ){
1112 XNextEvent( dp, &ev );
1113 switch( ev.type ){
1114 case KeyPress:
1115 case KeyRelease:
1116 key_check( ev );
1117 break;
1118 case Expose:
1119 draw_win();
1120 draw_mesg();
1121 }
1122 }
1123 }
1124
key_check(ev)1125 key_check( ev )
1126 XKeyEvent ev;
1127 {
1128 register int set=0;
1129 KeySym ksym;
1130 char ch;
1131
1132 if( ev.type == KeyPress )
1133 set = 1;
1134
1135 XLookupString( &ev, &ch, 1, &ksym, NULL );
1136 switch( ksym ){
1137 case XK_Left:
1138 key_left = set;
1139 break;
1140 case XK_Right:
1141 key_right = set;
1142 break;
1143 case XK_space:
1144 key_space = set;
1145 break;
1146 case XK_Up:
1147 jump_key = set;
1148 break;
1149 case XK_Down:
1150 soft_key = set * 9;
1151 break;
1152 case XK_Return:
1153 if( ev.type == KeyPress )
1154 restart = 1;
1155 break;
1156 case XK_Escape:
1157 if( ev.type == KeyPress )
1158 escape = 1;
1159 break;
1160 case XK_q:
1161 end_prog();
1162 }
1163 }
1164
end_prog()1165 void end_prog()
1166 {
1167 if( dp ){
1168 #ifdef MITSHM
1169 if( shm ){
1170 if( shminfo[0].shmid > 0 )
1171 XShmDetach( dp, &(shminfo[0]) );
1172 if( shminfo[1].shmid > 0 )
1173 XShmDetach( dp, &(shminfo[1]) );
1174 }
1175 #endif
1176 XAutoRepeatOn( dp );
1177 XCloseDisplay( dp );
1178 }
1179 #ifdef MITSHM
1180 if( shm ){
1181 if( image[0] )
1182 shmdt( image[0] );
1183 if( image[1] )
1184 shmdt( image[1] );
1185 if( shminfo[0].shmid >= 0 )
1186 shmctl( shminfo[0].shmid, IPC_RMID, 0 );
1187 if( shminfo[1].shmid >= 0 )
1188 shmctl( shminfo[1].shmid, IPC_RMID, 0 );
1189 }
1190 #endif
1191 exit(0);
1192 }
1193