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