rnd-19981017-1
[rocksndiamonds.git] / src / buttons.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  buttons.c                                               *
12 ***********************************************************/
13
14 #include "buttons.h"
15 #include "tools.h"
16 #include "misc.h"
17 #include "editor.h"
18 #include "tape.h"
19
20 /****************************************************************/
21 /********** drawing buttons and corresponding displays **********/
22 /****************************************************************/
23
24 void DrawVideoDisplay(unsigned long state, unsigned long value)
25 {
26   int i;
27   int part_label = 0, part_symbol = 1;
28   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
29   static char *monatsname[12] =
30   {
31     "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
32     "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
33   };
34   static int video_pos[10][2][4] =
35   {
36     {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
37        VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE },
38      { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
39        VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }},
40
41     {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
42        VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE },
43      { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
44        VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }},
45
46     {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
47        VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE },
48      { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
49        VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }},
50
51     {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
52        VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE },
53      { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
54        VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }},
55
56     {{ 0,0,
57        0,0 },
58      { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
59        VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }},
60
61     {{ VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS,
62        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
63      { 0,0,
64        0,0 }},
65
66     {{ VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS,
67        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
68      { 0,0,
69        0,0 }},
70
71     {{ VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS,
72        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
73      { 0,0,
74        0,0 }},
75
76     {{ VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS,
77        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
78      { 0,0,
79        0,0 }},
80
81     {{ VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS,
82        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
83      { 0,0,
84        0,0 }}
85   };
86
87   for(i=0;i<20;i++)
88   {
89     if (state & (1<<i))
90     {
91       int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
92
93       if (i%2)                  /* i ungerade => STATE_ON / PRESS_OFF */
94         cx = DOOR_GFX_PAGEX4;
95       else
96         cx = DOOR_GFX_PAGEX3;   /* i gerade => STATE_OFF / PRESS_ON */
97
98       if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
99         XCopyArea(display,pix[PIX_DOOR],drawto,gc,
100                   cx + video_pos[pos][part_label][xpos],
101                   cy + video_pos[pos][part_label][ypos],
102                   video_pos[pos][part_label][xsize],
103                   video_pos[pos][part_label][ysize],
104                   VX + video_pos[pos][part_label][xpos],
105                   VY + video_pos[pos][part_label][ypos]);
106       if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
107         XCopyArea(display,pix[PIX_DOOR],drawto,gc,
108                   cx + video_pos[pos][part_symbol][xpos],
109                   cy + video_pos[pos][part_symbol][ypos],
110                   video_pos[pos][part_symbol][xsize],
111                   video_pos[pos][part_symbol][ysize],
112                   VX + video_pos[pos][part_symbol][xpos],
113                   VY + video_pos[pos][part_symbol][ypos]);
114     }
115   }
116
117   if (state & VIDEO_STATE_FFWD_ON)
118   {
119     int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
120
121     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
122               cx + VIDEO_PLAY_SYMBOL_XPOS,
123               cy + VIDEO_PLAY_SYMBOL_YPOS,
124               VIDEO_PLAY_SYMBOL_XSIZE - 2,
125               VIDEO_PLAY_SYMBOL_YSIZE,
126               VX + VIDEO_PLAY_SYMBOL_XPOS - 9,
127               VY + VIDEO_PLAY_SYMBOL_YPOS);
128   }
129
130   if (state & VIDEO_STATE_DATE_ON)
131   {
132     int tag = value % 100;
133     int monat = (value/100) % 100;
134     int jahr = (value/10000);
135
136     DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
137              int2str(tag,2),FS_SMALL,FC_SPECIAL1);
138     DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
139              monatsname[monat],FS_SMALL,FC_SPECIAL1);
140     DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
141              int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
142   }
143
144   if (state & VIDEO_STATE_TIME_ON)
145   {
146     int min = value / 60;
147     int sec = value % 60;
148
149     DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
150              int2str(min,2),FS_SMALL,FC_SPECIAL1);
151     DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
152              int2str(sec,2),FS_SMALL,FC_SPECIAL1);
153   }
154
155   if (state & VIDEO_STATE_DATE)
156     redraw_mask |= REDRAW_VIDEO_1;
157   if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
158     redraw_mask |= REDRAW_VIDEO_2;
159   if (state & VIDEO_PRESS)
160     redraw_mask |= REDRAW_VIDEO_3;
161 }
162
163 void DrawCompleteVideoDisplay()
164 {
165   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
166             DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY);
167   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
168             DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS,
169             DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS,
170             VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
171             VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
172
173   DrawVideoDisplay(VIDEO_ALL_OFF,0);
174   if (tape.date && tape.length)
175   {
176     DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
177     DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds);
178   }
179
180   XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
181             VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
182 }
183
184 void DrawSoundDisplay(unsigned long state)
185 {
186   int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
187
188   pos = (state & BUTTON_SOUND_MUSIC ? SOUND_BUTTON_MUSIC_XPOS :
189          state & BUTTON_SOUND_LOOPS ? SOUND_BUTTON_LOOPS_XPOS :
190          SOUND_BUTTON_SIMPLE_XPOS);
191
192   if (state & BUTTON_ON)
193     cy -= SOUND_BUTTON_YSIZE;
194
195   if (state & BUTTON_PRESSED)
196     cx = DOOR_GFX_PAGEX3;
197
198   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
199             cx + pos,cy + SOUND_BUTTON_ANY_YPOS,
200             SOUND_BUTTON_XSIZE,SOUND_BUTTON_YSIZE,
201             DX + pos,DY + SOUND_BUTTON_ANY_YPOS);
202
203   redraw_mask |= REDRAW_DOOR_1;
204 }
205
206 void DrawGameButton(unsigned long state)
207 {
208   int pos, cx = DOOR_GFX_PAGEX4, cy = -GAME_BUTTON_YSIZE;
209
210   pos = (state & BUTTON_GAME_STOP ? GAME_BUTTON_STOP_XPOS :
211          state & BUTTON_GAME_PAUSE ? GAME_BUTTON_PAUSE_XPOS :
212          GAME_BUTTON_PLAY_XPOS);
213
214   if (state & BUTTON_PRESSED)
215     cx = DOOR_GFX_PAGEX3;
216
217   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
218             cx + pos,cy + GAME_BUTTON_ANY_YPOS,
219             GAME_BUTTON_XSIZE,GAME_BUTTON_YSIZE,
220             DX + pos,DY + GAME_BUTTON_ANY_YPOS);
221
222   redraw_mask |= REDRAW_DOOR_1;
223 }
224
225 void DrawYesNoButton(unsigned long state, int mode)
226 {
227   Drawable dest_drawto;
228   int dest_xoffset, dest_yoffset;
229   int xpos, cx = DOOR_GFX_PAGEX4;
230
231   if (mode == DB_INIT)
232   {
233     dest_drawto = pix[PIX_DB_DOOR];
234     dest_xoffset = DOOR_GFX_PAGEX1;
235     dest_yoffset = 0;
236   }
237   else
238   {
239     dest_drawto = drawto;
240     dest_xoffset = DX;
241     dest_yoffset = DY;
242   }
243
244   xpos = (state & BUTTON_OK ? OK_BUTTON_XPOS : NO_BUTTON_XPOS);
245
246   if (state & BUTTON_PRESSED)
247     cx = DOOR_GFX_PAGEX3;
248
249   XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
250             cx + xpos, OK_BUTTON_GFX_YPOS,
251             OK_BUTTON_XSIZE, OK_BUTTON_YSIZE,
252             dest_xoffset + xpos, dest_yoffset + OK_BUTTON_YPOS);
253
254   redraw_mask |= REDRAW_DOOR_1;
255 }
256
257 void DrawConfirmButton(unsigned long state, int mode)
258 {
259   Drawable dest_drawto;
260   int dest_xoffset, dest_yoffset;
261   int cx = DOOR_GFX_PAGEX4;
262
263   if (mode == DB_INIT)
264   {
265     dest_drawto = pix[PIX_DB_DOOR];
266     dest_xoffset = DOOR_GFX_PAGEX1;
267     dest_yoffset = 0;
268   }
269   else
270   {
271     dest_drawto = drawto;
272     dest_xoffset = DX;
273     dest_yoffset = DY;
274   }
275
276   if (state & BUTTON_PRESSED)
277     cx = DOOR_GFX_PAGEX3;
278
279   XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
280             cx + CONFIRM_BUTTON_XPOS, CONFIRM_BUTTON_GFX_YPOS,
281             CONFIRM_BUTTON_XSIZE, CONFIRM_BUTTON_YSIZE,
282             dest_xoffset + CONFIRM_BUTTON_XPOS,
283             dest_yoffset + CONFIRM_BUTTON_YPOS);
284
285   redraw_mask |= REDRAW_DOOR_1;
286 }
287
288 void DrawPlayerButton(unsigned long state, int mode)
289 {
290   Drawable dest_drawto;
291   int dest_xoffset, dest_yoffset;
292   int graphic;
293   int graphic_offset = (PLAYER_BUTTON_XSIZE - TILEX/2)/2;
294   int xpos, ypos;
295   int cx = DOOR_GFX_PAGEX4, cy = 0;
296
297   if (mode == DB_INIT)
298   {
299     dest_drawto = pix[PIX_DB_DOOR];
300     dest_xoffset = DOOR_GFX_PAGEX1;
301     dest_yoffset = 0;
302   }
303   else
304   {
305     dest_drawto = drawto;
306     dest_xoffset = DX;
307     dest_yoffset = DY;
308   }
309
310   if (state & BUTTON_PLAYER_1)
311     graphic = GFX_SPIELER1;
312   else if (state & BUTTON_PLAYER_2)
313     graphic = GFX_SPIELER2;
314   else if (state & BUTTON_PLAYER_3)
315     graphic = GFX_SPIELER3;
316   else if (state & BUTTON_PLAYER_4)
317     graphic = GFX_SPIELER4;
318
319   xpos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_3 ?
320           PLAYER_BUTTON_1_XPOS : PLAYER_BUTTON_2_XPOS);
321   ypos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_2 ?
322           PLAYER_BUTTON_1_YPOS : PLAYER_BUTTON_3_YPOS);
323
324   if (state & BUTTON_PRESSED)
325   {
326     cx = DOOR_GFX_PAGEX3;
327     graphic_offset += 1;
328   }
329
330   XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
331             cx + PLAYER_BUTTON_GFX_XPOS, cy + PLAYER_BUTTON_GFX_YPOS,
332             PLAYER_BUTTON_XSIZE, PLAYER_BUTTON_YSIZE,
333             dest_xoffset + xpos, dest_yoffset + ypos);
334   DrawMiniGraphicExt(dest_drawto,gc,
335                      dest_xoffset + xpos + graphic_offset,
336                      dest_yoffset + ypos + graphic_offset,
337                      graphic);
338
339   redraw_mask |= REDRAW_DOOR_1;
340 }
341
342 /* several buttons in the level editor */
343
344 void DrawEditButton(unsigned long state)
345 {
346   int i;
347   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
348   int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY2;
349   static int edit_pos[6][4] =
350   {
351    {ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS,
352     ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE},
353
354    {ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS,
355     ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE},
356
357    {ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS,
358     ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE},
359
360    {ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS,
361     ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE},
362
363    {ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS,
364     ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE},
365
366    {ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS,
367     ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE}
368   };
369
370   if (state & ED_BUTTON_PRESSED)
371     cx = DOOR_GFX_PAGEX5;
372
373   for(i=0;i<6;i++)
374   {
375     if (state & (1<<i))
376       XCopyArea(display,pix[PIX_DOOR],drawto,gc,
377                 cx + edit_pos[i][xpos],
378                 cy + edit_pos[i][ypos],
379                 edit_pos[i][xsize],
380                 edit_pos[i][ysize],
381                 VX + edit_pos[i][xpos],
382                 VY + edit_pos[i][ypos]);
383   }
384
385   redraw_mask |= REDRAW_DOOR_2;
386 }
387
388 void DrawCtrlButton(unsigned long state)
389 {
390   int i;
391   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
392   int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY1+80;
393   static int edit_pos[4][4] =
394   {
395    {ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS,
396     ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE},
397
398    {ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS,
399     ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE},
400
401    {ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS,
402     ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE},
403
404    {ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS,
405     ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE}
406   };
407
408   if (state & ED_BUTTON_PRESSED)
409     cx = DOOR_GFX_PAGEX3;
410
411   for(i=0;i<4;i++)
412   {
413     if (state & (1<<(i+6)))
414       XCopyArea(display,pix[PIX_DOOR],drawto,gc,
415                 cx + edit_pos[i][xpos],
416                 cy + edit_pos[i][ypos],
417                 edit_pos[i][xsize],
418                 edit_pos[i][ysize],
419                 VX + edit_pos[i][xpos],
420                 VY + edit_pos[i][ypos]);
421   }
422
423   redraw_mask |= REDRAW_DOOR_2;
424 }
425
426 void DrawElemButton(int button_nr, int button_state)
427 {
428   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
429   int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
430   int from_x, from_y, to_x,to_y, size_x, size_y;
431   static int edit_pos[3][4] =
432   {
433    {ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS,
434     ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE},
435
436    {ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS,
437     ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE},
438
439    {ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS,
440     ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE}
441   };
442
443   if (button_nr<ED_BUTTON_ELEM)
444   {
445     int pos = button_nr;
446
447     from_x = cx + edit_pos[pos][xpos];
448     from_y = cy + edit_pos[pos][ypos];
449     size_x = edit_pos[pos][xsize];
450     size_y = edit_pos[pos][ysize];
451     to_x   = DX + edit_pos[pos][xpos];
452     to_y   = DY + edit_pos[pos][ypos];
453
454     if (button_state & ED_BUTTON_PRESSED)
455     {
456       if (button_nr==ED_BUTTON_EUP)
457         from_y = cy + ED_BUTTON_EUP_Y2POS;
458       else
459         from_y = cy + ED_BUTTON_EDOWN_Y2POS;
460     }
461
462     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
463               from_x,from_y, size_x,size_y, to_x,to_y);
464   }
465   else
466   {
467     int pos = ED_BUTTON_ELEM;
468     int elem_pos = button_nr-ED_BUTTON_ELEM;
469     int x = elem_pos % MAX_ELEM_X;
470     int y = elem_pos / MAX_ELEM_X;
471     int graphic;
472     int shift = 0;
473
474     if (elem_pos+element_shift < elements_in_list)
475       graphic = el2gfx(editor_element[elem_pos+element_shift]);
476     else
477       graphic = GFX_LEERRAUM;
478
479     from_x = cx + edit_pos[pos][xpos];
480     from_y = cy + edit_pos[pos][ypos];
481     size_x = edit_pos[pos][xsize];
482     size_y = edit_pos[pos][ysize];
483     to_x   = DX + edit_pos[pos][xpos] + x * ED_BUTTON_ELEM_XSIZE;
484     to_y   = DY + edit_pos[pos][ypos] + y * ED_BUTTON_ELEM_YSIZE;
485
486     if (button_state & ED_BUTTON_PRESSED)
487     {
488       from_y = ED_BUTTON_ELEM_Y2POS;
489       shift = 1;
490     }
491
492     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
493               from_x,from_y, size_x,size_y, to_x,to_y);
494
495     DrawMiniGraphicExt(drawto,gc,
496                        DX+ED_BUTTON_ELEM_XPOS+3+shift + 
497                        (elem_pos % MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
498                        DY+ED_BUTTON_ELEM_YPOS+3-shift +
499                        (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
500                        graphic);
501   }
502
503   redraw_mask |= REDRAW_DOOR_1;
504 }
505
506 void DrawCountButton(int button_nr, int button_state)
507 {
508   int from_x, from_y, to_x,to_y, size_x, size_y;
509
510   from_x =
511     DOOR_GFX_PAGEX4+(button_nr%2 ? ED_BUTTON_PLUS_XPOS : ED_BUTTON_MINUS_XPOS);
512   from_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
513   size_x = ED_BUTTON_MINUS_XSIZE;
514   size_y = ED_BUTTON_MINUS_YSIZE;
515   to_x = (button_nr<32 ? ED_COUNT_GADGET_XPOS : ED_SIZE_GADGET_XPOS);
516   if (button_nr % 2)
517     to_x += (ED_BUTTON_PLUS_XPOS - ED_BUTTON_MINUS_XPOS);
518   to_y = (button_nr<32 ? ED_COUNT_GADGET_YPOS : ED_SIZE_GADGET_YPOS) +
519     ((button_nr<32 ? button_nr : button_nr-32)/2)*ED_COUNT_GADGET_YSIZE;
520
521   if (button_state & ED_BUTTON_PRESSED)
522     from_x -= DXSIZE;
523
524   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
525             from_x,from_y, size_x,size_y, to_x,to_y);
526   XCopyArea(display,pix[PIX_DOOR],window,gc,
527             from_x,from_y, size_x,size_y, to_x,to_y);
528 }
529
530 /**********************************************************************/
531 /********** checking buttons (and redrawing them, if needed) **********/
532 /**********************************************************************/
533
534 int CheckVideoButtons(int mx, int my, int button)
535 {
536   int return_code = 0;
537   static int choice = -1;
538   static boolean pressed = FALSE;
539   static int video_button[5] =
540   {
541     VIDEO_PRESS_EJECT_ON,
542     VIDEO_PRESS_STOP_ON,
543     VIDEO_PRESS_PAUSE_ON,
544     VIDEO_PRESS_REC_ON,
545     VIDEO_PRESS_PLAY_ON
546   };
547
548   if (button)
549   {
550     if (!motion_status)         /* Maustaste neu gedrückt */
551     {
552       if (ON_VIDEO_BUTTON(mx,my))
553       {
554         choice = VIDEO_BUTTON(mx);
555         pressed = TRUE;
556         DrawVideoDisplay(video_button[choice],0);
557       }
558     }
559     else                        /* Mausbewegung bei gedrückter Maustaste */
560     {
561       if ((!ON_VIDEO_BUTTON(mx,my) || VIDEO_BUTTON(mx)!=choice) &&
562           choice>=0 && pressed)
563       {
564         pressed = FALSE;
565         DrawVideoDisplay(video_button[choice]<<1,0);
566       }
567       else if (ON_VIDEO_BUTTON(mx,my) && VIDEO_BUTTON(mx)==choice && !pressed)
568       {
569         pressed = TRUE;
570         DrawVideoDisplay(video_button[choice],0);
571       }
572     }
573   }
574   else                          /* Maustaste wieder losgelassen */
575   {
576     if (ON_VIDEO_BUTTON(mx,my) && VIDEO_BUTTON(mx)==choice && pressed)
577     {
578       DrawVideoDisplay(video_button[choice]<<1,0);
579       return_code = choice+1;
580       choice = -1;
581       pressed = FALSE;
582     }
583     else
584     {
585       choice = -1;
586       pressed = FALSE;
587     }
588   }
589
590   BackToFront();
591   return(return_code);
592 }
593
594 int CheckSoundButtons(int mx, int my, int button)
595 {
596   int return_code = 0;
597   static int choice = -1;
598   static boolean pressed = FALSE;
599   int sound_state[3];
600
601   sound_state[0] = BUTTON_SOUND_MUSIC  | (BUTTON_ON * setup.sound_music_on);
602   sound_state[1] = BUTTON_SOUND_LOOPS  | (BUTTON_ON * setup.sound_loops_on);
603   sound_state[2] = BUTTON_SOUND_SIMPLE | (BUTTON_ON * setup.sound_simple_on);
604
605   if (button)
606   {
607     if (!motion_status)         /* Maustaste neu gedrückt */
608     {
609       if (ON_SOUND_BUTTON(mx,my))
610       {
611         choice = SOUND_BUTTON(mx);
612         pressed = TRUE;
613         DrawSoundDisplay(sound_state[choice] | BUTTON_PRESSED);
614       }
615     }
616     else                        /* Mausbewegung bei gedrückter Maustaste */
617     {
618       if ((!ON_SOUND_BUTTON(mx,my) || SOUND_BUTTON(mx)!=choice) &&
619           choice>=0 && pressed)
620       {
621         pressed = FALSE;
622         DrawSoundDisplay(sound_state[choice] | BUTTON_RELEASED);
623       }
624       else if (ON_SOUND_BUTTON(mx,my) && SOUND_BUTTON(mx)==choice && !pressed)
625       {
626         pressed = TRUE;
627         DrawSoundDisplay(sound_state[choice] | BUTTON_PRESSED);
628       }
629     }
630   }
631   else                          /* Maustaste wieder losgelassen */
632   {
633     if (ON_SOUND_BUTTON(mx,my) && SOUND_BUTTON(mx)==choice && pressed)
634     {
635       DrawSoundDisplay(sound_state[choice] | BUTTON_RELEASED);
636       return_code = 1<<choice;
637       choice = -1;
638       pressed = FALSE;
639     }
640     else
641     {
642       choice = -1;
643       pressed = FALSE;
644     }
645   }
646
647   BackToFront();
648   return(return_code);
649 }
650
651 int CheckGameButtons(int mx, int my, int button)
652 {
653   int return_code = 0;
654   static int choice = -1;
655   static boolean pressed = FALSE;
656   int game_state[3] =
657   {
658     BUTTON_GAME_STOP,
659     BUTTON_GAME_PAUSE,
660     BUTTON_GAME_PLAY
661   };
662
663   if (button)
664   {
665     if (!motion_status)         /* Maustaste neu gedrückt */
666     {
667       if (ON_GAME_BUTTON(mx,my))
668       {
669         choice = GAME_BUTTON(mx);
670         pressed = TRUE;
671         DrawGameButton(game_state[choice] | BUTTON_PRESSED);
672       }
673     }
674     else                        /* Mausbewegung bei gedrückter Maustaste */
675     {
676       if ((!ON_GAME_BUTTON(mx,my) || GAME_BUTTON(mx)!=choice) &&
677           choice>=0 && pressed)
678       {
679         pressed = FALSE;
680         DrawGameButton(game_state[choice] | BUTTON_RELEASED);
681       }
682       else if (ON_GAME_BUTTON(mx,my) && GAME_BUTTON(mx)==choice && !pressed)
683       {
684         pressed = TRUE;
685         DrawGameButton(game_state[choice] | BUTTON_PRESSED);
686       }
687     }
688   }
689   else                          /* Maustaste wieder losgelassen */
690   {
691     if (ON_GAME_BUTTON(mx,my) && GAME_BUTTON(mx)==choice && pressed)
692     {
693       DrawGameButton(game_state[choice] | BUTTON_RELEASED);
694       return_code = 1<<choice;
695       choice = -1;
696       pressed = FALSE;
697     }
698     else
699     {
700       choice = -1;
701       pressed = FALSE;
702     }
703   }
704
705   BackToFront();
706   return(return_code);
707 }
708
709 int CheckYesNoButtons(int mx, int my, int button)
710 {
711   int return_code = 0;
712   static int choice = -1;
713   static boolean pressed = FALSE;
714   static int yesno_button[5] =
715   {
716     BUTTON_OK,
717     BUTTON_NO
718   };
719
720   if (button)
721   {
722     if (!motion_status)         /* Maustaste neu gedrückt */
723     {
724       if (ON_YESNO_BUTTON(mx,my))
725       {
726         choice = YESNO_BUTTON(mx);
727         pressed = TRUE;
728         DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED, DB_NORMAL);
729       }
730     }
731     else                        /* Mausbewegung bei gedrückter Maustaste */
732     {
733       if ((!ON_YESNO_BUTTON(mx,my) || YESNO_BUTTON(mx)!=choice) &&
734           choice>=0 && pressed)
735       {
736         pressed = FALSE;
737         DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED, DB_NORMAL);
738       }
739       else if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && !pressed)
740       {
741         pressed = TRUE;
742         DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED, DB_NORMAL);
743       }
744     }
745   }
746   else                          /* Maustaste wieder losgelassen */
747   {
748     if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && pressed)
749     {
750       DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED, DB_NORMAL);
751       return_code = choice+1;
752       choice = -1;
753       pressed = FALSE;
754     }
755     else
756     {
757       choice = -1;
758       pressed = FALSE;
759     }
760   }
761
762   BackToFront();
763   return(return_code);
764 }
765
766 int CheckConfirmButton(int mx, int my, int button)
767 {
768   int return_code = 0;
769   static int choice = -1;
770   static boolean pressed = FALSE;
771
772   if (button)
773   {
774     if (!motion_status)         /* Maustaste neu gedrückt */
775     {
776       if (ON_CONFIRM_BUTTON(mx,my))
777       {
778         choice = 0;
779         pressed = TRUE;
780         DrawConfirmButton(BUTTON_PRESSED, DB_NORMAL);
781       }
782     }
783     else                        /* Mausbewegung bei gedrückter Maustaste */
784     {
785       if (!ON_CONFIRM_BUTTON(mx,my) && choice>=0 && pressed)
786       {
787         pressed = FALSE;
788         DrawConfirmButton(BUTTON_RELEASED, DB_NORMAL);
789       }
790       else if (ON_CONFIRM_BUTTON(mx,my) && !pressed)
791       {
792         pressed = TRUE;
793         DrawConfirmButton(BUTTON_PRESSED, DB_NORMAL);
794       }
795     }
796   }
797   else                          /* Maustaste wieder losgelassen */
798   {
799     if (ON_CONFIRM_BUTTON(mx,my) && pressed)
800     {
801       DrawConfirmButton(BUTTON_RELEASED, DB_NORMAL);
802       return_code = BUTTON_CONFIRM;
803       choice = -1;
804       pressed = FALSE;
805     }
806     else
807     {
808       choice = -1;
809       pressed = FALSE;
810     }
811   }
812
813   BackToFront();
814   return(return_code);
815 }
816
817 int CheckPlayerButtons(int mx, int my, int button)
818 {
819   int return_code = 0;
820   static int choice = -1;
821   static boolean pressed = FALSE;
822   int player_state[4] =
823   {
824     BUTTON_PLAYER_1,
825     BUTTON_PLAYER_2,
826     BUTTON_PLAYER_3,
827     BUTTON_PLAYER_4
828   };
829
830   if (button)
831   {
832     if (!motion_status)         /* Maustaste neu gedrückt */
833     {
834       if (ON_PLAYER_BUTTON(mx,my))
835       {
836         choice = PLAYER_BUTTON(mx,my);
837         pressed = TRUE;
838         DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL);
839       }
840     }
841     else                        /* Mausbewegung bei gedrückter Maustaste */
842     {
843       if ((!ON_PLAYER_BUTTON(mx,my) || PLAYER_BUTTON(mx,my)!=choice) &&
844           choice>=0 && pressed)
845       {
846         pressed = FALSE;
847         DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL);
848       }
849       else if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && !pressed)
850       {
851         pressed = TRUE;
852         DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL);
853       }
854     }
855   }
856   else                          /* Maustaste wieder losgelassen */
857   {
858     if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && pressed)
859     {
860       DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL);
861       return_code = player_state[choice];
862       choice = -1;
863       pressed = FALSE;
864     }
865     else
866     {
867       choice = -1;
868       pressed = FALSE;
869     }
870   }
871
872   BackToFront();
873   return(return_code);
874 }
875
876 /* several buttons in the level editor */
877
878 int CheckEditButtons(int mx, int my, int button)
879 {
880   int return_code = 0;
881   static int choice = -1;
882   static boolean pressed = FALSE;
883   static int edit_button[6] =
884   {
885     ED_BUTTON_CTRL,
886     ED_BUTTON_FILL,
887     ED_BUTTON_LEFT,
888     ED_BUTTON_UP,
889     ED_BUTTON_DOWN,
890     ED_BUTTON_RIGHT
891   };
892
893   if (button)
894   {
895     if (!motion_status)         /* Maustaste neu gedrückt */
896     {
897       if (ON_EDIT_BUTTON(mx,my))
898       {
899         choice = EDIT_BUTTON(mx,my);
900         pressed = TRUE;
901         DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
902         if (edit_button[choice]!=ED_BUTTON_CTRL &&
903             edit_button[choice]!=ED_BUTTON_FILL)
904           return_code = 1<<choice;
905       }
906     }
907     else                        /* Mausbewegung bei gedrückter Maustaste */
908     {
909       if ((!ON_EDIT_BUTTON(mx,my) || EDIT_BUTTON(mx,my)!=choice) &&
910           choice>=0 && pressed)
911       {
912         pressed = FALSE;
913         DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
914       }
915       else if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice)
916       {
917         if (!pressed)
918           DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
919         pressed = TRUE;
920         if (edit_button[choice]!=ED_BUTTON_CTRL &&
921             edit_button[choice]!=ED_BUTTON_FILL)
922           return_code = 1<<choice;
923       }
924     }
925   }
926   else                          /* Maustaste wieder losgelassen */
927   {
928     if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice && pressed)
929     {
930       DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
931       if (edit_button[choice]==ED_BUTTON_CTRL ||
932           edit_button[choice]==ED_BUTTON_FILL)
933         return_code = 1<<choice;
934       choice = -1;
935       pressed = FALSE;
936     }
937     else
938     {
939       choice = -1;
940       pressed = FALSE;
941     }
942   }
943
944   BackToFront();
945   return(return_code);
946 }
947
948 int CheckCtrlButtons(int mx, int my, int button)
949 {
950   int return_code = 0;
951   static int choice = -1;
952   static boolean pressed = FALSE;
953   static int ctrl_button[4] =
954   {
955     ED_BUTTON_EDIT,
956     ED_BUTTON_CLEAR,
957     ED_BUTTON_UNDO,
958     ED_BUTTON_EXIT
959   };
960
961   if (button)
962   {
963     if (!motion_status)         /* Maustaste neu gedrückt */
964     {
965       if (ON_CTRL_BUTTON(mx,my))
966       {
967         choice = CTRL_BUTTON(mx,my);
968         pressed = TRUE;
969         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
970       }
971     }
972     else                        /* Mausbewegung bei gedrückter Maustaste */
973     {
974       if ((!ON_CTRL_BUTTON(mx,my) || CTRL_BUTTON(mx,my)!=choice) &&
975           choice>=0 && pressed)
976       {
977         pressed = FALSE;
978         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
979       }
980       else if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && !pressed)
981       {
982         pressed = TRUE;
983         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
984       }
985     }
986   }
987   else                          /* Maustaste wieder losgelassen */
988   {
989     if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && pressed)
990     {
991       DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
992       return_code = 1<<(choice+6);
993       choice = -1;
994       pressed = FALSE;
995     }
996     else
997     {
998       choice = -1;
999       pressed = FALSE;
1000     }
1001   }
1002
1003   BackToFront();
1004   return(return_code);
1005 }
1006
1007 int CheckElemButtons(int mx, int my, int button)
1008 {
1009   int return_code = -1;
1010   static int choice = -1;
1011   static boolean pressed = FALSE;
1012
1013   if (button)
1014   {
1015     if (!motion_status)         /* Maustaste neu gedrückt */
1016     {
1017       if (ON_ELEM_BUTTON(mx,my))
1018       {
1019         choice = ELEM_BUTTON(mx,my);
1020         pressed = TRUE;
1021         DrawElemButton(choice,ED_BUTTON_PRESSED);
1022         if (choice==ED_BUTTON_EUP ||
1023             choice==ED_BUTTON_EDOWN)
1024           return_code = choice;
1025       }
1026     }
1027     else                        /* Mausbewegung bei gedrückter Maustaste */
1028     {
1029       if ((!ON_ELEM_BUTTON(mx,my) || ELEM_BUTTON(mx,my)!=choice) &&
1030           choice>=0 && pressed)
1031       {
1032         pressed = FALSE;
1033         DrawElemButton(choice,ED_BUTTON_RELEASED);
1034       }
1035       else if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice)
1036       {
1037         if (!pressed)
1038           DrawElemButton(choice,ED_BUTTON_PRESSED);
1039         pressed = TRUE;
1040         if (choice==ED_BUTTON_EUP ||
1041             choice==ED_BUTTON_EDOWN)
1042           return_code = choice;
1043       }
1044     }
1045   }
1046   else                          /* Maustaste wieder losgelassen */
1047   {
1048     if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice && pressed)
1049     {
1050       DrawElemButton(choice,ED_BUTTON_RELEASED);
1051       if (choice!=ED_BUTTON_EUP &&
1052           choice!=ED_BUTTON_EDOWN)
1053         return_code = choice;
1054       choice = -1;
1055       pressed = FALSE;
1056     }
1057     else
1058     {
1059       choice = -1;
1060       pressed = FALSE;
1061     }
1062   }
1063
1064   BackToFront();
1065   return(return_code);
1066 }
1067
1068 int CheckCountButtons(int mx, int my, int button)
1069 {
1070   int return_code = -1;
1071   static int choice = -1;
1072   static boolean pressed = FALSE;
1073
1074   if (button)
1075   {
1076     if (!motion_status)         /* Maustaste neu gedrückt */
1077     {
1078       if (ON_COUNT_BUTTON(mx,my))
1079       {
1080         choice = COUNT_BUTTON(mx,my);
1081         pressed = TRUE;
1082         DrawCountButton(choice,ED_BUTTON_PRESSED);
1083         return_code = choice;
1084       }
1085     }
1086     else                        /* Mausbewegung bei gedrückter Maustaste */
1087     {
1088       if ((!ON_COUNT_BUTTON(mx,my) || COUNT_BUTTON(mx,my)!=choice) &&
1089           choice>=0 && pressed)
1090       {
1091         pressed = FALSE;
1092         DrawCountButton(choice,ED_BUTTON_RELEASED);
1093       }
1094       else if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice)
1095       {
1096         if (!pressed)
1097           DrawCountButton(choice,ED_BUTTON_PRESSED);
1098         pressed = TRUE;
1099         return_code = choice;
1100       }
1101     }
1102   }
1103   else                          /* Maustaste wieder losgelassen */
1104   {
1105     if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice && pressed)
1106     {
1107       DrawCountButton(choice,ED_BUTTON_RELEASED);
1108       choice = -1;
1109       pressed = FALSE;
1110     }
1111     else
1112     {
1113       choice = -1;
1114       pressed = FALSE;
1115     }
1116   }
1117
1118   BackToFront();
1119   return(return_code);
1120 }