1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
22 /* some positions in the video tape control window */
23 #define VIDEO_BUTTON_EJECT_XPOS (VIDEO_CONTROL_XPOS + 0 * VIDEO_BUTTON_XSIZE)
24 #define VIDEO_BUTTON_STOP_XPOS (VIDEO_CONTROL_XPOS + 1 * VIDEO_BUTTON_XSIZE)
25 #define VIDEO_BUTTON_PAUSE_XPOS (VIDEO_CONTROL_XPOS + 2 * VIDEO_BUTTON_XSIZE)
26 #define VIDEO_BUTTON_REC_XPOS (VIDEO_CONTROL_XPOS + 3 * VIDEO_BUTTON_XSIZE)
27 #define VIDEO_BUTTON_PLAY_XPOS (VIDEO_CONTROL_XPOS + 4 * VIDEO_BUTTON_XSIZE)
28 #define VIDEO_BUTTON_ANY_YPOS (VIDEO_CONTROL_YPOS)
29 #define VIDEO_DATE_LABEL_XPOS (VIDEO_DISPLAY1_XPOS)
30 #define VIDEO_DATE_LABEL_YPOS (VIDEO_DISPLAY1_YPOS)
31 #define VIDEO_DATE_LABEL_XSIZE (VIDEO_DISPLAY_XSIZE)
32 #define VIDEO_DATE_LABEL_YSIZE (VIDEO_DISPLAY_YSIZE)
33 #define VIDEO_DATE_XPOS (VIDEO_DISPLAY1_XPOS+1)
34 #define VIDEO_DATE_YPOS (VIDEO_DISPLAY1_YPOS+14)
35 #define VIDEO_DATE_XSIZE (VIDEO_DISPLAY_XSIZE)
36 #define VIDEO_DATE_YSIZE 16
37 #define VIDEO_REC_LABEL_XPOS (VIDEO_DISPLAY2_XPOS)
38 #define VIDEO_REC_LABEL_YPOS (VIDEO_DISPLAY2_YPOS)
39 #define VIDEO_REC_LABEL_XSIZE 20
40 #define VIDEO_REC_LABEL_YSIZE 12
41 #define VIDEO_REC_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS+20)
42 #define VIDEO_REC_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
43 #define VIDEO_REC_SYMBOL_XSIZE 16
44 #define VIDEO_REC_SYMBOL_YSIZE 16
45 #define VIDEO_PLAY_LABEL_XPOS (VIDEO_DISPLAY2_XPOS+65)
46 #define VIDEO_PLAY_LABEL_YPOS (VIDEO_DISPLAY2_YPOS)
47 #define VIDEO_PLAY_LABEL_XSIZE 22
48 #define VIDEO_PLAY_LABEL_YSIZE 12
49 #define VIDEO_PLAY_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS+52)
50 #define VIDEO_PLAY_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
51 #define VIDEO_PLAY_SYMBOL_XSIZE 11
52 #define VIDEO_PLAY_SYMBOL_YSIZE 13
53 #define VIDEO_PAUSE_LABEL_XPOS (VIDEO_DISPLAY2_XPOS)
54 #define VIDEO_PAUSE_LABEL_YPOS (VIDEO_DISPLAY2_YPOS+20)
55 #define VIDEO_PAUSE_LABEL_XSIZE 35
56 #define VIDEO_PAUSE_LABEL_YSIZE 8
57 #define VIDEO_PAUSE_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS+35)
58 #define VIDEO_PAUSE_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
59 #define VIDEO_PAUSE_SYMBOL_XSIZE 17
60 #define VIDEO_PAUSE_SYMBOL_YSIZE 13
61 #define VIDEO_TIME_XPOS (VIDEO_DISPLAY2_XPOS+38)
62 #define VIDEO_TIME_YPOS (VIDEO_DISPLAY2_YPOS+14)
63 #define VIDEO_TIME_XSIZE 50
64 #define VIDEO_TIME_YSIZE 16
67 #define VIDEO_PBEND_LABEL_XPOS 6
68 #define VIDEO_PBEND_LABEL_YPOS 220
69 #define VIDEO_PBEND_LABEL_XSIZE 35
70 #define VIDEO_PBEND_LABEL_YSIZE 30
72 #define ON_VIDEO_BUTTON(x,y) ((x)>=(VX+VIDEO_CONTROL_XPOS) && \
73 (x)< (VX+VIDEO_CONTROL_XPOS + \
74 VIDEO_CONTROL_XSIZE) && \
75 (y)>=(VY+VIDEO_CONTROL_YPOS) && \
76 (y)< (VY+VIDEO_CONTROL_YPOS + \
78 #define VIDEO_BUTTON(x) (((x)-(VX+VIDEO_CONTROL_XPOS))/VIDEO_BUTTON_XSIZE)
80 #define VIDEO_STATE_OFF (VIDEO_STATE_PLAY_OFF | \
81 VIDEO_STATE_REC_OFF | \
82 VIDEO_STATE_PAUSE_OFF | \
83 VIDEO_STATE_FFWD_OFF | \
84 VIDEO_STATE_PBEND_OFF | \
85 VIDEO_STATE_DATE_OFF | \
87 #define VIDEO_PRESS_OFF (VIDEO_PRESS_PLAY_OFF | \
88 VIDEO_PRESS_REC_OFF | \
89 VIDEO_PRESS_PAUSE_OFF | \
90 VIDEO_PRESS_STOP_OFF | \
91 VIDEO_PRESS_EJECT_OFF)
92 #define VIDEO_ALL_OFF (VIDEO_STATE_OFF | VIDEO_PRESS_OFF)
94 #define VIDEO_STATE_ON (VIDEO_STATE_PLAY_ON | \
95 VIDEO_STATE_REC_ON | \
96 VIDEO_STATE_PAUSE_ON | \
97 VIDEO_STATE_FFWD_ON | \
98 VIDEO_STATE_PBEND_ON | \
99 VIDEO_STATE_DATE_ON | \
101 #define VIDEO_PRESS_ON (VIDEO_PRESS_PLAY_ON | \
102 VIDEO_PRESS_REC_ON | \
103 VIDEO_PRESS_PAUSE_ON | \
104 VIDEO_PRESS_STOP_ON | \
105 VIDEO_PRESS_EJECT_ON)
106 #define VIDEO_ALL_ON (VIDEO_STATE_ON | VIDEO_PRESS_ON)
108 #define VIDEO_STATE (VIDEO_STATE_ON | VIDEO_STATE_OFF)
109 #define VIDEO_PRESS (VIDEO_PRESS_ON | VIDEO_PRESS_OFF)
110 #define VIDEO_ALL (VIDEO_ALL_ON | VIDEO_ALL_OFF)
113 /* some positions in the sound control window */
114 #define SOUND_BUTTON_XSIZE 30
115 #define SOUND_BUTTON_YSIZE 30
116 #define SOUND_CONTROL_XPOS 5
117 #define SOUND_CONTROL_YPOS 245
118 #define SOUND_CONTROL_XSIZE (3*SOUND_BUTTON_XSIZE)
119 #define SOUND_CONTROL_YSIZE (1*SOUND_BUTTON_YSIZE)
120 #define SOUND_BUTTON_MUSIC_XPOS (SOUND_CONTROL_XPOS + 0 * SOUND_BUTTON_XSIZE)
121 #define SOUND_BUTTON_LOOPS_XPOS (SOUND_CONTROL_XPOS + 1 * SOUND_BUTTON_XSIZE)
122 #define SOUND_BUTTON_SIMPLE_XPOS (SOUND_CONTROL_XPOS + 2 * SOUND_BUTTON_XSIZE)
123 #define SOUND_BUTTON_ANY_YPOS (SOUND_CONTROL_YPOS)
125 #define ON_SOUND_BUTTON(x,y) ((x)>=(DX+SOUND_CONTROL_XPOS) && \
126 (x)< (DX+SOUND_CONTROL_XPOS + \
127 SOUND_CONTROL_XSIZE) && \
128 (y)>=(DY+SOUND_CONTROL_YPOS) && \
129 (y)< (DY+SOUND_CONTROL_YPOS + \
130 SOUND_CONTROL_YSIZE))
131 #define SOUND_BUTTON(x) (((x)-(DX+SOUND_CONTROL_XPOS))/SOUND_BUTTON_XSIZE)
133 /* some positions in the game control window */
134 #define GAME_BUTTON_STOP_XPOS (GAME_CONTROL_XPOS + 0 * GAME_BUTTON_XSIZE)
135 #define GAME_BUTTON_PAUSE_XPOS (GAME_CONTROL_XPOS + 1 * GAME_BUTTON_XSIZE)
136 #define GAME_BUTTON_PLAY_XPOS (GAME_CONTROL_XPOS + 2 * GAME_BUTTON_XSIZE)
137 #define GAME_BUTTON_ANY_YPOS (GAME_CONTROL_YPOS)
139 #define ON_GAME_BUTTON(x,y) ((x)>=(DX+GAME_CONTROL_XPOS) && \
140 (x)< (DX+GAME_CONTROL_XPOS + \
141 GAME_CONTROL_XSIZE) && \
142 (y)>=(DY+GAME_CONTROL_YPOS) && \
143 (y)< (DY+GAME_CONTROL_YPOS + \
145 #define GAME_BUTTON(x) (((x)-(DX+GAME_CONTROL_XPOS))/GAME_BUTTON_XSIZE)
147 /* some positions in the asking window */
148 #define OK_BUTTON_XPOS 2
149 #define OK_BUTTON_YPOS 250
150 #define OK_BUTTON_GFX_YPOS 0
151 #define OK_BUTTON_XSIZE 46
152 #define OK_BUTTON_YSIZE 28
153 #define NO_BUTTON_XPOS 52
154 #define NO_BUTTON_YPOS OK_BUTTON_YPOS
155 #define NO_BUTTON_XSIZE OK_BUTTON_XSIZE
156 #define NO_BUTTON_YSIZE OK_BUTTON_YSIZE
157 #define CONFIRM_BUTTON_XPOS 2
158 #define CONFIRM_BUTTON_GFX_YPOS 30
159 #define CONFIRM_BUTTON_YPOS OK_BUTTON_YPOS
160 #define CONFIRM_BUTTON_XSIZE 96
161 #define CONFIRM_BUTTON_YSIZE OK_BUTTON_YSIZE
163 #define ON_YESNO_BUTTON(x,y) (((x)>=(DX+OK_BUTTON_XPOS) && \
164 (x)< (DX+OK_BUTTON_XPOS + \
165 OK_BUTTON_XSIZE) && \
166 (y)>=(DY+OK_BUTTON_YPOS) && \
167 (y)< (DY+OK_BUTTON_YPOS + \
168 OK_BUTTON_YSIZE)) || \
169 ((x)>=(DX+NO_BUTTON_XPOS) && \
170 (x)< (DX+NO_BUTTON_XPOS + \
171 NO_BUTTON_XSIZE) && \
172 (y)>=(DY+NO_BUTTON_YPOS) && \
173 (y)< (DY+NO_BUTTON_YPOS + \
175 #define ON_CONFIRM_BUTTON(x,y) (((x)>=(DX+CONFIRM_BUTTON_XPOS) && \
176 (x)< (DX+CONFIRM_BUTTON_XPOS + \
177 CONFIRM_BUTTON_XSIZE) && \
178 (y)>=(DY+CONFIRM_BUTTON_YPOS) && \
179 (y)< (DY+CONFIRM_BUTTON_YPOS + \
180 CONFIRM_BUTTON_YSIZE)))
181 #define YESNO_BUTTON(x) (((x)-(DX+OK_BUTTON_XPOS))/OK_BUTTON_XSIZE)
183 /* some positions in the choose player window */
184 #define PLAYER_BUTTON_XSIZE 30
185 #define PLAYER_BUTTON_YSIZE 30
186 #define PLAYER_BUTTON_GFX_XPOS 5
187 #define PLAYER_BUTTON_GFX_YPOS (215-30)
188 #define PLAYER_CONTROL_XPOS (5 + PLAYER_BUTTON_XSIZE/2)
189 #define PLAYER_CONTROL_YPOS (215 - PLAYER_BUTTON_YSIZE/2)
190 #define PLAYER_CONTROL_XSIZE (2*PLAYER_BUTTON_XSIZE)
191 #define PLAYER_CONTROL_YSIZE (2*PLAYER_BUTTON_YSIZE)
192 #define PLAYER_BUTTON_1_XPOS (PLAYER_CONTROL_XPOS + 0 * PLAYER_BUTTON_XSIZE)
193 #define PLAYER_BUTTON_2_XPOS (PLAYER_CONTROL_XPOS + 1 * PLAYER_BUTTON_XSIZE)
194 #define PLAYER_BUTTON_3_XPOS (PLAYER_CONTROL_XPOS + 0 * PLAYER_BUTTON_XSIZE)
195 #define PLAYER_BUTTON_4_XPOS (PLAYER_CONTROL_XPOS + 1 * PLAYER_BUTTON_XSIZE)
196 #define PLAYER_BUTTON_1_YPOS (PLAYER_CONTROL_YPOS + 0 * PLAYER_BUTTON_YSIZE)
197 #define PLAYER_BUTTON_2_YPOS (PLAYER_CONTROL_YPOS + 0 * PLAYER_BUTTON_YSIZE)
198 #define PLAYER_BUTTON_3_YPOS (PLAYER_CONTROL_YPOS + 1 * PLAYER_BUTTON_YSIZE)
199 #define PLAYER_BUTTON_4_YPOS (PLAYER_CONTROL_YPOS + 1 * PLAYER_BUTTON_YSIZE)
201 #define ON_PLAYER_BUTTON(x,y) ((x)>=(DX+PLAYER_CONTROL_XPOS) && \
202 (x)< (DX+PLAYER_CONTROL_XPOS + \
203 PLAYER_CONTROL_XSIZE) && \
204 (y)>=(DY+PLAYER_CONTROL_YPOS) && \
205 (y)< (DY+PLAYER_CONTROL_YPOS + \
206 PLAYER_CONTROL_YSIZE))
207 #define PLAYER_BUTTON(x,y) ((((x)-(DX+PLAYER_CONTROL_XPOS)) / \
208 PLAYER_BUTTON_XSIZE) + 2 * \
209 (((y)-(DY+PLAYER_CONTROL_YPOS)) / \
210 PLAYER_BUTTON_YSIZE))
213 /* some definitions for the editor control window */
215 #define ON_EDIT_BUTTON(x,y) (((x)>=(VX+ED_BUTTON_CTRL_XPOS) && \
216 (x)< (VX+ED_BUTTON_CTRL_XPOS + \
217 ED_BUTTON_CTRL_XSIZE) && \
218 (y)>=(VY+ED_BUTTON_CTRL_YPOS) && \
219 (y)< (VY+ED_BUTTON_CTRL_YPOS + \
220 ED_BUTTON_CTRL_YSIZE + \
221 ED_BUTTON_FILL_YSIZE)) || \
222 ((x)>=(VX+ED_BUTTON_LEFT_XPOS) && \
223 (x)< (VX+ED_BUTTON_LEFT_XPOS + \
224 ED_BUTTON_LEFT_XSIZE + \
225 ED_BUTTON_UP_XSIZE + \
226 ED_BUTTON_RIGHT_XSIZE) && \
227 (y)>=(VY+ED_BUTTON_LEFT_YPOS) && \
228 (y)< (VY+ED_BUTTON_LEFT_YPOS + \
229 ED_BUTTON_LEFT_YSIZE)) || \
230 ((x)>=(VX+ED_BUTTON_UP_XPOS) && \
231 (x)< (VX+ED_BUTTON_UP_XPOS + \
232 ED_BUTTON_UP_XSIZE) && \
233 (y)>=(VY+ED_BUTTON_UP_YPOS) && \
234 (y)< (VY+ED_BUTTON_UP_YPOS + \
235 ED_BUTTON_UP_YSIZE + \
236 ED_BUTTON_DOWN_YSIZE)))
238 #define ON_CTRL_BUTTON(x,y) ((x)>=(VX+ED_BUTTON_EDIT_XPOS) && \
239 (x)< (VX+ED_BUTTON_EDIT_XPOS + \
240 ED_BUTTON_EDIT_XSIZE) && \
241 (y)>=(VY+ED_BUTTON_EDIT_YPOS) && \
242 (y)< (VY+ED_BUTTON_EDIT_YPOS + \
243 ED_BUTTON_EDIT_YSIZE + \
244 ED_BUTTON_CLEAR_YSIZE + \
245 ED_BUTTON_UNDO_YSIZE + \
246 ED_BUTTON_EXIT_YSIZE))
248 #define ON_ELEM_BUTTON(x,y) (((x)>=(DX+ED_BUTTON_EUP_XPOS) && \
249 (x)< (DX+ED_BUTTON_EUP_XPOS + \
250 ED_BUTTON_EUP_XSIZE) && \
251 (y)>=(DY+ED_BUTTON_EUP_YPOS) && \
252 (y)< (DY+ED_BUTTON_EUP_YPOS + \
253 ED_BUTTON_EUP_YSIZE)) || \
254 ((x)>=(DX+ED_BUTTON_EDOWN_XPOS) && \
255 (x)< (DX+ED_BUTTON_EDOWN_XPOS + \
256 ED_BUTTON_EDOWN_XSIZE) && \
257 (y)>=(DY+ED_BUTTON_EDOWN_YPOS) && \
258 (y)< (DY+ED_BUTTON_EDOWN_YPOS + \
259 ED_BUTTON_EDOWN_YSIZE)) || \
260 ((x)>=(DX+ED_BUTTON_ELEM_XPOS) && \
261 (x)< (DX+ED_BUTTON_ELEM_XPOS + \
262 MAX_ELEM_X*ED_BUTTON_ELEM_XSIZE) && \
263 (y)>=(DY+ED_BUTTON_ELEM_YPOS) && \
264 (y)< (DY+ED_BUTTON_ELEM_YPOS + \
265 MAX_ELEM_Y*ED_BUTTON_ELEM_YSIZE)))
267 #define ON_COUNT_BUTTON(x,y) (((((x)>=ED_COUNT_GADGET_XPOS && \
268 (x)<(ED_COUNT_GADGET_XPOS + \
269 ED_BUTTON_MINUS_XSIZE)) || \
270 ((x)>=(ED_COUNT_GADGET_XPOS + \
271 (ED_BUTTON_PLUS_XPOS - \
272 ED_BUTTON_MINUS_XPOS)) && \
273 (x)<(ED_COUNT_GADGET_XPOS + \
274 (ED_BUTTON_PLUS_XPOS - \
275 ED_BUTTON_MINUS_XPOS) + \
276 ED_BUTTON_PLUS_XSIZE))) && \
277 ((y)>=ED_COUNT_GADGET_YPOS && \
278 (y)<(ED_COUNT_GADGET_YPOS + \
279 16*ED_COUNT_GADGET_YSIZE)) && \
280 (((y)-ED_COUNT_GADGET_YPOS) % \
281 ED_COUNT_GADGET_YSIZE) < \
282 ED_BUTTON_MINUS_YSIZE) || \
283 ((((x)>=ED_SIZE_GADGET_XPOS && \
284 (x)<(ED_SIZE_GADGET_XPOS + \
285 ED_BUTTON_MINUS_XSIZE)) || \
286 ((x)>=(ED_SIZE_GADGET_XPOS + \
287 (ED_BUTTON_PLUS_XPOS - \
288 ED_BUTTON_MINUS_XPOS)) && \
289 (x)<(ED_SIZE_GADGET_XPOS + \
290 (ED_BUTTON_PLUS_XPOS - \
291 ED_BUTTON_MINUS_XPOS) + \
292 ED_BUTTON_PLUS_XSIZE))) && \
293 ((y)>=ED_SIZE_GADGET_YPOS && \
294 (y)<(ED_SIZE_GADGET_YPOS + \
295 2*ED_SIZE_GADGET_YSIZE)) && \
296 (((y)-ED_SIZE_GADGET_YPOS) % \
297 ED_SIZE_GADGET_YSIZE) < \
298 ED_BUTTON_MINUS_YSIZE))
300 #define EDIT_BUTTON(x,y) (((y) < (VY + ED_BUTTON_CTRL_YPOS + \
301 ED_BUTTON_CTRL_YSIZE)) ? 0 : \
302 ((y) < (VY + ED_BUTTON_CTRL_YPOS + \
303 ED_BUTTON_CTRL_YSIZE + \
304 ED_BUTTON_FILL_YSIZE)) ? 1 : \
305 ((x) < (VX + ED_BUTTON_LEFT_XPOS + \
306 ED_BUTTON_LEFT_XSIZE) ? 2 : \
307 (x) > (VX + ED_BUTTON_LEFT_XPOS + \
308 ED_BUTTON_LEFT_XSIZE + \
309 ED_BUTTON_UP_XSIZE) ? 5 : \
310 3+(((y)-(VY + ED_BUTTON_CTRL_YPOS + \
311 ED_BUTTON_CTRL_YSIZE + \
312 ED_BUTTON_FILL_YSIZE)) / \
313 ED_BUTTON_UP_YSIZE)))
315 #define CTRL_BUTTON(x,y) (((y) < (VY + ED_BUTTON_EDIT_YPOS + \
316 ED_BUTTON_EDIT_YSIZE)) ? 0 : \
317 1+(((y)-(VY + ED_BUTTON_EDIT_YPOS + \
318 ED_BUTTON_EDIT_YSIZE)) / \
319 ED_BUTTON_CLEAR_YSIZE))
321 #define ELEM_BUTTON(x,y) (((y) < (DY + ED_BUTTON_EUP_YPOS + \
322 ED_BUTTON_EUP_YSIZE)) ? 0 : \
323 ((y) > (DY + ED_BUTTON_EDOWN_YPOS)) ? 1 : \
324 2+(((y) - (DY + ED_BUTTON_ELEM_YPOS)) / \
325 ED_BUTTON_ELEM_YSIZE)*MAX_ELEM_X + \
326 ((x) - (DX + ED_BUTTON_ELEM_XPOS)) / \
327 ED_BUTTON_ELEM_XSIZE)
329 #define COUNT_BUTTON(x,y) ((x) < ED_SIZE_GADGET_XPOS ? \
330 ((((y) - ED_COUNT_GADGET_YPOS) / \
331 ED_COUNT_GADGET_YSIZE)*2 + \
332 ((x) < (ED_COUNT_GADGET_XPOS + \
333 ED_BUTTON_MINUS_XSIZE) ? 0 : 1)) : \
334 32+((((y) - ED_SIZE_GADGET_YPOS) / \
335 ED_SIZE_GADGET_YSIZE)*2 + \
336 ((x) < (ED_SIZE_GADGET_XPOS + \
337 ED_BUTTON_MINUS_XSIZE) ? 0 : 1)))
339 /****************************************************************/
340 /********** drawing buttons and corresponding displays **********/
341 /****************************************************************/
343 void DrawVideoDisplay(unsigned long state, unsigned long value)
346 int part_label = 0, part_symbol = 1;
347 int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
348 static char *monatsname[12] =
350 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
351 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
353 static int video_pos[10][2][4] =
355 {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
356 VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE },
357 { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
358 VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }},
360 {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
361 VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE },
362 { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
363 VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }},
365 {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
366 VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE },
367 { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
368 VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }},
370 {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
371 VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE },
372 { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
373 VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }},
377 { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
378 VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }},
380 {{ VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS,
381 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
385 {{ VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS,
386 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
390 {{ VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS,
391 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
395 {{ VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS,
396 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
400 {{ VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS,
401 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE },
406 if (state & VIDEO_STATE_PBEND_OFF)
408 int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2;
410 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
411 cx + VIDEO_REC_LABEL_XPOS,
412 cy + VIDEO_REC_LABEL_YPOS,
413 VIDEO_PBEND_LABEL_XSIZE,
414 VIDEO_PBEND_LABEL_YSIZE,
415 VX + VIDEO_REC_LABEL_XPOS,
416 VY + VIDEO_REC_LABEL_YPOS);
423 int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
425 if (i%2) /* i ungerade => STATE_ON / PRESS_OFF */
426 cx = DOOR_GFX_PAGEX4;
428 cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */
430 if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
431 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
432 cx + video_pos[pos][part_label][xpos],
433 cy + video_pos[pos][part_label][ypos],
434 video_pos[pos][part_label][xsize],
435 video_pos[pos][part_label][ysize],
436 VX + video_pos[pos][part_label][xpos],
437 VY + video_pos[pos][part_label][ypos]);
438 if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
439 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
440 cx + video_pos[pos][part_symbol][xpos],
441 cy + video_pos[pos][part_symbol][ypos],
442 video_pos[pos][part_symbol][xsize],
443 video_pos[pos][part_symbol][ysize],
444 VX + video_pos[pos][part_symbol][xpos],
445 VY + video_pos[pos][part_symbol][ypos]);
449 if (state & VIDEO_STATE_FFWD_ON)
451 int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
453 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
454 cx + VIDEO_PLAY_SYMBOL_XPOS,
455 cy + VIDEO_PLAY_SYMBOL_YPOS,
456 VIDEO_PLAY_SYMBOL_XSIZE - 2,
457 VIDEO_PLAY_SYMBOL_YSIZE,
458 VX + VIDEO_PLAY_SYMBOL_XPOS - 9,
459 VY + VIDEO_PLAY_SYMBOL_YPOS);
462 if (state & VIDEO_STATE_PBEND_ON)
464 int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
466 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
467 cx + VIDEO_PBEND_LABEL_XPOS,
468 cy + VIDEO_PBEND_LABEL_YPOS,
469 VIDEO_PBEND_LABEL_XSIZE,
470 VIDEO_PBEND_LABEL_YSIZE,
471 VX + VIDEO_REC_LABEL_XPOS,
472 VY + VIDEO_REC_LABEL_YPOS);
475 if (state & VIDEO_STATE_DATE_ON)
477 int tag = value % 100;
478 int monat = (value/100) % 100;
479 int jahr = (value/10000);
481 DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
482 int2str(tag,2),FS_SMALL,FC_SPECIAL1);
483 DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
484 monatsname[monat],FS_SMALL,FC_SPECIAL1);
485 DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
486 int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
489 if (state & VIDEO_STATE_TIME_ON)
491 int min = value / 60;
492 int sec = value % 60;
494 DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
495 int2str(min,2),FS_SMALL,FC_SPECIAL1);
496 DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
497 int2str(sec,2),FS_SMALL,FC_SPECIAL1);
500 if (state & VIDEO_STATE_DATE)
501 redraw_mask |= REDRAW_VIDEO_1;
502 if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
503 redraw_mask |= REDRAW_VIDEO_2;
504 if (state & VIDEO_PRESS)
505 redraw_mask |= REDRAW_VIDEO_3;
508 void DrawCompleteVideoDisplay()
510 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
511 DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY);
512 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
513 DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS,
514 DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS,
515 VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
516 VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
518 DrawVideoDisplay(VIDEO_ALL_OFF,0);
519 if (tape.date && tape.length)
521 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
522 DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds);
525 XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
526 VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
529 void DrawSoundDisplay(unsigned long state)
531 int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
533 pos = (state & BUTTON_SOUND_MUSIC ? SOUND_BUTTON_MUSIC_XPOS :
534 state & BUTTON_SOUND_LOOPS ? SOUND_BUTTON_LOOPS_XPOS :
535 SOUND_BUTTON_SIMPLE_XPOS);
537 if (state & BUTTON_ON)
538 cy -= SOUND_BUTTON_YSIZE;
540 if (state & BUTTON_PRESSED)
541 cx = DOOR_GFX_PAGEX3;
543 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
544 cx + pos,cy + SOUND_BUTTON_ANY_YPOS,
545 SOUND_BUTTON_XSIZE,SOUND_BUTTON_YSIZE,
546 DX + pos,DY + SOUND_BUTTON_ANY_YPOS);
548 redraw_mask |= REDRAW_DOOR_1;
551 void DrawGameButton(unsigned long state)
553 int pos, cx = DOOR_GFX_PAGEX4, cy = -GAME_BUTTON_YSIZE;
555 pos = (state & BUTTON_GAME_STOP ? GAME_BUTTON_STOP_XPOS :
556 state & BUTTON_GAME_PAUSE ? GAME_BUTTON_PAUSE_XPOS :
557 GAME_BUTTON_PLAY_XPOS);
559 if (state & BUTTON_PRESSED)
560 cx = DOOR_GFX_PAGEX3;
562 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
563 cx + pos,cy + GAME_BUTTON_ANY_YPOS,
564 GAME_BUTTON_XSIZE,GAME_BUTTON_YSIZE,
565 DX + pos,DY + GAME_BUTTON_ANY_YPOS);
567 redraw_mask |= REDRAW_DOOR_1;
570 void DrawYesNoButton(unsigned long state, int mode)
572 Drawable dest_drawto;
573 int dest_xoffset, dest_yoffset;
574 int xpos, cx = DOOR_GFX_PAGEX4;
578 dest_drawto = pix[PIX_DB_DOOR];
579 dest_xoffset = DOOR_GFX_PAGEX1;
584 dest_drawto = drawto;
589 xpos = (state & BUTTON_OK ? OK_BUTTON_XPOS : NO_BUTTON_XPOS);
591 if (state & BUTTON_PRESSED)
592 cx = DOOR_GFX_PAGEX3;
594 XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
595 cx + xpos, OK_BUTTON_GFX_YPOS,
596 OK_BUTTON_XSIZE, OK_BUTTON_YSIZE,
597 dest_xoffset + xpos, dest_yoffset + OK_BUTTON_YPOS);
599 redraw_mask |= REDRAW_DOOR_1;
602 void DrawConfirmButton(unsigned long state, int mode)
604 Drawable dest_drawto;
605 int dest_xoffset, dest_yoffset;
606 int cx = DOOR_GFX_PAGEX4;
610 dest_drawto = pix[PIX_DB_DOOR];
611 dest_xoffset = DOOR_GFX_PAGEX1;
616 dest_drawto = drawto;
621 if (state & BUTTON_PRESSED)
622 cx = DOOR_GFX_PAGEX3;
624 XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
625 cx + CONFIRM_BUTTON_XPOS, CONFIRM_BUTTON_GFX_YPOS,
626 CONFIRM_BUTTON_XSIZE, CONFIRM_BUTTON_YSIZE,
627 dest_xoffset + CONFIRM_BUTTON_XPOS,
628 dest_yoffset + CONFIRM_BUTTON_YPOS);
630 redraw_mask |= REDRAW_DOOR_1;
633 void DrawPlayerButton(unsigned long state, int mode)
635 Drawable dest_drawto;
636 int dest_xoffset, dest_yoffset;
637 int graphic = GFX_SPIELER1; /* default */
638 int graphic_offset = (PLAYER_BUTTON_XSIZE - TILEX/2)/2;
640 int cx = DOOR_GFX_PAGEX4, cy = 0;
644 dest_drawto = pix[PIX_DB_DOOR];
645 dest_xoffset = DOOR_GFX_PAGEX1;
650 dest_drawto = drawto;
655 if (state & BUTTON_PLAYER_1)
656 graphic = GFX_SPIELER1;
657 else if (state & BUTTON_PLAYER_2)
658 graphic = GFX_SPIELER2;
659 else if (state & BUTTON_PLAYER_3)
660 graphic = GFX_SPIELER3;
661 else if (state & BUTTON_PLAYER_4)
662 graphic = GFX_SPIELER4;
664 xpos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_3 ?
665 PLAYER_BUTTON_1_XPOS : PLAYER_BUTTON_2_XPOS);
666 ypos = (state & BUTTON_PLAYER_1 || state & BUTTON_PLAYER_2 ?
667 PLAYER_BUTTON_1_YPOS : PLAYER_BUTTON_3_YPOS);
669 if (state & BUTTON_PRESSED)
671 cx = DOOR_GFX_PAGEX3;
675 XCopyArea(display, pix[PIX_DOOR], dest_drawto, gc,
676 cx + PLAYER_BUTTON_GFX_XPOS, cy + PLAYER_BUTTON_GFX_YPOS,
677 PLAYER_BUTTON_XSIZE, PLAYER_BUTTON_YSIZE,
678 dest_xoffset + xpos, dest_yoffset + ypos);
679 DrawMiniGraphicExt(dest_drawto,gc,
680 dest_xoffset + xpos + graphic_offset,
681 dest_yoffset + ypos + graphic_offset,
684 redraw_mask |= REDRAW_DOOR_1;
687 /* several buttons in the level editor */
689 void DrawEditButton(unsigned long state)
692 int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
693 int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY2;
694 static int edit_pos[6][4] =
696 {ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS,
697 ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE},
699 {ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS,
700 ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE},
702 {ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS,
703 ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE},
705 {ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS,
706 ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE},
708 {ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS,
709 ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE},
711 {ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS,
712 ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE}
715 if (state & ED_BUTTON_PRESSED)
716 cx = DOOR_GFX_PAGEX5;
721 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
722 cx + edit_pos[i][xpos],
723 cy + edit_pos[i][ypos],
726 VX + edit_pos[i][xpos],
727 VY + edit_pos[i][ypos]);
730 redraw_mask |= REDRAW_DOOR_2;
733 void DrawCtrlButton(unsigned long state)
736 int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
737 int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY1+80;
738 static int edit_pos[4][4] =
740 {ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS,
741 ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE},
743 {ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS,
744 ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE},
746 {ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS,
747 ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE},
749 {ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS,
750 ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE}
753 if (state & ED_BUTTON_PRESSED)
754 cx = DOOR_GFX_PAGEX3;
758 if (state & (1<<(i+6)))
759 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
760 cx + edit_pos[i][xpos],
761 cy + edit_pos[i][ypos],
764 VX + edit_pos[i][xpos],
765 VY + edit_pos[i][ypos]);
768 redraw_mask |= REDRAW_DOOR_2;
771 void DrawElemButton(int button_nr, int button_state)
773 int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
774 int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
775 int from_x, from_y, to_x,to_y, size_x, size_y;
776 static int edit_pos[3][4] =
778 {ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS,
779 ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE},
781 {ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS,
782 ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE},
784 {ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS,
785 ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE}
788 if (button_nr<ED_BUTTON_ELEM)
792 from_x = cx + edit_pos[pos][xpos];
793 from_y = cy + edit_pos[pos][ypos];
794 size_x = edit_pos[pos][xsize];
795 size_y = edit_pos[pos][ysize];
796 to_x = DX + edit_pos[pos][xpos];
797 to_y = DY + edit_pos[pos][ypos];
799 if (button_state & ED_BUTTON_PRESSED)
801 if (button_nr==ED_BUTTON_EUP)
802 from_y = cy + ED_BUTTON_EUP_Y2POS;
804 from_y = cy + ED_BUTTON_EDOWN_Y2POS;
807 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
808 from_x,from_y, size_x,size_y, to_x,to_y);
812 int pos = ED_BUTTON_ELEM;
813 int elem_pos = button_nr-ED_BUTTON_ELEM;
814 int x = elem_pos % MAX_ELEM_X;
815 int y = elem_pos / MAX_ELEM_X;
819 if (elem_pos+element_shift < elements_in_list)
820 graphic = el2gfx(editor_element[elem_pos+element_shift]);
822 graphic = GFX_LEERRAUM;
824 from_x = cx + edit_pos[pos][xpos];
825 from_y = cy + edit_pos[pos][ypos];
826 size_x = edit_pos[pos][xsize];
827 size_y = edit_pos[pos][ysize];
828 to_x = DX + edit_pos[pos][xpos] + x * ED_BUTTON_ELEM_XSIZE;
829 to_y = DY + edit_pos[pos][ypos] + y * ED_BUTTON_ELEM_YSIZE;
831 if (button_state & ED_BUTTON_PRESSED)
833 from_y = ED_BUTTON_ELEM_Y2POS;
837 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
838 from_x,from_y, size_x,size_y, to_x,to_y);
840 DrawMiniGraphicExt(drawto,gc,
841 DX+ED_BUTTON_ELEM_XPOS+3+shift +
842 (elem_pos % MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
843 DY+ED_BUTTON_ELEM_YPOS+3+shift +
844 (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
848 redraw_mask |= REDRAW_DOOR_1;
851 void DrawCountButton(int button_nr, int button_state)
853 int from_x, from_y, to_x,to_y, size_x, size_y;
856 DOOR_GFX_PAGEX4+(button_nr%2 ? ED_BUTTON_PLUS_XPOS : ED_BUTTON_MINUS_XPOS);
857 from_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
858 size_x = ED_BUTTON_MINUS_XSIZE;
859 size_y = ED_BUTTON_MINUS_YSIZE;
860 to_x = (button_nr<32 ? ED_COUNT_GADGET_XPOS : ED_SIZE_GADGET_XPOS);
862 to_x += (ED_BUTTON_PLUS_XPOS - ED_BUTTON_MINUS_XPOS);
863 to_y = (button_nr<32 ? ED_COUNT_GADGET_YPOS : ED_SIZE_GADGET_YPOS) +
864 ((button_nr<32 ? button_nr : button_nr-32)/2)*ED_COUNT_GADGET_YSIZE;
866 if (button_state & ED_BUTTON_PRESSED)
869 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
870 from_x,from_y, size_x,size_y, to_x,to_y);
871 XCopyArea(display,pix[PIX_DOOR],window,gc,
872 from_x,from_y, size_x,size_y, to_x,to_y);
875 /**********************************************************************/
876 /********** checking buttons (and redrawing them, if needed) **********/
877 /**********************************************************************/
879 int CheckVideoButtons(int mx, int my, int button)
882 static int choice = -1;
883 static boolean pressed = FALSE;
884 static int video_button[5] =
886 VIDEO_PRESS_EJECT_ON,
888 VIDEO_PRESS_PAUSE_ON,
895 if (!motion_status) /* Maustaste neu gedrückt */
897 if (ON_VIDEO_BUTTON(mx,my))
899 choice = VIDEO_BUTTON(mx);
901 DrawVideoDisplay(video_button[choice],0);
904 else /* Mausbewegung bei gedrückter Maustaste */
906 if ((!ON_VIDEO_BUTTON(mx,my) || VIDEO_BUTTON(mx)!=choice) &&
907 choice>=0 && pressed)
910 DrawVideoDisplay(video_button[choice]<<1,0);
912 else if (ON_VIDEO_BUTTON(mx,my) && VIDEO_BUTTON(mx)==choice && !pressed)
915 DrawVideoDisplay(video_button[choice],0);
919 else /* Maustaste wieder losgelassen */
921 if (ON_VIDEO_BUTTON(mx,my) && VIDEO_BUTTON(mx)==choice && pressed)
923 DrawVideoDisplay(video_button[choice]<<1,0);
924 return_code = choice+1;
939 int CheckSoundButtons(int mx, int my, int button)
942 static int choice = -1;
943 static boolean pressed = FALSE;
946 sound_state[0] = BUTTON_SOUND_MUSIC | (BUTTON_ON * setup.sound_music);
947 sound_state[1] = BUTTON_SOUND_LOOPS | (BUTTON_ON * setup.sound_loops);
948 sound_state[2] = BUTTON_SOUND_SIMPLE | (BUTTON_ON * setup.sound_simple);
952 if (!motion_status) /* Maustaste neu gedrückt */
954 if (ON_SOUND_BUTTON(mx,my))
956 choice = SOUND_BUTTON(mx);
958 DrawSoundDisplay(sound_state[choice] | BUTTON_PRESSED);
961 else /* Mausbewegung bei gedrückter Maustaste */
963 if ((!ON_SOUND_BUTTON(mx,my) || SOUND_BUTTON(mx)!=choice) &&
964 choice>=0 && pressed)
967 DrawSoundDisplay(sound_state[choice] | BUTTON_RELEASED);
969 else if (ON_SOUND_BUTTON(mx,my) && SOUND_BUTTON(mx)==choice && !pressed)
972 DrawSoundDisplay(sound_state[choice] | BUTTON_PRESSED);
976 else /* Maustaste wieder losgelassen */
978 if (ON_SOUND_BUTTON(mx,my) && SOUND_BUTTON(mx)==choice && pressed)
980 DrawSoundDisplay(sound_state[choice] | BUTTON_RELEASED);
981 return_code = 1<<choice;
996 int CheckGameButtons(int mx, int my, int button)
999 static int choice = -1;
1000 static boolean pressed = FALSE;
1010 if (!motion_status) /* Maustaste neu gedrückt */
1012 if (ON_GAME_BUTTON(mx,my))
1014 choice = GAME_BUTTON(mx);
1016 DrawGameButton(game_state[choice] | BUTTON_PRESSED);
1019 else /* Mausbewegung bei gedrückter Maustaste */
1021 if ((!ON_GAME_BUTTON(mx,my) || GAME_BUTTON(mx)!=choice) &&
1022 choice>=0 && pressed)
1025 DrawGameButton(game_state[choice] | BUTTON_RELEASED);
1027 else if (ON_GAME_BUTTON(mx,my) && GAME_BUTTON(mx)==choice && !pressed)
1030 DrawGameButton(game_state[choice] | BUTTON_PRESSED);
1034 else /* Maustaste wieder losgelassen */
1036 if (ON_GAME_BUTTON(mx,my) && GAME_BUTTON(mx)==choice && pressed)
1038 DrawGameButton(game_state[choice] | BUTTON_RELEASED);
1039 return_code = 1<<choice;
1051 return(return_code);
1054 int CheckYesNoButtons(int mx, int my, int button)
1056 int return_code = 0;
1057 static int choice = -1;
1058 static boolean pressed = FALSE;
1059 static int yesno_button[5] =
1067 if (!motion_status) /* Maustaste neu gedrückt */
1069 if (ON_YESNO_BUTTON(mx,my))
1071 choice = YESNO_BUTTON(mx);
1073 DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED, DB_NORMAL);
1076 else /* Mausbewegung bei gedrückter Maustaste */
1078 if ((!ON_YESNO_BUTTON(mx,my) || YESNO_BUTTON(mx)!=choice) &&
1079 choice>=0 && pressed)
1082 DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED, DB_NORMAL);
1084 else if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && !pressed)
1087 DrawYesNoButton(yesno_button[choice] | BUTTON_PRESSED, DB_NORMAL);
1091 else /* Maustaste wieder losgelassen */
1093 if (ON_YESNO_BUTTON(mx,my) && YESNO_BUTTON(mx)==choice && pressed)
1095 DrawYesNoButton(yesno_button[choice] | BUTTON_RELEASED, DB_NORMAL);
1096 return_code = choice+1;
1108 return(return_code);
1111 int CheckConfirmButton(int mx, int my, int button)
1113 int return_code = 0;
1114 static int choice = -1;
1115 static boolean pressed = FALSE;
1119 if (!motion_status) /* Maustaste neu gedrückt */
1121 if (ON_CONFIRM_BUTTON(mx,my))
1125 DrawConfirmButton(BUTTON_PRESSED, DB_NORMAL);
1128 else /* Mausbewegung bei gedrückter Maustaste */
1130 if (!ON_CONFIRM_BUTTON(mx,my) && choice>=0 && pressed)
1133 DrawConfirmButton(BUTTON_RELEASED, DB_NORMAL);
1135 else if (ON_CONFIRM_BUTTON(mx,my) && !pressed)
1138 DrawConfirmButton(BUTTON_PRESSED, DB_NORMAL);
1142 else /* Maustaste wieder losgelassen */
1144 if (ON_CONFIRM_BUTTON(mx,my) && pressed)
1146 DrawConfirmButton(BUTTON_RELEASED, DB_NORMAL);
1147 return_code = BUTTON_CONFIRM;
1159 return(return_code);
1162 int CheckPlayerButtons(int mx, int my, int button)
1164 int return_code = 0;
1165 static int choice = -1;
1166 static boolean pressed = FALSE;
1167 int player_state[4] =
1177 if (!motion_status) /* Maustaste neu gedrückt */
1179 if (ON_PLAYER_BUTTON(mx,my))
1181 choice = PLAYER_BUTTON(mx,my);
1183 DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL);
1186 else /* Mausbewegung bei gedrückter Maustaste */
1188 if ((!ON_PLAYER_BUTTON(mx,my) || PLAYER_BUTTON(mx,my)!=choice) &&
1189 choice>=0 && pressed)
1192 DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL);
1194 else if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && !pressed)
1197 DrawPlayerButton(player_state[choice] | BUTTON_PRESSED, DB_NORMAL);
1201 else /* Maustaste wieder losgelassen */
1203 if (ON_PLAYER_BUTTON(mx,my) && PLAYER_BUTTON(mx,my)==choice && pressed)
1205 DrawPlayerButton(player_state[choice] | BUTTON_RELEASED, DB_NORMAL);
1206 return_code = player_state[choice];
1218 return(return_code);
1221 /* several buttons in the level editor */
1223 int CheckEditButtons(int mx, int my, int button)
1225 int return_code = 0;
1226 static int choice = -1;
1227 static boolean pressed = FALSE;
1228 static int edit_button[6] =
1240 if (!motion_status) /* Maustaste neu gedrückt */
1242 if (ON_EDIT_BUTTON(mx,my))
1244 choice = EDIT_BUTTON(mx,my);
1246 DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
1247 if (edit_button[choice]!=ED_BUTTON_CTRL &&
1248 edit_button[choice]!=ED_BUTTON_FILL)
1249 return_code = 1<<choice;
1252 else /* Mausbewegung bei gedrückter Maustaste */
1254 if ((!ON_EDIT_BUTTON(mx,my) || EDIT_BUTTON(mx,my)!=choice) &&
1255 choice>=0 && pressed)
1258 DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
1260 else if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice)
1263 DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
1265 if (edit_button[choice]!=ED_BUTTON_CTRL &&
1266 edit_button[choice]!=ED_BUTTON_FILL)
1267 return_code = 1<<choice;
1271 else /* Maustaste wieder losgelassen */
1273 if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice && pressed)
1275 DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
1276 if (edit_button[choice]==ED_BUTTON_CTRL ||
1277 edit_button[choice]==ED_BUTTON_FILL)
1278 return_code = 1<<choice;
1290 return(return_code);
1293 int CheckCtrlButtons(int mx, int my, int button)
1295 int return_code = 0;
1296 static int choice = -1;
1297 static boolean pressed = FALSE;
1298 static int ctrl_button[4] =
1308 if (!motion_status) /* Maustaste neu gedrückt */
1310 if (ON_CTRL_BUTTON(mx,my))
1312 choice = CTRL_BUTTON(mx,my);
1314 DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
1317 else /* Mausbewegung bei gedrückter Maustaste */
1319 if ((!ON_CTRL_BUTTON(mx,my) || CTRL_BUTTON(mx,my)!=choice) &&
1320 choice>=0 && pressed)
1323 DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
1325 else if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && !pressed)
1328 DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
1332 else /* Maustaste wieder losgelassen */
1334 if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && pressed)
1336 DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
1337 return_code = 1<<(choice+6);
1349 return(return_code);
1352 int CheckElemButtons(int mx, int my, int button)
1354 int return_code = -1;
1355 static int choice = -1;
1356 static boolean pressed = FALSE;
1360 if (!motion_status) /* Maustaste neu gedrückt */
1362 if (ON_ELEM_BUTTON(mx,my))
1364 choice = ELEM_BUTTON(mx,my);
1366 DrawElemButton(choice,ED_BUTTON_PRESSED);
1367 if (choice==ED_BUTTON_EUP ||
1368 choice==ED_BUTTON_EDOWN)
1369 return_code = choice;
1372 else /* Mausbewegung bei gedrückter Maustaste */
1374 if ((!ON_ELEM_BUTTON(mx,my) || ELEM_BUTTON(mx,my)!=choice) &&
1375 choice>=0 && pressed)
1378 DrawElemButton(choice,ED_BUTTON_RELEASED);
1380 else if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice)
1383 DrawElemButton(choice,ED_BUTTON_PRESSED);
1385 if (choice==ED_BUTTON_EUP ||
1386 choice==ED_BUTTON_EDOWN)
1387 return_code = choice;
1391 else /* Maustaste wieder losgelassen */
1393 if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice && pressed)
1395 DrawElemButton(choice,ED_BUTTON_RELEASED);
1396 if (choice!=ED_BUTTON_EUP &&
1397 choice!=ED_BUTTON_EDOWN)
1398 return_code = choice;
1410 return(return_code);
1413 int CheckCountButtons(int mx, int my, int button)
1415 int return_code = -1;
1416 static int choice = -1;
1417 static boolean pressed = FALSE;
1421 if (!motion_status) /* Maustaste neu gedrückt */
1423 if (ON_COUNT_BUTTON(mx,my))
1425 choice = COUNT_BUTTON(mx,my);
1427 DrawCountButton(choice,ED_BUTTON_PRESSED);
1428 return_code = choice;
1431 else /* Mausbewegung bei gedrückter Maustaste */
1433 if ((!ON_COUNT_BUTTON(mx,my) || COUNT_BUTTON(mx,my)!=choice) &&
1434 choice>=0 && pressed)
1437 DrawCountButton(choice,ED_BUTTON_RELEASED);
1439 else if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice)
1442 DrawCountButton(choice,ED_BUTTON_PRESSED);
1444 return_code = choice;
1448 else /* Maustaste wieder losgelassen */
1450 if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice && pressed)
1452 DrawCountButton(choice,ED_BUTTON_RELEASED);
1464 return(return_code);
1468 /* NEW GADGET STUFF -------------------------------------------------------- */
1471 static struct GadgetInfo *gadget_list_first_entry = NULL;
1472 static struct GadgetInfo *gadget_list_last_entry = NULL;
1473 static int next_free_gadget_id = 1;
1474 static boolean gadget_id_wrapped = FALSE;
1476 static struct GadgetInfo *getGadgetInfoFromGadgetID(int id)
1478 struct GadgetInfo *gi = gadget_list_first_entry;
1480 while (gi && gi->id != id)
1486 static int getNewGadgetID()
1488 int id = next_free_gadget_id++;
1490 if (next_free_gadget_id <= 0) /* counter overrun */
1492 gadget_id_wrapped = TRUE; /* now we must check each ID */
1493 next_free_gadget_id = 0;
1496 if (gadget_id_wrapped)
1498 next_free_gadget_id++;
1499 while (getGadgetInfoFromGadgetID(next_free_gadget_id) != NULL)
1500 next_free_gadget_id++;
1503 if (next_free_gadget_id <= 0) /* cannot get new gadget id */
1504 Error(ERR_EXIT, "too much gadgets -- this should not happen");
1509 static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
1511 struct GadgetInfo *gi = gadget_list_first_entry;
1516 mx >= gi->x && mx < gi->x + gi->width &&
1517 my >= gi->y && my < gi->y + gi->height)
1521 if (gi->type & GD_TYPE_SCROLLBAR)
1525 if (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL)
1536 if (mpos >= gpos + gi->scrollbar.position &&
1537 mpos < gpos + gi->scrollbar.position + gi->scrollbar.size)
1552 static void default_callback_info(void *ptr)
1554 if (game_status == LEVELED)
1555 HandleEditorGadgetInfoText(ptr);
1558 static void default_callback_action(void *ptr)
1563 struct GadgetInfo *CreateGadget(int first_tag, ...)
1565 struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo));
1566 int tag = first_tag;
1569 va_start(ap, first_tag);
1571 /* always start with reliable default values */
1572 memset(new_gadget, 0, sizeof(struct GadgetInfo)); /* zero all fields */
1573 new_gadget->id = getNewGadgetID();
1574 new_gadget->callback_info = default_callback_info;
1575 new_gadget->callback_action = default_callback_action;
1577 while (tag != GDI_END)
1582 new_gadget->custom_id = va_arg(ap, int);
1587 int max_textsize = MAX_INFO_TEXTSIZE;
1589 strncpy(new_gadget->info_text, va_arg(ap, char *), max_textsize);
1590 new_gadget->info_text[max_textsize] = '\0';
1595 new_gadget->x = va_arg(ap, int);
1599 new_gadget->y = va_arg(ap, int);
1603 new_gadget->width = va_arg(ap, int);
1607 new_gadget->height = va_arg(ap, int);
1611 new_gadget->type = va_arg(ap, unsigned long);
1615 new_gadget->state = va_arg(ap, unsigned long);
1619 new_gadget->radio_nr = va_arg(ap, unsigned long);
1622 case GDI_RADIO_PRESSED:
1623 new_gadget->radio_pressed = va_arg(ap, boolean);
1626 case GDI_NUMBER_VALUE:
1627 new_gadget->text.number_value = va_arg(ap, long);
1628 sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value);
1629 new_gadget->text.cursor_position = strlen(new_gadget->text.value);
1632 case GDI_NUMBER_MIN:
1633 new_gadget->text.number_min = va_arg(ap, long);
1634 if (new_gadget->text.number_value < new_gadget->text.number_min)
1636 new_gadget->text.number_value = new_gadget->text.number_min;
1637 sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value);
1641 case GDI_NUMBER_MAX:
1642 new_gadget->text.number_max = va_arg(ap, long);
1643 if (new_gadget->text.number_value > new_gadget->text.number_max)
1645 new_gadget->text.number_value = new_gadget->text.number_max;
1646 sprintf(new_gadget->text.value, "%d", new_gadget->text.number_value);
1650 case GDI_TEXT_VALUE:
1652 int max_textsize = MAX_GADGET_TEXTSIZE;
1654 if (new_gadget->text.size)
1655 max_textsize = MIN(new_gadget->text.size, MAX_GADGET_TEXTSIZE - 1);
1657 strncpy(new_gadget->text.value, va_arg(ap, char *), max_textsize);
1658 new_gadget->text.value[max_textsize] = '\0';
1659 new_gadget->text.cursor_position = strlen(new_gadget->text.value);
1665 int tag_value = va_arg(ap, int);
1666 int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1);
1668 new_gadget->text.size = max_textsize;
1669 new_gadget->text.value[max_textsize] = '\0';
1671 if (new_gadget->width == 0 && new_gadget->height == 0)
1673 new_gadget->width = (new_gadget->text.size + 1) * FONT2_XSIZE + 6;
1674 new_gadget->height = ED_WIN_COUNT_YSIZE;
1679 case GDI_DESIGN_UNPRESSED:
1680 new_gadget->design[GD_BUTTON_UNPRESSED].pixmap = va_arg(ap, Pixmap);
1681 new_gadget->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int);
1682 new_gadget->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int);
1685 case GDI_DESIGN_PRESSED:
1686 new_gadget->design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap);
1687 new_gadget->design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
1688 new_gadget->design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
1691 case GDI_ALT_DESIGN_UNPRESSED:
1692 new_gadget->alt_design[GD_BUTTON_UNPRESSED].pixmap= va_arg(ap, Pixmap);
1693 new_gadget->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int);
1694 new_gadget->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int);
1697 case GDI_ALT_DESIGN_PRESSED:
1698 new_gadget->alt_design[GD_BUTTON_PRESSED].pixmap = va_arg(ap, Pixmap);
1699 new_gadget->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
1700 new_gadget->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
1703 case GDI_DESIGN_BORDER:
1704 new_gadget->design_border = va_arg(ap, int);
1707 case GDI_EVENT_MASK:
1708 new_gadget->event_mask = va_arg(ap, unsigned long);
1712 new_gadget->drawing.area_xsize = va_arg(ap, int);
1713 new_gadget->drawing.area_ysize = va_arg(ap, int);
1715 /* determine dependent values for drawing area gadget, if needed */
1716 if (new_gadget->width == 0 &&
1717 new_gadget->height == 0 &&
1718 new_gadget->drawing.item_xsize !=0 &&
1719 new_gadget->drawing.item_ysize !=0)
1722 new_gadget->drawing.area_xsize * new_gadget->drawing.item_xsize;
1723 new_gadget->height =
1724 new_gadget->drawing.area_ysize * new_gadget->drawing.item_ysize;
1726 else if (new_gadget->drawing.item_xsize == 0 &&
1727 new_gadget->drawing.item_ysize == 0 &&
1728 new_gadget->width != 0 &&
1729 new_gadget->height != 0)
1731 new_gadget->drawing.item_xsize =
1732 new_gadget->width / new_gadget->drawing.area_xsize;
1733 new_gadget->drawing.item_ysize =
1734 new_gadget->height / new_gadget->drawing.area_ysize;
1739 new_gadget->drawing.item_xsize = va_arg(ap, int);
1740 new_gadget->drawing.item_ysize = va_arg(ap, int);
1742 /* determine dependent values for drawing area gadget, if needed */
1743 if (new_gadget->width == 0 &&
1744 new_gadget->height == 0 &&
1745 new_gadget->drawing.area_xsize !=0 &&
1746 new_gadget->drawing.area_ysize !=0)
1749 new_gadget->drawing.area_xsize * new_gadget->drawing.item_xsize;
1750 new_gadget->height =
1751 new_gadget->drawing.area_ysize * new_gadget->drawing.item_ysize;
1753 else if (new_gadget->drawing.area_xsize == 0 &&
1754 new_gadget->drawing.area_ysize == 0 &&
1755 new_gadget->width != 0 &&
1756 new_gadget->height != 0)
1758 new_gadget->drawing.area_xsize =
1759 new_gadget->width / new_gadget->drawing.item_xsize;
1760 new_gadget->drawing.area_ysize =
1761 new_gadget->height / new_gadget->drawing.item_ysize;
1765 case GDI_SCROLLBAR_ITEMS_MAX:
1766 new_gadget->scrollbar.items_max = va_arg(ap, int);
1769 case GDI_SCROLLBAR_ITEMS_VISIBLE:
1770 new_gadget->scrollbar.items_visible = va_arg(ap, int);
1773 case GDI_SCROLLBAR_ITEM_POSITION:
1774 new_gadget->scrollbar.item_position = va_arg(ap, int);
1777 case GDI_CALLBACK_INFO:
1778 new_gadget->callback_info = va_arg(ap, gadget_function);
1781 case GDI_CALLBACK_ACTION:
1782 new_gadget->callback_action = va_arg(ap, gadget_function);
1786 Error(ERR_EXIT, "CreateGadget(): unknown tag %d", tag);
1789 tag = va_arg(ap, int); /* read next tag */
1794 /* check if gadget complete */
1795 if (new_gadget->type != GD_TYPE_DRAWING_AREA &&
1796 (!new_gadget->design[GD_BUTTON_UNPRESSED].pixmap ||
1797 !new_gadget->design[GD_BUTTON_PRESSED].pixmap))
1798 Error(ERR_EXIT, "gadget incomplete (missing Pixmap)");
1800 if (new_gadget->type & GD_TYPE_SCROLLBAR)
1802 struct GadgetScrollbar *gs = &new_gadget->scrollbar;
1804 if (new_gadget->width == 0 || new_gadget->height == 0 ||
1805 gs->items_max == 0 || gs->items_visible == 0)
1806 Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)");
1808 /* calculate internal scrollbar values */
1809 gs->size_max = (new_gadget->type == GD_TYPE_SCROLLBAR_VERTICAL ?
1810 new_gadget->height : new_gadget->width);
1811 gs->size = gs->size_max * gs->items_visible / gs->items_max;
1812 gs->position = gs->size_max * gs->item_position / gs->items_max;
1813 gs->position_max = gs->size_max - gs->size;
1816 /* insert new gadget into global gadget list */
1817 if (gadget_list_last_entry)
1819 gadget_list_last_entry->next = new_gadget;
1820 gadget_list_last_entry = gadget_list_last_entry->next;
1823 gadget_list_first_entry = gadget_list_last_entry = new_gadget;
1828 void FreeGadget(struct GadgetInfo *gi)
1830 struct GadgetInfo *gi_previous = gadget_list_first_entry;
1832 while (gi_previous && gi_previous->next != gi)
1833 gi_previous = gi_previous->next;
1835 if (gi == gadget_list_first_entry)
1836 gadget_list_first_entry = gi->next;
1838 if (gi == gadget_list_last_entry)
1839 gadget_list_last_entry = gi_previous;
1841 gi_previous->next = gi->next;
1845 /* values for DrawGadget() */
1846 #define DG_UNPRESSED 0
1847 #define DG_PRESSED 1
1848 #define DG_BUFFERED 0
1851 static void CheckRangeOfNumericInputGadget(struct GadgetInfo *gi)
1853 if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC)
1856 gi->text.number_value = atoi(gi->text.value);
1858 if (gi->text.number_value < gi->text.number_min)
1859 gi->text.number_value = gi->text.number_min;
1860 if (gi->text.number_value > gi->text.number_max)
1861 gi->text.number_value = gi->text.number_max;
1863 sprintf(gi->text.value, "%d", gi->text.number_value);
1865 if (gi->text.cursor_position < 0)
1866 gi->text.cursor_position = 0;
1867 else if (gi->text.cursor_position > strlen(gi->text.value))
1868 gi->text.cursor_position = strlen(gi->text.value);
1871 static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
1873 int state = (pressed ? 1 : 0);
1874 struct GadgetDesign *gd = (gi->radio_pressed ?
1875 &gi->alt_design[state] :
1876 &gi->design[state]);
1880 case GD_TYPE_NORMAL_BUTTON:
1881 case GD_TYPE_RADIO_BUTTON:
1882 XCopyArea(display, gd->pixmap, drawto, gc,
1883 gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
1886 case GD_TYPE_TEXTINPUT_ALPHANUMERIC:
1887 case GD_TYPE_TEXTINPUT_NUMERIC:
1891 char cursor_string[3];
1892 char text[MAX_GADGET_TEXTSIZE + 1];
1893 int font_color = FC_YELLOW;
1894 int border = gi->design_border;
1895 strcpy(text, gi->text.value);
1898 /* left part of gadget */
1899 XCopyArea(display, gd->pixmap, drawto, gc,
1900 gd->x, gd->y, border, gi->height, gi->x, gi->y);
1902 /* middle part of gadget */
1903 for (i=0; i<=gi->text.size; i++)
1904 XCopyArea(display, gd->pixmap, drawto, gc,
1905 gd->x + border, gd->y, FONT2_XSIZE, gi->height,
1906 gi->x + border + i * FONT2_XSIZE, gi->y);
1908 /* right part of gadget */
1909 XCopyArea(display, gd->pixmap, drawto, gc,
1910 gd->x + ED_WIN_COUNT_XSIZE - border, gd->y,
1911 border, gi->height, gi->x + gi->width - border, gi->y);
1913 /* gadget text value */
1914 DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_color);
1916 cursor_letter = gi->text.value[gi->text.cursor_position];
1917 cursor_string[0] = '~';
1918 cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' ');
1919 cursor_string[2] = '\0';
1921 /* draw cursor, if active */
1923 DrawText(gi->x + border + gi->text.cursor_position * FONT2_XSIZE,
1924 gi->y + border, cursor_string, FS_SMALL, font_color);
1928 case GD_TYPE_SCROLLBAR_VERTICAL:
1932 int ypos = gi->y + gi->scrollbar.position;
1933 int design_full = gi->width;
1934 int design_body = design_full - 2 * gi->design_border;
1935 int size_full = gi->scrollbar.size;
1936 int size_body = size_full - 2 * gi->design_border;
1937 int num_steps = size_body / design_body;
1938 int step_size_remain = size_body - num_steps * design_body;
1940 /* clear scrollbar area */
1941 XFillRectangle(display, backbuffer, gc,
1942 gi->x, gi->y, gi->width, gi->height);
1944 /* upper part of gadget */
1945 XCopyArea(display, gd->pixmap, drawto, gc,
1947 gi->width, gi->design_border,
1950 /* middle part of gadget */
1951 for (i=0; i<num_steps; i++)
1952 XCopyArea(display, gd->pixmap, drawto, gc,
1953 gd->x, gd->y + gi->design_border,
1954 gi->width, design_body,
1955 xpos, ypos + gi->design_border + i * design_body);
1957 /* remaining middle part of gadget */
1958 if (step_size_remain > 0)
1959 XCopyArea(display, gd->pixmap, drawto, gc,
1960 gd->x, gd->y + gi->design_border,
1961 gi->width, step_size_remain,
1962 xpos, ypos + gi->design_border + num_steps * design_body);
1964 /* lower part of gadget */
1965 XCopyArea(display, gd->pixmap, drawto, gc,
1966 gd->x, gd->y + design_full - gi->design_border,
1967 gi->width, gi->design_border,
1968 xpos, ypos + size_full - gi->design_border);
1972 case GD_TYPE_SCROLLBAR_HORIZONTAL:
1975 int xpos = gi->x + gi->scrollbar.position;
1977 int design_full = gi->height;
1978 int design_body = design_full - 2 * gi->design_border;
1979 int size_full = gi->scrollbar.size;
1980 int size_body = size_full - 2 * gi->design_border;
1981 int num_steps = size_body / design_body;
1982 int step_size_remain = size_body - num_steps * design_body;
1984 /* clear scrollbar area */
1985 XFillRectangle(display, backbuffer, gc,
1986 gi->x, gi->y, gi->width, gi->height);
1988 /* left part of gadget */
1989 XCopyArea(display, gd->pixmap, drawto, gc,
1991 gi->design_border, gi->height,
1994 /* middle part of gadget */
1995 for (i=0; i<num_steps; i++)
1996 XCopyArea(display, gd->pixmap, drawto, gc,
1997 gd->x + gi->design_border, gd->y,
1998 design_body, gi->height,
1999 xpos + gi->design_border + i * design_body, ypos);
2001 /* remaining middle part of gadget */
2002 if (step_size_remain > 0)
2003 XCopyArea(display, gd->pixmap, drawto, gc,
2004 gd->x + gi->design_border, gd->y,
2005 step_size_remain, gi->height,
2006 xpos + gi->design_border + num_steps * design_body, ypos);
2008 /* right part of gadget */
2009 XCopyArea(display, gd->pixmap, drawto, gc,
2010 gd->x + design_full - gi->design_border, gd->y,
2011 gi->design_border, gi->height,
2012 xpos + size_full - gi->design_border, ypos);
2021 XCopyArea(display, drawto, window, gc,
2022 gi->x, gi->y, gi->width, gi->height, gi->x, gi->y);
2024 redraw_mask |= REDRAW_ALL;
2027 void ClickOnGadget(struct GadgetInfo *gi)
2029 /* simulate releasing mouse button over last gadget, if still pressed */
2031 HandleGadgets(-1, -1, 0);
2033 /* simulate pressing mouse button over specified gadget */
2034 HandleGadgets(gi->x, gi->y, 1);
2036 /* simulate releasing mouse button over specified gadget */
2037 HandleGadgets(gi->x, gi->y, 0);
2040 void AdjustScrollbar(struct GadgetInfo *gi, int items_max, int item_pos)
2042 struct GadgetScrollbar *gs = &gi->scrollbar;
2044 gs->items_max = items_max;
2045 gs->item_position = item_pos;
2047 gs->size = gs->size_max * gs->items_visible / gs->items_max;
2048 gs->position = gs->size_max * gs->item_position / gs->items_max;
2049 gs->position_max = gs->size_max - gs->size;
2051 /* finetuning for maximal right/bottom position */
2052 if (gs->item_position == gs->items_max - gs->items_visible)
2053 gs->position = gs->position_max;
2056 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2059 void ModifyTextInputTextValue(struct GadgetInfo *gi, char *new_text)
2061 struct GadgetTextInput *text = &gi->text;
2062 int max_textsize = MAX_GADGET_TEXTSIZE;
2065 max_textsize = MIN(text->size, MAX_GADGET_TEXTSIZE - 1);
2067 strncpy(text->value, new_text, max_textsize);
2068 text->value[max_textsize] = '\0';
2069 text->cursor_position = strlen(text->value);
2072 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2075 void ModifyTextInputNumberValue(struct GadgetInfo *gi, int new_value)
2077 struct GadgetTextInput *text = &gi->text;
2079 text->number_value = (new_value < text->number_min ? text->number_min :
2080 new_value > text->number_max ? text->number_max :
2083 sprintf(text->value, "%d", text->number_value);
2086 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2089 /* global pointer to gadget actually in use (when mouse button pressed) */
2090 static struct GadgetInfo *last_gi = NULL;
2092 void MapGadget(struct GadgetInfo *gi)
2094 if (gi == NULL || gi->mapped)
2099 DrawGadget(gi, DG_UNPRESSED, DG_BUFFERED);
2102 void UnmapGadget(struct GadgetInfo *gi)
2104 if (gi == NULL || !gi->mapped)
2113 void HandleGadgets(int mx, int my, int button)
2115 static struct GadgetInfo *last_info_gi = NULL;
2116 static unsigned long pressed_delay = 0;
2117 static int last_button = 0;
2118 static int last_mx = 0, last_my = 0;
2119 int scrollbar_mouse_pos;
2120 struct GadgetInfo *new_gi, *gi;
2121 boolean press_event;
2122 boolean release_event;
2123 boolean mouse_moving;
2124 boolean gadget_pressed;
2125 boolean gadget_pressed_repeated;
2126 boolean gadget_moving;
2127 boolean gadget_moving_inside;
2128 boolean gadget_moving_off_borders;
2129 boolean gadget_released;
2130 boolean gadget_released_inside;
2131 boolean gadget_released_off_borders;
2132 boolean changed_position = FALSE;
2134 /* check if there are any gadgets defined */
2135 if (gadget_list_first_entry == NULL)
2138 /* check which gadget is under the mouse pointer */
2139 new_gi = getGadgetInfoFromMousePosition(mx, my);
2141 /* check if button state has changed since last invocation */
2142 press_event = (button != 0 && last_button == 0);
2143 release_event = (button == 0 && last_button != 0);
2144 last_button = button;
2146 /* check if mouse has been moved since last invocation */
2147 mouse_moving = ((mx != last_mx || my != last_my) && motion_status);
2151 /* special treatment for text and number input gadgets */
2152 if (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped &&
2153 button != 0 && !motion_status)
2155 struct GadgetInfo *gi = last_gi;
2157 if (new_gi == last_gi)
2159 /* if mouse button pressed inside activated text gadget, set cursor */
2160 gi->text.cursor_position = (mx - gi->x) / FONT2_XSIZE;
2162 if (gi->text.cursor_position < 0)
2163 gi->text.cursor_position = 0;
2164 else if (gi->text.cursor_position > strlen(gi->text.value))
2165 gi->text.cursor_position = strlen(gi->text.value);
2167 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2171 /* if mouse button pressed outside text input gadget, deactivate it */
2172 CheckRangeOfNumericInputGadget(gi);
2173 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2175 if (gi->event_mask & GD_EVENT_TEXT_LEAVING)
2176 gi->callback_action(gi);
2183 (button != 0 && last_gi == NULL && new_gi != NULL && press_event);
2184 gadget_pressed_repeated =
2185 (button != 0 && last_gi != NULL && new_gi == last_gi);
2187 gadget_released = (release_event && last_gi != NULL);
2188 gadget_released_inside = (gadget_released && new_gi == last_gi);
2189 gadget_released_off_borders = (gadget_released && new_gi != last_gi);
2191 gadget_moving = (button != 0 && last_gi != NULL && mouse_moving);
2192 gadget_moving_inside = (gadget_moving && new_gi == last_gi);
2193 gadget_moving_off_borders = (gadget_moving && new_gi != last_gi);
2195 /* if new gadget pressed, store this gadget */
2199 /* 'gi' is actually handled gadget */
2202 /* if gadget is scrollbar, choose mouse position value */
2203 if (gi && gi->type & GD_TYPE_SCROLLBAR)
2204 scrollbar_mouse_pos =
2205 (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y);
2207 /* if mouse button released, no gadget needs to be handled anymore */
2208 if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT))
2211 /* modify event position values even if no gadget is pressed */
2212 if (button == 0 && !release_event)
2217 int last_x = gi->event.x;
2218 int last_y = gi->event.y;
2220 gi->event.x = mx - gi->x;
2221 gi->event.y = my - gi->y;
2223 if (gi->type == GD_TYPE_DRAWING_AREA)
2225 gi->event.x /= gi->drawing.item_xsize;
2226 gi->event.y /= gi->drawing.item_ysize;
2228 if (last_x != gi->event.x || last_y != gi->event.y)
2229 changed_position = TRUE;
2233 /* handle gadget popup info text */
2234 if (last_info_gi != new_gi ||
2235 (new_gi && new_gi->type == GD_TYPE_DRAWING_AREA && changed_position))
2237 last_info_gi = new_gi;
2239 if (new_gi != NULL && (button == 0 || new_gi == last_gi))
2241 new_gi->event.type = 0;
2242 new_gi->callback_info(new_gi);
2245 default_callback_info(NULL);
2250 if (gi->type == GD_TYPE_RADIO_BUTTON)
2252 struct GadgetInfo *rgi = gadget_list_first_entry;
2257 rgi->type == GD_TYPE_RADIO_BUTTON &&
2258 rgi->radio_nr == gi->radio_nr &&
2261 rgi->radio_pressed = FALSE;
2262 DrawGadget(rgi, DG_UNPRESSED, DG_DIRECT);
2268 gi->radio_pressed = TRUE;
2270 else if (gi->type & GD_TYPE_SCROLLBAR)
2274 if (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL)
2285 if (mpos >= gpos + gi->scrollbar.position &&
2286 mpos < gpos + gi->scrollbar.position + gi->scrollbar.size)
2288 /* drag scrollbar */
2289 gi->scrollbar.drag_position =
2290 scrollbar_mouse_pos - gi->scrollbar.position;
2294 /* click scrollbar one scrollbar length up/left or down/right */
2296 struct GadgetScrollbar *gs = &gi->scrollbar;
2297 int old_item_position = gs->item_position;
2299 changed_position = FALSE;
2301 gs->item_position +=
2302 gs->items_visible * (mpos < gpos + gi->scrollbar.position ? -1 : +1);
2304 if (gs->item_position < 0)
2305 gs->item_position = 0;
2306 if (gs->item_position > gs->items_max - gs->items_visible)
2307 gs->item_position = gs->items_max - gs->items_visible;
2309 if (old_item_position != gs->item_position)
2311 gi->event.item_position = gs->item_position;
2312 changed_position = TRUE;
2315 AdjustScrollbar(gi, gs->items_max, gs->item_position);
2317 gi->state = GD_BUTTON_UNPRESSED;
2318 gi->event.type = GD_EVENT_MOVING;
2319 gi->event.off_borders = FALSE;
2321 if (gi->event_mask & GD_EVENT_MOVING && changed_position)
2322 gi->callback_action(gi);
2324 /* don't handle this scrollbar anymore while mouse button pressed */
2331 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2333 gi->state = GD_BUTTON_PRESSED;
2334 gi->event.type = GD_EVENT_PRESSED;
2335 gi->event.button = button;
2336 gi->event.off_borders = FALSE;
2338 /* initialize delay counter */
2339 DelayReached(&pressed_delay, 0);
2341 if (gi->event_mask & GD_EVENT_PRESSED)
2342 gi->callback_action(gi);
2345 if (gadget_pressed_repeated)
2347 if (gi->event_mask & GD_EVENT_REPEATED &&
2348 DelayReached(&pressed_delay, GADGET_FRAME_DELAY))
2349 gi->callback_action(gi);
2354 if (gi->type & GD_TYPE_BUTTON)
2356 if (gadget_moving_inside && gi->state == GD_BUTTON_UNPRESSED)
2357 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2358 else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED)
2359 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2362 if (gi->type & GD_TYPE_SCROLLBAR)
2364 struct GadgetScrollbar *gs = &gi->scrollbar;
2365 int old_item_position = gs->item_position;
2367 gs->position = scrollbar_mouse_pos - gs->drag_position;
2369 if (gs->position < 0)
2371 if (gs->position > gs->position_max)
2372 gs->position = gs->position_max;
2374 gs->item_position = gs->items_max * gs->position / gs->size_max;
2376 if (old_item_position != gs->item_position)
2378 gi->event.item_position = gs->item_position;
2379 changed_position = TRUE;
2382 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2385 gi->state = (gadget_moving_inside || gi->type & GD_TYPE_SCROLLBAR ?
2386 GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED);
2387 gi->event.type = GD_EVENT_MOVING;
2388 gi->event.off_borders = gadget_moving_off_borders;
2390 if (gi->event_mask & GD_EVENT_MOVING && changed_position &&
2391 (gadget_moving_inside || gi->event_mask & GD_EVENT_OFF_BORDERS))
2392 gi->callback_action(gi);
2395 if (gadget_released_inside)
2397 if (!(gi->type & GD_TYPE_TEXTINPUT))
2398 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2400 gi->state = GD_BUTTON_UNPRESSED;
2401 gi->event.type = GD_EVENT_RELEASED;
2403 if (gi->event_mask & GD_EVENT_RELEASED)
2404 gi->callback_action(gi);
2407 if (gadget_released_off_borders)
2409 if (gi->type & GD_TYPE_SCROLLBAR)
2410 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2412 gi->event.type = GD_EVENT_RELEASED;
2414 if (gi->event_mask & GD_EVENT_RELEASED &&
2415 gi->event_mask & GD_EVENT_OFF_BORDERS)
2416 gi->callback_action(gi);
2420 void HandleGadgetsKeyInput(KeySym key)
2422 struct GadgetInfo *gi = last_gi;
2423 char text[MAX_GADGET_TEXTSIZE];
2427 boolean legal_letter;
2429 if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped)
2432 text_length = strlen(gi->text.value);
2433 cursor_pos = gi->text.cursor_position;
2434 letter = getCharFromKeySym(key);
2435 legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ?
2436 letter >= '0' && letter <= '9' :
2439 if (legal_letter && text_length < gi->text.size)
2441 strcpy(text, gi->text.value);
2442 strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]);
2443 gi->text.value[cursor_pos] = letter;
2444 gi->text.cursor_position++;
2445 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2447 else if (key == XK_Left && cursor_pos > 0)
2449 gi->text.cursor_position--;
2450 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2452 else if (key == XK_Right && cursor_pos < text_length)
2454 gi->text.cursor_position++;
2455 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2457 else if (key == XK_BackSpace && cursor_pos > 0)
2459 strcpy(text, gi->text.value);
2460 strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]);
2461 gi->text.cursor_position--;
2462 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2464 else if (key == XK_Delete && cursor_pos < text_length)
2466 strcpy(text, gi->text.value);
2467 strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]);
2468 DrawGadget(gi, DG_PRESSED, DG_DIRECT);
2470 else if (key == XK_Return)
2472 CheckRangeOfNumericInputGadget(gi);
2473 DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
2475 if (gi->event_mask & GD_EVENT_TEXT_RETURN)
2476 gi->callback_action(gi);