1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
22 /* positions in the level editor */
23 #define ED_WIN_MB_LEFT_XPOS 7
24 #define ED_WIN_MB_LEFT_YPOS 6
25 #define ED_WIN_LEVELNR_XPOS 77
26 #define ED_WIN_LEVELNR_YPOS 7
27 #define ED_WIN_MB_MIDDLE_XPOS 7
28 #define ED_WIN_MB_MIDDLE_YPOS 258
29 #define ED_WIN_MB_RIGHT_XPOS 77
30 #define ED_WIN_MB_RIGHT_YPOS 258
32 /* other constants for the editor */
33 #define ED_SCROLL_NO 0
34 #define ED_SCROLL_LEFT 1
35 #define ED_SCROLL_RIGHT 2
36 #define ED_SCROLL_UP 4
37 #define ED_SCROLL_DOWN 8
39 /* screens in the level editor */
40 #define ED_MODE_DRAWING 0
41 #define ED_MODE_INFO 1
42 #define ED_MODE_PROPERTIES 2
44 /* how many steps can be cancelled */
45 #define NUM_UNDO_STEPS (10 + 1)
47 /* values for random placement */
48 #define RANDOM_USE_PERCENTAGE 0
49 #define RANDOM_USE_NUM_OBJECTS 1
51 /* values for the control window */
52 #define ED_CTRL_BUTTONS_GFX_YPOS 236
53 #define ED_CTRL1_BUTTONS_HORIZ 4
54 #define ED_CTRL1_BUTTONS_VERT 4
55 #define ED_CTRL1_BUTTON_XSIZE 22
56 #define ED_CTRL1_BUTTON_YSIZE 22
57 #define ED_CTRL1_BUTTONS_XPOS 6
58 #define ED_CTRL1_BUTTONS_YPOS 6
59 #define ED_CTRL2_BUTTONS_HORIZ 3
60 #define ED_CTRL2_BUTTONS_VERT 2
61 #define ED_CTRL2_BUTTON_XSIZE 30
62 #define ED_CTRL2_BUTTON_YSIZE 20
63 #define ED_CTRL2_BUTTONS_XPOS 5
64 #define ED_CTRL2_BUTTONS_YPOS 100
65 #define ED_NUM_CTRL1_BUTTONS (ED_CTRL1_BUTTONS_HORIZ * ED_CTRL1_BUTTONS_VERT)
66 #define ED_NUM_CTRL2_BUTTONS (ED_CTRL2_BUTTONS_HORIZ * ED_CTRL2_BUTTONS_VERT)
67 #define ED_NUM_CTRL_BUTTONS (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS)
69 /* values for other gadgets */
70 #define ED_SCORE_XPOS TILEX
71 #define ED_SCORE_YPOS (7 * TILEY)
72 #define ED_COUNT_VALUE_XOFFSET 5
73 #define ED_COUNT_VALUE_YOFFSET 3
75 /* control button identifiers */
76 #define ED_CTRL_ID_SINGLE_ITEMS 0
77 #define ED_CTRL_ID_CONNECTED_ITEMS 1
78 #define ED_CTRL_ID_LINE 2
79 #define ED_CTRL_ID_TEXT 3
80 #define ED_CTRL_ID_RECTANGLE 4
81 #define ED_CTRL_ID_FILLED_BOX 5
82 #define ED_CTRL_ID_WRAP_UP 6
83 #define ED_CTRL_ID_PROPERTIES 7
84 #define ED_CTRL_ID_FLOOD_FILL 8
85 #define ED_CTRL_ID_WRAP_LEFT 9
86 #define ED_CTRL_ID_WRAP_RIGHT 11
87 #define ED_CTRL_ID_RANDOM_PLACEMENT 12
88 #define ED_CTRL_ID_BRUSH 13
89 #define ED_CTRL_ID_WRAP_DOWN 14
90 #define ED_CTRL_ID_UNDO 16
91 #define ED_CTRL_ID_INFO 17
92 #define ED_CTRL_ID_SAVE 18
93 #define ED_CTRL_ID_CLEAR 19
94 #define ED_CTRL_ID_TEST 20
95 #define ED_CTRL_ID_EXIT 21
97 /* counter button identifiers */
98 #define ED_CTRL_ID_SCORE_DOWN 22
99 #define ED_CTRL_ID_SCORE_UP 23
101 /* drawing area identifiers */
102 #define ED_CTRL_ID_DRAWING_LEVEL 24
104 #define ED_NUM_GADGETS 25
106 /* values for counter gadgets */
107 #define ED_COUNTER_SCORE 0
109 #define ED_NUM_COUNTERS 1
115 } counter_info[ED_NUM_COUNTERS] =
117 { ED_SCORE_XPOS, ED_SCORE_YPOS, ED_CTRL_ID_SCORE_DOWN }
120 /* forward declaration for internal use */
121 static void DrawDrawingWindow();
122 static void DrawPropertiesWindow(int);
123 static void CopyLevelToUndoBuffer();
124 static void HandleDrawingAreas(struct GadgetInfo *);
125 static void HandleCounterButtons(struct GadgetInfo *);
126 static void HandleControlButtons(struct GadgetInfo *);
128 static struct GadgetInfo *level_editor_gadget[ED_NUM_GADGETS];
129 static boolean level_editor_gadgets_created = FALSE;
131 static int drawing_function = ED_CTRL_ID_SINGLE_ITEMS;
133 static short OrigBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
134 static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY];
135 static int undo_buffer_position = 0;
136 static int undo_buffer_steps = 0;
138 static int random_placement_percentage = 10;
139 static int random_placement_num_objects = 10;
141 static int random_placement_method = RANDOM_USE_PERCENTAGE;
143 static int random_placement_method = RANDOM_USE_NUM_OBJECTS;
146 /* pointer to score value */
147 static int *gadget_score_value;
149 static int level_xpos,level_ypos;
150 static int edit_mode;
151 static boolean name_typing;
152 static int new_element1 = EL_MAUERWERK;
153 static int new_element2 = EL_LEERRAUM;
154 static int new_element3 = EL_ERDREICH;
157 int editor_element[] =
159 EL_CHAR_A + ('B' - 'A'),
160 EL_CHAR_A + ('O' - 'A'),
161 EL_CHAR_A + ('U' - 'A'),
162 EL_CHAR_A + ('L' - 'A'),
165 EL_CHAR_A + ('D' - 'A'),
166 EL_CHAR_A + ('E' - 'A'),
167 EL_CHAR_A + ('R' - 'A'),
169 EL_CHAR_A + ('D' - 'A'),
170 EL_CHAR_A + ('A' - 'A'),
171 EL_CHAR_A + ('S' - 'A'),
172 EL_CHAR_A + ('H' - 'A'),
199 EL_CHAR_A + ('E' - 'A'),
200 EL_CHAR_A + ('M' - 'A'),
201 EL_CHAR_A + ('E' - 'A'),
204 EL_CHAR_A + ('R' - 'A'),
205 EL_CHAR_A + ('A' - 'A'),
206 EL_CHAR_A + ('L' - 'A'),
207 EL_CHAR_A + ('D' - 'A'),
209 EL_CHAR_A + ('M' - 'A'),
210 EL_CHAR_A + ('I' - 'A'),
211 EL_CHAR_A + ('N' - 'A'),
212 EL_CHAR_A + ('E' - 'A'),
289 EL_CHAR_A + ('M' - 'A'),
290 EL_CHAR_A + ('O' - 'A'),
291 EL_CHAR_A + ('R' - 'A'),
292 EL_CHAR_A + ('E' - 'A'),
339 EL_CHAR_A + ('S' - 'A'),
340 EL_CHAR_A + ('O' - 'A'),
341 EL_CHAR_A + ('K' - 'A'),
342 EL_CHAR_A + ('O' - 'A'),
345 EL_CHAR_A + ('B' - 'A'),
346 EL_CHAR_A + ('A' - 'A'),
347 EL_CHAR_A + ('N' - 'A'),
350 EL_SOKOBAN_FELD_LEER,
351 EL_SOKOBAN_FELD_VOLL,
355 EL_CHAR_A + ('D' - 'A'),
356 EL_CHAR_A + ('Y' - 'A'),
357 EL_CHAR_A + ('N' - 'A'),
358 EL_CHAR_A + ('A' - 'A'),
360 EL_CHAR_A + ('B' - 'A'),
361 EL_CHAR_A + ('L' - 'A'),
362 EL_CHAR_A + ('A' - 'A'),
363 EL_CHAR_A + ('S' - 'A'),
366 EL_CHAR_A + ('T' - 'A'),
367 EL_CHAR_A + ('E' - 'A'),
368 EL_CHAR_A + ('R' - 'A'),
450 int elements_in_list = sizeof(editor_element)/sizeof(int);
452 static void ScrollMiniLevel(int from_x, int from_y, int scroll)
455 int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
456 int dy = (scroll==ED_SCROLL_UP ? -1 : scroll==ED_SCROLL_DOWN ? 1 : 0);
458 XCopyArea(display,drawto,drawto,gc,
459 SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
460 SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
461 SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
464 x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
465 for(y=0;y<2*SCR_FIELDY;y++)
466 DrawMiniElementOrWall(x,y,from_x,from_y);
470 y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
471 for(x=0;x<2*SCR_FIELDX;x++)
472 DrawMiniElementOrWall(x,y,from_x,from_y);
475 redraw_mask |= REDRAW_FIELD;
479 void InitLevelEditorGadgets()
483 for (i=0; i<ED_NUM_GADGETS; i++)
484 level_editor_gadget[i] = NULL;
487 static void CreateControlButtons()
491 for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
493 Pixmap gd_pixmap = pix[PIX_DOOR];
494 struct GadgetInfo *gi;
495 int gd_xoffset, gd_yoffset;
496 int gd_x1, gd_x2, gd_y;
498 unsigned long event_mask;
501 if (i < ED_NUM_CTRL1_BUTTONS)
503 int x = i % ED_CTRL1_BUTTONS_HORIZ;
504 int y = i / ED_CTRL1_BUTTONS_HORIZ;
506 gd_xoffset = ED_CTRL1_BUTTONS_XPOS + x * ED_CTRL1_BUTTON_XSIZE;
507 gd_yoffset = ED_CTRL1_BUTTONS_YPOS + y * ED_CTRL1_BUTTON_YSIZE;
508 width = ED_CTRL1_BUTTON_XSIZE;
509 height = ED_CTRL1_BUTTON_YSIZE;
513 int x = (i - ED_NUM_CTRL1_BUTTONS) % ED_CTRL2_BUTTONS_HORIZ;
514 int y = (i - ED_NUM_CTRL1_BUTTONS) / ED_CTRL2_BUTTONS_HORIZ;
516 gd_xoffset = ED_CTRL2_BUTTONS_XPOS + x * ED_CTRL2_BUTTON_XSIZE;
517 gd_yoffset = ED_CTRL2_BUTTONS_YPOS + y * ED_CTRL2_BUTTON_YSIZE;
518 width = ED_CTRL2_BUTTON_XSIZE;
519 height = ED_CTRL2_BUTTON_YSIZE;
522 gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
523 gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
524 gd_y = DOOR_GFX_PAGEY1 + ED_CTRL_BUTTONS_GFX_YPOS + gd_yoffset;
526 if (i == ED_CTRL_ID_WRAP_LEFT ||
527 i == ED_CTRL_ID_WRAP_RIGHT ||
528 i == ED_CTRL_ID_WRAP_UP ||
529 i == ED_CTRL_ID_WRAP_DOWN)
530 event_mask = GD_EVENT_PRESSED_REPEATED;
532 event_mask = GD_EVENT_RELEASED;
534 gi = CreateGadget(GDI_CUSTOM_ID, id,
535 GDI_X, EX + gd_xoffset,
536 GDI_Y, EY + gd_yoffset,
539 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
540 GDI_STATE, GD_BUTTON_UNPRESSED,
541 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
542 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
543 GDI_EVENT_MASK, event_mask,
544 GDI_CALLBACK, HandleControlButtons,
548 Error(ERR_EXIT, "cannot create gadget");
550 level_editor_gadget[id] = gi;
558 static void test1(struct GadgetInfo *gi)
560 int event_type = gi->event.type;
562 printf("HandleControlButtons: (%d,%d) (%d,%d) [%d] ",
564 gi->event.x, gi->event.y, gi->event.button);
566 if (event_type == GD_EVENT_PRESSED)
567 printf("GD_EVENT_PRESSED\n");
568 else if (event_type == GD_EVENT_RELEASED)
569 printf("GD_EVENT_RELEASED\n");
570 else if (event_type == GD_EVENT_MOVING)
571 printf("GD_EVENT_MOVING\n");
580 static void CreateCounterButtons(int counter_id)
586 Pixmap gd_pixmap = pix[PIX_DOOR];
587 struct GadgetInfo *gi;
589 int gd_x1, gd_x2, gd_y;
590 int id = counter_info[counter_id].gadget_id + i;
592 gd_xoffset = (i == 0 ? ED_BUTTON_MINUS_XPOS : ED_BUTTON_PLUS_XPOS);
593 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
594 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
595 gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_COUNT_YPOS;
597 gi = CreateGadget(GDI_CUSTOM_ID, id,
598 GDI_X, SX + counter_info[counter_id].x + gd_xoffset,
599 GDI_Y, SY + counter_info[counter_id].y,
600 GDI_WIDTH, ED_BUTTON_COUNT_XSIZE,
601 GDI_HEIGHT, ED_BUTTON_COUNT_YSIZE,
602 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
603 GDI_STATE, GD_BUTTON_UNPRESSED,
604 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
605 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
606 GDI_EVENT_MASK, GD_EVENT_PRESSED_REPEATED,
607 GDI_CALLBACK, HandleCounterButtons,
611 Error(ERR_EXIT, "cannot create gadget");
613 level_editor_gadget[id] = gi;
617 static void CreateDrawingAreas()
619 struct GadgetInfo *gi;
620 unsigned long event_mask;
622 event_mask = GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING;
624 gi = CreateGadget(GDI_CUSTOM_ID, ED_CTRL_ID_DRAWING_LEVEL,
629 GDI_TYPE, GD_TYPE_DRAWING_AREA,
630 GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
631 GDI_EVENT_MASK, event_mask,
632 GDI_CALLBACK, HandleDrawingAreas,
636 Error(ERR_EXIT, "cannot create gadget");
638 level_editor_gadget[ED_CTRL_ID_DRAWING_LEVEL] = gi;
641 static void CreateLevelEditorGadgets()
643 if (level_editor_gadgets_created)
646 CreateControlButtons();
647 CreateCounterButtons(ED_COUNTER_SCORE);
648 CreateDrawingAreas();
650 level_editor_gadgets_created = TRUE;
653 static void MapControlButtons()
657 for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
658 MapGadget(level_editor_gadget[i]);
661 static void MapCounterButtons(int counter_id)
666 MapGadget(level_editor_gadget[counter_info[counter_id].gadget_id + i]);
669 static void MapMainDrawingArea()
671 MapGadget(level_editor_gadget[ED_CTRL_ID_DRAWING_LEVEL]);
674 void UnmapLevelEditorWindowGadgets()
678 for (i=ED_NUM_CTRL_BUTTONS; i<ED_NUM_GADGETS; i++)
679 UnmapGadget(level_editor_gadget[i]);
682 void UnmapLevelEditorGadgets()
686 for (i=0; i<ED_NUM_GADGETS; i++)
687 UnmapGadget(level_editor_gadget[i]);
692 int i, x, y, graphic;
696 edit_mode = ED_MODE_DRAWING;
700 CloseDoor(DOOR_CLOSE_ALL);
702 if (level_editor_test_game)
704 for(x=0; x<lev_fieldx; x++)
705 for(y=0; y<lev_fieldy; y++)
706 Feld[x][y] = Ur[x][y];
708 for(x=0; x<lev_fieldx; x++)
709 for(y=0; y<lev_fieldy; y++)
710 Ur[x][y] = OrigBackup[x][y];
712 level_editor_test_game = FALSE;
716 undo_buffer_position = -1;
717 undo_buffer_steps = -1;
718 CopyLevelToUndoBuffer();
721 DrawMiniLevel(level_xpos,level_ypos);
724 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
725 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY1,
727 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
728 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
729 DOOR_GFX_PAGEX6+ED_BUTTON_ELEM_XPOS,
730 DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS,
731 4*ED_BUTTON_ELEM_XSIZE,5*ED_BUTTON_ELEM_YSIZE,
732 DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS,
733 DOOR_GFX_PAGEY1+ED_BUTTON_EUP_Y2POS);
735 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
737 if (i < elements_in_list)
738 graphic = el2gfx(editor_element[i]);
740 graphic = GFX_LEERRAUM;
742 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
743 DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS+3 +
744 (i%MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
745 DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS+3 +
746 (i/MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
750 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
751 DOOR_GFX_PAGEX1+ED_WIN_MB_LEFT_XPOS,
752 DOOR_GFX_PAGEY1+ED_WIN_MB_LEFT_YPOS,
753 el2gfx(new_element1));
754 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
755 DOOR_GFX_PAGEX1+ED_WIN_MB_MIDDLE_XPOS,
756 DOOR_GFX_PAGEY1+ED_WIN_MB_MIDDLE_YPOS,
757 el2gfx(new_element2));
758 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
759 DOOR_GFX_PAGEX1+ED_WIN_MB_RIGHT_XPOS,
760 DOOR_GFX_PAGEY1+ED_WIN_MB_RIGHT_YPOS,
761 el2gfx(new_element3));
762 DrawTextExt(pix[PIX_DB_DOOR],gc,
763 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS,
764 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
765 int2str(level_nr,2),FS_SMALL,FC_SPECIAL1);
766 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
767 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+3,
768 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
770 DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS,
771 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
772 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
773 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+14,
774 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
776 DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS+9,
777 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
779 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
780 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
782 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
784 /* draw bigger door */
785 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
790 /* draw new control window */
791 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
792 DOOR_GFX_PAGEX8, 236,
796 redraw_mask |= REDRAW_ALL;
798 OpenDoor(DOOR_OPEN_1);
800 if (!level_editor_gadgets_created)
801 CreateLevelEditorGadgets();
804 MapMainDrawingArea();
807 OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
811 void DrawControlWindow()
816 UnmapLevelEditorWindowGadgets();
818 /* Inhalt der Mampfer */
819 DrawText(ED_COUNT_GADGET_XPOS+1,SY+6,
820 "Contents of a smashed cruncher:",FS_SMALL,FC_YELLOW);
821 for(i=0;i<4;i++) for(y=0;y<4;y++) for(x=0;x<4;x++)
823 DrawMiniElement(1+5*i+x,2+y,EL_ERDREICH);
824 XFillRectangle(display,drawto,gc,
825 SX+(1+5*i)*MINI_TILEX+MINI_TILEX/2-1,
826 SY+(2)*MINI_TILEY+MINI_TILEY/2-1,
827 3*MINI_TILEX+2,3*MINI_TILEY+2);
829 XCopyArea(display,drawto,drawto,gc,
830 SX+1*MINI_TILEX,SY+2*MINI_TILEY,
831 4*5*MINI_TILEX,5*MINI_TILEY,
832 SX+1*MINI_TILEX-MINI_TILEX/2,SY+2*MINI_TILEY-MINI_TILEY/2);
835 for(y=0;y<3;y++) for(x=0;x<3;x++)
836 DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
838 DrawText(SX+MINI_TILEX+(5*i+1)*MINI_TILEX+1,
839 SY+2*MINI_TILEY+(4)*MINI_TILEY-4,
840 int2str(i+1,1),FS_SMALL,FC_YELLOW);
843 /* Inhalt der Amöbe */
844 for(y=0;y<2;y++) for(x=0;x<2;x++)
846 DrawMiniElement(29+x,26+y,EL_ERDREICH);
847 XFillRectangle(display,drawto,gc,
848 SX+29*MINI_TILEX+MINI_TILEX/2-1,
849 SY+26*MINI_TILEY+MINI_TILEY/2-1,
850 MINI_TILEX+2,MINI_TILEY+2);
852 XCopyArea(display,drawto,drawto,gc,
853 SX+29*MINI_TILEX,SY+26*MINI_TILEY,
854 3*MINI_TILEX,3*MINI_TILEY,
855 SX+29*MINI_TILEX-MINI_TILEX/2,SY+26*MINI_TILEY-MINI_TILEY/2);
856 DrawMiniElement(29,26,level.amoebe_inhalt);
858 for(i=0;i<11+3+2;i++)
860 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
861 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
862 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
863 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
864 ED_COUNT_GADGET_XPOS,
865 ED_COUNT_GADGET_YPOS+i*ED_COUNT_GADGET_YSIZE);
868 DrawText(ED_COUNT_VALUE_XPOS,
869 ED_COUNT_VALUE_YPOS+i*ED_COUNT_GADGET_YSIZE,
870 int2str(level.score[i],3),FS_SMALL,FC_YELLOW);
872 DrawText(ED_COUNT_VALUE_XPOS,
873 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
874 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
876 DrawText(ED_COUNT_VALUE_XPOS,
877 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
878 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
880 DrawText(ED_COUNT_VALUE_XPOS,
881 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
882 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
884 DrawText(ED_COUNT_VALUE_XPOS,
885 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
886 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
888 DrawText(ED_COUNT_VALUE_XPOS,
889 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
890 int2str(level.time,3),FS_SMALL,FC_YELLOW);
893 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+0*ED_COUNT_TEXT_YSIZE,
894 "Score for Emerald",FS_SMALL,FC_YELLOW);
895 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+1*ED_COUNT_TEXT_YSIZE,
896 "Score for Diamond",FS_SMALL,FC_YELLOW);
897 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+2*ED_COUNT_TEXT_YSIZE,
898 "Score for smashing a Bug",FS_SMALL,FC_YELLOW);
899 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+3*ED_COUNT_TEXT_YSIZE,
900 "Score for smashing a Spaceship",FS_SMALL,FC_YELLOW);
901 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+4*ED_COUNT_TEXT_YSIZE,
902 "Score for smashing a Cruncher",FS_SMALL,FC_YELLOW);
903 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+5*ED_COUNT_TEXT_YSIZE,
904 "Score for smashing an Alien",FS_SMALL,FC_YELLOW);
905 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+6*ED_COUNT_TEXT_YSIZE,
906 "Score for smashing a Pacman",FS_SMALL,FC_YELLOW);
907 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+7*ED_COUNT_TEXT_YSIZE,
908 "Score for cracking a nut",FS_SMALL,FC_YELLOW);
909 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+8*ED_COUNT_TEXT_YSIZE,
910 "Score for dynamite",FS_SMALL,FC_YELLOW);
911 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+9*ED_COUNT_TEXT_YSIZE,
912 "Score for key",FS_SMALL,FC_YELLOW);
913 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+10*ED_COUNT_TEXT_YSIZE,
914 "Score for each 10 seconds left",FS_SMALL,FC_YELLOW);
915 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+11*ED_COUNT_TEXT_YSIZE,
916 "Speed of the amoeba / Content",FS_SMALL,FC_YELLOW);
917 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+12*ED_COUNT_TEXT_YSIZE,
918 "Time for magic wall",FS_SMALL,FC_YELLOW);
919 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+13*ED_COUNT_TEXT_YSIZE,
920 "Time for wheel",FS_SMALL,FC_YELLOW);
921 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+14*ED_COUNT_TEXT_YSIZE,
922 "Emeralds needed in this level",FS_SMALL,FC_YELLOW);
923 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+15*ED_COUNT_TEXT_YSIZE,
924 "Time available for this level",FS_SMALL,FC_YELLOW);
926 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
927 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS,
928 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
929 ED_WIN_COUNT_XSIZE,ED_WIN_COUNT_YSIZE,
930 ED_COUNT_GADGET_XPOS,
931 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
933 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
934 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS+3+2*FONT2_XSIZE,
935 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
936 ED_WIN_COUNT_XSIZE-3-2*FONT2_XSIZE,ED_WIN_COUNT_YSIZE,
937 ED_COUNT_GADGET_XPOS+3+i*FONT2_XSIZE,
938 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
939 DrawText(ED_COUNT_GADGET_XPOS+5,
940 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
941 level.name,FS_SMALL,FC_YELLOW);
942 DrawText(ED_COUNT_GADGET_XPOS+(30+3)*FONT2_XSIZE-5,
943 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
944 "Title",FS_SMALL,FC_YELLOW);
946 DrawText(ED_SIZE_GADGET_XPOS,ED_SIZE_GADGET_YPOS-18,
947 "Playfield size:",FS_SMALL,FC_YELLOW);
948 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
949 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
950 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
951 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
953 ED_SIZE_GADGET_YPOS+0*ED_COUNT_GADGET_YSIZE);
954 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
955 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
956 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
957 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
959 ED_SIZE_GADGET_YPOS+1*ED_COUNT_GADGET_YSIZE);
960 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+0*ED_SIZE_TEXT_YSIZE,
961 "Width",FS_SMALL,FC_YELLOW);
962 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+1*ED_SIZE_TEXT_YSIZE,
963 "Height",FS_SMALL,FC_YELLOW);
964 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
965 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
966 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
967 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
970 void AdjustLevelScrollPosition()
974 if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1)
975 level_xpos = lev_fieldx - 2*SCR_FIELDX + 1;
976 if (lev_fieldx < 2*SCR_FIELDX - 2)
981 if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1)
982 level_ypos = lev_fieldy - 2*SCR_FIELDY + 1;
983 if (lev_fieldy < 2*SCR_FIELDY - 2)
987 void LevelEd(int mx, int my, int button)
989 static int last_button = 0;
990 static int in_field_pressed = FALSE;
991 static boolean use_floodfill = FALSE;
995 int x = (mx-SX)/MINI_TILEX;
996 int y = (my-SY)/MINI_TILEY;
1000 HandlePressedControlButtons();
1001 HandleDrawingFunctions(mx, my, button);
1004 if (use_floodfill) /********** FLOOD FILL **********/
1012 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
1017 if (x>lev_fieldx || y>lev_fieldy ||
1018 (x==0 && level_xpos<0) ||
1019 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
1020 (y==0 && level_ypos<0) ||
1021 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY))
1024 from_x = x+level_xpos;
1025 from_y = y+level_ypos;
1026 fill_element = (button==1 ? new_element1 :
1027 button==2 ? new_element2 :
1028 button==3 ? new_element3 : 0);
1030 FloodFill(from_x,from_y,fill_element);
1031 DrawMiniLevel(level_xpos,level_ypos);
1034 use_floodfill = FALSE;
1035 CloseDoor(DOOR_CLOSE_1);
1036 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1045 else /********** EDIT/CTRL-FENSTER **********/
1047 static unsigned long choice_delay = 0;
1048 int choice = CheckElemButtons(mx,my,button);
1049 int elem_pos = choice-ED_BUTTON_ELEM;
1051 if (((choice == ED_BUTTON_EUP && element_shift>0) ||
1052 (choice == ED_BUTTON_EDOWN &&
1053 element_shift<elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)) &&
1054 DelayReached(&choice_delay, GADGET_FRAME_DELAY))
1058 step = (button==1 ? MAX_ELEM_X : button==2 ? 5*MAX_ELEM_X :
1060 element_shift += (choice==ED_BUTTON_EUP ? -step : step);
1061 if (element_shift<0)
1063 if (element_shift>elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)
1064 element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y;
1065 if (element_shift % MAX_ELEM_X)
1066 element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X);
1068 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
1069 DrawElemButton(i+2,ED_BUTTON_RELEASED);
1071 else if (elem_pos>=0 && elem_pos<MAX_ELEM_X*MAX_ELEM_Y)
1075 if (elem_pos+element_shift < elements_in_list)
1076 new_element = editor_element[elem_pos+element_shift];
1078 new_element = EL_LEERRAUM;
1081 new_element1 = new_element;
1082 else if (last_button==2)
1083 new_element2 = new_element;
1084 else if (last_button==3)
1085 new_element3 = new_element;
1087 DrawMiniGraphicExt(drawto,gc,
1088 DX+ED_WIN_MB_LEFT_XPOS,
1089 DY+ED_WIN_MB_LEFT_YPOS,
1090 el2gfx(new_element1));
1091 DrawMiniGraphicExt(drawto,gc,
1092 DX+ED_WIN_MB_MIDDLE_XPOS,
1093 DY+ED_WIN_MB_MIDDLE_YPOS,
1094 el2gfx(new_element2));
1095 DrawMiniGraphicExt(drawto,gc,
1096 DX+ED_WIN_MB_RIGHT_XPOS,
1097 DY+ED_WIN_MB_RIGHT_YPOS,
1098 el2gfx(new_element3));
1099 redraw_mask |= REDRAW_DOOR_1;
1101 if (edit_mode == ED_MODE_PROPERTIES)
1102 DrawPropertiesWindow(new_element);
1105 if (edit_mode == ED_MODE_DRAWING) /********** EDIT-FENSTER **********/
1112 switch(CheckEditButtons(mx,my,button))
1114 case ED_BUTTON_CTRL:
1115 CloseDoor(DOOR_CLOSE_2);
1116 DrawControlWindow();
1117 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1118 DOOR_GFX_PAGEX4,DOOR_GFX_PAGEY1+80,
1120 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1121 OpenDoor(DOOR_OPEN_2);
1122 edit_mode = ED_MODE_INFO;
1124 case ED_BUTTON_FILL:
1125 Request("Caution ! Flood fill mode ! Choose area !",REQ_OPEN);
1126 use_floodfill = TRUE;
1129 case ED_BUTTON_LEFT:
1132 if (!DelayReached(&choice_delay, GADGET_FRAME_DELAY))
1134 if (lev_fieldx<2*SCR_FIELDX-2)
1137 level_xpos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
1141 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT);
1143 DrawMiniLevel(level_xpos,level_ypos);
1146 case ED_BUTTON_RIGHT:
1147 if (level_xpos<=lev_fieldx-2*SCR_FIELDX)
1149 if (!DelayReached(&choice_delay, GADGET_FRAME_DELAY))
1151 if (lev_fieldx<2*SCR_FIELDX-2)
1154 level_xpos += (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
1155 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
1156 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
1158 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT);
1160 DrawMiniLevel(level_xpos,level_ypos);
1166 if (!DelayReached(&choice_delay, GADGET_FRAME_DELAY))
1168 if (lev_fieldy<2*SCR_FIELDY-2)
1171 level_ypos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
1175 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN);
1177 DrawMiniLevel(level_xpos,level_ypos);
1180 case ED_BUTTON_DOWN:
1181 if (level_ypos<=lev_fieldy-2*SCR_FIELDY)
1183 if (!DelayReached(&choice_delay, GADGET_FRAME_DELAY))
1185 if (lev_fieldy<2*SCR_FIELDY-2)
1188 level_ypos += (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
1189 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
1190 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
1192 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP);
1194 DrawMiniLevel(level_xpos,level_ypos);
1207 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
1211 if (button && !motion_status)
1212 in_field_pressed = TRUE;
1214 if (!button || !in_field_pressed || button<1 || button>3 ||
1215 (y==0 && level_ypos<0) ||
1216 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY) ||
1217 (x==0 && level_xpos<0) ||
1218 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
1219 x>lev_fieldx || y>lev_fieldy)
1222 new_element = (button==1 ? new_element1 :
1223 button==2 ? new_element2 :
1224 button==3 ? new_element3 : 0);
1226 if (new_element != Feld[x+level_xpos][y+level_ypos])
1228 if (new_element==EL_SPIELFIGUR) /* Jeder nur EINE Figur bitte... */
1232 for(x=0;x<lev_fieldx;x++) for(y=0;y<lev_fieldy;y++)
1234 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
1236 Feld[x][y] = EL_LEERRAUM;
1237 if (x-level_xpos>=0 && x-level_xpos<2*SCR_FIELDX &&
1238 y-level_ypos>=0 && y-level_ypos<2*SCR_FIELDY)
1239 DrawMiniElement(x-level_xpos,y-level_ypos,EL_LEERRAUM);
1244 Feld[x+level_xpos][y+level_ypos] = new_element;
1245 DrawMiniElement(x,y,new_element);
1248 else if (!motion_status) /* Mauszeiger nicht im Level-Feld */
1249 in_field_pressed = FALSE;
1256 else if (edit_mode == ED_MODE_INFO)/********** KONTROLL-FENSTER **********/
1258 int choice = CheckCountButtons(mx,my,button);
1259 int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0);
1261 if (choice >= 0 && choice < 36 &&
1262 DelayReached(&choice_delay, GADGET_FRAME_DELAY))
1271 level.score[choice] += step;
1272 if (level.score[choice]<0)
1273 level.score[choice] = 0;
1274 else if (level.score[choice]>255)
1275 level.score[choice] = 255;
1277 else if (choice==11)
1279 level.tempo_amoebe += step;
1280 if (level.tempo_amoebe<0)
1281 level.tempo_amoebe = 0;
1282 else if (level.tempo_amoebe>255)
1283 level.tempo_amoebe = 255;
1285 else if (choice==12)
1287 level.dauer_sieb += step;
1288 if (level.dauer_sieb<0)
1289 level.dauer_sieb = 0;
1290 else if (level.dauer_sieb>255)
1291 level.dauer_sieb = 255;
1293 else if (choice==13)
1295 level.dauer_ablenk += step;
1296 if (level.dauer_ablenk<0)
1297 level.dauer_ablenk = 0;
1298 else if (level.dauer_ablenk>255)
1299 level.dauer_ablenk = 255;
1301 else if (choice==14)
1303 level.edelsteine += step;
1304 if (level.edelsteine<0)
1305 level.edelsteine = 0;
1306 else if (level.edelsteine>999)
1307 level.edelsteine = 999;
1309 else if (choice==15)
1314 else if (level.time>999)
1317 else if (choice==16)
1320 if (lev_fieldx<MIN_LEV_FIELDX)
1321 lev_fieldx = MIN_LEV_FIELDX;
1322 else if (lev_fieldx>MAX_LEV_FIELDX)
1323 lev_fieldx = MAX_LEV_FIELDX;
1324 level.fieldx = lev_fieldx;
1326 else if (choice==17)
1329 if (lev_fieldy<MIN_LEV_FIELDY)
1330 lev_fieldy = MIN_LEV_FIELDY;
1331 else if (lev_fieldy>MAX_LEV_FIELDY)
1332 lev_fieldy = MAX_LEV_FIELDY;
1333 level.fieldy = lev_fieldy;
1337 DrawText(ED_COUNT_VALUE_XPOS,
1338 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1339 int2str(level.score[choice],3),FS_SMALL,FC_YELLOW);
1340 else if (choice==11)
1341 DrawText(ED_COUNT_VALUE_XPOS,
1342 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
1343 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
1344 else if (choice==12)
1345 DrawText(ED_COUNT_VALUE_XPOS,
1346 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
1347 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
1348 else if (choice==13)
1349 DrawText(ED_COUNT_VALUE_XPOS,
1350 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
1351 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
1352 else if (choice==14)
1353 DrawText(ED_COUNT_VALUE_XPOS,
1354 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
1355 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
1356 else if (choice==15)
1357 DrawText(ED_COUNT_VALUE_XPOS,
1358 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
1359 int2str(level.time,3),FS_SMALL,FC_YELLOW);
1360 else if (choice==16)
1361 DrawText(ED_SIZE_VALUE_XPOS,
1362 ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
1363 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
1364 else if (choice==17)
1365 DrawText(ED_SIZE_VALUE_XPOS,
1366 ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
1367 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
1369 redraw_mask &= ~REDRAW_FIELD;
1371 XCopyArea(display,drawto,window,gc,
1372 ED_COUNT_VALUE_XPOS,
1373 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1374 3*FONT2_XSIZE,FONT2_YSIZE,
1375 ED_COUNT_VALUE_XPOS,
1376 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE);
1378 XCopyArea(display,drawto,window,gc,
1380 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE,
1381 3*FONT2_XSIZE,FONT2_YSIZE,
1383 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE);
1391 switch(CheckCtrlButtons(mx,my,button))
1393 case ED_BUTTON_EDIT:
1394 CloseDoor(DOOR_CLOSE_2);
1395 AdjustLevelScrollPosition();
1396 DrawMiniLevel(level_xpos,level_ypos);
1397 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1398 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
1400 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1401 OpenDoor(DOOR_OPEN_2);
1402 edit_mode = ED_MODE_DRAWING;
1404 case ED_BUTTON_CLEAR:
1405 if (Request("Are you sure to clear this level ?",REQ_ASK))
1407 for(x=0;x<MAX_LEV_FIELDX;x++)
1408 for(y=0;y<MAX_LEV_FIELDY;y++)
1409 Feld[x][y] = EL_ERDREICH;
1410 DrawMiniLevel(level_xpos,level_ypos);
1413 case ED_BUTTON_UNDO:
1414 if (leveldir[leveldir_nr].readonly ||
1415 Request("Exit without saving ?",REQ_ASK | REQ_STAY_OPEN))
1417 CloseDoor(DOOR_CLOSE_ALL);
1418 game_status=MAINMENU;
1423 CloseDoor(DOOR_CLOSE_1);
1424 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1427 case ED_BUTTON_EXIT:
1429 int figur_vorhanden = FALSE;
1431 if (leveldir[leveldir_nr].readonly)
1433 Request("This level is read only !",REQ_CONFIRM);
1437 for(y=0;y<lev_fieldy;y++)
1438 for(x=0;x<lev_fieldx;x++)
1439 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
1440 figur_vorhanden = TRUE;
1442 if (!figur_vorhanden)
1443 Request("No Level without Gregor Mc Duffin please !",
1447 if (Request("Save this level and kill the old ?",
1448 REQ_ASK | REQ_STAY_OPEN))
1450 for(x=0;x<lev_fieldx;x++)
1451 for(y=0;y<lev_fieldy;y++)
1452 Ur[x][y]=Feld[x][y];
1453 SaveLevel(level_nr);
1455 CloseDoor(DOOR_CLOSE_ALL);
1456 game_status=MAINMENU;
1469 if (mx>=ED_COUNT_GADGET_XPOS &&
1470 mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
1471 my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
1472 my<ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE+ED_WIN_COUNT_YSIZE)
1477 DrawText(ED_COUNT_GADGET_XPOS+5,
1478 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1479 level.name,FS_SMALL,FC_GREEN);
1480 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1481 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1482 "<",FS_SMALL,FC_RED);
1489 name_typing = FALSE;
1490 DrawText(ED_COUNT_GADGET_XPOS+5,
1491 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1492 level.name,FS_SMALL,FC_YELLOW);
1493 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1494 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1495 " ",FS_SMALL,FC_RED);
1499 if (mx>=SX+29*MINI_TILEX && mx<SX+30*MINI_TILEX &&
1500 my>=SY+26*MINI_TILEY && my<SY+27*MINI_TILEY)
1504 if (!button || button<1 || button>3)
1507 new_element = (button==1 ? new_element1 :
1508 button==2 ? new_element2 :
1509 button==3 ? new_element3 : 0);
1511 if (new_element != level.amoebe_inhalt)
1513 level.amoebe_inhalt = new_element;
1514 DrawMiniElement(29,26,new_element);
1518 if (mx>=SX+1*MINI_TILEX && mx<SX+(1+4*5)*MINI_TILEX &&
1519 my>=SY+2*MINI_TILEY && my<SY+(2+3)*MINI_TILEY)
1521 int x = (mx-SX-1*MINI_TILEX)/MINI_TILEX;
1522 int y = (my-SY-2*MINI_TILEY)/MINI_TILEY;
1527 if (i>=0 && i<43 && x>=0 && x<3 && y>=0 && y<3)
1529 if (button && !motion_status)
1530 in_field_pressed = TRUE;
1532 if (!button || !in_field_pressed || button<1 || button>3)
1535 new_element = (button==1 ? new_element1 :
1536 button==2 ? new_element2 :
1537 button==3 ? new_element3 : 0);
1539 if (new_element != level.mampfer_inhalt[i][x][y])
1541 level.mampfer_inhalt[i][x][y] = new_element;
1542 DrawMiniElement(1+5*i+x,2+y,new_element);
1545 else if (!motion_status)/* Mauszeiger nicht im Cruncher-Feld */
1546 in_field_pressed = FALSE;
1548 else if (!motion_status) /* Mauszeiger nicht im Cruncher-Feld */
1549 in_field_pressed = FALSE;
1553 last_button = button;
1558 void LevelNameTyping(KeySym key)
1560 unsigned char ascii = 0;
1561 int len = strlen(level.name);
1566 if (key>=XK_A && key<=XK_Z)
1567 ascii = 'A'+(char)(key-XK_A);
1568 else if (key>=XK_a && key<=XK_z)
1569 ascii = 'a'+(char)(key-XK_a);
1570 else if (key>=XK_0 && key<=XK_9)
1571 ascii = '0'+(char)(key-XK_0);
1573 else if (key>=XK_space && key<=XK_at)
1574 ascii = ' '+(char)(key-XK_space);
1575 else if (key==XK_Adiaeresis)
1577 else if (key==XK_Odiaeresis)
1579 else if (key==XK_Udiaeresis)
1581 else if (key==XK_adiaeresis)
1583 else if (key==XK_odiaeresis)
1585 else if (key==XK_udiaeresis)
1587 else if (key==XK_underscore)
1591 if (ascii && len<MAX_LEVNAMLEN-2)
1593 level.name[len] = ascii;
1594 level.name[len+1] = 0;
1597 DrawTextExt(drawto,gc,
1598 ED_COUNT_GADGET_XPOS+5,
1599 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1600 level.name,FS_SMALL,FC_GREEN);
1601 DrawTextExt(window,gc,
1602 ED_COUNT_GADGET_XPOS+5,
1603 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1604 level.name,FS_SMALL,FC_GREEN);
1605 DrawTextExt(drawto,gc,
1606 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1607 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1608 "<",FS_SMALL,FC_RED);
1609 DrawTextExt(window,gc,
1610 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1611 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1612 "<",FS_SMALL,FC_RED);
1614 else if ((key==XK_Delete || key==XK_BackSpace) && len>0)
1616 level.name[len-1] = 0;
1619 DrawTextExt(drawto,gc,
1620 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1621 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1622 "< ",FS_SMALL,FC_GREEN);
1623 DrawTextExt(window,gc,
1624 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1625 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1626 "< ",FS_SMALL,FC_GREEN);
1628 else if (key==XK_Return)
1630 DrawTextExt(drawto,gc,
1631 ED_COUNT_GADGET_XPOS+5,
1632 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1633 level.name,FS_SMALL,FC_YELLOW);
1634 DrawTextExt(window,gc,
1635 ED_COUNT_GADGET_XPOS+5,
1636 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1637 level.name,FS_SMALL,FC_YELLOW);
1638 DrawTextExt(drawto,gc,
1639 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1640 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1641 " ",FS_SMALL,FC_YELLOW);
1642 DrawTextExt(window,gc,
1643 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1644 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1645 " ",FS_SMALL,FC_YELLOW);
1647 name_typing = FALSE;
1651 static void DrawCounterValueField(int counter_id, int value)
1653 int x = SX + counter_info[counter_id].x + ED_WIN_COUNT_XPOS;
1654 int y = SY + counter_info[counter_id].y;
1656 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
1657 DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS,
1658 DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS,
1659 ED_WIN_COUNT_XSIZE, ED_WIN_COUNT_YSIZE,
1662 DrawText(x + ED_COUNT_VALUE_XOFFSET, y + ED_COUNT_VALUE_YOFFSET,
1663 int2str(value, 3), FS_SMALL, FC_YELLOW);
1666 #define TEXT_COLLECTING "Score for collecting"
1667 #define TEXT_SMASHING "Score for smashing"
1668 #define TEXT_CRACKING "Score for cracking"
1669 #define TEXT_SPEED "Speed of growth"
1670 #define TEXT_DURATION "Duration when activated"
1672 static void DrawDrawingWindow()
1675 UnmapLevelEditorWindowGadgets();
1676 MapMainDrawingArea();
1677 AdjustLevelScrollPosition();
1678 DrawMiniLevel(level_xpos, level_ypos);
1681 static void DrawPropertiesWindow(int element)
1684 int num_elements_in_level;
1690 } elements_with_counter[] =
1692 { EL_EDELSTEIN, &level.score[0], TEXT_COLLECTING },
1693 { EL_EDELSTEIN_BD, &level.score[0], TEXT_COLLECTING },
1694 { EL_EDELSTEIN_GELB,&level.score[0], TEXT_COLLECTING },
1695 { EL_EDELSTEIN_ROT, &level.score[0], TEXT_COLLECTING },
1696 { EL_EDELSTEIN_LILA,&level.score[0], TEXT_COLLECTING },
1697 { EL_DIAMANT, &level.score[1], TEXT_COLLECTING },
1698 { EL_KAEFER_R, &level.score[2], TEXT_SMASHING },
1699 { EL_KAEFER_O, &level.score[2], TEXT_SMASHING },
1700 { EL_KAEFER_L, &level.score[2], TEXT_SMASHING },
1701 { EL_KAEFER_U, &level.score[2], TEXT_SMASHING },
1702 { EL_BUTTERFLY_R, &level.score[2], TEXT_SMASHING },
1703 { EL_BUTTERFLY_O, &level.score[2], TEXT_SMASHING },
1704 { EL_BUTTERFLY_L, &level.score[2], TEXT_SMASHING },
1705 { EL_BUTTERFLY_U, &level.score[2], TEXT_SMASHING },
1706 { EL_FLIEGER_R, &level.score[3], TEXT_SMASHING },
1707 { EL_FLIEGER_O, &level.score[3], TEXT_SMASHING },
1708 { EL_FLIEGER_L, &level.score[3], TEXT_SMASHING },
1709 { EL_FLIEGER_U, &level.score[3], TEXT_SMASHING },
1710 { EL_FIREFLY_R, &level.score[3], TEXT_SMASHING },
1711 { EL_FIREFLY_O, &level.score[3], TEXT_SMASHING },
1712 { EL_FIREFLY_L, &level.score[3], TEXT_SMASHING },
1713 { EL_FIREFLY_U, &level.score[3], TEXT_SMASHING },
1714 { EL_MAMPFER, &level.score[4], TEXT_SMASHING },
1715 { EL_MAMPFER2, &level.score[4], TEXT_SMASHING },
1716 { EL_ROBOT, &level.score[5], TEXT_SMASHING },
1717 { EL_PACMAN_R, &level.score[6], TEXT_SMASHING },
1718 { EL_PACMAN_O, &level.score[6], TEXT_SMASHING },
1719 { EL_PACMAN_L, &level.score[6], TEXT_SMASHING },
1720 { EL_PACMAN_U, &level.score[6], TEXT_SMASHING },
1721 { EL_KOKOSNUSS, &level.score[7], TEXT_CRACKING },
1722 { EL_DYNAMIT_AUS, &level.score[8], TEXT_COLLECTING },
1723 { EL_SCHLUESSEL1, &level.score[9], TEXT_COLLECTING },
1724 { EL_SCHLUESSEL2, &level.score[9], TEXT_COLLECTING },
1725 { EL_SCHLUESSEL3, &level.score[9], TEXT_COLLECTING },
1726 { EL_SCHLUESSEL4, &level.score[9], TEXT_COLLECTING },
1727 { EL_AMOEBE_NASS, &level.tempo_amoebe, TEXT_SPEED },
1728 { EL_AMOEBE_NORM, &level.tempo_amoebe, TEXT_SPEED },
1729 { EL_AMOEBE_VOLL, &level.tempo_amoebe, TEXT_SPEED },
1730 { EL_AMOEBE_BD, &level.tempo_amoebe, TEXT_SPEED },
1731 { EL_SIEB_LEER, &level.dauer_sieb, TEXT_DURATION },
1732 { EL_ABLENK_AUS, &level.dauer_ablenk, TEXT_DURATION },
1737 UnmapLevelEditorWindowGadgets();
1739 DrawGraphic(1, 1, el2gfx(element));
1740 DrawText(SX + 3*TILEX, SY + 5*TILEY/4, "Element Properties",
1741 FS_SMALL, FC_YELLOW);
1743 num_elements_in_level = 0;
1744 for(y=0; y<lev_fieldy; y++)
1745 for(x=0; x<lev_fieldx; x++)
1746 if (Feld[x][y] == element)
1747 num_elements_in_level++;
1749 DrawTextF(TILEX, 5*TILEY, FC_YELLOW, "%d x contained in level",
1750 num_elements_in_level);
1752 for (i=0; elements_with_counter[i].element != -1; i++)
1754 if (elements_with_counter[i].element == element)
1756 int x = SX + counter_info[ED_COUNTER_SCORE].x + DXSIZE;
1757 int y = SY + counter_info[ED_COUNTER_SCORE].y;
1759 gadget_score_value = elements_with_counter[i].counter_value;
1760 DrawCounterValueField(ED_COUNTER_SCORE, *gadget_score_value);
1761 DrawText(x + ED_COUNT_VALUE_XOFFSET, y + ED_COUNT_VALUE_YOFFSET,
1762 elements_with_counter[i].text, FS_SMALL, FC_YELLOW);
1763 MapCounterButtons(ED_COUNTER_SCORE);
1769 static void swap_numbers(int *i1, int *i2)
1777 static void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
1789 static void DrawLineElement(int sx, int sy, int element, boolean change_level)
1791 int lx = sx + level_xpos;
1792 int ly = sy + level_ypos;
1794 DrawMiniElement(sx, sy, (element < 0 ? Feld[lx][ly] : element));
1797 Feld[lx][ly] = element;
1800 static void DrawLine(int from_x, int from_y, int to_x, int to_y,
1801 int element, boolean change_level)
1803 if (from_y == to_y) /* horizontal line */
1809 swap_numbers(&from_x, &to_x);
1811 for (x=from_x; x<=to_x; x++)
1812 DrawLineElement(x, y, element, change_level);
1814 else if (from_x == to_x) /* vertical line */
1820 swap_numbers(&from_y, &to_y);
1822 for (y=from_y; y<=to_y; y++)
1823 DrawLineElement(x, y, element, change_level);
1825 else /* diagonal line */
1827 int len_x = ABS(to_x - from_x);
1828 int len_y = ABS(to_y - from_y);
1831 if (len_y < len_x) /* a < 1 */
1833 float a = (float)len_y / (float)len_x;
1836 swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
1838 for (x=0; x<=len_x; x++)
1840 int y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1);
1842 DrawLineElement(from_x + x, from_y + y, element, change_level);
1847 float a = (float)len_x / (float)len_y;
1850 swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
1852 for (y=0; y<=len_y; y++)
1854 int x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1);
1856 DrawLineElement(from_x + x, from_y + y, element, change_level);
1862 static void DrawRectangle(int from_x, int from_y, int to_x, int to_y,
1863 int element, boolean change_level)
1865 DrawLine(from_x, from_y, from_x, to_y, element, change_level);
1866 DrawLine(from_x, to_y, to_x, to_y, element, change_level);
1867 DrawLine(to_x, to_y, to_x, from_y, element, change_level);
1868 DrawLine(to_x, from_y, from_x, from_y, element, change_level);
1871 static void DrawFilledBox(int from_x, int from_y, int to_x, int to_y,
1872 int element, boolean change_level)
1877 swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
1879 for (y=from_y; y<=to_y; y++)
1880 DrawLine(from_x, y, to_x, y, element, change_level);
1883 static void FloodFill(int from_x, int from_y, int fill_element)
1887 static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
1888 static int safety = 0;
1890 /* check if starting field still has the desired content */
1891 if (Feld[from_x][from_y] == fill_element)
1896 if (safety > lev_fieldx*lev_fieldy)
1897 Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
1899 old_element = Feld[from_x][from_y];
1900 Feld[from_x][from_y] = fill_element;
1904 x = from_x + check[i][0];
1905 y = from_y + check[i][1];
1907 if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
1908 FloodFill(x, y, fill_element);
1914 static void CopyLevelToUndoBuffer()
1918 undo_buffer_position = (undo_buffer_position + 1) % NUM_UNDO_STEPS;
1920 if (undo_buffer_steps < NUM_UNDO_STEPS - 1)
1921 undo_buffer_steps++;
1923 for(x=0; x<lev_fieldx; x++)
1924 for(y=0; y<lev_fieldy; y++)
1925 UndoBuffer[undo_buffer_position][x][y] = Feld[x][y];
1930 printf("state saved to undo buffer %d\n", undo_buffer_position);
1934 static void RandomPlacement(int button)
1939 new_element = (button == 1 ? new_element1 :
1940 button == 2 ? new_element2 :
1941 button == 3 ? new_element3 : 0);
1943 if (random_placement_method == RANDOM_USE_PERCENTAGE)
1945 for(x=0; x<lev_fieldx; x++)
1946 for(y=0; y<lev_fieldy; y++)
1947 if (RND(100) < random_placement_percentage)
1948 Feld[x][y] = new_element;
1952 int elements_left = random_placement_num_objects;
1954 while (elements_left > 0)
1956 x = RND(lev_fieldx);
1957 y = RND(lev_fieldy);
1959 if (Feld[x][y] != new_element)
1961 Feld[x][y] = new_element;
1967 DrawMiniLevel(level_xpos, level_ypos);
1971 static void HandleDrawingAreas(int mx, int my, int button)
1974 static void HandleDrawingAreas(struct GadgetInfo *gi)
1976 static int last_button = 0;
1977 static int last_element = 0;
1978 static boolean started_inside_drawing_area = FALSE;
1979 boolean inside_drawing_area;
1980 boolean button_press_event;
1981 boolean button_release_event;
1983 int button = gi->event.button;
1984 int mx = SX + gi->event.x * MINI_TILEX;
1985 int my = SX + gi->event.y * MINI_TILEY;
1986 int min_mx = SX, max_mx = SX + SXSIZE -1;
1987 int min_my = SY, max_my = SY + SYSIZE -1;
1992 if (edit_mode != ED_MODE_DRAWING)
1995 button_press_event = (last_button == 0 && button != 0);
1996 button_release_event = (last_button != 0 && button == 0);
1997 last_button = button;
1999 inside_drawing_area =
2000 (mx >= min_mx && mx <= max_mx && my >= min_my && my <= max_my);
2002 mx = (mx < min_mx ? min_mx : mx > max_mx ? max_mx : mx);
2003 my = (my < min_my ? min_my : my > max_my ? max_my : my);
2004 sx = (mx - SX) / MINI_TILEX;
2005 sy = (my - SY) / MINI_TILEY;
2006 lx = sx + level_xpos;
2007 ly = sy + level_ypos;
2009 if (button_press_event)
2010 started_inside_drawing_area = inside_drawing_area;
2012 if (!started_inside_drawing_area)
2015 if ((!button && !button_release_event) ||
2016 sx > lev_fieldx || sy > lev_fieldy ||
2017 (sx == 0 && level_xpos<0) ||
2018 (sx == 2*SCR_FIELDX - 1 && level_xpos > lev_fieldx - 2*SCR_FIELDX) ||
2019 (sy == 0 && level_ypos < 0) ||
2020 (sy == 2*SCR_FIELDY - 1 && level_ypos > lev_fieldy - 2*SCR_FIELDY))
2023 new_element = (button == 1 ? new_element1 :
2024 button == 2 ? new_element2 :
2025 button == 3 ? new_element3 : 0);
2027 switch (drawing_function)
2029 case ED_CTRL_ID_SINGLE_ITEMS:
2030 if (button_release_event)
2031 CopyLevelToUndoBuffer();
2036 if (new_element != Feld[lx][ly])
2038 if (new_element == EL_SPIELFIGUR)
2040 /* remove player at old position */
2041 for(y=0; y<lev_fieldy; y++)
2043 for(x=0; x<lev_fieldx; x++)
2045 if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1)
2047 Feld[x][y] = EL_LEERRAUM;
2048 if (x - level_xpos >= 0 && x - level_xpos < 2*SCR_FIELDX &&
2049 y - level_ypos >= 0 && y - level_ypos < 2*SCR_FIELDY)
2050 DrawMiniElement(x - level_xpos, y - level_ypos, EL_LEERRAUM);
2056 Feld[lx][ly] = new_element;
2057 DrawMiniElement(sx, sy, new_element);
2061 case ED_CTRL_ID_CONNECTED_ITEMS:
2063 static int last_sx = -1;
2064 static int last_sy = -1;
2066 if (button_release_event)
2067 CopyLevelToUndoBuffer();
2071 if (!button_press_event)
2072 DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE);
2080 case ED_CTRL_ID_LINE:
2081 case ED_CTRL_ID_RECTANGLE:
2082 case ED_CTRL_ID_FILLED_BOX:
2084 static int last_sx = -1;
2085 static int last_sy = -1;
2086 static int start_sx = -1;
2087 static int start_sy = -1;
2088 void (*draw_func)(int, int, int, int, int, boolean);
2090 if (drawing_function == ED_CTRL_ID_LINE)
2091 draw_func = DrawLine;
2092 else if (drawing_function == ED_CTRL_ID_RECTANGLE)
2093 draw_func = DrawRectangle;
2095 draw_func = DrawFilledBox;
2097 if (button_press_event)
2099 last_sx = start_sx = sx;
2100 last_sy = start_sy = sy;
2101 draw_func(sx, sy, sx, sy, new_element, FALSE);
2103 else if (button_release_event)
2105 draw_func(start_sx, start_sy, sx, sy, last_element, TRUE);
2106 CopyLevelToUndoBuffer();
2108 else if (last_sx != sx || last_sy != sy)
2110 draw_func(start_sx, start_sy, last_sx, last_sy, -1, FALSE);
2111 draw_func(start_sx, start_sy, sx, sy, new_element, FALSE);
2118 case ED_CTRL_ID_FLOOD_FILL:
2119 if (button_press_event && Feld[lx][ly] != new_element)
2121 FloodFill(lx, ly, new_element);
2122 DrawMiniLevel(level_xpos, level_ypos);
2123 CopyLevelToUndoBuffer();
2131 last_element = new_element;
2138 static void HandlePressedControlButtons()
2140 static unsigned long button_delay = 0;
2143 /* buttons with action when held pressed */
2147 ED_CTRL_ID_WRAP_LEFT,
2148 ED_CTRL_ID_WRAP_RIGHT,
2149 ED_CTRL_ID_WRAP_DOWN,
2150 ED_CTRL_ID_SCORE_DOWN,
2151 ED_CTRL_ID_SCORE_UP,
2155 if (!DelayReached(&button_delay, GADGET_FRAME_DELAY))
2158 for (i=0; gadget_id[i] != -1; i++)
2160 int id = gadget_id[i];
2161 int state = level_editor_gadget[id]->state;
2162 int button = level_editor_gadget[id]->event.button;
2163 int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
2165 if (state != GD_BUTTON_PRESSED)
2170 case ED_CTRL_ID_WRAP_LEFT:
2171 if (level_xpos >= 0)
2173 if (lev_fieldx < 2*SCR_FIELDX - 2)
2177 if (level_xpos <- 1)
2180 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT);
2182 DrawMiniLevel(level_xpos, level_ypos);
2186 case ED_CTRL_ID_WRAP_RIGHT:
2187 if (level_xpos <= lev_fieldx - 2*SCR_FIELDX)
2189 if (lev_fieldx < 2*SCR_FIELDX - 2)
2193 if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1)
2194 level_xpos = lev_fieldx - 2*SCR_FIELDX + 1;
2196 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT);
2198 DrawMiniLevel(level_xpos, level_ypos);
2202 case ED_CTRL_ID_WRAP_UP:
2203 if (level_ypos >= 0)
2205 if (lev_fieldy < 2*SCR_FIELDY - 2)
2209 if (level_ypos < -1)
2212 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN);
2214 DrawMiniLevel(level_xpos, level_ypos);
2218 case ED_CTRL_ID_WRAP_DOWN:
2219 if (level_ypos <= lev_fieldy - 2*SCR_FIELDY)
2221 if (lev_fieldy < 2*SCR_FIELDY - 2)
2225 if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1)
2226 level_ypos = lev_fieldy - 2*SCR_FIELDY + 1;
2228 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP);
2230 DrawMiniLevel(level_xpos, level_ypos);
2234 case ED_CTRL_ID_SCORE_DOWN:
2235 case ED_CTRL_ID_SCORE_UP:
2236 *gadget_score_value += (id == ED_CTRL_ID_SCORE_DOWN ? -step : step);
2237 if (*gadget_score_value < 0)
2238 *gadget_score_value = 0;
2239 else if (*gadget_score_value > 255)
2240 *gadget_score_value = 255;
2242 DrawCounterValueField(ED_COUNTER_SCORE, *gadget_score_value);
2255 static void HandleCounterButtons(struct GadgetInfo *gi)
2257 int id = gi->custom_id;
2258 int button = gi->event.button;
2259 int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
2263 case ED_CTRL_ID_SCORE_DOWN:
2264 case ED_CTRL_ID_SCORE_UP:
2265 *gadget_score_value += (id == ED_CTRL_ID_SCORE_DOWN ? -step : step);
2266 if (*gadget_score_value < 0)
2267 *gadget_score_value = 0;
2268 else if (*gadget_score_value > 255)
2269 *gadget_score_value = 255;
2271 DrawCounterValueField(ED_COUNTER_SCORE, *gadget_score_value);
2279 static void HandleControlButtons(struct GadgetInfo *gi)
2281 int id = gi->custom_id;
2282 int event_type = gi->event.type;
2283 int button = gi->event.button;
2284 int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
2286 int player_present = FALSE;
2287 int level_changed = FALSE;
2290 new_element = (button == 1 ? new_element1 :
2291 button == 2 ? new_element2 :
2292 button == 3 ? new_element3 : 0);
2294 if (id < ED_NUM_CTRL1_BUTTONS && edit_mode != ED_MODE_DRAWING)
2296 DrawDrawingWindow();
2297 edit_mode = ED_MODE_DRAWING;
2302 case ED_CTRL_ID_SINGLE_ITEMS:
2303 case ED_CTRL_ID_CONNECTED_ITEMS:
2304 case ED_CTRL_ID_LINE:
2305 case ED_CTRL_ID_TEXT:
2306 case ED_CTRL_ID_RECTANGLE:
2307 case ED_CTRL_ID_FILLED_BOX:
2308 case ED_CTRL_ID_FLOOD_FILL:
2309 case ED_CTRL_ID_BRUSH:
2310 drawing_function = id;
2313 case ED_CTRL_ID_WRAP_LEFT:
2314 if (level_xpos >= 0)
2316 if (lev_fieldx < 2*SCR_FIELDX - 2)
2320 if (level_xpos <- 1)
2323 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT);
2325 DrawMiniLevel(level_xpos, level_ypos);
2329 case ED_CTRL_ID_WRAP_RIGHT:
2330 if (level_xpos <= lev_fieldx - 2*SCR_FIELDX)
2332 if (lev_fieldx < 2*SCR_FIELDX - 2)
2336 if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1)
2337 level_xpos = lev_fieldx - 2*SCR_FIELDX + 1;
2339 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT);
2341 DrawMiniLevel(level_xpos, level_ypos);
2345 case ED_CTRL_ID_WRAP_UP:
2346 if (level_ypos >= 0)
2348 if (lev_fieldy < 2*SCR_FIELDY - 2)
2352 if (level_ypos < -1)
2355 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN);
2357 DrawMiniLevel(level_xpos, level_ypos);
2361 case ED_CTRL_ID_WRAP_DOWN:
2362 if (level_ypos <= lev_fieldy - 2*SCR_FIELDY)
2364 if (lev_fieldy < 2*SCR_FIELDY - 2)
2368 if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1)
2369 level_ypos = lev_fieldy - 2*SCR_FIELDY + 1;
2371 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP);
2373 DrawMiniLevel(level_xpos, level_ypos);
2377 case ED_CTRL_ID_PROPERTIES:
2378 DrawPropertiesWindow(new_element);
2379 edit_mode = ED_MODE_PROPERTIES;
2382 case ED_CTRL_ID_RANDOM_PLACEMENT:
2383 RandomPlacement(button);
2384 CopyLevelToUndoBuffer();
2387 case ED_CTRL_ID_UNDO:
2388 if (undo_buffer_steps == 0)
2390 Request("Undo buffer empty !", REQ_CONFIRM);
2394 undo_buffer_position =
2395 (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS;
2396 undo_buffer_steps--;
2398 for(x=0; x<lev_fieldx; x++)
2399 for(y=0; y<lev_fieldy; y++)
2400 Feld[x][y] = UndoBuffer[undo_buffer_position][x][y];
2401 DrawMiniLevel(level_xpos,level_ypos);
2404 case ED_CTRL_ID_INFO:
2405 if (edit_mode != ED_MODE_INFO)
2407 DrawControlWindow();
2408 edit_mode = ED_MODE_INFO;
2412 AdjustLevelScrollPosition();
2413 DrawMiniLevel(level_xpos, level_ypos);
2414 edit_mode = ED_MODE_DRAWING;
2418 case ED_CTRL_ID_CLEAR:
2419 for(x=0; x<MAX_LEV_FIELDX; x++)
2420 for(y=0; y<MAX_LEV_FIELDY; y++)
2421 Feld[x][y] = new_element3;
2422 CopyLevelToUndoBuffer();
2424 DrawMiniLevel(level_xpos, level_ypos);
2427 case ED_CTRL_ID_SAVE:
2428 if (leveldir[leveldir_nr].readonly)
2430 Request("This level is read only !", REQ_CONFIRM);
2434 for(y=0; y<lev_fieldy; y++)
2435 for(x=0; x<lev_fieldx; x++)
2436 if (Feld[x][y] != Ur[x][y])
2437 level_changed = TRUE;
2441 Request("Level has not changed !", REQ_CONFIRM);
2445 for(y=0; y<lev_fieldy; y++)
2446 for(x=0; x<lev_fieldx; x++)
2447 if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1)
2448 player_present = TRUE;
2450 if (!player_present)
2451 Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
2454 if (Request("Save this level and kill the old ?", REQ_ASK))
2456 for(x=0; x<lev_fieldx; x++)
2457 for(y=0; y<lev_fieldy; y++)
2458 Ur[x][y] = Feld[x][y];
2459 SaveLevel(level_nr);
2464 case ED_CTRL_ID_TEST:
2465 for(y=0; y<lev_fieldy; y++)
2466 for(x=0; x<lev_fieldx; x++)
2467 if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1)
2468 player_present = TRUE;
2470 if (!player_present)
2471 Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
2474 for(x=0; x<lev_fieldx; x++)
2475 for(y=0; y<lev_fieldy; y++)
2476 OrigBackup[x][y] = Ur[x][y];
2478 for(x=0; x<lev_fieldx; x++)
2479 for(y=0; y<lev_fieldy; y++)
2480 Ur[x][y] = Feld[x][y];
2482 level_editor_test_game = TRUE;
2483 game_status = PLAYING;
2488 case ED_CTRL_ID_EXIT:
2489 for(y=0; y<lev_fieldy; y++)
2490 for(x=0; x<lev_fieldx; x++)
2491 if (Feld[x][y] != Ur[x][y])
2492 level_changed = TRUE;
2494 if (!level_changed ||
2495 Request("Level has changed! Exit without saving ?",
2496 REQ_ASK | REQ_STAY_OPEN))
2498 CloseDoor(DOOR_CLOSE_1);
2501 CloseDoor(DOOR_CLOSE_ALL);
2504 /* draw smaller door */
2505 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
2506 DOOR_GFX_PAGEX7, 64,
2509 redraw_mask |= REDRAW_ALL;
2511 game_status = MAINMENU;
2516 CloseDoor(DOOR_CLOSE_1);
2517 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
2518 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
2519 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
2520 OpenDoor(DOOR_OPEN_1);
2525 if (event_type == GD_EVENT_PRESSED)
2526 printf("default: HandleControlButtons: GD_EVENT_PRESSED\n");
2527 else if (event_type == GD_EVENT_RELEASED)
2528 printf("default: HandleControlButtons: GD_EVENT_RELEASED\n");
2529 else if (event_type == GD_EVENT_MOVING)
2530 printf("default: HandleControlButtons: GD_EVENT_MOVING\n");
2532 printf("default: HandleControlButtons: ?\n");