fixed code to compile with current gcc and 64-bit systems
[rocksndiamonds.git] / src / editor.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  ©1995 Artsoft Development                               *
5 *        Holger Schemel                                    *
6 *        33659 Bielefeld-Senne                             *
7 *        Telefon: (0521) 493245                            *
8 *        eMail: aeglos@valinor.owl.de                      *
9 *               aeglos@uni-paderborn.de                    *
10 *               q99492@pbhrzx.uni-paderborn.de             *
11 *----------------------------------------------------------*
12 *  editor.c                                                *
13 *                                                          *
14 *  Letzte Aenderung: 15.06.1995                            *
15 ***********************************************************/
16
17 #include "editor.h"
18 #include "screens.h"
19 #include "game.h"
20 #include "tools.h"
21 #include "misc.h"
22
23 static int level_xpos,level_ypos;
24 static BOOL edit_mode;
25 static BOOL name_typing;
26 static int element_shift;
27 static int new_element1 = EL_MAUERWERK;
28 static int new_element2 = EL_LEERRAUM;
29 static int new_element3 = EL_ERDREICH;
30 static int editor_element[] =
31 {
32   EL_SPIELFIGUR,
33   EL_LEERRAUM,
34   EL_ERDREICH,
35   EL_FELSBROCKEN,
36
37   EL_BETON,
38   EL_MAUERWERK,
39   EL_FELSBODEN,
40   EL_SIEB_LEER,
41
42   EL_EDELSTEIN,
43   EL_DIAMANT,
44   EL_KOKOSNUSS,
45   EL_BOMBE,
46
47   EL_MORAST_LEER,
48   EL_MORAST_VOLL,
49   EL_AUSGANG_ZU,
50   EL_AUSGANG_AUF,
51
52   EL_KAEFER,
53   EL_FLIEGER,
54   EL_MAMPFER,
55   EL_ZOMBIE,
56
57   EL_PACMAN,
58   EL_DYNAMIT_AUS,
59   EL_DYNAMIT,
60   EL_ABLENK_AUS,
61
62   EL_BADEWANNE1,
63   EL_SALZSAEURE,
64   EL_BADEWANNE2,
65   EL_BADEWANNE,
66
67   EL_BADEWANNE3,
68   EL_BADEWANNE4,
69   EL_BADEWANNE5,
70   EL_UNSICHTBAR,
71
72   EL_TROPFEN,
73   EL_AMOEBE1,
74   EL_AMOEBE2,
75   EL_AMOEBE3,
76
77   EL_LIFE,
78   EL_LIFE_ASYNC,
79
80   EL_ERZ_1,
81   EL_ERZ_2,
82
83 /*
84   EL_BIRNE_AUS,
85   EL_BIRNE_EIN,
86 */
87
88   EL_SCHLUESSEL1,
89   EL_SCHLUESSEL2,
90   EL_SCHLUESSEL3,
91   EL_SCHLUESSEL4,
92
93   EL_PFORTE1,
94   EL_PFORTE2,
95   EL_PFORTE3,
96   EL_PFORTE4,
97
98   EL_PFORTE1X,
99   EL_PFORTE2X,
100   EL_PFORTE3X,
101   EL_PFORTE4X,
102
103   EL_KAEFER_R,
104   EL_KAEFER_O,
105   EL_KAEFER_L,
106   EL_KAEFER_U,
107
108   EL_FLIEGER_R,
109   EL_FLIEGER_O,
110   EL_FLIEGER_L,
111   EL_FLIEGER_U,
112
113   EL_PACMAN_R,
114   EL_PACMAN_O,
115   EL_PACMAN_L,
116   EL_PACMAN_U,
117
118   EL_CHAR_AUSRUF,
119   EL_CHAR_ZOLL,
120   EL_CHAR_DOLLAR,
121   EL_CHAR_PROZ,
122
123   EL_CHAR_APOSTR,
124   EL_CHAR_KLAMM1,
125   EL_CHAR_KLAMM2,
126   EL_CHAR_PLUS,
127
128   EL_CHAR_KOMMA,
129   EL_CHAR_MINUS,
130   EL_CHAR_PUNKT,
131   EL_CHAR_SLASH,
132
133   EL_CHAR_0 + 0,
134   EL_CHAR_0 + 1,
135   EL_CHAR_0 + 2,
136   EL_CHAR_0 + 3,
137
138   EL_CHAR_0 + 4,
139   EL_CHAR_0 + 5,
140   EL_CHAR_0 + 6,
141   EL_CHAR_0 + 7,
142
143   EL_CHAR_0 + 8,
144   EL_CHAR_0 + 9,
145   EL_CHAR_DOPPEL,
146   EL_CHAR_SEMIKL,
147
148   EL_CHAR_LT,
149   EL_CHAR_GLEICH,
150   EL_CHAR_GT,
151   EL_CHAR_FRAGE,
152
153   EL_CHAR_AT,
154   EL_CHAR_A + 0,
155   EL_CHAR_A + 1,
156   EL_CHAR_A + 2,
157
158   EL_CHAR_A + 3,
159   EL_CHAR_A + 4,
160   EL_CHAR_A + 5,
161   EL_CHAR_A + 6,
162
163   EL_CHAR_A + 7,
164   EL_CHAR_A + 8,
165   EL_CHAR_A + 9,
166   EL_CHAR_A + 10,
167
168   EL_CHAR_A + 11,
169   EL_CHAR_A + 12,
170   EL_CHAR_A + 13,
171   EL_CHAR_A + 14,
172
173   EL_CHAR_A + 15,
174   EL_CHAR_A + 16,
175   EL_CHAR_A + 17,
176   EL_CHAR_A + 18,
177
178   EL_CHAR_A + 19,
179   EL_CHAR_A + 20,
180   EL_CHAR_A + 21,
181   EL_CHAR_A + 22,
182
183   EL_CHAR_A + 23,
184   EL_CHAR_A + 24,
185   EL_CHAR_A + 25,
186   EL_CHAR_AE,
187
188   EL_CHAR_OE,
189   EL_CHAR_UE,
190   EL_CHAR_COPY
191 };
192 static int elements_in_list = sizeof(editor_element)/sizeof(int);
193
194 void DrawLevelEd()
195 {
196   int i, graphic;
197
198   level_xpos=-1;
199   level_ypos=-1;
200   edit_mode = TRUE;
201   name_typing = FALSE;
202   element_shift = 0;
203
204   CloseDoor(DOOR_CLOSE_2);
205
206   DrawMiniLevel(level_xpos,level_ypos);
207   FadeToFront();
208
209   XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
210             DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY1,
211             DXSIZE,DYSIZE,
212             DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
213   XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
214             DOOR_GFX_PAGEX6+ED_BUTTON_ELEM_XPOS,
215             DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS,
216             4*ED_BUTTON_ELEM_XSIZE,5*ED_BUTTON_ELEM_YSIZE,
217             DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS,
218             DOOR_GFX_PAGEY1+ED_BUTTON_EUP_Y2POS);
219
220   for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
221   {
222     if (i < elements_in_list)
223       graphic = el2gfx(editor_element[i]);
224     else
225       graphic = GFX_LEERRAUM;
226
227     DrawMiniGraphicExtHiRes(pix[PIX_DB_DOOR],gc,
228                             DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS+3 + 
229                             (i%MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
230                             DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS+3 +
231                             (i/MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
232                             graphic);
233   }
234
235   DrawMiniGraphicExtHiRes(pix[PIX_DB_DOOR],gc,
236                           DOOR_GFX_PAGEX1+ED_WIN_MB_LEFT_XPOS,
237                           DOOR_GFX_PAGEY1+ED_WIN_MB_LEFT_YPOS,
238                           el2gfx(new_element1));
239   DrawMiniGraphicExtHiRes(pix[PIX_DB_DOOR],gc,
240                           DOOR_GFX_PAGEX1+ED_WIN_MB_MIDDLE_XPOS,
241                           DOOR_GFX_PAGEY1+ED_WIN_MB_MIDDLE_YPOS,
242                           el2gfx(new_element2));
243   DrawMiniGraphicExtHiRes(pix[PIX_DB_DOOR],gc,
244                           DOOR_GFX_PAGEX1+ED_WIN_MB_RIGHT_XPOS,
245                           DOOR_GFX_PAGEY1+ED_WIN_MB_RIGHT_YPOS,
246                           el2gfx(new_element3));
247   DrawTextExt(pix[PIX_DB_DOOR],gc,
248               DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS,
249               DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
250               int2str(level_nr,2),FS_SMALL,FC_SPECIAL1);
251   XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
252             DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+3,
253             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
254             7,FONT3_YSIZE,
255             DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS,
256             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
257   XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
258             DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+14,
259             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
260             7,FONT3_YSIZE,
261             DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS+9,
262             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
263
264   XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
265             DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
266             VXSIZE,VYSIZE,
267             DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
268
269   OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
270 }
271
272 void DrawControlWindow()
273 {
274   int i,x,y;
275
276   ClearWindow();
277
278   DrawText(ED_COUNT_GADGET_XPOS+1,SY+6,
279            "Contents of a smashed cruncher:",FS_SMALL,FC_YELLOW);
280   for(i=0;i<4;i++) for(y=0;y<4;y++) for(x=0;x<4;x++)
281   {
282     DrawMiniElement(1+5*i+x,2+y,EL_ERDREICH);
283     XFillRectangle(display,drawto,gc,
284                    SX+(2+5*i)*MINI_TILEX-MINI_TILEX/2-1,
285                    SY+(3)*MINI_TILEY-MINI_TILEY/2-1,
286                    3*MINI_TILEX+2,3*MINI_TILEY+2);
287   }
288   XCopyArea(display,drawto,drawto,gc,
289             SX+MINI_TILEX,SY+2*MINI_TILEY,
290             4*5*MINI_TILEX,5*MINI_TILEY,
291             SX+MINI_TILEX-MINI_TILEX/2,SY+2*MINI_TILEY-MINI_TILEY/2);
292   for(i=0;i<4;i++)
293   {
294     for(y=0;y<3;y++) for(x=0;x<3;x++)
295       DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
296
297     DrawText(SX+MINI_TILEX+(5*i+1)*MINI_TILEX+1,
298              SY+2*MINI_TILEY+(4)*MINI_TILEY-4,
299              int2str(i+1,1),FS_SMALL,FC_YELLOW);
300   }
301
302   for(i=0;i<11+3+2;i++)
303   {
304     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
305               DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
306               DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
307               DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
308               ED_COUNT_GADGET_XPOS,
309               ED_COUNT_GADGET_YPOS+i*ED_COUNT_GADGET_YSIZE);
310
311     if (i<11)
312       DrawText(ED_COUNT_VALUE_XPOS,
313                ED_COUNT_VALUE_YPOS+i*ED_COUNT_GADGET_YSIZE,
314                int2str(level.score[i],3),FS_SMALL,FC_YELLOW);
315     else if (i==11)
316       DrawText(ED_COUNT_VALUE_XPOS,
317                ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
318                int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
319     else if (i==12)
320       DrawText(ED_COUNT_VALUE_XPOS,
321                ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
322                int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
323     else if (i==13)
324       DrawText(ED_COUNT_VALUE_XPOS,
325                ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
326                int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
327     else if (i==14)
328       DrawText(ED_COUNT_VALUE_XPOS,
329                ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
330                int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
331     else if (i==15)
332       DrawText(ED_COUNT_VALUE_XPOS,
333                ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
334                int2str(level.time,3),FS_SMALL,FC_YELLOW);
335   }
336
337   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+0*ED_COUNT_TEXT_YSIZE,
338            "Score for Emerald",FS_SMALL,FC_YELLOW);
339   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+1*ED_COUNT_TEXT_YSIZE,
340            "Score for Diamond",FS_SMALL,FC_YELLOW);
341   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+2*ED_COUNT_TEXT_YSIZE,
342            "Score for smashing a Bug",FS_SMALL,FC_YELLOW);
343   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+3*ED_COUNT_TEXT_YSIZE,
344            "Score for smashing a Spaceship",FS_SMALL,FC_YELLOW);
345   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+4*ED_COUNT_TEXT_YSIZE,
346            "Score for smashing a Cruncher",FS_SMALL,FC_YELLOW);
347   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+5*ED_COUNT_TEXT_YSIZE,
348            "Score for smashing an Alien",FS_SMALL,FC_YELLOW);
349   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+6*ED_COUNT_TEXT_YSIZE,
350            "Score for smashing a Pacman",FS_SMALL,FC_YELLOW);
351   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+7*ED_COUNT_TEXT_YSIZE,
352            "Score for cracking a nut",FS_SMALL,FC_YELLOW);
353   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+8*ED_COUNT_TEXT_YSIZE,
354            "Score for dynamite",FS_SMALL,FC_YELLOW);
355   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+9*ED_COUNT_TEXT_YSIZE,
356            "Score for key",FS_SMALL,FC_YELLOW);
357   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+10*ED_COUNT_TEXT_YSIZE,
358            "Score for each 10 seconds left",FS_SMALL,FC_YELLOW);
359   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+11*ED_COUNT_TEXT_YSIZE,
360            "Speed of the amoeba",FS_SMALL,FC_YELLOW);
361   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+12*ED_COUNT_TEXT_YSIZE,
362            "Time for magic wall",FS_SMALL,FC_YELLOW);
363   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+13*ED_COUNT_TEXT_YSIZE,
364            "Time for wheel",FS_SMALL,FC_YELLOW);
365   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+14*ED_COUNT_TEXT_YSIZE,
366            "Emeralds needed in this level",FS_SMALL,FC_YELLOW);
367   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+15*ED_COUNT_TEXT_YSIZE,
368            "Time available for this level",FS_SMALL,FC_YELLOW);
369
370   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
371             DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS,
372             DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
373             ED_WIN_COUNT_XSIZE,ED_WIN_COUNT_YSIZE,
374             ED_COUNT_GADGET_XPOS,
375             ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
376   for(i=1;i<31;i++)
377     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
378               DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS+3+2*FONT2_XSIZE,
379               DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
380               ED_WIN_COUNT_XSIZE-3-2*FONT2_XSIZE,ED_WIN_COUNT_YSIZE,
381               ED_COUNT_GADGET_XPOS+3+i*FONT2_XSIZE,
382               ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
383   DrawText(ED_COUNT_GADGET_XPOS+5,
384            ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
385            level.name,FS_SMALL,FC_YELLOW);
386   DrawText(ED_COUNT_GADGET_XPOS+(30+3)*FONT2_XSIZE-5,
387            ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
388            "Title",FS_SMALL,FC_YELLOW);
389
390   DrawText(ED_SIZE_GADGET_XPOS,ED_SIZE_GADGET_YPOS-18,
391            "Playfield size:",FS_SMALL,FC_YELLOW);
392   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
393             DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
394             DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
395             DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
396             ED_SIZE_GADGET_XPOS,
397             ED_SIZE_GADGET_YPOS+0*ED_COUNT_GADGET_YSIZE);
398   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
399             DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
400             DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
401             DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
402             ED_SIZE_GADGET_XPOS,
403             ED_SIZE_GADGET_YPOS+1*ED_COUNT_GADGET_YSIZE);
404   DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+0*ED_SIZE_TEXT_YSIZE,
405            "Width",FS_SMALL,FC_YELLOW);
406   DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+1*ED_SIZE_TEXT_YSIZE,
407            "Height",FS_SMALL,FC_YELLOW);
408   DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
409            int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
410   DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
411            int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
412 }
413
414 void ScrollMiniLevel(int from_x, int from_y, int scroll)
415 {
416   int x,y;
417   int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
418   int dy = (scroll==ED_SCROLL_UP   ? -1 : scroll==ED_SCROLL_DOWN  ? 1 : 0);
419
420   XCopyArea(display,drawto,drawto,gc,
421             SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
422             SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
423             SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
424   if (dx)
425   {
426     x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
427     for(y=0;y<2*SCR_FIELDY;y++)
428       DrawMiniElementOrWall(x,y,from_x,from_y);
429   }
430   else if (dy)
431   {
432     y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
433     for(x=0;x<2*SCR_FIELDX;x++)
434       DrawMiniElementOrWall(x,y,from_x,from_y);
435   }
436
437   redraw_mask |= REDRAW_FIELD;
438   BackToFront();
439 }
440
441 void AdjustLevelScrollPosition()
442 {
443   if (level_xpos<-1)
444     level_xpos = -1;
445   if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
446     level_xpos = lev_fieldx-2*SCR_FIELDX+1;
447   if (lev_fieldx<2*SCR_FIELDX-2)
448     level_xpos = -1;
449
450   if (level_ypos<-1)
451     level_ypos = -1;
452   if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
453     level_ypos = lev_fieldy-2*SCR_FIELDY+1;
454   if (lev_fieldy<2*SCR_FIELDY-2)
455     level_ypos = -1;
456 }
457
458 void FloodFill(int from_x, int from_y, int fill_element)
459 {
460   int i,x,y;
461   int old_element;
462   static int check[4][2] = { -1,0, 0,-1, 1,0, 0,1 };
463   static int safety = 0;
464
465   safety++;
466
467   if (safety>lev_fieldx*lev_fieldy)
468   {
469     fprintf(stderr,"Something went wrong in 'FloodFill()'. Please debug.\n");
470     exit(-1);
471   }
472
473   old_element = Feld[from_x][from_y];
474   Feld[from_x][from_y] = fill_element;
475
476   for(i=0;i<4;i++)
477   {
478     x = from_x+check[i][0];
479     y = from_y+check[i][1];
480
481     if (IN_LEV_FIELD(x,y) && Feld[x][y]==old_element)
482       FloodFill(x,y,fill_element);
483   }
484
485   safety--;
486 }
487
488 void LevelEd(int mx, int my, int button)
489 {
490   static int last_button = 0;
491   static int in_field_pressed = FALSE;
492   static BOOL use_floodfill = FALSE;
493   int x = (mx-SX)/MINI_TILEX; 
494   int y = (my-SY)/MINI_TILEY; 
495
496   if (use_floodfill)            /********** FLOOD FILL **********/
497   {
498     if (button)
499     {
500       if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
501       {
502         int from_x, from_y;
503         int fill_element;
504
505         if (x>lev_fieldx || y>lev_fieldy ||
506             (x==0 && level_xpos<0) ||
507             (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
508             (y==0 && level_ypos<0) ||
509             (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY))
510           return;
511
512         from_x = x+level_xpos;
513         from_y = y+level_ypos;
514         fill_element = (button==1 ? new_element1 :
515                         button==2 ? new_element2 :
516                         button==3 ? new_element3 : 0);
517
518         FloodFill(from_x,from_y,fill_element);
519         DrawMiniLevel(level_xpos,level_ypos);
520       }
521
522       use_floodfill = FALSE;
523       CloseDoor(DOOR_CLOSE_1);
524       OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
525     }
526     return;
527   }
528   else                          /********** EDIT/CTRL-FENSTER **********/
529   {
530     int choice = CheckElemButtons(mx,my,button);
531     int elem_pos = choice-ED_BUTTON_ELEM;
532
533     switch(choice)
534     {
535       case ED_BUTTON_EUP:
536       case ED_BUTTON_EDOWN:
537         if ((choice==ED_BUTTON_EUP && element_shift>0) ||
538             (choice==ED_BUTTON_EDOWN &&
539              element_shift<elements_in_list-MAX_ELEM_X*MAX_ELEM_Y))
540         {
541           int i, step;
542
543           step = (button==1 ? MAX_ELEM_X : button==2 ? 5*MAX_ELEM_X :
544                   elements_in_list);
545           element_shift += (choice==ED_BUTTON_EUP ? -step : step);
546           if (element_shift<0)
547             element_shift = 0;
548           if (element_shift>elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)
549             element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y;
550           if (element_shift % MAX_ELEM_X)
551             element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X);
552
553           for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
554             DrawElemButton(i+2,ED_BUTTON_RELEASED);
555           BackToFront();
556           Delay(100000);
557         }
558         break;
559       default:
560         if (elem_pos>=0 && elem_pos<MAX_ELEM_X*MAX_ELEM_Y)
561         {
562           int new_element;
563
564           if (elem_pos+element_shift < elements_in_list)
565             new_element = editor_element[elem_pos+element_shift];
566           else
567             new_element = EL_LEERRAUM;
568
569           if (last_button==1)
570             new_element1 = new_element;
571           else if (last_button==2)
572             new_element2 = new_element;
573           else if (last_button==3)
574             new_element3 = new_element;
575
576           DrawMiniGraphicExtHiRes(drawto,gc,
577                                   DX+ED_WIN_MB_LEFT_XPOS,
578                                   DY+ED_WIN_MB_LEFT_YPOS,
579                                   el2gfx(new_element1));
580           DrawMiniGraphicExtHiRes(drawto,gc,
581                                   DX+ED_WIN_MB_MIDDLE_XPOS,
582                                   DY+ED_WIN_MB_MIDDLE_YPOS,
583                                   el2gfx(new_element2));
584           DrawMiniGraphicExtHiRes(drawto,gc,
585                                   DX+ED_WIN_MB_RIGHT_XPOS,
586                                   DY+ED_WIN_MB_RIGHT_YPOS,
587                                   el2gfx(new_element3));
588           redraw_mask |= REDRAW_DOOR_1;
589         }
590         break;
591     }
592
593     if (edit_mode)              /********** EDIT-FENSTER **********/
594     {
595       switch(CheckEditButtons(mx,my,button))
596       {
597         case ED_BUTTON_CTRL:
598           CloseDoor(DOOR_CLOSE_2);
599           DrawControlWindow();
600           XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
601                     DOOR_GFX_PAGEX4,DOOR_GFX_PAGEY1+80,
602                     VXSIZE,VYSIZE,
603                     DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
604           OpenDoor(DOOR_OPEN_2);
605           edit_mode = FALSE;
606           break;
607         case ED_BUTTON_FILL:
608           AreYouSure("Caution ! Flood fill mode ! Choose area !",AYS_OPEN);
609           use_floodfill = TRUE;
610           return;
611           break;
612         case ED_BUTTON_LEFT:
613           if (level_xpos>=0)
614           {
615             if (lev_fieldx<2*SCR_FIELDX-2)
616               break;
617
618             level_xpos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
619             if (level_xpos<-1)
620               level_xpos = -1;
621             if (button==1)
622               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT);
623             else
624               DrawMiniLevel(level_xpos,level_ypos);
625             BackToFront();
626             Delay(100000);
627           }
628           break;
629         case ED_BUTTON_RIGHT:
630           if (level_xpos<=lev_fieldx-2*SCR_FIELDX)
631           {
632             if (lev_fieldx<2*SCR_FIELDX-2)
633               break;
634
635             level_xpos += (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
636             if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
637               level_xpos = lev_fieldx-2*SCR_FIELDX+1;
638             if (button==1)
639               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT);
640             else
641               DrawMiniLevel(level_xpos,level_ypos);
642             BackToFront();
643             Delay(100000);
644           }
645           break;
646         case ED_BUTTON_UP:
647           if (level_ypos>=0)
648           {
649             if (lev_fieldy<2*SCR_FIELDY-2)
650               break;
651
652             level_ypos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
653             if (level_ypos<-1)
654               level_ypos = -1;
655             if (button==1)
656               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN);
657             else
658               DrawMiniLevel(level_xpos,level_ypos);
659             BackToFront();
660             Delay(100000);
661           }
662           break;
663         case ED_BUTTON_DOWN:
664           if (level_ypos<=lev_fieldy-2*SCR_FIELDY)
665           {
666             if (lev_fieldy<2*SCR_FIELDY-2)
667               break;
668
669             level_ypos += (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
670             if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
671               level_ypos = lev_fieldy-2*SCR_FIELDY+1;
672             if (button==1)
673               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP);
674             else
675               DrawMiniLevel(level_xpos,level_ypos);
676             BackToFront();
677             Delay(100000);
678           }
679           break;
680         default:
681           break;
682       }
683
684       if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
685       {
686         int new_element;
687
688         if (button && !motion_status)
689           in_field_pressed = TRUE;
690
691         if (!button || !in_field_pressed || button<1 || button>3 ||
692             (y==0 && level_ypos<0) ||
693             (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY) ||
694             (x==0 && level_xpos<0) ||
695             (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
696             x>lev_fieldx || y>lev_fieldy)
697           return;
698
699         new_element = (button==1 ? new_element1 :
700                        button==2 ? new_element2 :
701                        button==3 ? new_element3 : 0);
702
703         if (new_element != Feld[x+level_xpos][y+level_ypos])
704         {
705           if (new_element==EL_SPIELFIGUR) /* Jeder nur EINE Figur bitte... */
706           {
707             int x,y;
708
709             for(x=0;x<lev_fieldx;x++) for(y=0;y<lev_fieldy;y++)
710             {
711               if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
712               {
713                 Feld[x][y] = EL_LEERRAUM;
714                 if (x-level_xpos>=0 && x-level_xpos<2*SCR_FIELDX &&
715                     y-level_ypos>=0 && y-level_ypos<2*SCR_FIELDY)
716                   DrawMiniElement(x-level_xpos,y-level_ypos,EL_LEERRAUM);
717               }
718             }
719           }
720
721           Feld[x+level_xpos][y+level_ypos] = new_element;
722           DrawMiniElement(x,y,new_element);
723         }
724       }
725       else if (!motion_status)  /* Mauszeiger nicht im Level-Feld */
726         in_field_pressed = FALSE;
727     }
728     else                        /********** KONTROLL-FENSTER **********/
729     {
730       static int choice_delay = 0;
731       int choice = CheckCountButtons(mx,my,button);
732       int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0);
733
734       if (choice>=0 && choice<36 && DelayReached(&choice_delay,10))
735       {
736         if (!(choice % 2))
737           step = -step;
738
739         choice /= 2;
740
741         if (choice<11)
742         {
743           level.score[choice] += step;
744           if (level.score[choice]<0)
745             level.score[choice] = 0;
746           else if (level.score[choice]>255)
747             level.score[choice] = 255;
748         }
749         else if (choice==11)
750         {
751           level.tempo_amoebe += step;
752           if (level.tempo_amoebe<0)
753             level.tempo_amoebe = 0;
754           else if (level.tempo_amoebe>255)
755             level.tempo_amoebe = 255;
756         }
757         else if (choice==12)
758         {
759           level.dauer_sieb += step;
760           if (level.dauer_sieb<0)
761             level.dauer_sieb = 0;
762           else if (level.dauer_sieb>255)
763             level.dauer_sieb = 255;
764         }
765         else if (choice==13)
766         {
767           level.dauer_ablenk += step;
768           if (level.dauer_ablenk<0)
769             level.dauer_ablenk = 0;
770           else if (level.dauer_ablenk>255)
771             level.dauer_ablenk = 255;
772         }
773         else if (choice==14)
774         {
775           level.edelsteine += step;
776           if (level.edelsteine<0)
777             level.edelsteine = 0;
778           else if (level.edelsteine>999)
779             level.edelsteine = 999;
780         }
781         else if (choice==15)
782         {
783           level.time += step;
784           if (level.time<0)
785             level.time = 0;
786           else if (level.time>999)
787             level.time = 999;
788         }
789         else if (choice==16)
790         {
791           lev_fieldx += step;
792           if (lev_fieldx<MIN_LEV_FIELDX)
793             lev_fieldx = MIN_LEV_FIELDX;
794           else if (lev_fieldx>MAX_LEV_FIELDX)
795             lev_fieldx = MAX_LEV_FIELDX;
796           level.fieldx = lev_fieldx;
797         }
798         else if (choice==17)
799         {
800           lev_fieldy += step;
801           if (lev_fieldy<MIN_LEV_FIELDY)
802             lev_fieldy = MIN_LEV_FIELDY;
803           else if (lev_fieldy>MAX_LEV_FIELDY)
804             lev_fieldy = MAX_LEV_FIELDY;
805           level.fieldy = lev_fieldy;
806         }
807
808         if (choice<11)
809           DrawText(ED_COUNT_VALUE_XPOS,
810                    ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
811                    int2str(level.score[choice],3),FS_SMALL,FC_YELLOW);
812         else if (choice==11)
813           DrawText(ED_COUNT_VALUE_XPOS,
814                    ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
815                    int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
816         else if (choice==12)
817           DrawText(ED_COUNT_VALUE_XPOS,
818                    ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
819                    int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
820         else if (choice==13)
821           DrawText(ED_COUNT_VALUE_XPOS,
822                    ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
823                    int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
824         else if (choice==14)
825           DrawText(ED_COUNT_VALUE_XPOS,
826                    ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
827                    int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
828         else if (choice==15)
829           DrawText(ED_COUNT_VALUE_XPOS,
830                    ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
831                    int2str(level.time,3),FS_SMALL,FC_YELLOW);
832         else if (choice==16)
833           DrawText(ED_SIZE_VALUE_XPOS,
834                    ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
835                    int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
836         else if (choice==17)
837           DrawText(ED_SIZE_VALUE_XPOS,
838                    ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
839                    int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
840
841         redraw_mask &= ~REDRAW_FIELD;
842         if (choice<16)
843           XCopyArea(display,drawto,window,gc,
844                     ED_COUNT_VALUE_XPOS,
845                     ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
846                     3*FONT2_XSIZE,FONT2_YSIZE,
847                     ED_COUNT_VALUE_XPOS,
848                     ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE);
849         else
850           XCopyArea(display,drawto,window,gc,
851                     ED_SIZE_VALUE_XPOS,
852                     ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE,
853                     3*FONT2_XSIZE,FONT2_YSIZE,
854                     ED_SIZE_VALUE_XPOS,
855                     ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE);
856         XFlush(display);
857       }
858
859       switch(CheckCtrlButtons(mx,my,button))
860       {
861         case ED_BUTTON_EDIT:
862           CloseDoor(DOOR_CLOSE_2);
863           AdjustLevelScrollPosition();
864           DrawMiniLevel(level_xpos,level_ypos);
865           XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
866                     DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
867                     VXSIZE,VYSIZE,
868                     DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
869           OpenDoor(DOOR_OPEN_2);
870           edit_mode = TRUE;
871           break;
872         case ED_BUTTON_CLEAR:
873           if (AreYouSure("Are you sure to clear this level ?",AYS_ASK))
874           {
875             for(x=0;x<MAX_LEV_FIELDX;x++) 
876               for(y=0;y<MAX_LEV_FIELDY;y++) 
877                 Feld[x][y] = EL_ERDREICH;
878             DrawMiniLevel(level_xpos,level_ypos);
879           }
880           break;
881         case ED_BUTTON_UNDO:
882           if (AreYouSure("Exit without saving ?",AYS_ASK | AYS_STAY_OPEN))
883           {
884             CloseDoor(DOOR_CLOSE_BOTH);
885             game_status=MAINMENU;
886             DrawMainMenu();
887           }
888           else
889           {
890             CloseDoor(DOOR_CLOSE_1);
891             OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
892           }
893           break;
894         case ED_BUTTON_EXIT:
895           {
896             int figur_vorhanden = FALSE;
897             for(y=0;y<lev_fieldy;y++) 
898               for(x=0;x<lev_fieldx;x++)
899                 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1) 
900                   figur_vorhanden = TRUE;
901
902             if (!figur_vorhanden)
903               AreYouSure("No Level without Gregor Mc Duffin please !",
904                          AYS_CONFIRM);
905             else
906             {
907               if (AreYouSure("Save this level and kill the old ?",
908                              AYS_ASK | AYS_STAY_OPEN))
909               {
910                 for(x=0;x<lev_fieldx;x++)
911                   for(y=0;y<lev_fieldy;y++) 
912                     Ur[x][y]=Feld[x][y];
913                 SaveLevel(level_nr);
914               }
915               CloseDoor(DOOR_CLOSE_BOTH);
916               game_status=MAINMENU;
917               DrawMainMenu();
918             }
919           }
920           break;
921         default:
922           break;
923       }
924
925       if (mx>=ED_COUNT_GADGET_XPOS &&
926           mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
927           my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
928           my<ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE+ED_WIN_COUNT_YSIZE)
929       {
930         if (!name_typing)
931         {
932           name_typing = TRUE;
933           DrawText(ED_COUNT_GADGET_XPOS+5,
934                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
935                    level.name,FS_SMALL,FC_GREEN);
936           DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
937                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
938                    "<",FS_SMALL,FC_RED);
939         }
940       }
941       else
942       {
943         if (name_typing)
944         {
945           name_typing = FALSE;
946           DrawText(ED_COUNT_GADGET_XPOS+5,
947                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
948                    level.name,FS_SMALL,FC_YELLOW);
949           DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
950                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
951                    " ",FS_SMALL,FC_RED);
952         }
953       }
954
955       if (mx>=SX+1*MINI_TILEX && mx<SX+(1+4*5)*MINI_TILEX &&
956           my>=SY+2*MINI_TILEY && my<SY+(2+3)*MINI_TILEY)
957       {
958         int x = (mx-SX-1*MINI_TILEX)/MINI_TILEX;
959         int y = (my-SY-2*MINI_TILEY)/MINI_TILEY;
960         int i = x/5;
961         int new_element;
962
963         x = x-i*5;
964         if (i>=0 && i<43 && x>=0 && x<3 && y>=0 && y<3)
965         {
966           if (button && !motion_status)
967             in_field_pressed = TRUE;
968
969           if (!button || !in_field_pressed || button<1 || button>3)
970             return;
971
972           new_element = (button==1 ? new_element1 :
973                          button==2 ? new_element2 :
974                          button==3 ? new_element3 : 0);
975
976           if (new_element != level.mampfer_inhalt[i][x][y])
977           {
978             level.mampfer_inhalt[i][x][y] = new_element;
979             DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
980           }
981         }
982         else if (!motion_status)/* Mauszeiger nicht im Cruncher-Feld */
983           in_field_pressed = FALSE;
984       }
985       else if (!motion_status)  /* Mauszeiger nicht im Cruncher-Feld */
986         in_field_pressed = FALSE;
987     }
988   }
989
990   last_button = button;
991
992   BackToFront();
993 }
994
995 void LevelNameTyping(KeySym key)
996 {
997   unsigned char ascii = 0;
998   int len = strlen(level.name);
999
1000   if (!name_typing)
1001     return;
1002
1003   if (key>=XK_A && key<=XK_Z)
1004     ascii = 'A'+(char)(key-XK_A);
1005   else if (key>=XK_a && key<=XK_z)
1006     ascii = 'a'+(char)(key-XK_a);
1007   else if (key>=XK_0 && key<=XK_9)
1008     ascii = '0'+(char)(key-XK_0);
1009 #ifdef XK_LATIN1
1010   else if (key>=XK_space && key<=XK_at)
1011     ascii = ' '+(char)(key-XK_space);
1012   else if (key==XK_Adiaeresis)
1013     ascii = 'Ä';
1014   else if (key==XK_Odiaeresis)
1015     ascii = 'Ö';
1016   else if (key==XK_Udiaeresis)
1017     ascii = 'Ü';
1018   else if (key==XK_adiaeresis)
1019     ascii = 'ä';
1020   else if (key==XK_odiaeresis)
1021     ascii = 'ö';
1022   else if (key==XK_udiaeresis)
1023     ascii = 'ü';
1024   else if (key==XK_underscore)
1025     ascii = '_';
1026 #endif
1027
1028   if (ascii && len<MAX_LEVNAMLEN-2)
1029   {
1030     level.name[len] = ascii;
1031     level.name[len+1] = 0;
1032     len++;
1033
1034     DrawTextExt(drawto,gc,
1035                 ED_COUNT_GADGET_XPOS+5,
1036                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1037                 level.name,FS_SMALL,FC_GREEN);
1038     DrawTextExt(window,gc,
1039                 ED_COUNT_GADGET_XPOS+5,
1040                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1041                 level.name,FS_SMALL,FC_GREEN);
1042     DrawTextExt(drawto,gc,
1043                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1044                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1045                 "<",FS_SMALL,FC_RED);
1046     DrawTextExt(window,gc,
1047                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1048                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1049                 "<",FS_SMALL,FC_RED);
1050   }
1051   else if (key==XK_Delete && len>0)
1052   {
1053     level.name[len-1] = 0;
1054     len--;
1055
1056     DrawTextExt(drawto,gc,
1057                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1058                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1059                 "< ",FS_SMALL,FC_GREEN);
1060     DrawTextExt(window,gc,
1061                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1062                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1063                 "< ",FS_SMALL,FC_GREEN);
1064   }
1065   else if (key==XK_Return)
1066   {
1067     DrawTextExt(drawto,gc,
1068                 ED_COUNT_GADGET_XPOS+5,
1069                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1070                 level.name,FS_SMALL,FC_YELLOW);
1071     DrawTextExt(window,gc,
1072                 ED_COUNT_GADGET_XPOS+5,
1073                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1074                 level.name,FS_SMALL,FC_YELLOW);
1075     DrawTextExt(drawto,gc,
1076                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1077                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1078                 " ",FS_SMALL,FC_YELLOW);
1079     DrawTextExt(window,gc,
1080                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1081                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1082                 " ",FS_SMALL,FC_YELLOW);
1083
1084     name_typing = FALSE;
1085   }
1086 }
1087
1088 void DrawEditButton(unsigned int state)
1089 {
1090   int i;
1091   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
1092   int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY2;
1093   static int edit_pos[6][4] =
1094   {
1095     ED_BUTTON_CTRL_XPOS,ED_BUTTON_CTRL_YPOS,
1096     ED_BUTTON_CTRL_XSIZE,ED_BUTTON_CTRL_YSIZE,
1097
1098     ED_BUTTON_FILL_XPOS,ED_BUTTON_FILL_YPOS,
1099     ED_BUTTON_FILL_XSIZE,ED_BUTTON_FILL_YSIZE,
1100
1101     ED_BUTTON_LEFT_XPOS,ED_BUTTON_LEFT_YPOS,
1102     ED_BUTTON_LEFT_XSIZE,ED_BUTTON_LEFT_YSIZE,
1103
1104     ED_BUTTON_UP_XPOS,ED_BUTTON_UP_YPOS,
1105     ED_BUTTON_UP_XSIZE,ED_BUTTON_UP_YSIZE,
1106
1107     ED_BUTTON_DOWN_XPOS,ED_BUTTON_DOWN_YPOS,
1108     ED_BUTTON_DOWN_XSIZE,ED_BUTTON_DOWN_YSIZE,
1109
1110     ED_BUTTON_RIGHT_XPOS,ED_BUTTON_RIGHT_YPOS,
1111     ED_BUTTON_RIGHT_XSIZE,ED_BUTTON_RIGHT_YSIZE
1112   };
1113
1114   if (state & ED_BUTTON_PRESSED)
1115     cx = DOOR_GFX_PAGEX5;
1116
1117   for(i=0;i<6;i++)
1118   {
1119     if (state & (1<<i))
1120       XCopyArea(display,pix[PIX_DOOR],drawto,gc,
1121                 cx + edit_pos[i][xpos],
1122                 cy + edit_pos[i][ypos],
1123                 edit_pos[i][xsize],
1124                 edit_pos[i][ysize],
1125                 VX + edit_pos[i][xpos],
1126                 VY + edit_pos[i][ypos]);
1127   }
1128
1129   redraw_mask |= REDRAW_DOOR_2;
1130 }
1131
1132 void DrawCtrlButton(unsigned int state)
1133 {
1134   int i;
1135   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
1136   int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY1+80;
1137   static int edit_pos[4][4] =
1138   {
1139     ED_BUTTON_EDIT_XPOS,ED_BUTTON_EDIT_YPOS,
1140     ED_BUTTON_EDIT_XSIZE,ED_BUTTON_EDIT_YSIZE,
1141
1142     ED_BUTTON_CLEAR_XPOS,ED_BUTTON_CLEAR_YPOS,
1143     ED_BUTTON_CLEAR_XSIZE,ED_BUTTON_CLEAR_YSIZE,
1144
1145     ED_BUTTON_UNDO_XPOS,ED_BUTTON_UNDO_YPOS,
1146     ED_BUTTON_UNDO_XSIZE,ED_BUTTON_UNDO_YSIZE,
1147
1148     ED_BUTTON_EXIT_XPOS,ED_BUTTON_EXIT_YPOS,
1149     ED_BUTTON_EXIT_XSIZE,ED_BUTTON_EXIT_YSIZE
1150   };
1151
1152   if (state & ED_BUTTON_PRESSED)
1153     cx = DOOR_GFX_PAGEX3;
1154
1155   for(i=0;i<4;i++)
1156   {
1157     if (state & (1<<(i+6)))
1158       XCopyArea(display,pix[PIX_DOOR],drawto,gc,
1159                 cx + edit_pos[i][xpos],
1160                 cy + edit_pos[i][ypos],
1161                 edit_pos[i][xsize],
1162                 edit_pos[i][ysize],
1163                 VX + edit_pos[i][xpos],
1164                 VY + edit_pos[i][ypos]);
1165   }
1166
1167   redraw_mask |= REDRAW_DOOR_2;
1168 }
1169
1170 void DrawElemButton(int button_nr, int button_state)
1171 {
1172   int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
1173   int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
1174   int from_x, from_y, to_x,to_y, size_x, size_y;
1175   static int edit_pos[3][4] =
1176   {
1177     ED_BUTTON_EUP_XPOS,ED_BUTTON_EUP_YPOS,
1178     ED_BUTTON_EUP_XSIZE,ED_BUTTON_EUP_YSIZE,
1179
1180     ED_BUTTON_EDOWN_XPOS,ED_BUTTON_EDOWN_YPOS,
1181     ED_BUTTON_EDOWN_XSIZE,ED_BUTTON_EDOWN_YSIZE,
1182
1183     ED_BUTTON_ELEM_XPOS,ED_BUTTON_ELEM_YPOS,
1184     ED_BUTTON_ELEM_XSIZE,ED_BUTTON_ELEM_YSIZE
1185   };
1186
1187   if (button_nr<ED_BUTTON_ELEM)
1188   {
1189     int pos = button_nr;
1190
1191     from_x = cx + edit_pos[pos][xpos];
1192     from_y = cy + edit_pos[pos][ypos];
1193     size_x = edit_pos[pos][xsize];
1194     size_y = edit_pos[pos][ysize];
1195     to_x   = DX + edit_pos[pos][xpos];
1196     to_y   = DY + edit_pos[pos][ypos];
1197
1198     if (button_state & ED_BUTTON_PRESSED)
1199     {
1200       if (button_nr==ED_BUTTON_EUP)
1201         from_y = cy + ED_BUTTON_EUP_Y2POS;
1202       else
1203         from_y = cy + ED_BUTTON_EDOWN_Y2POS;
1204     }
1205
1206     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
1207               from_x,from_y, size_x,size_y, to_x,to_y);
1208   }
1209   else
1210   {
1211     int pos = ED_BUTTON_ELEM;
1212     int elem_pos = button_nr-ED_BUTTON_ELEM;
1213     int x = elem_pos % MAX_ELEM_X;
1214     int y = elem_pos / MAX_ELEM_X;
1215     int graphic;
1216     int shift = 0;
1217
1218     if (elem_pos+element_shift < elements_in_list)
1219       graphic = el2gfx(editor_element[elem_pos+element_shift]);
1220     else
1221       graphic = GFX_LEERRAUM;
1222
1223     from_x = cx + edit_pos[pos][xpos];
1224     from_y = cy + edit_pos[pos][ypos];
1225     size_x = edit_pos[pos][xsize];
1226     size_y = edit_pos[pos][ysize];
1227     to_x   = DX + edit_pos[pos][xpos] + x * ED_BUTTON_ELEM_XSIZE;
1228     to_y   = DY + edit_pos[pos][ypos] + y * ED_BUTTON_ELEM_YSIZE;
1229
1230     if (button_state & ED_BUTTON_PRESSED)
1231     {
1232       from_y = ED_BUTTON_ELEM_Y2POS;
1233       shift = 1;
1234     }
1235
1236     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
1237               from_x,from_y, size_x,size_y, to_x,to_y);
1238
1239     DrawMiniGraphicExtHiRes(drawto,gc,
1240                             DX+ED_BUTTON_ELEM_XPOS+3+shift + 
1241                             (elem_pos % MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
1242                             DY+ED_BUTTON_ELEM_YPOS+3-shift +
1243                             (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
1244                             graphic);
1245   }
1246
1247   redraw_mask |= REDRAW_DOOR_1;
1248 }
1249
1250 void DrawCountButton(int button_nr, int button_state)
1251 {
1252   int from_x, from_y, to_x,to_y, size_x, size_y;
1253
1254   from_x =
1255     DOOR_GFX_PAGEX4+(button_nr%2 ? ED_BUTTON_PLUS_XPOS : ED_BUTTON_MINUS_XPOS);
1256   from_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
1257   size_x = ED_BUTTON_MINUS_XSIZE;
1258   size_y = ED_BUTTON_MINUS_YSIZE;
1259   to_x = (button_nr<32 ? ED_COUNT_GADGET_XPOS : ED_SIZE_GADGET_XPOS);
1260   if (button_nr % 2)
1261     to_x += (ED_BUTTON_PLUS_XPOS - ED_BUTTON_MINUS_XPOS);
1262   to_y = (button_nr<32 ? ED_COUNT_GADGET_YPOS : ED_SIZE_GADGET_YPOS) +
1263     ((button_nr<32 ? button_nr : button_nr-32)/2)*ED_COUNT_GADGET_YSIZE;
1264
1265   if (button_state & ED_BUTTON_PRESSED)
1266     from_x -= DXSIZE;
1267
1268   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
1269             from_x,from_y, size_x,size_y, to_x,to_y);
1270   XCopyArea(display,pix[PIX_DOOR],window,gc,
1271             from_x,from_y, size_x,size_y, to_x,to_y);
1272 }
1273
1274 int CheckEditButtons(int mx, int my, int button)
1275 {
1276   int return_code = 0;
1277   static int choice = -1;
1278   static BOOL pressed = FALSE;
1279   static int edit_button[6] =
1280   {
1281     ED_BUTTON_CTRL,
1282     ED_BUTTON_FILL,
1283     ED_BUTTON_LEFT,
1284     ED_BUTTON_UP,
1285     ED_BUTTON_DOWN,
1286     ED_BUTTON_RIGHT
1287   };
1288
1289   if (button)
1290   {
1291     if (!motion_status)         /* Maustaste neu gedrückt */
1292     {
1293       if (ON_EDIT_BUTTON(mx,my))
1294       {
1295         choice = EDIT_BUTTON(mx,my);
1296         pressed = TRUE;
1297         DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
1298         if (edit_button[choice]!=ED_BUTTON_CTRL &&
1299             edit_button[choice]!=ED_BUTTON_FILL)
1300           return_code = 1<<choice;
1301       }
1302     }
1303     else                        /* Mausbewegung bei gedrückter Maustaste */
1304     {
1305       if ((!ON_EDIT_BUTTON(mx,my) || EDIT_BUTTON(mx,my)!=choice) &&
1306           choice>=0 && pressed)
1307       {
1308         pressed = FALSE;
1309         DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
1310       }
1311       else if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice)
1312       {
1313         if (!pressed)
1314           DrawEditButton(edit_button[choice] | ED_BUTTON_PRESSED);
1315         pressed = TRUE;
1316         if (edit_button[choice]!=ED_BUTTON_CTRL &&
1317             edit_button[choice]!=ED_BUTTON_FILL)
1318           return_code = 1<<choice;
1319       }
1320     }
1321   }
1322   else                          /* Maustaste wieder losgelassen */
1323   {
1324     if (ON_EDIT_BUTTON(mx,my) && EDIT_BUTTON(mx,my)==choice && pressed)
1325     {
1326       DrawEditButton(edit_button[choice] | ED_BUTTON_RELEASED);
1327       if (edit_button[choice]==ED_BUTTON_CTRL ||
1328           edit_button[choice]==ED_BUTTON_FILL)
1329         return_code = 1<<choice;
1330       choice = -1;
1331       pressed = FALSE;
1332     }
1333     else
1334     {
1335       choice = -1;
1336       pressed = FALSE;
1337     }
1338   }
1339
1340   BackToFront();
1341   return(return_code);
1342 }
1343
1344 int CheckCtrlButtons(int mx, int my, int button)
1345 {
1346   int return_code = 0;
1347   static int choice = -1;
1348   static BOOL pressed = FALSE;
1349   static int ctrl_button[4] =
1350   {
1351     ED_BUTTON_EDIT,
1352     ED_BUTTON_CLEAR,
1353     ED_BUTTON_UNDO,
1354     ED_BUTTON_EXIT
1355   };
1356
1357   if (button)
1358   {
1359     if (!motion_status)         /* Maustaste neu gedrückt */
1360     {
1361       if (ON_CTRL_BUTTON(mx,my))
1362       {
1363         choice = CTRL_BUTTON(mx,my);
1364         pressed = TRUE;
1365         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
1366       }
1367     }
1368     else                        /* Mausbewegung bei gedrückter Maustaste */
1369     {
1370       if ((!ON_CTRL_BUTTON(mx,my) || CTRL_BUTTON(mx,my)!=choice) &&
1371           choice>=0 && pressed)
1372       {
1373         pressed = FALSE;
1374         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
1375       }
1376       else if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && !pressed)
1377       {
1378         pressed = TRUE;
1379         DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_PRESSED);
1380       }
1381     }
1382   }
1383   else                          /* Maustaste wieder losgelassen */
1384   {
1385     if (ON_CTRL_BUTTON(mx,my) && CTRL_BUTTON(mx,my)==choice && pressed)
1386     {
1387       DrawCtrlButton(ctrl_button[choice] | ED_BUTTON_RELEASED);
1388       return_code = 1<<(choice+6);
1389       choice = -1;
1390       pressed = FALSE;
1391     }
1392     else
1393     {
1394       choice = -1;
1395       pressed = FALSE;
1396     }
1397   }
1398
1399   BackToFront();
1400   return(return_code);
1401 }
1402
1403 int CheckElemButtons(int mx, int my, int button)
1404 {
1405   int return_code = -1;
1406   static int choice = -1;
1407   static BOOL pressed = FALSE;
1408
1409   if (button)
1410   {
1411     if (!motion_status)         /* Maustaste neu gedrückt */
1412     {
1413       if (ON_ELEM_BUTTON(mx,my))
1414       {
1415         choice = ELEM_BUTTON(mx,my);
1416         pressed = TRUE;
1417         DrawElemButton(choice,ED_BUTTON_PRESSED);
1418         if (choice==ED_BUTTON_EUP ||
1419             choice==ED_BUTTON_EDOWN)
1420           return_code = choice;
1421       }
1422     }
1423     else                        /* Mausbewegung bei gedrückter Maustaste */
1424     {
1425       if ((!ON_ELEM_BUTTON(mx,my) || ELEM_BUTTON(mx,my)!=choice) &&
1426           choice>=0 && pressed)
1427       {
1428         pressed = FALSE;
1429         DrawElemButton(choice,ED_BUTTON_RELEASED);
1430       }
1431       else if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice)
1432       {
1433         if (!pressed)
1434           DrawElemButton(choice,ED_BUTTON_PRESSED);
1435         pressed = TRUE;
1436         if (choice==ED_BUTTON_EUP ||
1437             choice==ED_BUTTON_EDOWN)
1438           return_code = choice;
1439       }
1440     }
1441   }
1442   else                          /* Maustaste wieder losgelassen */
1443   {
1444     if (ON_ELEM_BUTTON(mx,my) && ELEM_BUTTON(mx,my)==choice && pressed)
1445     {
1446       DrawElemButton(choice,ED_BUTTON_RELEASED);
1447       if (choice!=ED_BUTTON_EUP &&
1448           choice!=ED_BUTTON_EDOWN)
1449         return_code = choice;
1450       choice = -1;
1451       pressed = FALSE;
1452     }
1453     else
1454     {
1455       choice = -1;
1456       pressed = FALSE;
1457     }
1458   }
1459
1460   BackToFront();
1461   return(return_code);
1462 }
1463
1464 int CheckCountButtons(int mx, int my, int button)
1465 {
1466   int return_code = -1;
1467   static int choice = -1;
1468   static BOOL pressed = FALSE;
1469
1470   if (button)
1471   {
1472     if (!motion_status)         /* Maustaste neu gedrückt */
1473     {
1474       if (ON_COUNT_BUTTON(mx,my))
1475       {
1476         choice = COUNT_BUTTON(mx,my);
1477         pressed = TRUE;
1478         DrawCountButton(choice,ED_BUTTON_PRESSED);
1479         return_code = choice;
1480       }
1481     }
1482     else                        /* Mausbewegung bei gedrückter Maustaste */
1483     {
1484       if ((!ON_COUNT_BUTTON(mx,my) || COUNT_BUTTON(mx,my)!=choice) &&
1485           choice>=0 && pressed)
1486       {
1487         pressed = FALSE;
1488         DrawCountButton(choice,ED_BUTTON_RELEASED);
1489       }
1490       else if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice)
1491       {
1492         if (!pressed)
1493           DrawCountButton(choice,ED_BUTTON_PRESSED);
1494         pressed = TRUE;
1495         return_code = choice;
1496       }
1497     }
1498   }
1499   else                          /* Maustaste wieder losgelassen */
1500   {
1501     if (ON_COUNT_BUTTON(mx,my) && COUNT_BUTTON(mx,my)==choice && pressed)
1502     {
1503       DrawCountButton(choice,ED_BUTTON_RELEASED);
1504       choice = -1;
1505       pressed = FALSE;
1506     }
1507     else
1508     {
1509       choice = -1;
1510       pressed = FALSE;
1511     }
1512   }
1513
1514   BackToFront();
1515   return(return_code);
1516 }