rnd-19981204-2
[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 /* some positions in the video tape control window */
21 #define VIDEO_BUTTON_EJECT_XPOS (VIDEO_CONTROL_XPOS + 0 * VIDEO_BUTTON_XSIZE)
22 #define VIDEO_BUTTON_STOP_XPOS  (VIDEO_CONTROL_XPOS + 1 * VIDEO_BUTTON_XSIZE)
23 #define VIDEO_BUTTON_PAUSE_XPOS (VIDEO_CONTROL_XPOS + 2 * VIDEO_BUTTON_XSIZE)
24 #define VIDEO_BUTTON_REC_XPOS   (VIDEO_CONTROL_XPOS + 3 * VIDEO_BUTTON_XSIZE)
25 #define VIDEO_BUTTON_PLAY_XPOS  (VIDEO_CONTROL_XPOS + 4 * VIDEO_BUTTON_XSIZE)
26 #define VIDEO_BUTTON_ANY_YPOS   (VIDEO_CONTROL_YPOS)
27 #define VIDEO_DATE_LABEL_XPOS   (VIDEO_DISPLAY1_XPOS)
28 #define VIDEO_DATE_LABEL_YPOS   (VIDEO_DISPLAY1_YPOS)
29 #define VIDEO_DATE_LABEL_XSIZE  (VIDEO_DISPLAY_XSIZE)
30 #define VIDEO_DATE_LABEL_YSIZE  (VIDEO_DISPLAY_YSIZE)
31 #define VIDEO_DATE_XPOS         (VIDEO_DISPLAY1_XPOS+1)
32 #define VIDEO_DATE_YPOS         (VIDEO_DISPLAY1_YPOS+14)
33 #define VIDEO_DATE_XSIZE        (VIDEO_DISPLAY_XSIZE)
34 #define VIDEO_DATE_YSIZE        16
35 #define VIDEO_REC_LABEL_XPOS    (VIDEO_DISPLAY2_XPOS)
36 #define VIDEO_REC_LABEL_YPOS    (VIDEO_DISPLAY2_YPOS)
37 #define VIDEO_REC_LABEL_XSIZE   20
38 #define VIDEO_REC_LABEL_YSIZE   12
39 #define VIDEO_REC_SYMBOL_XPOS   (VIDEO_DISPLAY2_XPOS+20)
40 #define VIDEO_REC_SYMBOL_YPOS   (VIDEO_DISPLAY2_YPOS)
41 #define VIDEO_REC_SYMBOL_XSIZE  16
42 #define VIDEO_REC_SYMBOL_YSIZE  16
43 #define VIDEO_PLAY_LABEL_XPOS   (VIDEO_DISPLAY2_XPOS+65)
44 #define VIDEO_PLAY_LABEL_YPOS   (VIDEO_DISPLAY2_YPOS)
45 #define VIDEO_PLAY_LABEL_XSIZE  22
46 #define VIDEO_PLAY_LABEL_YSIZE  12
47 #define VIDEO_PLAY_SYMBOL_XPOS  (VIDEO_DISPLAY2_XPOS+52)
48 #define VIDEO_PLAY_SYMBOL_YPOS  (VIDEO_DISPLAY2_YPOS)
49 #define VIDEO_PLAY_SYMBOL_XSIZE 11
50 #define VIDEO_PLAY_SYMBOL_YSIZE 13
51 #define VIDEO_PAUSE_LABEL_XPOS  (VIDEO_DISPLAY2_XPOS)
52 #define VIDEO_PAUSE_LABEL_YPOS  (VIDEO_DISPLAY2_YPOS+20)
53 #define VIDEO_PAUSE_LABEL_XSIZE 35
54 #define VIDEO_PAUSE_LABEL_YSIZE 8
55 #define VIDEO_PAUSE_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS+35)
56 #define VIDEO_PAUSE_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
57 #define VIDEO_PAUSE_SYMBOL_XSIZE 17
58 #define VIDEO_PAUSE_SYMBOL_YSIZE 13
59 #define VIDEO_TIME_XPOS         (VIDEO_DISPLAY2_XPOS+38)
60 #define VIDEO_TIME_YPOS         (VIDEO_DISPLAY2_YPOS+14)
61 #define VIDEO_TIME_XSIZE        50
62 #define VIDEO_TIME_YSIZE        16
63
64 /* special */
65 #define VIDEO_PBEND_LABEL_XPOS  6
66 #define VIDEO_PBEND_LABEL_YPOS  220
67 #define VIDEO_PBEND_LABEL_XSIZE 35
68 #define VIDEO_PBEND_LABEL_YSIZE 30
69
70 #define ON_VIDEO_BUTTON(x,y)    ((x)>=(VX+VIDEO_CONTROL_XPOS) &&        \
71                                  (x)< (VX+VIDEO_CONTROL_XPOS +          \
72                                        VIDEO_CONTROL_XSIZE) &&          \
73                                  (y)>=(VY+VIDEO_CONTROL_YPOS) &&        \
74                                  (y)< (VY+VIDEO_CONTROL_YPOS +          \
75                                        VIDEO_CONTROL_YSIZE))
76 #define VIDEO_BUTTON(x)         (((x)-(VX+VIDEO_CONTROL_XPOS))/VIDEO_BUTTON_XSIZE)
77
78 #define VIDEO_STATE_OFF         (VIDEO_STATE_PLAY_OFF   |       \
79                                  VIDEO_STATE_REC_OFF    |       \
80                                  VIDEO_STATE_PAUSE_OFF  |       \
81                                  VIDEO_STATE_FFWD_OFF   |       \
82                                  VIDEO_STATE_PBEND_OFF  |       \
83                                  VIDEO_STATE_DATE_OFF   |       \
84                                  VIDEO_STATE_TIME_OFF)
85 #define VIDEO_PRESS_OFF         (VIDEO_PRESS_PLAY_OFF   |       \
86                                  VIDEO_PRESS_REC_OFF    |       \
87                                  VIDEO_PRESS_PAUSE_OFF  |       \
88                                  VIDEO_PRESS_STOP_OFF   |       \
89                                  VIDEO_PRESS_EJECT_OFF)
90 #define VIDEO_ALL_OFF           (VIDEO_STATE_OFF | VIDEO_PRESS_OFF)
91
92 #define VIDEO_STATE_ON          (VIDEO_STATE_PLAY_ON    |       \
93                                  VIDEO_STATE_REC_ON     |       \
94                                  VIDEO_STATE_PAUSE_ON   |       \
95                                  VIDEO_STATE_FFWD_ON    |       \
96                                  VIDEO_STATE_PBEND_ON   |       \
97                                  VIDEO_STATE_DATE_ON    |       \
98                                  VIDEO_STATE_TIME_ON)
99 #define VIDEO_PRESS_ON          (VIDEO_PRESS_PLAY_ON    |       \
100                                  VIDEO_PRESS_REC_ON     |       \
101                                  VIDEO_PRESS_PAUSE_ON   |       \
102                                  VIDEO_PRESS_STOP_ON    |       \
103                                  VIDEO_PRESS_EJECT_ON)
104 #define VIDEO_ALL_ON            (VIDEO_STATE_ON | VIDEO_PRESS_ON)
105
106 #define VIDEO_STATE             (VIDEO_STATE_ON | VIDEO_STATE_OFF)
107 #define VIDEO_PRESS             (VIDEO_PRESS_ON | VIDEO_PRESS_OFF)
108 #define VIDEO_ALL               (VIDEO_ALL_ON | VIDEO_ALL_OFF)
109
110
111 /* some positions in the sound control window */
112 #define SOUND_BUTTON_XSIZE      30
113 #define SOUND_BUTTON_YSIZE      30
114 #define SOUND_CONTROL_XPOS      5
115 #define SOUND_CONTROL_YPOS      245
116 #define SOUND_CONTROL_XSIZE      (3*SOUND_BUTTON_XSIZE)
117 #define SOUND_CONTROL_YSIZE      (1*SOUND_BUTTON_YSIZE)
118 #define SOUND_BUTTON_MUSIC_XPOS  (SOUND_CONTROL_XPOS + 0 * SOUND_BUTTON_XSIZE)
119 #define SOUND_BUTTON_LOOPS_XPOS  (SOUND_CONTROL_XPOS + 1 * SOUND_BUTTON_XSIZE)
120 #define SOUND_BUTTON_SIMPLE_XPOS (SOUND_CONTROL_XPOS + 2 * SOUND_BUTTON_XSIZE)
121 #define SOUND_BUTTON_ANY_YPOS    (SOUND_CONTROL_YPOS)
122
123 #define ON_SOUND_BUTTON(x,y)    ((x)>=(DX+SOUND_CONTROL_XPOS) &&        \
124                                  (x)< (DX+SOUND_CONTROL_XPOS +          \
125                                        SOUND_CONTROL_XSIZE) &&          \
126                                  (y)>=(DY+SOUND_CONTROL_YPOS) &&        \
127                                  (y)< (DY+SOUND_CONTROL_YPOS +          \
128                                        SOUND_CONTROL_YSIZE))
129 #define SOUND_BUTTON(x)         (((x)-(DX+SOUND_CONTROL_XPOS))/SOUND_BUTTON_XSIZE)
130
131 /* some positions in the game control window */
132 #define GAME_BUTTON_STOP_XPOS   (GAME_CONTROL_XPOS + 0 * GAME_BUTTON_XSIZE)
133 #define GAME_BUTTON_PAUSE_XPOS  (GAME_CONTROL_XPOS + 1 * GAME_BUTTON_XSIZE)
134 #define GAME_BUTTON_PLAY_XPOS   (GAME_CONTROL_XPOS + 2 * GAME_BUTTON_XSIZE)
135 #define GAME_BUTTON_ANY_YPOS    (GAME_CONTROL_YPOS)
136
137 #define ON_GAME_BUTTON(x,y)     ((x)>=(DX+GAME_CONTROL_XPOS) && \
138                                  (x)< (DX+GAME_CONTROL_XPOS +           \
139                                        GAME_CONTROL_XSIZE) &&           \
140                                  (y)>=(DY+GAME_CONTROL_YPOS) && \
141                                  (y)< (DY+GAME_CONTROL_YPOS +           \
142                                        GAME_CONTROL_YSIZE))
143 #define GAME_BUTTON(x)          (((x)-(DX+GAME_CONTROL_XPOS))/GAME_BUTTON_XSIZE)
144
145 /* some positions in the asking window */
146 #define OK_BUTTON_XPOS          2
147 #define OK_BUTTON_YPOS          250
148 #define OK_BUTTON_GFX_YPOS      0
149 #define OK_BUTTON_XSIZE         46
150 #define OK_BUTTON_YSIZE         28
151 #define NO_BUTTON_XPOS          52
152 #define NO_BUTTON_YPOS          OK_BUTTON_YPOS
153 #define NO_BUTTON_XSIZE         OK_BUTTON_XSIZE
154 #define NO_BUTTON_YSIZE         OK_BUTTON_YSIZE
155 #define CONFIRM_BUTTON_XPOS     2
156 #define CONFIRM_BUTTON_GFX_YPOS 30
157 #define CONFIRM_BUTTON_YPOS     OK_BUTTON_YPOS
158 #define CONFIRM_BUTTON_XSIZE    96
159 #define CONFIRM_BUTTON_YSIZE    OK_BUTTON_YSIZE
160
161 #define ON_YESNO_BUTTON(x,y)    (((x)>=(DX+OK_BUTTON_XPOS) &&           \
162                                   (x)< (DX+OK_BUTTON_XPOS +             \
163                                         OK_BUTTON_XSIZE) &&             \
164                                   (y)>=(DY+OK_BUTTON_YPOS) &&           \
165                                   (y)< (DY+OK_BUTTON_YPOS +             \
166                                         OK_BUTTON_YSIZE)) ||            \
167                                  ((x)>=(DX+NO_BUTTON_XPOS) &&           \
168                                   (x)< (DX+NO_BUTTON_XPOS +             \
169                                         NO_BUTTON_XSIZE) &&             \
170                                   (y)>=(DY+NO_BUTTON_YPOS) &&           \
171                                   (y)< (DY+NO_BUTTON_YPOS +             \
172                                         NO_BUTTON_YSIZE)))
173 #define ON_CONFIRM_BUTTON(x,y)  (((x)>=(DX+CONFIRM_BUTTON_XPOS) &&      \
174                                   (x)< (DX+CONFIRM_BUTTON_XPOS +        \
175                                         CONFIRM_BUTTON_XSIZE) &&        \
176                                   (y)>=(DY+CONFIRM_BUTTON_YPOS) &&      \
177                                   (y)< (DY+CONFIRM_BUTTON_YPOS +        \
178                                         CONFIRM_BUTTON_YSIZE)))
179 #define YESNO_BUTTON(x)         (((x)-(DX+OK_BUTTON_XPOS))/OK_BUTTON_XSIZE)
180
181 /* some positions in the choose player window */
182 #define PLAYER_BUTTON_XSIZE     30
183 #define PLAYER_BUTTON_YSIZE     30
184 #define PLAYER_BUTTON_GFX_XPOS  5
185 #define PLAYER_BUTTON_GFX_YPOS  (215-30)
186 #define PLAYER_CONTROL_XPOS     (5 + PLAYER_BUTTON_XSIZE/2)
187 #define PLAYER_CONTROL_YPOS     (215 - PLAYER_BUTTON_YSIZE/2)
188 #define PLAYER_CONTROL_XSIZE    (2*PLAYER_BUTTON_XSIZE)
189 #define PLAYER_CONTROL_YSIZE    (2*PLAYER_BUTTON_YSIZE)
190 #define PLAYER_BUTTON_1_XPOS    (PLAYER_CONTROL_XPOS + 0 * PLAYER_BUTTON_XSIZE)
191 #define PLAYER_BUTTON_2_XPOS    (PLAYER_CONTROL_XPOS + 1 * PLAYER_BUTTON_XSIZE)
192 #define PLAYER_BUTTON_3_XPOS    (PLAYER_CONTROL_XPOS + 0 * PLAYER_BUTTON_XSIZE)
193 #define PLAYER_BUTTON_4_XPOS    (PLAYER_CONTROL_XPOS + 1 * PLAYER_BUTTON_XSIZE)
194 #define PLAYER_BUTTON_1_YPOS    (PLAYER_CONTROL_YPOS + 0 * PLAYER_BUTTON_YSIZE)
195 #define PLAYER_BUTTON_2_YPOS    (PLAYER_CONTROL_YPOS + 0 * PLAYER_BUTTON_YSIZE)
196 #define PLAYER_BUTTON_3_YPOS    (PLAYER_CONTROL_YPOS + 1 * PLAYER_BUTTON_YSIZE)
197 #define PLAYER_BUTTON_4_YPOS    (PLAYER_CONTROL_YPOS + 1 * PLAYER_BUTTON_YSIZE)
198
199 #define ON_PLAYER_BUTTON(x,y)   ((x)>=(DX+PLAYER_CONTROL_XPOS) &&       \
200                                  (x)< (DX+PLAYER_CONTROL_XPOS +         \
201                                        PLAYER_CONTROL_XSIZE) &&         \
202                                  (y)>=(DY+PLAYER_CONTROL_YPOS) &&       \
203                                  (y)< (DY+PLAYER_CONTROL_YPOS +         \
204                                        PLAYER_CONTROL_YSIZE))
205 #define PLAYER_BUTTON(x,y)      ((((x)-(DX+PLAYER_CONTROL_XPOS)) /      \
206                                   PLAYER_BUTTON_XSIZE) + 2 *            \
207                                  (((y)-(DY+PLAYER_CONTROL_YPOS)) /      \
208                                   PLAYER_BUTTON_YSIZE))
209
210
211 /* some definitions for the editor control window */
212
213 #define ON_EDIT_BUTTON(x,y)     (((x)>=(VX+ED_BUTTON_CTRL_XPOS) &&      \
214                                   (x)< (VX+ED_BUTTON_CTRL_XPOS +        \
215                                         ED_BUTTON_CTRL_XSIZE) &&        \
216                                   (y)>=(VY+ED_BUTTON_CTRL_YPOS) &&      \
217                                   (y)< (VY+ED_BUTTON_CTRL_YPOS +        \
218                                         ED_BUTTON_CTRL_YSIZE +          \
219                                         ED_BUTTON_FILL_YSIZE)) ||       \
220                                  ((x)>=(VX+ED_BUTTON_LEFT_XPOS) &&      \
221                                   (x)< (VX+ED_BUTTON_LEFT_XPOS +        \
222                                         ED_BUTTON_LEFT_XSIZE +          \
223                                         ED_BUTTON_UP_XSIZE +            \
224                                         ED_BUTTON_RIGHT_XSIZE) &&       \
225                                   (y)>=(VY+ED_BUTTON_LEFT_YPOS) &&      \
226                                   (y)< (VY+ED_BUTTON_LEFT_YPOS +        \
227                                         ED_BUTTON_LEFT_YSIZE)) ||       \
228                                  ((x)>=(VX+ED_BUTTON_UP_XPOS) &&        \
229                                   (x)< (VX+ED_BUTTON_UP_XPOS +          \
230                                         ED_BUTTON_UP_XSIZE) &&          \
231                                   (y)>=(VY+ED_BUTTON_UP_YPOS) &&        \
232                                   (y)< (VY+ED_BUTTON_UP_YPOS +          \
233                                         ED_BUTTON_UP_YSIZE +            \
234                                         ED_BUTTON_DOWN_YSIZE)))
235
236 #define ON_CTRL_BUTTON(x,y)     ((x)>=(VX+ED_BUTTON_EDIT_XPOS) &&       \
237                                  (x)< (VX+ED_BUTTON_EDIT_XPOS +         \
238                                        ED_BUTTON_EDIT_XSIZE) &&         \
239                                  (y)>=(VY+ED_BUTTON_EDIT_YPOS) &&       \
240                                  (y)< (VY+ED_BUTTON_EDIT_YPOS +         \
241                                        ED_BUTTON_EDIT_YSIZE +           \
242                                        ED_BUTTON_CLEAR_YSIZE +          \
243                                        ED_BUTTON_UNDO_YSIZE +           \
244                                        ED_BUTTON_EXIT_YSIZE))
245
246 #define ON_ELEM_BUTTON(x,y)     (((x)>=(DX+ED_BUTTON_EUP_XPOS) &&       \
247                                   (x)< (DX+ED_BUTTON_EUP_XPOS +         \
248                                         ED_BUTTON_EUP_XSIZE) &&         \
249                                   (y)>=(DY+ED_BUTTON_EUP_YPOS) &&       \
250                                   (y)< (DY+ED_BUTTON_EUP_YPOS +         \
251                                         ED_BUTTON_EUP_YSIZE)) ||        \
252                                  ((x)>=(DX+ED_BUTTON_EDOWN_XPOS) &&     \
253                                   (x)< (DX+ED_BUTTON_EDOWN_XPOS +       \
254                                         ED_BUTTON_EDOWN_XSIZE) &&       \
255                                   (y)>=(DY+ED_BUTTON_EDOWN_YPOS) &&     \
256                                   (y)< (DY+ED_BUTTON_EDOWN_YPOS +       \
257                                         ED_BUTTON_EDOWN_YSIZE)) ||      \
258                                  ((x)>=(DX+ED_BUTTON_ELEM_XPOS) &&      \
259                                   (x)< (DX+ED_BUTTON_ELEM_XPOS +        \
260                                         MAX_ELEM_X*ED_BUTTON_ELEM_XSIZE) && \
261                                   (y)>=(DY+ED_BUTTON_ELEM_YPOS) &&      \
262                                   (y)< (DY+ED_BUTTON_ELEM_YPOS +        \
263                                         MAX_ELEM_Y*ED_BUTTON_ELEM_YSIZE)))
264
265 #define ON_COUNT_BUTTON(x,y)    (((((x)>=ED_COUNT_GADGET_XPOS &&        \
266                                     (x)<(ED_COUNT_GADGET_XPOS +         \
267                                          ED_BUTTON_MINUS_XSIZE)) ||     \
268                                    ((x)>=(ED_COUNT_GADGET_XPOS +        \
269                                           (ED_BUTTON_PLUS_XPOS -        \
270                                            ED_BUTTON_MINUS_XPOS)) &&    \
271                                     (x)<(ED_COUNT_GADGET_XPOS +         \
272                                          (ED_BUTTON_PLUS_XPOS -         \
273                                           ED_BUTTON_MINUS_XPOS) +       \
274                                          ED_BUTTON_PLUS_XSIZE))) &&     \
275                                   ((y)>=ED_COUNT_GADGET_YPOS &&         \
276                                    (y)<(ED_COUNT_GADGET_YPOS +          \
277                                         16*ED_COUNT_GADGET_YSIZE)) &&   \
278                                   (((y)-ED_COUNT_GADGET_YPOS) %         \
279                                    ED_COUNT_GADGET_YSIZE) <             \
280                                   ED_BUTTON_MINUS_YSIZE) ||             \
281                                  ((((x)>=ED_SIZE_GADGET_XPOS &&         \
282                                     (x)<(ED_SIZE_GADGET_XPOS +          \
283                                          ED_BUTTON_MINUS_XSIZE)) ||     \
284                                    ((x)>=(ED_SIZE_GADGET_XPOS +         \
285                                           (ED_BUTTON_PLUS_XPOS -        \
286                                            ED_BUTTON_MINUS_XPOS)) &&    \
287                                     (x)<(ED_SIZE_GADGET_XPOS +          \
288                                          (ED_BUTTON_PLUS_XPOS -         \
289                                           ED_BUTTON_MINUS_XPOS) +       \
290                                          ED_BUTTON_PLUS_XSIZE))) &&     \
291                                   ((y)>=ED_SIZE_GADGET_YPOS &&          \
292                                    (y)<(ED_SIZE_GADGET_YPOS +           \
293                                         2*ED_SIZE_GADGET_YSIZE)) &&     \
294                                   (((y)-ED_SIZE_GADGET_YPOS) %          \
295                                    ED_SIZE_GADGET_YSIZE) <              \
296                                   ED_BUTTON_MINUS_YSIZE))
297
298 #define EDIT_BUTTON(x,y)        (((y) < (VY + ED_BUTTON_CTRL_YPOS +     \
299                                          ED_BUTTON_CTRL_YSIZE)) ? 0 :   \
300                                  ((y) < (VY + ED_BUTTON_CTRL_YPOS +     \
301                                          ED_BUTTON_CTRL_YSIZE +         \
302                                          ED_BUTTON_FILL_YSIZE)) ? 1 :   \
303                                  ((x) < (VX + ED_BUTTON_LEFT_XPOS +     \
304                                          ED_BUTTON_LEFT_XSIZE) ? 2 :    \
305                                   (x) > (VX + ED_BUTTON_LEFT_XPOS +     \
306                                          ED_BUTTON_LEFT_XSIZE +         \
307                                          ED_BUTTON_UP_XSIZE) ? 5 :      \
308                                   3+(((y)-(VY + ED_BUTTON_CTRL_YPOS +   \
309                                            ED_BUTTON_CTRL_YSIZE +       \
310                                            ED_BUTTON_FILL_YSIZE)) /     \
311                                      ED_BUTTON_UP_YSIZE)))
312
313 #define CTRL_BUTTON(x,y)        (((y) < (VY + ED_BUTTON_EDIT_YPOS +     \
314                                          ED_BUTTON_EDIT_YSIZE)) ? 0 :   \
315                                  1+(((y)-(VY + ED_BUTTON_EDIT_YPOS +    \
316                                          ED_BUTTON_EDIT_YSIZE)) /       \
317                                     ED_BUTTON_CLEAR_YSIZE))
318
319 #define ELEM_BUTTON(x,y)        (((y) < (DY + ED_BUTTON_EUP_YPOS +      \
320                                          ED_BUTTON_EUP_YSIZE)) ? 0 :    \
321                                  ((y) > (DY + ED_BUTTON_EDOWN_YPOS)) ? 1 : \
322                                  2+(((y) - (DY + ED_BUTTON_ELEM_YPOS)) /   \
323                                  ED_BUTTON_ELEM_YSIZE)*MAX_ELEM_X +     \
324                                  ((x) - (DX + ED_BUTTON_ELEM_XPOS)) /   \
325                                  ED_BUTTON_ELEM_XSIZE)
326
327 #define COUNT_BUTTON(x,y)       ((x) < ED_SIZE_GADGET_XPOS ?            \
328                                  ((((y) - ED_COUNT_GADGET_YPOS) /       \
329                                    ED_COUNT_GADGET_YSIZE)*2 +           \
330                                   ((x) < (ED_COUNT_GADGET_XPOS +        \
331                                           ED_BUTTON_MINUS_XSIZE) ? 0 : 1)) : \
332                                  32+((((y) - ED_SIZE_GADGET_YPOS) /     \
333                                       ED_SIZE_GADGET_YSIZE)*2 +         \
334                                      ((x) < (ED_SIZE_GADGET_XPOS +      \
335                                              ED_BUTTON_MINUS_XSIZE) ? 0 : 1)))
336
337 /****************************************************************/
338 /********** drawing buttons and corresponding displays **********/
339 /****************************************************************/
340
341 void DrawVideoDisplay(unsigned long state, unsigned long value)
342 {
343   int i;
344   int part_label = 0, part_symbol = 1;
345   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
346   static char *monatsname[12] =
347   {
348     "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
349     "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
350   };
351   static int video_pos[10][2][4] =
352   {
353     {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
354        VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE },
355      { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
356        VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }},
357
358     {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
359        VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE },
360      { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
361        VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }},
362
363     {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
364        VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE },
365      { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
366        VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }},
367
368     {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
369        VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE },
370      { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
371        VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }},
372
373     {{ 0,0,
374        0,0 },
375      { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
376        VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }},
377
378     {{ VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS,
379        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
380      { 0,0,
381        0,0 }},
382
383     {{ VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS,
384        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
385      { 0,0,
386        0,0 }},
387
388     {{ VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS,
389        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
390      { 0,0,
391        0,0 }},
392
393     {{ VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS,
394        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
395      { 0,0,
396        0,0 }},
397
398     {{ VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS,
399        VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
400      { 0,0,
401        0,0 }}
402   };
403
404   if (state & VIDEO_STATE_PBEND_OFF)
405   {
406     int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2;
407
408     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
409               cx + VIDEO_REC_LABEL_XPOS,
410               cy + VIDEO_REC_LABEL_YPOS,
411               VIDEO_PBEND_LABEL_XSIZE,
412               VIDEO_PBEND_LABEL_YSIZE,
413               VX + VIDEO_REC_LABEL_XPOS,
414               VY + VIDEO_REC_LABEL_YPOS);
415   }
416
417   for(i=0;i<20;i++)
418   {
419     if (state & (1<<i))
420     {
421       int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
422
423       if (i%2)                  /* i ungerade => STATE_ON / PRESS_OFF */
424         cx = DOOR_GFX_PAGEX4;
425       else
426         cx = DOOR_GFX_PAGEX3;   /* i gerade => STATE_OFF / PRESS_ON */
427
428       if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
429         XCopyArea(display,pix[PIX_DOOR],drawto,gc,
430                   cx + video_pos[pos][part_label][xpos],
431                   cy + video_pos[pos][part_label][ypos],
432                   video_pos[pos][part_label][xsize],
433                   video_pos[pos][part_label][ysize],
434                   VX + video_pos[pos][part_label][xpos],
435                   VY + video_pos[pos][part_label][ypos]);
436       if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
437         XCopyArea(display,pix[PIX_DOOR],drawto,gc,
438                   cx + video_pos[pos][part_symbol][xpos],
439                   cy + video_pos[pos][part_symbol][ypos],
440                   video_pos[pos][part_symbol][xsize],
441                   video_pos[pos][part_symbol][ysize],
442                   VX + video_pos[pos][part_symbol][xpos],
443                   VY + video_pos[pos][part_symbol][ypos]);
444     }
445   }
446
447   if (state & VIDEO_STATE_FFWD_ON)
448   {
449     int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
450
451     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
452               cx + VIDEO_PLAY_SYMBOL_XPOS,
453               cy + VIDEO_PLAY_SYMBOL_YPOS,
454               VIDEO_PLAY_SYMBOL_XSIZE - 2,
455               VIDEO_PLAY_SYMBOL_YSIZE,
456               VX + VIDEO_PLAY_SYMBOL_XPOS - 9,
457               VY + VIDEO_PLAY_SYMBOL_YPOS);
458   }
459
460   if (state & VIDEO_STATE_PBEND_ON)
461   {
462     int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
463
464     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
465               cx + VIDEO_PBEND_LABEL_XPOS,
466               cy + VIDEO_PBEND_LABEL_YPOS,
467               VIDEO_PBEND_LABEL_XSIZE,
468               VIDEO_PBEND_LABEL_YSIZE,
469               VX + VIDEO_REC_LABEL_XPOS,
470               VY + VIDEO_REC_LABEL_YPOS);
471   }
472
473   if (state & VIDEO_STATE_DATE_ON)
474   {
475     int tag = value % 100;
476     int monat = (value/100) % 100;
477     int jahr = (value/10000);
478
479     DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
480              int2str(tag,2),FS_SMALL,FC_SPECIAL1);
481     DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
482              monatsname[monat],FS_SMALL,FC_SPECIAL1);
483     DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
484              int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
485   }
486
487   if (state & VIDEO_STATE_TIME_ON)
488   {
489     int min = value / 60;
490     int sec = value % 60;
491
492     DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
493              int2str(min,2),FS_SMALL,FC_SPECIAL1);
494     DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
495              int2str(sec,2),FS_SMALL,FC_SPECIAL1);
496   }
497
498   if (state & VIDEO_STATE_DATE)
499     redraw_mask |= REDRAW_VIDEO_1;
500   if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
501     redraw_mask |= REDRAW_VIDEO_2;
502   if (state & VIDEO_PRESS)
503     redraw_mask |= REDRAW_VIDEO_3;
504 }
505
506 void DrawCompleteVideoDisplay()
507 {
508   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
509             DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY);
510   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
511             DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS,
512             DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS,
513             VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
514             VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
515
516   DrawVideoDisplay(VIDEO_ALL_OFF,0);
517   if (tape.date && tape.length)
518   {
519     DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
520     DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds);
521   }
522
523   XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
524             VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
525 }
526
527 void DrawSoundDisplay(unsigned long state)
528 {
529   int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
530
531   pos = (state & BUTTON_SOUND_MUSIC ? SOUND_BUTTON_MUSIC_XPOS :
532          state & BUTTON_SOUND_LOOPS ? SOUND_BUTTON_LOOPS_XPOS :
533          SOUND_BUTTON_SIMPLE_XPOS);
534
535   if (state & BUTTON_ON)
536     cy -= SOUND_BUTTON_YSIZE;
537
538   if (state & BUTTON_PRESSED)
539     cx = DOOR_GFX_PAGEX3;
540
541   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
542             cx + pos,cy + SOUND_BUTTON_ANY_YPOS,
543             SOUND_BUTTON_XSIZE,SOUND_BUTTON_YSIZE,
544             DX + pos,DY + SOUND_BUTTON_ANY_YPOS);
545
546   redraw_mask |= REDRAW_DOOR_1;
547 }
548
549 void DrawGameButton(unsigned long state)
550 {
551   int pos, cx = DOOR_GFX_PAGEX4, cy = -GAME_BUTTON_YSIZE;
552
553   pos = (state & BUTTON_GAME_STOP ? GAME_BUTTON_STOP_XPOS :
554          state & BUTTON_GAME_PAUSE ? GAME_BUTTON_PAUSE_XPOS :
555          GAME_BUTTON_PLAY_XPOS);
556
557   if (state & BUTTON_PRESSED)
558     cx = DOOR_GFX_PAGEX3;
559
560   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
561             cx + pos,cy + GAME_BUTTON_ANY_YPOS,
562             GAME_BUTTON_XSIZE,GAME_BUTTON_YSIZE,
563             DX + pos,DY + GAME_BUTTON_ANY_YPOS);
564
565   redraw_mask |= REDRAW_DOOR_1;
566 }
567
568 void DrawYesNoButton(unsigned long state, int mode)
569 {
570   Drawable dest_drawto;
571   int dest_xoffset, dest_yoffset;
572   int xpos, cx = DOOR_GFX_PAGEX4;
573
574   if (mode == DB_INIT)
575   {
576     dest_drawto = pix[PIX_DB_DOOR];
577     dest_xoffset = DOOR_GFX_PAGEX1;
578     dest_yoffset = 0;
579   }
580   else
581   {
582     dest_drawto = drawto;
583     dest_xoffset = DX;
584     dest_yoffset = DY;
585   }
586
587   xpos = (state & BUTTON_OK ? OK_BUTTON_XPOS : NO_BUTTON_XPOS);
588
589   if (state & BUTTON_PRESSED)
590     cx = DOOR_GFX_PAGEX3;
591
592   XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
593             cx + xpos, OK_BUTTON_GFX_YPOS,
594             OK_BUTTON_XSIZE, OK_BUTTON_YSIZE,
595             dest_xoffset + xpos, dest_yoffset + OK_BUTTON_YPOS);
596
597   redraw_mask |= REDRAW_DOOR_1;
598 }
599
600 void DrawConfirmButton(unsigned long state, int mode)
601 {
602   Drawable dest_drawto;
603   int dest_xoffset, dest_yoffset;
604   int cx = DOOR_GFX_PAGEX4;
605
606   if (mode == DB_INIT)
607   {
608     dest_drawto = pix[PIX_DB_DOOR];
609     dest_xoffset = DOOR_GFX_PAGEX1;
610     dest_yoffset = 0;
611   }
612   else
613   {
614     dest_drawto = drawto;
615     dest_xoffset = DX;
616     dest_yoffset = DY;
617   }
618
619   if (state & BUTTON_PRESSED)
620     cx = DOOR_GFX_PAGEX3;
621
622   XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
623             cx + CONFIRM_BUTTON_XPOS, CONFIRM_BUTTON_GFX_YPOS,
624             CONFIRM_BUTTON_XSIZE, CONFIRM_BUTTON_YSIZE,
625             dest_xoffset + CONFIRM_BUTTON_XPOS,
626             dest_yoffset + CONFIRM_BUTTON_YPOS);
627
628   redraw_mask |= REDRAW_DOOR_1;
629 }
630
631 void DrawPlayerButton(unsigned long state, int mode)
632 {
633   Drawable dest_drawto;
634   int dest_xoffset, dest_yoffset;
635   int graphic = GFX_SPIELER1;   /* default */
636   int graphic_offset = (PLAYER_BUTTON_XSIZE - TILEX/2)/2;
637   int xpos, ypos;
638   int cx = DOOR_GFX_PAGEX4, cy = 0;
639
640   if (mode == DB_INIT)
641   {
642     dest_drawto = pix[PIX_DB_DOOR];
643     dest_xoffset = DOOR_GFX_PAGEX1;
644     dest_yoffset = 0;
645   }
646   else
647   {
648     dest_drawto = drawto;
649     dest_xoffset = DX;
650     dest_yoffset = DY;
651   }
652
653   if (state & BUTTON_PLAYER_1)
654     graphic = GFX_SPIELER1;
655   else if (state & BUTTON_PLAYER_2)
656     graphic = GFX_SPIELER2;
657   else if (state & BUTTON_PLAYER_3)
658     graphic = GFX_SPIELER3;
659   else if (state & BUTTON_PLAYER_4)
660     graphic = GFX_SPIELER4;
661
662   xpos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_3 ?
663           PLAYER_BUTTON_1_XPOS : PLAYER_BUTTON_2_XPOS);
664   ypos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_2 ?
665           PLAYER_BUTTON_1_YPOS : PLAYER_BUTTON_3_YPOS);
666
667   if (state & BUTTON_PRESSED)
668   {
669     cx = DOOR_GFX_PAGEX3;
670     graphic_offset += 1;
671   }
672
673   XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
674             cx + PLAYER_BUTTON_GFX_XPOS, cy + PLAYER_BUTTON_GFX_YPOS,
675             PLAYER_BUTTON_XSIZE, PLAYER_BUTTON_YSIZE,
676             dest_xoffset + xpos, dest_yoffset + ypos);
677   DrawMiniGraphicExt(dest_drawto,gc,
678                      dest_xoffset + xpos + graphic_offset,
679                      dest_yoffset + ypos + graphic_offset,
680                      graphic);
681
682   redraw_mask |= REDRAW_DOOR_1;
683 }
684
685 /* several buttons in the level editor */
686
687 void DrawEditButton(unsigned long state)
688 {
689   int i;
690   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
691   int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY2;
692   static int edit_pos[6][4] =
693   {
694    {ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS,
695     ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE},
696
697    {ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS,
698     ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE},
699
700    {ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS,
701     ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE},
702
703    {ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS,
704     ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE},
705
706    {ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS,
707     ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE},
708
709    {ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS,
710     ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE}
711   };
712
713   if (state & ED_BUTTON_PRESSED)
714     cx = DOOR_GFX_PAGEX5;
715
716   for(i=0;i<6;i++)
717   {
718     if (state & (1<<i))
719       XCopyArea(display,pix[PIX_DOOR],drawto,gc,
720                 cx + edit_pos[i][xpos],
721                 cy + edit_pos[i][ypos],
722                 edit_pos[i][xsize],
723                 edit_pos[i][ysize],
724                 VX + edit_pos[i][xpos],
725                 VY + edit_pos[i][ypos]);
726   }
727
728   redraw_mask |= REDRAW_DOOR_2;
729 }
730
731 void DrawCtrlButton(unsigned long state)
732 {
733   int i;
734   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
735   int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY1+80;
736   static int edit_pos[4][4] =
737   {
738    {ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS,
739     ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE},
740
741    {ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS,
742     ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE},
743
744    {ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS,
745     ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE},
746
747    {ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS,
748     ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE}
749   };
750
751   if (state & ED_BUTTON_PRESSED)
752     cx = DOOR_GFX_PAGEX3;
753
754   for(i=0;i<4;i++)
755   {
756     if (state & (1<<(i+6)))
757       XCopyArea(display,pix[PIX_DOOR],drawto,gc,
758                 cx + edit_pos[i][xpos],
759                 cy + edit_pos[i][ypos],
760                 edit_pos[i][xsize],
761                 edit_pos[i][ysize],
762                 VX + edit_pos[i][xpos],
763                 VY + edit_pos[i][ypos]);
764   }
765
766   redraw_mask |= REDRAW_DOOR_2;
767 }
768
769 void DrawElemButton(int button_nr, int button_state)
770 {
771   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
772   int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
773   int from_x, from_y, to_x,to_y, size_x, size_y;
774   static int edit_pos[3][4] =
775   {
776    {ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS,
777     ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE},
778
779    {ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS,
780     ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE},
781
782    {ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS,
783     ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE}
784   };
785
786   if (button_nr<ED_BUTTON_ELEM)
787   {
788     int pos = button_nr;
789
790     from_x = cx + edit_pos[pos][xpos];
791     from_y = cy + edit_pos[pos][ypos];
792     size_x = edit_pos[pos][xsize];
793     size_y = edit_pos[pos][ysize];
794     to_x   = DX + edit_pos[pos][xpos];
795     to_y   = DY + edit_pos[pos][ypos];
796
797     if (button_state & ED_BUTTON_PRESSED)
798     {
799       if (button_nr==ED_BUTTON_EUP)
800         from_y = cy + ED_BUTTON_EUP_Y2POS;
801       else
802         from_y = cy + ED_BUTTON_EDOWN_Y2POS;
803     }
804
805     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
806               from_x,from_y, size_x,size_y, to_x,to_y);
807   }
808   else
809   {
810     int pos = ED_BUTTON_ELEM;
811     int elem_pos = button_nr-ED_BUTTON_ELEM;
812     int x = elem_pos % MAX_ELEM_X;
813     int y = elem_pos / MAX_ELEM_X;
814     int graphic;
815     int shift = 0;
816
817     if (elem_pos+element_shift < elements_in_list)
818       graphic = el2gfx(editor_element[elem_pos+element_shift]);
819     else
820       graphic = GFX_LEERRAUM;
821
822     from_x = cx + edit_pos[pos][xpos];
823     from_y = cy + edit_pos[pos][ypos];
824     size_x = edit_pos[pos][xsize];
825     size_y = edit_pos[pos][ysize];
826     to_x   = DX + edit_pos[pos][xpos] + x * ED_BUTTON_ELEM_XSIZE;
827     to_y   = DY + edit_pos[pos][ypos] + y * ED_BUTTON_ELEM_YSIZE;
828
829     if (button_state & ED_BUTTON_PRESSED)
830     {
831       from_y = ED_BUTTON_ELEM_Y2POS;
832       shift = 1;
833     }
834
835     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
836               from_x,from_y, size_x,size_y, to_x,to_y);
837
838     DrawMiniGraphicExt(drawto,gc,
839                        DX+ED_BUTTON_ELEM_XPOS+3+shift + 
840                        (elem_pos % MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
841                        DY+ED_BUTTON_ELEM_YPOS+3-shift +
842                        (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
843                        graphic);
844   }
845
846   redraw_mask |= REDRAW_DOOR_1;
847 }
848
849 void DrawCountButton(int button_nr, int button_state)
850 {
851   int from_x, from_y, to_x,to_y, size_x, size_y;
852
853   from_x =
854     DOOR_GFX_PAGEX4+(button_nr%2 ? ED_BUTTON_PLUS_XPOS : ED_BUTTON_MINUS_XPOS);
855   from_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
856   size_x = ED_BUTTON_MINUS_XSIZE;
857   size_y = ED_BUTTON_MINUS_YSIZE;
858   to_x = (button_nr<32 ? ED_COUNT_GADGET_XPOS : ED_SIZE_GADGET_XPOS);
859   if (button_nr % 2)
860     to_x += (ED_BUTTON_PLUS_XPOS - ED_BUTTON_MINUS_XPOS);
861   to_y = (button_nr<32 ? ED_COUNT_GADGET_YPOS : ED_SIZE_GADGET_YPOS) +
862     ((button_nr<32 ? button_nr : button_nr-32)/2)*ED_COUNT_GADGET_YSIZE;
863
864   if (button_state & ED_BUTTON_PRESSED)
865     from_x -= DXSIZE;
866
867   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
868             from_x,from_y, size_x,size_y, to_x,to_y);
869   XCopyArea(display,pix[PIX_DOOR],window,gc,
870             from_x,from_y, size_x,size_y, to_x,to_y);
871 }
872
873 /**********************************************************************/
874 /********** checking buttons (and redrawing them, if needed) **********/
875 /**********************************************************************/
876
877 int CheckVideoButtons(int mx, int my, int button)
878 {
879   int return_code = 0;
880   static int choice = -1;
881   static boolean pressed = FALSE;
882   static int video_button[5] =
883   {
884     VIDEO_PRESS_EJECT_ON,
885     VIDEO_PRESS_STOP_ON,
886     VIDEO_PRESS_PAUSE_ON,
887     VIDEO_PRESS_REC_ON,
888     VIDEO_PRESS_PLAY_ON
889   };
890
891   if (button)
892   {
893     if (!motion_status)         /* Maustaste neu gedrückt */
894     {
895       if (ON_VIDEO_BUTTON(mx,my))
896       {
897         choice = VIDEO_BUTTON(mx);
898         pressed = TRUE;
899         DrawVideoDisplay(video_button[choice],0);
900       }
901     }
902     else                        /* Mausbewegung bei gedrückter Maustaste */
903     {
904       if ((!ON_VIDEO_BUTTON(mx,my) || VIDEO_BUTTON(mx)!=choice) &&
905           choice>=0 && pressed)
906       {
907         pressed = FALSE;
908         DrawVideoDisplay(video_button[choice]<<1,0);
909       }
910       else if (ON_VIDEO_BUTTON(mx,my) && VIDEO_BUTTON(mx)==choice && !pressed)
911       {
912         pressed = TRUE;
913         DrawVideoDisplay(video_button[choice],0);
914       }
915     }
916   }
917   else                          /* Maustaste wieder losgelassen */
918   {
919     if (ON_VIDEO_BUTTON(mx,my) && VIDEO_BUTTON(mx)==choice && pressed)
920     {
921       DrawVideoDisplay(video_button[choice]<<1,0);
922       return_code = choice+1;
923       choice = -1;
924       pressed = FALSE;
925     }
926     else
927     {
928       choice = -1;
929       pressed = FALSE;
930     }
931   }
932
933   BackToFront();
934   return(return_code);
935 }
936
937 int CheckSoundButtons(int mx, int my, int button)
938 {
939   int return_code = 0;
940   static int choice = -1;
941   static boolean pressed = FALSE;
942   int sound_state[3];
943
944   sound_state[0] = BUTTON_SOUND_MUSIC  | (BUTTON_ON * setup.sound_music);
945   sound_state[1] = BUTTON_SOUND_LOOPS  | (BUTTON_ON * setup.sound_loops);
946   sound_state[2] = BUTTON_SOUND_SIMPLE | (BUTTON_ON * setup.sound_simple);
947
948   if (button)
949   {
950     if (!motion_status)         /* Maustaste neu gedrückt */
951     {
952       if (ON_SOUND_BUTTON(mx,my))
953       {
954         choice = SOUND_BUTTON(mx);
955         pressed = TRUE;
956         DrawSoundDisplay(sound_state[choice] | BUTTON_PRESSED);
957       }
958     }
959     else                        /* Mausbewegung bei gedrückter Maustaste */
960     {
961       if ((!ON_SOUND_BUTTON(mx,my) || SOUND_BUTTON(mx)!=choice) &&
962           choice>=0 && pressed)
963       {
964         pressed = FALSE;
965         DrawSoundDisplay(sound_state[choice] | BUTTON_RELEASED);
966       }
967       else if (ON_SOUND_BUTTON(mx,my) && SOUND_BUTTON(mx)==choice && !pressed)
968       {
969         pressed = TRUE;
970         DrawSoundDisplay(sound_state[choice] | BUTTON_PRESSED);
971       }
972     }
973   }
974   else                          /* Maustaste wieder losgelassen */
975   {
976     if (ON_SOUND_BUTTON(mx,my) && SOUND_BUTTON(mx)==choice && pressed)
977     {
978       DrawSoundDisplay(sound_state[choice] | BUTTON_RELEASED);
979       return_code = 1<<choice;
980       choice = -1;
981       pressed = FALSE;
982     }
983     else
984     {
985       choice = -1;
986       pressed = FALSE;
987     }
988   }
989
990   BackToFront();
991   return(return_code);
992 }
993
994 int CheckGameButtons(int mx, int my, int button)
995 {
996   int return_code = 0;
997   static int choice = -1;
998   static boolean pressed = FALSE;
999   int game_state[3] =
1000   {
1001     BUTTON_GAME_STOP,
1002     BUTTON_GAME_PAUSE,
1003     BUTTON_GAME_PLAY
1004   };
1005
1006   if (button)
1007   {
1008     if (!motion_status)         /* Maustaste neu gedrückt */
1009     {
1010       if (ON_GAME_BUTTON(mx,my))
1011       {
1012         choice = GAME_BUTTON(mx);
1013         pressed = TRUE;
1014         DrawGameButton(game_state[choice] | BUTTON_PRESSED);
1015       }
1016     }
1017     else                        /* Mausbewegung bei gedrückter Maustaste */
1018     {
1019       if ((!ON_GAME_BUTTON(mx,my) || GAME_BUTTON(mx)!=choice) &&
1020           choice>=0 && pressed)
1021       {
1022         pressed = FALSE;
1023         DrawGameButton(game_state[choice] | BUTTON_RELEASED);
1024       }
1025       else if (ON_GAME_BUTTON(mx,my) && GAME_BUTTON(mx)==choice && !pressed)
1026       {
1027         pressed = TRUE;
1028         DrawGameButton(game_state[choice] | BUTTON_PRESSED);
1029       }
1030     }
1031   }
1032   else                          /* Maustaste wieder losgelassen */
1033   {
1034     if (ON_GAME_BUTTON(mx,my) && GAME_BUTTON(mx)==choice && pressed)
1035     {
1036       DrawGameButton(game_state[choice] | BUTTON_RELEASED);
1037       return_code = 1<<choice;
1038       choice = -1;
1039       pressed = FALSE;
1040     }
1041     else
1042     {
1043       choice = -1;
1044       pressed = FALSE;
1045     }
1046   }
1047
1048   BackToFront();
1049   return(return_code);
1050 }
1051
1052 int CheckYesNoButtons(int mx, int my, int button)
1053 {
1054   int return_code = 0;
1055   static int choice = -1;
1056   static boolean pressed = FALSE;
1057   static int yesno_button[5] =
1058   {
1059     BUTTON_OK,
1060     BUTTON_NO
1061   };
1062
1063   if (button)
1064   {
1065     if (!motion_status)         /* Maustaste neu gedrückt */
1066     {
1067       if (ON_YESNO_BUTTON(mx,my))
1068       {
1069         choice = YESNO_BUTTON(mx);
1070         pressed = TRUE;
1071         DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED, DB_NORMAL);
1072       }
1073     }
1074     else                        /* Mausbewegung bei gedrückter Maustaste */
1075     {
1076       if ((!ON_YESNO_BUTTON(mx,my) || YESNO_BUTTON(mx)!=choice) &&
1077           choice>=0 && pressed)
1078       {
1079         pressed = FALSE;
1080         DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED, DB_NORMAL);
1081       }
1082       else if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && !pressed)
1083       {
1084         pressed = TRUE;
1085         DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED, DB_NORMAL);
1086       }
1087     }
1088   }
1089   else                          /* Maustaste wieder losgelassen */
1090   {
1091     if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && pressed)
1092     {
1093       DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED, DB_NORMAL);
1094       return_code = choice+1;
1095       choice = -1;
1096       pressed = FALSE;
1097     }
1098     else
1099     {
1100       choice = -1;
1101       pressed = FALSE;
1102     }
1103   }
1104
1105   BackToFront();
1106   return(return_code);
1107 }
1108
1109 int CheckConfirmButton(int mx, int my, int button)
1110 {
1111   int return_code = 0;
1112   static int choice = -1;
1113   static boolean pressed = FALSE;
1114
1115   if (button)
1116   {
1117     if (!motion_status)         /* Maustaste neu gedrückt */
1118     {
1119       if (ON_CONFIRM_BUTTON(mx,my))
1120       {
1121         choice = 0;
1122         pressed = TRUE;
1123         DrawConfirmButton(BUTTON_PRESSED, DB_NORMAL);
1124       }
1125     }
1126     else                        /* Mausbewegung bei gedrückter Maustaste */
1127     {
1128       if (!ON_CONFIRM_BUTTON(mx,my) && choice>=0 && pressed)
1129       {
1130         pressed = FALSE;
1131         DrawConfirmButton(BUTTON_RELEASED, DB_NORMAL);
1132       }
1133       else if (ON_CONFIRM_BUTTON(mx,my) && !pressed)
1134       {
1135         pressed = TRUE;
1136         DrawConfirmButton(BUTTON_PRESSED, DB_NORMAL);
1137       }
1138     }
1139   }
1140   else                          /* Maustaste wieder losgelassen */
1141   {
1142     if (ON_CONFIRM_BUTTON(mx,my) && pressed)
1143     {
1144       DrawConfirmButton(BUTTON_RELEASED, DB_NORMAL);
1145       return_code = BUTTON_CONFIRM;
1146       choice = -1;
1147       pressed = FALSE;
1148     }
1149     else
1150     {
1151       choice = -1;
1152       pressed = FALSE;
1153     }
1154   }
1155
1156   BackToFront();
1157   return(return_code);
1158 }
1159
1160 int CheckPlayerButtons(int mx, int my, int button)
1161 {
1162   int return_code = 0;
1163   static int choice = -1;
1164   static boolean pressed = FALSE;
1165   int player_state[4] =
1166   {
1167     BUTTON_PLAYER_1,
1168     BUTTON_PLAYER_2,
1169     BUTTON_PLAYER_3,
1170     BUTTON_PLAYER_4
1171   };
1172
1173   if (button)
1174   {
1175     if (!motion_status)         /* Maustaste neu gedrückt */
1176     {
1177       if (ON_PLAYER_BUTTON(mx,my))
1178       {
1179         choice = PLAYER_BUTTON(mx,my);
1180         pressed = TRUE;
1181         DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL);
1182       }
1183     }
1184     else                        /* Mausbewegung bei gedrückter Maustaste */
1185     {
1186       if ((!ON_PLAYER_BUTTON(mx,my) || PLAYER_BUTTON(mx,my)!=choice) &&
1187           choice>=0 && pressed)
1188       {
1189         pressed = FALSE;
1190         DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL);
1191       }
1192       else if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && !pressed)
1193       {
1194         pressed = TRUE;
1195         DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL);
1196       }
1197     }
1198   }
1199   else                          /* Maustaste wieder losgelassen */
1200   {
1201     if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && pressed)
1202     {
1203       DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL);
1204       return_code = player_state[choice];
1205       choice = -1;
1206       pressed = FALSE;
1207     }
1208     else
1209     {
1210       choice = -1;
1211       pressed = FALSE;
1212     }
1213   }
1214
1215   BackToFront();
1216   return(return_code);
1217 }
1218
1219 /* several buttons in the level editor */
1220
1221 int CheckEditButtons(int mx, int my, int button)
1222 {
1223   int return_code = 0;
1224   static int choice = -1;
1225   static boolean pressed = FALSE;
1226   static int edit_button[6] =
1227   {
1228     ED_BUTTON_CTRL,
1229     ED_BUTTON_FILL,
1230     ED_BUTTON_LEFT,
1231     ED_BUTTON_UP,
1232     ED_BUTTON_DOWN,
1233     ED_BUTTON_RIGHT
1234   };
1235
1236   if (button)
1237   {
1238     if (!motion_status)         /* Maustaste neu gedrückt */
1239     {
1240       if (ON_EDIT_BUTTON(mx,my))
1241       {
1242         choice = EDIT_BUTTON(mx,my);
1243         pressed = TRUE;
1244         DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
1245         if (edit_button[choice]!=ED_BUTTON_CTRL &&
1246             edit_button[choice]!=ED_BUTTON_FILL)
1247           return_code = 1<<choice;
1248       }
1249     }
1250     else                        /* Mausbewegung bei gedrückter Maustaste */
1251     {
1252       if ((!ON_EDIT_BUTTON(mx,my) || EDIT_BUTTON(mx,my)!=choice) &&
1253           choice>=0 && pressed)
1254       {
1255         pressed = FALSE;
1256         DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
1257       }
1258       else if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice)
1259       {
1260         if (!pressed)
1261           DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
1262         pressed = TRUE;
1263         if (edit_button[choice]!=ED_BUTTON_CTRL &&
1264             edit_button[choice]!=ED_BUTTON_FILL)
1265           return_code = 1<<choice;
1266       }
1267     }
1268   }
1269   else                          /* Maustaste wieder losgelassen */
1270   {
1271     if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice && pressed)
1272     {
1273       DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
1274       if (edit_button[choice]==ED_BUTTON_CTRL ||
1275           edit_button[choice]==ED_BUTTON_FILL)
1276         return_code = 1<<choice;
1277       choice = -1;
1278       pressed = FALSE;
1279     }
1280     else
1281     {
1282       choice = -1;
1283       pressed = FALSE;
1284     }
1285   }
1286
1287   BackToFront();
1288   return(return_code);
1289 }
1290
1291 int CheckCtrlButtons(int mx, int my, int button)
1292 {
1293   int return_code = 0;
1294   static int choice = -1;
1295   static boolean pressed = FALSE;
1296   static int ctrl_button[4] =
1297   {
1298     ED_BUTTON_EDIT,
1299     ED_BUTTON_CLEAR,
1300     ED_BUTTON_UNDO,
1301     ED_BUTTON_EXIT
1302   };
1303
1304   if (button)
1305   {
1306     if (!motion_status)         /* Maustaste neu gedrückt */
1307     {
1308       if (ON_CTRL_BUTTON(mx,my))
1309       {
1310         choice = CTRL_BUTTON(mx,my);
1311         pressed = TRUE;
1312         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
1313       }
1314     }
1315     else                        /* Mausbewegung bei gedrückter Maustaste */
1316     {
1317       if ((!ON_CTRL_BUTTON(mx,my) || CTRL_BUTTON(mx,my)!=choice) &&
1318           choice>=0 && pressed)
1319       {
1320         pressed = FALSE;
1321         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
1322       }
1323       else if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && !pressed)
1324       {
1325         pressed = TRUE;
1326         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
1327       }
1328     }
1329   }
1330   else                          /* Maustaste wieder losgelassen */
1331   {
1332     if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && pressed)
1333     {
1334       DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
1335       return_code = 1<<(choice+6);
1336       choice = -1;
1337       pressed = FALSE;
1338     }
1339     else
1340     {
1341       choice = -1;
1342       pressed = FALSE;
1343     }
1344   }
1345
1346   BackToFront();
1347   return(return_code);
1348 }
1349
1350 int CheckElemButtons(int mx, int my, int button)
1351 {
1352   int return_code = -1;
1353   static int choice = -1;
1354   static boolean pressed = FALSE;
1355
1356   if (button)
1357   {
1358     if (!motion_status)         /* Maustaste neu gedrückt */
1359     {
1360       if (ON_ELEM_BUTTON(mx,my))
1361       {
1362         choice = ELEM_BUTTON(mx,my);
1363         pressed = TRUE;
1364         DrawElemButton(choice,ED_BUTTON_PRESSED);
1365         if (choice==ED_BUTTON_EUP ||
1366             choice==ED_BUTTON_EDOWN)
1367           return_code = choice;
1368       }
1369     }
1370     else                        /* Mausbewegung bei gedrückter Maustaste */
1371     {
1372       if ((!ON_ELEM_BUTTON(mx,my) || ELEM_BUTTON(mx,my)!=choice) &&
1373           choice>=0 && pressed)
1374       {
1375         pressed = FALSE;
1376         DrawElemButton(choice,ED_BUTTON_RELEASED);
1377       }
1378       else if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice)
1379       {
1380         if (!pressed)
1381           DrawElemButton(choice,ED_BUTTON_PRESSED);
1382         pressed = TRUE;
1383         if (choice==ED_BUTTON_EUP ||
1384             choice==ED_BUTTON_EDOWN)
1385           return_code = choice;
1386       }
1387     }
1388   }
1389   else                          /* Maustaste wieder losgelassen */
1390   {
1391     if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice && pressed)
1392     {
1393       DrawElemButton(choice,ED_BUTTON_RELEASED);
1394       if (choice!=ED_BUTTON_EUP &&
1395           choice!=ED_BUTTON_EDOWN)
1396         return_code = choice;
1397       choice = -1;
1398       pressed = FALSE;
1399     }
1400     else
1401     {
1402       choice = -1;
1403       pressed = FALSE;
1404     }
1405   }
1406
1407   BackToFront();
1408   return(return_code);
1409 }
1410
1411 int CheckCountButtons(int mx, int my, int button)
1412 {
1413   int return_code = -1;
1414   static int choice = -1;
1415   static boolean pressed = FALSE;
1416
1417   if (button)
1418   {
1419     if (!motion_status)         /* Maustaste neu gedrückt */
1420     {
1421       if (ON_COUNT_BUTTON(mx,my))
1422       {
1423         choice = COUNT_BUTTON(mx,my);
1424         pressed = TRUE;
1425         DrawCountButton(choice,ED_BUTTON_PRESSED);
1426         return_code = choice;
1427       }
1428     }
1429     else                        /* Mausbewegung bei gedrückter Maustaste */
1430     {
1431       if ((!ON_COUNT_BUTTON(mx,my) || COUNT_BUTTON(mx,my)!=choice) &&
1432           choice>=0 && pressed)
1433       {
1434         pressed = FALSE;
1435         DrawCountButton(choice,ED_BUTTON_RELEASED);
1436       }
1437       else if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice)
1438       {
1439         if (!pressed)
1440           DrawCountButton(choice,ED_BUTTON_PRESSED);
1441         pressed = TRUE;
1442         return_code = choice;
1443       }
1444     }
1445   }
1446   else                          /* Maustaste wieder losgelassen */
1447   {
1448     if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice && pressed)
1449     {
1450       DrawCountButton(choice,ED_BUTTON_RELEASED);
1451       choice = -1;
1452       pressed = FALSE;
1453     }
1454     else
1455     {
1456       choice = -1;
1457       pressed = FALSE;
1458     }
1459   }
1460
1461   BackToFront();
1462   return(return_code);
1463 }