1b40735e534c999ce503e86cabd0cee885e04257
[rocksndiamonds.git] / src / editor.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  editor.c                                                *
12 ***********************************************************/
13
14 #include "editor.h"
15 #include "screens.h"
16 #include "tools.h"
17 #include "misc.h"
18 #include "buttons.h"
19 #include "files.h"
20
21 /* positions in the level editor */
22 #define ED_WIN_MB_LEFT_XPOS     7
23 #define ED_WIN_MB_LEFT_YPOS     6
24 #define ED_WIN_LEVELNR_XPOS     77
25 #define ED_WIN_LEVELNR_YPOS     7
26 #define ED_WIN_MB_MIDDLE_XPOS   7
27 #define ED_WIN_MB_MIDDLE_YPOS   258
28 #define ED_WIN_MB_RIGHT_XPOS    77
29 #define ED_WIN_MB_RIGHT_YPOS    258
30
31 /* other constants for the editor */
32 #define ED_SCROLL_NO            0
33 #define ED_SCROLL_LEFT          1
34 #define ED_SCROLL_RIGHT         2
35 #define ED_SCROLL_UP            4
36 #define ED_SCROLL_DOWN          8
37
38 /* delay value to avoid too fast scrolling etc. */
39 #define CHOICE_DELAY_VALUE      100
40
41 static int level_xpos,level_ypos;
42 static boolean edit_mode;
43 static boolean name_typing;
44 static int new_element1 = EL_MAUERWERK;
45 static int new_element2 = EL_LEERRAUM;
46 static int new_element3 = EL_ERDREICH;
47
48 int element_shift;
49 int editor_element[] =
50 {
51   EL_CHAR_A + ('B' - 'A'),
52   EL_CHAR_A + ('O' - 'A'),
53   EL_CHAR_A + ('U' - 'A'),
54   EL_CHAR_A + ('L' - 'A'),
55
56   EL_CHAR_MINUS,
57   EL_CHAR_A + ('D' - 'A'),
58   EL_CHAR_A + ('E' - 'A'),
59   EL_CHAR_A + ('R' - 'A'),
60
61   EL_CHAR_A + ('D' - 'A'),
62   EL_CHAR_A + ('A' - 'A'),
63   EL_CHAR_A + ('S' - 'A'),
64   EL_CHAR_A + ('H' - 'A'),
65
66   EL_SPIELFIGUR,
67   EL_LEERRAUM,
68   EL_ERDREICH,
69   EL_BETON,
70
71   EL_FELSBODEN,
72   EL_SIEB2_LEER,
73   EL_AUSGANG_ZU,
74   EL_AUSGANG_AUF,
75
76   EL_EDELSTEIN_BD,
77   EL_BUTTERFLY_O,
78   EL_FIREFLY_O,
79   EL_FELSBROCKEN,
80
81   EL_BUTTERFLY_L,
82   EL_FIREFLY_L,
83   EL_BUTTERFLY_R,
84   EL_FIREFLY_R,
85
86   EL_AMOEBE_BD,
87   EL_BUTTERFLY_U,
88   EL_FIREFLY_U,
89   EL_LEERRAUM,
90
91   EL_CHAR_A + ('E' - 'A'),
92   EL_CHAR_A + ('M' - 'A'),
93   EL_CHAR_A + ('E' - 'A'),
94   EL_CHAR_MINUS,
95
96   EL_CHAR_A + ('R' - 'A'),
97   EL_CHAR_A + ('A' - 'A'),
98   EL_CHAR_A + ('L' - 'A'),
99   EL_CHAR_A + ('D' - 'A'),
100
101   EL_CHAR_A + ('M' - 'A'),
102   EL_CHAR_A + ('I' - 'A'),
103   EL_CHAR_A + ('N' - 'A'),
104   EL_CHAR_A + ('E' - 'A'),
105
106   EL_SPIELER1,
107   EL_SPIELER2,
108   EL_SPIELER3,
109   EL_SPIELER4,
110
111   EL_SPIELFIGUR,
112   EL_LEERRAUM,
113   EL_ERDREICH,
114   EL_FELSBROCKEN,
115
116   EL_BETON,
117   EL_MAUERWERK,
118   EL_FELSBODEN,
119   EL_SIEB_LEER,
120
121   EL_EDELSTEIN,
122   EL_DIAMANT,
123   EL_KOKOSNUSS,
124   EL_BOMBE,
125
126   EL_ERZ_EDEL,
127   EL_ERZ_DIAM,
128   EL_MORAST_LEER,
129   EL_MORAST_VOLL,
130
131   EL_DYNAMIT_AUS,
132   EL_DYNAMIT,
133   EL_AUSGANG_ZU,
134   EL_AUSGANG_AUF,
135
136   EL_MAMPFER,
137   EL_KAEFER_O,
138   EL_FLIEGER_O,
139   EL_ROBOT,
140
141   EL_KAEFER_L,
142   EL_FLIEGER_L,
143   EL_KAEFER_R,
144   EL_FLIEGER_R,
145
146   EL_ABLENK_AUS,
147   EL_KAEFER_U,
148   EL_FLIEGER_U,
149   EL_UNSICHTBAR,
150
151   EL_BADEWANNE1,
152   EL_SALZSAEURE,
153   EL_BADEWANNE2,
154   EL_LEERRAUM,
155
156   EL_BADEWANNE3,
157   EL_BADEWANNE4,
158   EL_BADEWANNE5,
159   EL_LEERRAUM,
160
161   EL_TROPFEN,
162   EL_AMOEBE_TOT,
163   EL_AMOEBE_NASS,
164   EL_AMOEBE_NORM,
165
166   EL_SCHLUESSEL1,
167   EL_SCHLUESSEL2,
168   EL_SCHLUESSEL3,
169   EL_SCHLUESSEL4,
170
171   EL_PFORTE1,
172   EL_PFORTE2,
173   EL_PFORTE3,
174   EL_PFORTE4,
175
176   EL_PFORTE1X,
177   EL_PFORTE2X,
178   EL_PFORTE3X,
179   EL_PFORTE4X,
180
181   EL_CHAR_A + ('M' - 'A'),
182   EL_CHAR_A + ('O' - 'A'),
183   EL_CHAR_A + ('R' - 'A'),
184   EL_CHAR_A + ('E' - 'A'),
185
186   EL_PFEIL_L,
187   EL_PFEIL_R,
188   EL_PFEIL_O,
189   EL_PFEIL_U,
190
191   EL_AMOEBE_VOLL,
192   EL_EDELSTEIN_GELB,
193   EL_EDELSTEIN_ROT,
194   EL_EDELSTEIN_LILA,
195
196   EL_ERZ_EDEL_BD,
197   EL_ERZ_EDEL_GELB,
198   EL_ERZ_EDEL_ROT,
199   EL_ERZ_EDEL_LILA,
200
201   EL_LIFE,
202   EL_PACMAN_O,
203   EL_ZEIT_VOLL,
204   EL_ZEIT_LEER,
205
206   EL_PACMAN_L,
207   EL_MAMPFER2,
208   EL_PACMAN_R,
209   EL_MAUER_LEBT,
210
211   EL_LIFE_ASYNC,
212   EL_PACMAN_U,
213   EL_BIRNE_AUS,
214   EL_BIRNE_EIN,
215
216   EL_DYNABOMB_NR,
217   EL_DYNABOMB_SZ,
218   EL_DYNABOMB_XL,
219   EL_BADEWANNE,
220
221   EL_MAULWURF,
222   EL_PINGUIN,
223   EL_SCHWEIN,
224   EL_DRACHE,
225
226   EL_SONDE,
227   EL_MAUER_X,
228   EL_MAUER_Y,
229   EL_MAUER_XY,
230
231   EL_CHAR_A + ('S' - 'A'),
232   EL_CHAR_A + ('O' - 'A'),
233   EL_CHAR_A + ('K' - 'A'),
234   EL_CHAR_A + ('O' - 'A'),
235
236   EL_CHAR_MINUS,
237   EL_CHAR_A + ('B' - 'A'),
238   EL_CHAR_A + ('A' - 'A'),
239   EL_CHAR_A + ('N' - 'A'),
240
241   EL_SOKOBAN_OBJEKT,
242   EL_SOKOBAN_FELD_LEER,
243   EL_SOKOBAN_FELD_VOLL,
244   EL_BETON,
245
246 /*
247   EL_CHAR_A + ('D' - 'A'),
248   EL_CHAR_A + ('Y' - 'A'),
249   EL_CHAR_A + ('N' - 'A'),
250   EL_CHAR_A + ('A' - 'A'),
251
252   EL_CHAR_A + ('B' - 'A'),
253   EL_CHAR_A + ('L' - 'A'),
254   EL_CHAR_A + ('A' - 'A'),
255   EL_CHAR_A + ('S' - 'A'),
256
257   EL_CHAR_MINUS,
258   EL_CHAR_A + ('T' - 'A'),
259   EL_CHAR_A + ('E' - 'A'),
260   EL_CHAR_A + ('R' - 'A'),
261 */
262
263   EL_LEERRAUM,
264   EL_LEERRAUM,
265   EL_LEERRAUM,
266   EL_LEERRAUM,
267
268   EL_CHAR_AUSRUF,
269   EL_CHAR_ZOLL,
270   EL_CHAR_DOLLAR,
271   EL_CHAR_PROZ,
272
273   EL_CHAR_APOSTR,
274   EL_CHAR_KLAMM1,
275   EL_CHAR_KLAMM2,
276   EL_CHAR_PLUS,
277
278   EL_CHAR_KOMMA,
279   EL_CHAR_MINUS,
280   EL_CHAR_PUNKT,
281   EL_CHAR_SLASH,
282
283   EL_CHAR_0 + 0,
284   EL_CHAR_0 + 1,
285   EL_CHAR_0 + 2,
286   EL_CHAR_0 + 3,
287
288   EL_CHAR_0 + 4,
289   EL_CHAR_0 + 5,
290   EL_CHAR_0 + 6,
291   EL_CHAR_0 + 7,
292
293   EL_CHAR_0 + 8,
294   EL_CHAR_0 + 9,
295   EL_CHAR_DOPPEL,
296   EL_CHAR_SEMIKL,
297
298   EL_CHAR_LT,
299   EL_CHAR_GLEICH,
300   EL_CHAR_GT,
301   EL_CHAR_FRAGE,
302
303   EL_CHAR_AT,
304   EL_CHAR_A + 0,
305   EL_CHAR_A + 1,
306   EL_CHAR_A + 2,
307
308   EL_CHAR_A + 3,
309   EL_CHAR_A + 4,
310   EL_CHAR_A + 5,
311   EL_CHAR_A + 6,
312
313   EL_CHAR_A + 7,
314   EL_CHAR_A + 8,
315   EL_CHAR_A + 9,
316   EL_CHAR_A + 10,
317
318   EL_CHAR_A + 11,
319   EL_CHAR_A + 12,
320   EL_CHAR_A + 13,
321   EL_CHAR_A + 14,
322
323   EL_CHAR_A + 15,
324   EL_CHAR_A + 16,
325   EL_CHAR_A + 17,
326   EL_CHAR_A + 18,
327
328   EL_CHAR_A + 19,
329   EL_CHAR_A + 20,
330   EL_CHAR_A + 21,
331   EL_CHAR_A + 22,
332
333   EL_CHAR_A + 23,
334   EL_CHAR_A + 24,
335   EL_CHAR_A + 25,
336   EL_CHAR_AE,
337
338   EL_CHAR_OE,
339   EL_CHAR_UE,
340   EL_CHAR_COPY
341 };
342 int elements_in_list = sizeof(editor_element)/sizeof(int);
343
344 void DrawLevelEd()
345 {
346   int i, graphic;
347
348   level_xpos=-1;
349   level_ypos=-1;
350   edit_mode = TRUE;
351   name_typing = FALSE;
352   element_shift = 0;
353
354   CloseDoor(DOOR_CLOSE_2);
355
356   DrawMiniLevel(level_xpos,level_ypos);
357   FadeToFront();
358
359   XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
360             DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY1,
361             DXSIZE,DYSIZE,
362             DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
363   XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
364             DOOR_GFX_PAGEX6+ED_BUTTON_ELEM_XPOS,
365             DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS,
366             4*ED_BUTTON_ELEM_XSIZE,5*ED_BUTTON_ELEM_YSIZE,
367             DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS,
368             DOOR_GFX_PAGEY1+ED_BUTTON_EUP_Y2POS);
369
370   for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
371   {
372     if (i < elements_in_list)
373       graphic = el2gfx(editor_element[i]);
374     else
375       graphic = GFX_LEERRAUM;
376
377     DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
378                        DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS+3 + 
379                        (i%MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
380                        DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS+3 +
381                        (i/MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
382                        graphic);
383   }
384
385   DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
386                      DOOR_GFX_PAGEX1+ED_WIN_MB_LEFT_XPOS,
387                      DOOR_GFX_PAGEY1+ED_WIN_MB_LEFT_YPOS,
388                      el2gfx(new_element1));
389   DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
390                      DOOR_GFX_PAGEX1+ED_WIN_MB_MIDDLE_XPOS,
391                      DOOR_GFX_PAGEY1+ED_WIN_MB_MIDDLE_YPOS,
392                      el2gfx(new_element2));
393   DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
394                      DOOR_GFX_PAGEX1+ED_WIN_MB_RIGHT_XPOS,
395                      DOOR_GFX_PAGEY1+ED_WIN_MB_RIGHT_YPOS,
396                      el2gfx(new_element3));
397   DrawTextExt(pix[PIX_DB_DOOR],gc,
398               DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS,
399               DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
400               int2str(level_nr,2),FS_SMALL,FC_SPECIAL1);
401   XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
402             DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+3,
403             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
404             7,FONT3_YSIZE,
405             DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS,
406             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
407   XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
408             DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+14,
409             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
410             7,FONT3_YSIZE,
411             DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS+9,
412             DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
413
414   XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
415             DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
416             VXSIZE,VYSIZE,
417             DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
418
419   OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
420 }
421
422
423
424 void test_func(struct GadgetInfo *gi)
425 {
426   if (gi->event == GD_EVENT_PRESSED)
427     printf("test_func: GD_EVENT_PRESSED\n");
428   else if (gi->event == GD_EVENT_RELEASED)
429     printf("test_func: GD_EVENT_RELEASED\n");
430   else 
431     printf("test_func: ?\n");
432 }
433
434
435
436
437
438 void DrawControlWindow()
439 {
440   int i,x,y;
441
442   ClearWindow();
443
444   /* Inhalt der Mampfer */
445   DrawText(ED_COUNT_GADGET_XPOS+1,SY+6,
446            "Contents of a smashed cruncher:",FS_SMALL,FC_YELLOW);
447   for(i=0;i<4;i++) for(y=0;y<4;y++) for(x=0;x<4;x++)
448   {
449     DrawMiniElement(1+5*i+x,2+y,EL_ERDREICH);
450     XFillRectangle(display,drawto,gc,
451                    SX+(1+5*i)*MINI_TILEX+MINI_TILEX/2-1,
452                    SY+(2)*MINI_TILEY+MINI_TILEY/2-1,
453                    3*MINI_TILEX+2,3*MINI_TILEY+2);
454   }
455   XCopyArea(display,drawto,drawto,gc,
456             SX+1*MINI_TILEX,SY+2*MINI_TILEY,
457             4*5*MINI_TILEX,5*MINI_TILEY,
458             SX+1*MINI_TILEX-MINI_TILEX/2,SY+2*MINI_TILEY-MINI_TILEY/2);
459   for(i=0;i<4;i++)
460   {
461     for(y=0;y<3;y++) for(x=0;x<3;x++)
462       DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
463
464     DrawText(SX+MINI_TILEX+(5*i+1)*MINI_TILEX+1,
465              SY+2*MINI_TILEY+(4)*MINI_TILEY-4,
466              int2str(i+1,1),FS_SMALL,FC_YELLOW);
467   }
468
469   /* Inhalt der Amöbe */
470   for(y=0;y<2;y++) for(x=0;x<2;x++)
471   {
472     DrawMiniElement(29+x,26+y,EL_ERDREICH);
473     XFillRectangle(display,drawto,gc,
474                    SX+29*MINI_TILEX+MINI_TILEX/2-1,
475                    SY+26*MINI_TILEY+MINI_TILEY/2-1,
476                    MINI_TILEX+2,MINI_TILEY+2);
477   }
478   XCopyArea(display,drawto,drawto,gc,
479             SX+29*MINI_TILEX,SY+26*MINI_TILEY,
480             3*MINI_TILEX,3*MINI_TILEY,
481             SX+29*MINI_TILEX-MINI_TILEX/2,SY+26*MINI_TILEY-MINI_TILEY/2);
482   DrawMiniElement(29,26,level.amoebe_inhalt);
483
484   for(i=0;i<11+3+2;i++)
485   {
486     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
487               DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
488               DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
489               DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
490               ED_COUNT_GADGET_XPOS,
491               ED_COUNT_GADGET_YPOS+i*ED_COUNT_GADGET_YSIZE);
492
493     if (i<11)
494       DrawText(ED_COUNT_VALUE_XPOS,
495                ED_COUNT_VALUE_YPOS+i*ED_COUNT_GADGET_YSIZE,
496                int2str(level.score[i],3),FS_SMALL,FC_YELLOW);
497     else if (i==11)
498       DrawText(ED_COUNT_VALUE_XPOS,
499                ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
500                int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
501     else if (i==12)
502       DrawText(ED_COUNT_VALUE_XPOS,
503                ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
504                int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
505     else if (i==13)
506       DrawText(ED_COUNT_VALUE_XPOS,
507                ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
508                int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
509     else if (i==14)
510       DrawText(ED_COUNT_VALUE_XPOS,
511                ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
512                int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
513     else if (i==15)
514       DrawText(ED_COUNT_VALUE_XPOS,
515                ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
516                int2str(level.time,3),FS_SMALL,FC_YELLOW);
517   }
518
519   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+0*ED_COUNT_TEXT_YSIZE,
520            "Score for Emerald",FS_SMALL,FC_YELLOW);
521   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+1*ED_COUNT_TEXT_YSIZE,
522            "Score for Diamond",FS_SMALL,FC_YELLOW);
523   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+2*ED_COUNT_TEXT_YSIZE,
524            "Score for smashing a Bug",FS_SMALL,FC_YELLOW);
525   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+3*ED_COUNT_TEXT_YSIZE,
526            "Score for smashing a Spaceship",FS_SMALL,FC_YELLOW);
527   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+4*ED_COUNT_TEXT_YSIZE,
528            "Score for smashing a Cruncher",FS_SMALL,FC_YELLOW);
529   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+5*ED_COUNT_TEXT_YSIZE,
530            "Score for smashing an Alien",FS_SMALL,FC_YELLOW);
531   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+6*ED_COUNT_TEXT_YSIZE,
532            "Score for smashing a Pacman",FS_SMALL,FC_YELLOW);
533   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+7*ED_COUNT_TEXT_YSIZE,
534            "Score for cracking a nut",FS_SMALL,FC_YELLOW);
535   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+8*ED_COUNT_TEXT_YSIZE,
536            "Score for dynamite",FS_SMALL,FC_YELLOW);
537   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+9*ED_COUNT_TEXT_YSIZE,
538            "Score for key",FS_SMALL,FC_YELLOW);
539   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+10*ED_COUNT_TEXT_YSIZE,
540            "Score for each 10 seconds left",FS_SMALL,FC_YELLOW);
541   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+11*ED_COUNT_TEXT_YSIZE,
542            "Speed of the amoeba / Content",FS_SMALL,FC_YELLOW);
543   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+12*ED_COUNT_TEXT_YSIZE,
544            "Time for magic wall",FS_SMALL,FC_YELLOW);
545   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+13*ED_COUNT_TEXT_YSIZE,
546            "Time for wheel",FS_SMALL,FC_YELLOW);
547   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+14*ED_COUNT_TEXT_YSIZE,
548            "Emeralds needed in this level",FS_SMALL,FC_YELLOW);
549   DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+15*ED_COUNT_TEXT_YSIZE,
550            "Time available for this level",FS_SMALL,FC_YELLOW);
551
552   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
553             DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS,
554             DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
555             ED_WIN_COUNT_XSIZE,ED_WIN_COUNT_YSIZE,
556             ED_COUNT_GADGET_XPOS,
557             ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
558   for(i=1;i<31;i++)
559     XCopyArea(display,pix[PIX_DOOR],drawto,gc,
560               DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS+3+2*FONT2_XSIZE,
561               DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
562               ED_WIN_COUNT_XSIZE-3-2*FONT2_XSIZE,ED_WIN_COUNT_YSIZE,
563               ED_COUNT_GADGET_XPOS+3+i*FONT2_XSIZE,
564               ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
565   DrawText(ED_COUNT_GADGET_XPOS+5,
566            ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
567            level.name,FS_SMALL,FC_YELLOW);
568   DrawText(ED_COUNT_GADGET_XPOS+(30+3)*FONT2_XSIZE-5,
569            ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
570            "Title",FS_SMALL,FC_YELLOW);
571
572   DrawText(ED_SIZE_GADGET_XPOS,ED_SIZE_GADGET_YPOS-18,
573            "Playfield size:",FS_SMALL,FC_YELLOW);
574   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
575             DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
576             DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
577             DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
578             ED_SIZE_GADGET_XPOS,
579             ED_SIZE_GADGET_YPOS+0*ED_COUNT_GADGET_YSIZE);
580   XCopyArea(display,pix[PIX_DOOR],drawto,gc,
581             DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
582             DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
583             DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
584             ED_SIZE_GADGET_XPOS,
585             ED_SIZE_GADGET_YPOS+1*ED_COUNT_GADGET_YSIZE);
586   DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+0*ED_SIZE_TEXT_YSIZE,
587            "Width",FS_SMALL,FC_YELLOW);
588   DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+1*ED_SIZE_TEXT_YSIZE,
589            "Height",FS_SMALL,FC_YELLOW);
590   DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
591            int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
592   DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
593            int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
594
595   {
596     Pixmap gd_pixmap = pix[PIX_DOOR];
597     int gd_x1 = DOOR_GFX_PAGEX4 + ED_BUTTON_MINUS_XPOS;
598     int gd_x2 = DOOR_GFX_PAGEX3 + ED_BUTTON_MINUS_XPOS;
599     int gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
600     struct GadgetInfo *gi;
601
602     gi = CreateGadget(GDI_X, 100,
603                       GDI_Y, 100,
604                       GDI_WIDTH, ED_BUTTON_MINUS_XSIZE,
605                       GDI_HEIGHT, ED_BUTTON_MINUS_YSIZE,
606                       GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
607                       GDI_STATE, GD_BUTTON_UNPRESSED,
608                       GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
609                       GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
610                       GDI_CALLBACK, test_func,
611                       GDI_END);
612
613     if (gi == NULL)
614       Error(ERR_EXIT, "cannot create gadget");
615
616     MapGadget(gi);
617   }
618
619
620 }
621
622 void ScrollMiniLevel(int from_x, int from_y, int scroll)
623 {
624   int x,y;
625   int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
626   int dy = (scroll==ED_SCROLL_UP   ? -1 : scroll==ED_SCROLL_DOWN  ? 1 : 0);
627
628   XCopyArea(display,drawto,drawto,gc,
629             SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
630             SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
631             SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
632   if (dx)
633   {
634     x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
635     for(y=0;y<2*SCR_FIELDY;y++)
636       DrawMiniElementOrWall(x,y,from_x,from_y);
637   }
638   else if (dy)
639   {
640     y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
641     for(x=0;x<2*SCR_FIELDX;x++)
642       DrawMiniElementOrWall(x,y,from_x,from_y);
643   }
644
645   redraw_mask |= REDRAW_FIELD;
646   BackToFront();
647 }
648
649 void AdjustLevelScrollPosition()
650 {
651   if (level_xpos<-1)
652     level_xpos = -1;
653   if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
654     level_xpos = lev_fieldx-2*SCR_FIELDX+1;
655   if (lev_fieldx<2*SCR_FIELDX-2)
656     level_xpos = -1;
657
658   if (level_ypos<-1)
659     level_ypos = -1;
660   if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
661     level_ypos = lev_fieldy-2*SCR_FIELDY+1;
662   if (lev_fieldy<2*SCR_FIELDY-2)
663     level_ypos = -1;
664 }
665
666 void FloodFill(int from_x, int from_y, int fill_element)
667 {
668   int i,x,y;
669   int old_element;
670   static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
671   static int safety = 0;
672
673   /* check if starting field still has the desired content */
674   if (Feld[from_x][from_y] == fill_element)
675     return;
676
677   safety++;
678
679   if (safety > lev_fieldx*lev_fieldy)
680     Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
681
682   old_element = Feld[from_x][from_y];
683   Feld[from_x][from_y] = fill_element;
684
685   for(i=0;i<4;i++)
686   {
687     x = from_x + check[i][0];
688     y = from_y + check[i][1];
689
690     if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
691       FloodFill(x, y, fill_element);
692   }
693
694   safety--;
695 }
696
697 void LevelEd(int mx, int my, int button)
698 {
699   static int last_button = 0;
700   static int in_field_pressed = FALSE;
701   static boolean use_floodfill = FALSE;
702   int x = (mx-SX)/MINI_TILEX; 
703   int y = (my-SY)/MINI_TILEY; 
704
705   if (use_floodfill)            /********** FLOOD FILL **********/
706   {
707     if (button)
708     {
709       if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
710       {
711         int from_x, from_y;
712         int fill_element;
713
714         if (x>lev_fieldx || y>lev_fieldy ||
715             (x==0 && level_xpos<0) ||
716             (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
717             (y==0 && level_ypos<0) ||
718             (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY))
719           return;
720
721         from_x = x+level_xpos;
722         from_y = y+level_ypos;
723         fill_element = (button==1 ? new_element1 :
724                         button==2 ? new_element2 :
725                         button==3 ? new_element3 : 0);
726
727         FloodFill(from_x,from_y,fill_element);
728         DrawMiniLevel(level_xpos,level_ypos);
729       }
730
731       use_floodfill = FALSE;
732       CloseDoor(DOOR_CLOSE_1);
733       OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
734     }
735     return;
736   }
737   else                          /********** EDIT/CTRL-FENSTER **********/
738   {
739     static unsigned long choice_delay = 0;
740     int choice = CheckElemButtons(mx,my,button);
741     int elem_pos = choice-ED_BUTTON_ELEM;
742
743     if (((choice == ED_BUTTON_EUP && element_shift>0) ||
744          (choice == ED_BUTTON_EDOWN &&
745           element_shift<elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)) &&
746         DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
747     {
748       int i, step;
749
750       step = (button==1 ? MAX_ELEM_X : button==2 ? 5*MAX_ELEM_X :
751               elements_in_list);
752       element_shift += (choice==ED_BUTTON_EUP ? -step : step);
753       if (element_shift<0)
754         element_shift = 0;
755       if (element_shift>elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)
756         element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y;
757       if (element_shift % MAX_ELEM_X)
758         element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X);
759
760       for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
761         DrawElemButton(i+2,ED_BUTTON_RELEASED);
762     }
763     else if (elem_pos>=0 && elem_pos<MAX_ELEM_X*MAX_ELEM_Y)
764     {
765       int new_element;
766
767       if (elem_pos+element_shift < elements_in_list)
768         new_element = editor_element[elem_pos+element_shift];
769       else
770         new_element = EL_LEERRAUM;
771
772       if (last_button==1)
773         new_element1 = new_element;
774       else if (last_button==2)
775         new_element2 = new_element;
776       else if (last_button==3)
777         new_element3 = new_element;
778
779       DrawMiniGraphicExt(drawto,gc,
780                          DX+ED_WIN_MB_LEFT_XPOS,
781                          DY+ED_WIN_MB_LEFT_YPOS,
782                          el2gfx(new_element1));
783       DrawMiniGraphicExt(drawto,gc,
784                          DX+ED_WIN_MB_MIDDLE_XPOS,
785                          DY+ED_WIN_MB_MIDDLE_YPOS,
786                          el2gfx(new_element2));
787       DrawMiniGraphicExt(drawto,gc,
788                          DX+ED_WIN_MB_RIGHT_XPOS,
789                          DY+ED_WIN_MB_RIGHT_YPOS,
790                          el2gfx(new_element3));
791       redraw_mask |= REDRAW_DOOR_1;
792     }
793   
794     if (edit_mode)              /********** EDIT-FENSTER **********/
795     {
796       switch(CheckEditButtons(mx,my,button))
797       {
798         case ED_BUTTON_CTRL:
799           CloseDoor(DOOR_CLOSE_2);
800           DrawControlWindow();
801           XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
802                     DOOR_GFX_PAGEX4,DOOR_GFX_PAGEY1+80,
803                     VXSIZE,VYSIZE,
804                     DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
805           OpenDoor(DOOR_OPEN_2);
806           edit_mode = FALSE;
807           break;
808         case ED_BUTTON_FILL:
809           Request("Caution ! Flood fill mode ! Choose area !",REQ_OPEN);
810           use_floodfill = TRUE;
811           return;
812           break;
813         case ED_BUTTON_LEFT:
814           if (level_xpos>=0)
815           {
816             if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
817               break;
818             if (lev_fieldx<2*SCR_FIELDX-2)
819               break;
820
821             level_xpos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
822             if (level_xpos<-1)
823               level_xpos = -1;
824             if (button==1)
825               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT);
826             else
827               DrawMiniLevel(level_xpos,level_ypos);
828           }
829           break;
830         case ED_BUTTON_RIGHT:
831           if (level_xpos<=lev_fieldx-2*SCR_FIELDX)
832           {
833             if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
834               break;
835             if (lev_fieldx<2*SCR_FIELDX-2)
836               break;
837
838             level_xpos += (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
839             if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
840               level_xpos = lev_fieldx-2*SCR_FIELDX+1;
841             if (button==1)
842               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT);
843             else
844               DrawMiniLevel(level_xpos,level_ypos);
845           }
846           break;
847         case ED_BUTTON_UP:
848           if (level_ypos>=0)
849           {
850             if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
851               break;
852             if (lev_fieldy<2*SCR_FIELDY-2)
853               break;
854
855             level_ypos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
856             if (level_ypos<-1)
857               level_ypos = -1;
858             if (button==1)
859               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN);
860             else
861               DrawMiniLevel(level_xpos,level_ypos);
862           }
863           break;
864         case ED_BUTTON_DOWN:
865           if (level_ypos<=lev_fieldy-2*SCR_FIELDY)
866           {
867             if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
868               break;
869             if (lev_fieldy<2*SCR_FIELDY-2)
870               break;
871
872             level_ypos += (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
873             if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
874               level_ypos = lev_fieldy-2*SCR_FIELDY+1;
875             if (button==1)
876               ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP);
877             else
878               DrawMiniLevel(level_xpos,level_ypos);
879           }
880           break;
881         default:
882           break;
883       }
884
885       if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
886       {
887         int new_element;
888
889         if (button && !motion_status)
890           in_field_pressed = TRUE;
891
892         if (!button || !in_field_pressed || button<1 || button>3 ||
893             (y==0 && level_ypos<0) ||
894             (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY) ||
895             (x==0 && level_xpos<0) ||
896             (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
897             x>lev_fieldx || y>lev_fieldy)
898           return;
899
900         new_element = (button==1 ? new_element1 :
901                        button==2 ? new_element2 :
902                        button==3 ? new_element3 : 0);
903
904         if (new_element != Feld[x+level_xpos][y+level_ypos])
905         {
906           if (new_element==EL_SPIELFIGUR) /* Jeder nur EINE Figur bitte... */
907           {
908             int x,y;
909
910             for(x=0;x<lev_fieldx;x++) for(y=0;y<lev_fieldy;y++)
911             {
912               if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
913               {
914                 Feld[x][y] = EL_LEERRAUM;
915                 if (x-level_xpos>=0 && x-level_xpos<2*SCR_FIELDX &&
916                     y-level_ypos>=0 && y-level_ypos<2*SCR_FIELDY)
917                   DrawMiniElement(x-level_xpos,y-level_ypos,EL_LEERRAUM);
918               }
919             }
920           }
921
922           Feld[x+level_xpos][y+level_ypos] = new_element;
923           DrawMiniElement(x,y,new_element);
924         }
925       }
926       else if (!motion_status)  /* Mauszeiger nicht im Level-Feld */
927         in_field_pressed = FALSE;
928     }
929     else                        /********** KONTROLL-FENSTER **********/
930     {
931       int choice = CheckCountButtons(mx,my,button);
932       int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0);
933
934       if (choice >= 0 && choice < 36 &&
935           DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
936       {
937         if (!(choice % 2))
938           step = -step;
939
940         choice /= 2;
941
942         if (choice<11)
943         {
944           level.score[choice] += step;
945           if (level.score[choice]<0)
946             level.score[choice] = 0;
947           else if (level.score[choice]>255)
948             level.score[choice] = 255;
949         }
950         else if (choice==11)
951         {
952           level.tempo_amoebe += step;
953           if (level.tempo_amoebe<0)
954             level.tempo_amoebe = 0;
955           else if (level.tempo_amoebe>255)
956             level.tempo_amoebe = 255;
957         }
958         else if (choice==12)
959         {
960           level.dauer_sieb += step;
961           if (level.dauer_sieb<0)
962             level.dauer_sieb = 0;
963           else if (level.dauer_sieb>255)
964             level.dauer_sieb = 255;
965         }
966         else if (choice==13)
967         {
968           level.dauer_ablenk += step;
969           if (level.dauer_ablenk<0)
970             level.dauer_ablenk = 0;
971           else if (level.dauer_ablenk>255)
972             level.dauer_ablenk = 255;
973         }
974         else if (choice==14)
975         {
976           level.edelsteine += step;
977           if (level.edelsteine<0)
978             level.edelsteine = 0;
979           else if (level.edelsteine>999)
980             level.edelsteine = 999;
981         }
982         else if (choice==15)
983         {
984           level.time += step;
985           if (level.time<0)
986             level.time = 0;
987           else if (level.time>999)
988             level.time = 999;
989         }
990         else if (choice==16)
991         {
992           lev_fieldx += step;
993           if (lev_fieldx<MIN_LEV_FIELDX)
994             lev_fieldx = MIN_LEV_FIELDX;
995           else if (lev_fieldx>MAX_LEV_FIELDX)
996             lev_fieldx = MAX_LEV_FIELDX;
997           level.fieldx = lev_fieldx;
998         }
999         else if (choice==17)
1000         {
1001           lev_fieldy += step;
1002           if (lev_fieldy<MIN_LEV_FIELDY)
1003             lev_fieldy = MIN_LEV_FIELDY;
1004           else if (lev_fieldy>MAX_LEV_FIELDY)
1005             lev_fieldy = MAX_LEV_FIELDY;
1006           level.fieldy = lev_fieldy;
1007         }
1008
1009         if (choice<11)
1010           DrawText(ED_COUNT_VALUE_XPOS,
1011                    ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1012                    int2str(level.score[choice],3),FS_SMALL,FC_YELLOW);
1013         else if (choice==11)
1014           DrawText(ED_COUNT_VALUE_XPOS,
1015                    ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
1016                    int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
1017         else if (choice==12)
1018           DrawText(ED_COUNT_VALUE_XPOS,
1019                    ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
1020                    int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
1021         else if (choice==13)
1022           DrawText(ED_COUNT_VALUE_XPOS,
1023                    ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
1024                    int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
1025         else if (choice==14)
1026           DrawText(ED_COUNT_VALUE_XPOS,
1027                    ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
1028                    int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
1029         else if (choice==15)
1030           DrawText(ED_COUNT_VALUE_XPOS,
1031                    ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
1032                    int2str(level.time,3),FS_SMALL,FC_YELLOW);
1033         else if (choice==16)
1034           DrawText(ED_SIZE_VALUE_XPOS,
1035                    ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
1036                    int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
1037         else if (choice==17)
1038           DrawText(ED_SIZE_VALUE_XPOS,
1039                    ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
1040                    int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
1041
1042         redraw_mask &= ~REDRAW_FIELD;
1043         if (choice<16)
1044           XCopyArea(display,drawto,window,gc,
1045                     ED_COUNT_VALUE_XPOS,
1046                     ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1047                     3*FONT2_XSIZE,FONT2_YSIZE,
1048                     ED_COUNT_VALUE_XPOS,
1049                     ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE);
1050         else
1051           XCopyArea(display,drawto,window,gc,
1052                     ED_SIZE_VALUE_XPOS,
1053                     ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE,
1054                     3*FONT2_XSIZE,FONT2_YSIZE,
1055                     ED_SIZE_VALUE_XPOS,
1056                     ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE);
1057         XFlush(display);
1058       }
1059
1060       switch(CheckCtrlButtons(mx,my,button))
1061       {
1062         case ED_BUTTON_EDIT:
1063           CloseDoor(DOOR_CLOSE_2);
1064           AdjustLevelScrollPosition();
1065           DrawMiniLevel(level_xpos,level_ypos);
1066           XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1067                     DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
1068                     VXSIZE,VYSIZE,
1069                     DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1070           OpenDoor(DOOR_OPEN_2);
1071           edit_mode = TRUE;
1072           break;
1073         case ED_BUTTON_CLEAR:
1074           if (Request("Are you sure to clear this level ?",REQ_ASK))
1075           {
1076             for(x=0;x<MAX_LEV_FIELDX;x++) 
1077               for(y=0;y<MAX_LEV_FIELDY;y++) 
1078                 Feld[x][y] = EL_ERDREICH;
1079             DrawMiniLevel(level_xpos,level_ypos);
1080           }
1081           break;
1082         case ED_BUTTON_UNDO:
1083           if (leveldir[leveldir_nr].readonly ||
1084               Request("Exit without saving ?",REQ_ASK | REQ_STAY_OPEN))
1085           {
1086             CloseDoor(DOOR_CLOSE_BOTH);
1087             game_status=MAINMENU;
1088             DrawMainMenu();
1089           }
1090           else
1091           {
1092             CloseDoor(DOOR_CLOSE_1);
1093             OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1094           }
1095           break;
1096         case ED_BUTTON_EXIT:
1097           {
1098             int figur_vorhanden = FALSE;
1099
1100             if (leveldir[leveldir_nr].readonly)
1101             {
1102               Request("This level is read only !",REQ_CONFIRM);
1103               break;
1104             }
1105
1106             for(y=0;y<lev_fieldy;y++) 
1107               for(x=0;x<lev_fieldx;x++)
1108                 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1) 
1109                   figur_vorhanden = TRUE;
1110
1111             if (!figur_vorhanden)
1112               Request("No Level without Gregor Mc Duffin please !",
1113                          REQ_CONFIRM);
1114             else
1115             {
1116               if (Request("Save this level and kill the old ?",
1117                              REQ_ASK | REQ_STAY_OPEN))
1118               {
1119                 for(x=0;x<lev_fieldx;x++)
1120                   for(y=0;y<lev_fieldy;y++) 
1121                     Ur[x][y]=Feld[x][y];
1122                 SaveLevel(level_nr);
1123               }
1124               CloseDoor(DOOR_CLOSE_BOTH);
1125               game_status=MAINMENU;
1126               DrawMainMenu();
1127             }
1128           }
1129           break;
1130         default:
1131           break;
1132       }
1133
1134       if (mx>=ED_COUNT_GADGET_XPOS &&
1135           mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
1136           my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
1137           my<ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE+ED_WIN_COUNT_YSIZE)
1138       {
1139         if (!name_typing)
1140         {
1141           name_typing = TRUE;
1142           DrawText(ED_COUNT_GADGET_XPOS+5,
1143                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1144                    level.name,FS_SMALL,FC_GREEN);
1145           DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1146                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1147                    "<",FS_SMALL,FC_RED);
1148         }
1149       }
1150       else
1151       {
1152         if (name_typing)
1153         {
1154           name_typing = FALSE;
1155           DrawText(ED_COUNT_GADGET_XPOS+5,
1156                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1157                    level.name,FS_SMALL,FC_YELLOW);
1158           DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1159                    ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1160                    " ",FS_SMALL,FC_RED);
1161         }
1162       }
1163
1164       if (mx>=SX+29*MINI_TILEX && mx<SX+30*MINI_TILEX &&
1165           my>=SY+26*MINI_TILEY && my<SY+27*MINI_TILEY)
1166       {
1167         int new_element;
1168
1169         if (!button || button<1 || button>3)
1170           return;
1171
1172         new_element = (button==1 ? new_element1 :
1173                        button==2 ? new_element2 :
1174                        button==3 ? new_element3 : 0);
1175
1176         if (new_element != level.amoebe_inhalt)
1177         {
1178           level.amoebe_inhalt = new_element;
1179           DrawMiniElement(29,26,new_element);
1180         }
1181       }
1182
1183       if (mx>=SX+1*MINI_TILEX && mx<SX+(1+4*5)*MINI_TILEX &&
1184           my>=SY+2*MINI_TILEY && my<SY+(2+3)*MINI_TILEY)
1185       {
1186         int x = (mx-SX-1*MINI_TILEX)/MINI_TILEX;
1187         int y = (my-SY-2*MINI_TILEY)/MINI_TILEY;
1188         int i = x/5;
1189         int new_element;
1190
1191         x = x-i*5;
1192         if (i>=0 && i<43 && x>=0 && x<3 && y>=0 && y<3)
1193         {
1194           if (button && !motion_status)
1195             in_field_pressed = TRUE;
1196
1197           if (!button || !in_field_pressed || button<1 || button>3)
1198             return;
1199
1200           new_element = (button==1 ? new_element1 :
1201                          button==2 ? new_element2 :
1202                          button==3 ? new_element3 : 0);
1203
1204           if (new_element != level.mampfer_inhalt[i][x][y])
1205           {
1206             level.mampfer_inhalt[i][x][y] = new_element;
1207             DrawMiniElement(1+5*i+x,2+y,new_element);
1208           }
1209         }
1210         else if (!motion_status)/* Mauszeiger nicht im Cruncher-Feld */
1211           in_field_pressed = FALSE;
1212       }
1213       else if (!motion_status)  /* Mauszeiger nicht im Cruncher-Feld */
1214         in_field_pressed = FALSE;
1215     }
1216   }
1217
1218   last_button = button;
1219
1220   BackToFront();
1221 }
1222
1223 void LevelNameTyping(KeySym key)
1224 {
1225   unsigned char ascii = 0;
1226   int len = strlen(level.name);
1227
1228   if (!name_typing)
1229     return;
1230
1231   if (key>=XK_A && key<=XK_Z)
1232     ascii = 'A'+(char)(key-XK_A);
1233   else if (key>=XK_a && key<=XK_z)
1234     ascii = 'a'+(char)(key-XK_a);
1235   else if (key>=XK_0 && key<=XK_9)
1236     ascii = '0'+(char)(key-XK_0);
1237 #ifdef XK_LATIN1
1238   else if (key>=XK_space && key<=XK_at)
1239     ascii = ' '+(char)(key-XK_space);
1240   else if (key==XK_Adiaeresis)
1241     ascii = 'Ä';
1242   else if (key==XK_Odiaeresis)
1243     ascii = 'Ö';
1244   else if (key==XK_Udiaeresis)
1245     ascii = 'Ü';
1246   else if (key==XK_adiaeresis)
1247     ascii = 'ä';
1248   else if (key==XK_odiaeresis)
1249     ascii = 'ö';
1250   else if (key==XK_udiaeresis)
1251     ascii = 'ü';
1252   else if (key==XK_underscore)
1253     ascii = '_';
1254 #endif
1255
1256   if (ascii && len<MAX_LEVNAMLEN-2)
1257   {
1258     level.name[len] = ascii;
1259     level.name[len+1] = 0;
1260     len++;
1261
1262     DrawTextExt(drawto,gc,
1263                 ED_COUNT_GADGET_XPOS+5,
1264                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1265                 level.name,FS_SMALL,FC_GREEN);
1266     DrawTextExt(window,gc,
1267                 ED_COUNT_GADGET_XPOS+5,
1268                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1269                 level.name,FS_SMALL,FC_GREEN);
1270     DrawTextExt(drawto,gc,
1271                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1272                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1273                 "<",FS_SMALL,FC_RED);
1274     DrawTextExt(window,gc,
1275                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1276                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1277                 "<",FS_SMALL,FC_RED);
1278   }
1279   else if ((key==XK_Delete || key==XK_BackSpace) && len>0)
1280   {
1281     level.name[len-1] = 0;
1282     len--;
1283
1284     DrawTextExt(drawto,gc,
1285                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1286                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1287                 "< ",FS_SMALL,FC_GREEN);
1288     DrawTextExt(window,gc,
1289                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1290                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1291                 "< ",FS_SMALL,FC_GREEN);
1292   }
1293   else if (key==XK_Return)
1294   {
1295     DrawTextExt(drawto,gc,
1296                 ED_COUNT_GADGET_XPOS+5,
1297                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1298                 level.name,FS_SMALL,FC_YELLOW);
1299     DrawTextExt(window,gc,
1300                 ED_COUNT_GADGET_XPOS+5,
1301                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1302                 level.name,FS_SMALL,FC_YELLOW);
1303     DrawTextExt(drawto,gc,
1304                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1305                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1306                 " ",FS_SMALL,FC_YELLOW);
1307     DrawTextExt(window,gc,
1308                 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1309                 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1310                 " ",FS_SMALL,FC_YELLOW);
1311
1312     name_typing = FALSE;
1313   }
1314 }