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 ***********************************************************/
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
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
38 /* delay value to avoid too fast scrolling etc. */
39 #define CHOICE_DELAY_VALUE 100
41 /* values for the control window */
42 #define ED_CTRL_BUTTONS_GFX_YPOS 236
43 #define ED_CTRL1_BUTTONS_HORIZ 4
44 #define ED_CTRL1_BUTTONS_VERT 4
45 #define ED_CTRL1_BUTTON_XSIZE 22
46 #define ED_CTRL1_BUTTON_YSIZE 22
47 #define ED_CTRL1_BUTTONS_XPOS 6
48 #define ED_CTRL1_BUTTONS_YPOS 6
49 #define ED_CTRL2_BUTTONS_HORIZ 3
50 #define ED_CTRL2_BUTTONS_VERT 2
51 #define ED_CTRL2_BUTTON_XSIZE 30
52 #define ED_CTRL2_BUTTON_YSIZE 20
53 #define ED_CTRL2_BUTTONS_XPOS 5
54 #define ED_CTRL2_BUTTONS_YPOS 100
55 #define ED_NUM_CTRL1_BUTTONS (ED_CTRL1_BUTTONS_HORIZ * ED_CTRL1_BUTTONS_VERT)
56 #define ED_NUM_CTRL2_BUTTONS (ED_CTRL2_BUTTONS_HORIZ * ED_CTRL2_BUTTONS_VERT)
57 #define ED_NUM_CTRL_BUTTONS (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS)
59 /* control button names */
60 #define ED_CTRL_ID_SINGLE_ITEMS 0
61 #define ED_CTRL_ID_CONNECTED_ITEMS 1
62 #define ED_CTRL_ID_LINES 2
63 #define ED_CTRL_ID_TEXT 3
64 #define ED_CTRL_ID_RECTANGLE 4
65 #define ED_CTRL_ID_BOX 5
66 #define ED_CTRL_ID_WRAP_UP 6
67 #define ED_CTRL_ID_ITEM_PROPERTIES 7
68 #define ED_CTRL_ID_FLOOD_FILL 8
69 #define ED_CTRL_ID_WRAP_LEFT 9
70 #define ED_CTRL_ID_WRAP_RIGHT 11
71 #define ED_CTRL_ID_RANDOM_PLACEMENT 12
72 #define ED_CTRL_ID_BRUSH 13
73 #define ED_CTRL_ID_WRAP_DOWN 14
74 #define ED_CTRL_ID_UNDO 16
75 #define ED_CTRL_ID_INFO 17
76 #define ED_CTRL_ID_SAVE 18
77 #define ED_CTRL_ID_CLEAR 19
78 #define ED_CTRL_ID_TEST 20
79 #define ED_CTRL_ID_EXIT 21
81 /* forward declaration for internal use */
82 void HandleDrawingFunction(int, int, int);
84 static struct GadgetInfo *control_button_gadget[ED_NUM_CTRL_BUTTONS];
85 static boolean control_button_gadgets_created = FALSE;
87 static int drawing_function = ED_CTRL_ID_SINGLE_ITEMS;
89 static int level_xpos,level_ypos;
90 static boolean edit_mode;
91 static boolean name_typing;
92 static int new_element1 = EL_MAUERWERK;
93 static int new_element2 = EL_LEERRAUM;
94 static int new_element3 = EL_ERDREICH;
97 int editor_element[] =
99 EL_CHAR_A + ('B' - 'A'),
100 EL_CHAR_A + ('O' - 'A'),
101 EL_CHAR_A + ('U' - 'A'),
102 EL_CHAR_A + ('L' - 'A'),
105 EL_CHAR_A + ('D' - 'A'),
106 EL_CHAR_A + ('E' - 'A'),
107 EL_CHAR_A + ('R' - 'A'),
109 EL_CHAR_A + ('D' - 'A'),
110 EL_CHAR_A + ('A' - 'A'),
111 EL_CHAR_A + ('S' - 'A'),
112 EL_CHAR_A + ('H' - 'A'),
139 EL_CHAR_A + ('E' - 'A'),
140 EL_CHAR_A + ('M' - 'A'),
141 EL_CHAR_A + ('E' - 'A'),
144 EL_CHAR_A + ('R' - 'A'),
145 EL_CHAR_A + ('A' - 'A'),
146 EL_CHAR_A + ('L' - 'A'),
147 EL_CHAR_A + ('D' - 'A'),
149 EL_CHAR_A + ('M' - 'A'),
150 EL_CHAR_A + ('I' - 'A'),
151 EL_CHAR_A + ('N' - 'A'),
152 EL_CHAR_A + ('E' - 'A'),
229 EL_CHAR_A + ('M' - 'A'),
230 EL_CHAR_A + ('O' - 'A'),
231 EL_CHAR_A + ('R' - 'A'),
232 EL_CHAR_A + ('E' - 'A'),
279 EL_CHAR_A + ('S' - 'A'),
280 EL_CHAR_A + ('O' - 'A'),
281 EL_CHAR_A + ('K' - 'A'),
282 EL_CHAR_A + ('O' - 'A'),
285 EL_CHAR_A + ('B' - 'A'),
286 EL_CHAR_A + ('A' - 'A'),
287 EL_CHAR_A + ('N' - 'A'),
290 EL_SOKOBAN_FELD_LEER,
291 EL_SOKOBAN_FELD_VOLL,
295 EL_CHAR_A + ('D' - 'A'),
296 EL_CHAR_A + ('Y' - 'A'),
297 EL_CHAR_A + ('N' - 'A'),
298 EL_CHAR_A + ('A' - 'A'),
300 EL_CHAR_A + ('B' - 'A'),
301 EL_CHAR_A + ('L' - 'A'),
302 EL_CHAR_A + ('A' - 'A'),
303 EL_CHAR_A + ('S' - 'A'),
306 EL_CHAR_A + ('T' - 'A'),
307 EL_CHAR_A + ('E' - 'A'),
308 EL_CHAR_A + ('R' - 'A'),
390 int elements_in_list = sizeof(editor_element)/sizeof(int);
392 void ScrollMiniLevel(int from_x, int from_y, int scroll)
395 int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
396 int dy = (scroll==ED_SCROLL_UP ? -1 : scroll==ED_SCROLL_DOWN ? 1 : 0);
398 XCopyArea(display,drawto,drawto,gc,
399 SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
400 SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
401 SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
404 x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
405 for(y=0;y<2*SCR_FIELDY;y++)
406 DrawMiniElementOrWall(x,y,from_x,from_y);
410 y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
411 for(x=0;x<2*SCR_FIELDX;x++)
412 DrawMiniElementOrWall(x,y,from_x,from_y);
415 redraw_mask |= REDRAW_FIELD;
419 void HandlePressedControlButtons()
421 static unsigned long button_delay = 0;
424 /* buttons with action when held pressed */
428 ED_CTRL_ID_WRAP_LEFT,
429 ED_CTRL_ID_WRAP_RIGHT,
430 ED_CTRL_ID_WRAP_DOWN,
434 if (!DelayReached(&button_delay, CHOICE_DELAY_VALUE))
437 while (gadget_id[i] != -1)
439 int id = gadget_id[i++];
440 int state = control_button_gadget[id]->state;
441 int button = control_button_gadget[id]->event.button;
442 int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
444 if (state != GD_BUTTON_PRESSED)
449 case ED_CTRL_ID_WRAP_LEFT:
452 if (lev_fieldx < 2*SCR_FIELDX - 2)
459 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT);
461 DrawMiniLevel(level_xpos, level_ypos);
465 case ED_CTRL_ID_WRAP_RIGHT:
466 if (level_xpos <= lev_fieldx - 2*SCR_FIELDX)
468 if (lev_fieldx < 2*SCR_FIELDX - 2)
472 if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1)
473 level_xpos = lev_fieldx - 2*SCR_FIELDX + 1;
475 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT);
477 DrawMiniLevel(level_xpos, level_ypos);
481 case ED_CTRL_ID_WRAP_UP:
484 if (lev_fieldy < 2*SCR_FIELDY - 2)
491 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN);
493 DrawMiniLevel(level_xpos, level_ypos);
497 case ED_CTRL_ID_WRAP_DOWN:
498 if (level_ypos <= lev_fieldy - 2*SCR_FIELDY)
500 if (lev_fieldy < 2*SCR_FIELDY - 2)
504 if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1)
505 level_ypos = lev_fieldy - 2*SCR_FIELDY + 1;
507 ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP);
509 DrawMiniLevel(level_xpos, level_ypos);
519 void HandleLevelEditorControlButtons(struct GadgetInfo *gi)
521 int event_type = gi->event.type;
524 int button = gi->event.button;
530 /* get the button id */
531 for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
532 if (gi->id == control_button_gadget[i]->id)
537 case ED_CTRL_ID_SINGLE_ITEMS:
538 case ED_CTRL_ID_CONNECTED_ITEMS:
539 case ED_CTRL_ID_LINES:
540 case ED_CTRL_ID_TEXT:
541 case ED_CTRL_ID_RECTANGLE:
543 case ED_CTRL_ID_FLOOD_FILL:
544 case ED_CTRL_ID_RANDOM_PLACEMENT:
545 case ED_CTRL_ID_BRUSH:
546 drawing_function = id;
549 case ED_CTRL_ID_CLEAR:
550 if (Request("Are you sure to clear this level ?", REQ_ASK))
552 for(x=0; x<MAX_LEV_FIELDX; x++)
553 for(y=0; y<MAX_LEV_FIELDY; y++)
554 Feld[x][y] = EL_ERDREICH;
556 DrawMiniLevel(level_xpos, level_ypos);
560 case ED_CTRL_ID_SAVE:
562 int player_present = FALSE;
564 if (leveldir[leveldir_nr].readonly)
566 Request("This level is read only !", REQ_CONFIRM);
570 for(y=0; y<lev_fieldy; y++)
571 for(x=0; x<lev_fieldx; x++)
572 if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1)
573 player_present = TRUE;
576 Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
579 if (Request("Save this level and kill the old ?", REQ_ASK))
581 for(x=0; x<lev_fieldx; x++)
582 for(y=0; y<lev_fieldy; y++)
583 Ur[x][y] = Feld[x][y];
590 case ED_CTRL_ID_EXIT:
591 if (Request("Exit level editor ?", REQ_ASK | REQ_STAY_OPEN))
593 CloseDoor(DOOR_CLOSE_1);
596 CloseDoor(DOOR_CLOSE_BOTH);
599 /* draw smaller door */
600 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
604 redraw_mask |= REDRAW_ALL;
606 game_status = MAINMENU;
611 CloseDoor(DOOR_CLOSE_1);
612 XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
613 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
614 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
615 OpenDoor(DOOR_OPEN_1);
620 if (event_type == GD_EVENT_PRESSED)
621 printf("test_func2: GD_EVENT_PRESSED\n");
622 else if (event_type == GD_EVENT_RELEASED)
623 printf("test_func2: GD_EVENT_RELEASED\n");
625 printf("test_func2: ?\n");
630 void CreateLevelEditorControlButtons()
634 if (control_button_gadgets_created)
637 for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
639 Pixmap gd_pixmap = pix[PIX_DOOR];
640 struct GadgetInfo *gi;
641 int gd_xoffset, gd_yoffset;
642 int gd_x1, gd_x2, gd_y;
644 unsigned long event_mask;
646 if (i < ED_NUM_CTRL1_BUTTONS)
648 int x = i % ED_CTRL1_BUTTONS_HORIZ;
649 int y = i / ED_CTRL1_BUTTONS_HORIZ;
651 gd_xoffset = ED_CTRL1_BUTTONS_XPOS + x * ED_CTRL1_BUTTON_XSIZE;
652 gd_yoffset = ED_CTRL1_BUTTONS_YPOS + y * ED_CTRL1_BUTTON_YSIZE;
653 width = ED_CTRL1_BUTTON_XSIZE;
654 height = ED_CTRL1_BUTTON_YSIZE;
658 int x = (i - ED_NUM_CTRL1_BUTTONS) % ED_CTRL2_BUTTONS_HORIZ;
659 int y = (i - ED_NUM_CTRL1_BUTTONS) / ED_CTRL2_BUTTONS_HORIZ;
661 gd_xoffset = ED_CTRL2_BUTTONS_XPOS + x * ED_CTRL2_BUTTON_XSIZE;
662 gd_yoffset = ED_CTRL2_BUTTONS_YPOS + y * ED_CTRL2_BUTTON_YSIZE;
663 width = ED_CTRL2_BUTTON_XSIZE;
664 height = ED_CTRL2_BUTTON_YSIZE;
667 gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
668 gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
669 gd_y = DOOR_GFX_PAGEY1 + ED_CTRL_BUTTONS_GFX_YPOS + gd_yoffset;
671 if (i == ED_CTRL_ID_WRAP_LEFT ||
672 i == ED_CTRL_ID_WRAP_RIGHT ||
673 i == ED_CTRL_ID_WRAP_UP ||
674 i == ED_CTRL_ID_WRAP_DOWN)
675 event_mask = GD_EVENT_PRESSED;
677 event_mask = GD_EVENT_RELEASED;
679 gi = CreateGadget(GDI_X, EX + gd_xoffset,
680 GDI_Y, EY + gd_yoffset,
683 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
684 GDI_STATE, GD_BUTTON_UNPRESSED,
685 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
686 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
687 GDI_EVENT_MASK, event_mask,
688 GDI_CALLBACK, HandleLevelEditorControlButtons,
692 Error(ERR_EXIT, "cannot create gadget");
694 control_button_gadget[i] = gi;
697 control_button_gadgets_created = TRUE;
700 void MapLevelEditorControlButtons()
704 if (!control_button_gadgets_created)
705 CreateLevelEditorControlButtons();
707 for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
708 MapGadget(control_button_gadget[i]);
711 void UnmapLevelEditorControlButtons()
715 if (!control_button_gadgets_created)
718 for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
719 UnmapGadget(control_button_gadget[i]);
732 CloseDoor(DOOR_CLOSE_2);
734 DrawMiniLevel(level_xpos,level_ypos);
737 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
738 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY1,
740 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
741 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
742 DOOR_GFX_PAGEX6+ED_BUTTON_ELEM_XPOS,
743 DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS,
744 4*ED_BUTTON_ELEM_XSIZE,5*ED_BUTTON_ELEM_YSIZE,
745 DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS,
746 DOOR_GFX_PAGEY1+ED_BUTTON_EUP_Y2POS);
748 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
750 if (i < elements_in_list)
751 graphic = el2gfx(editor_element[i]);
753 graphic = GFX_LEERRAUM;
755 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
756 DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS+3 +
757 (i%MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
758 DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS+3 +
759 (i/MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
763 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
764 DOOR_GFX_PAGEX1+ED_WIN_MB_LEFT_XPOS,
765 DOOR_GFX_PAGEY1+ED_WIN_MB_LEFT_YPOS,
766 el2gfx(new_element1));
767 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
768 DOOR_GFX_PAGEX1+ED_WIN_MB_MIDDLE_XPOS,
769 DOOR_GFX_PAGEY1+ED_WIN_MB_MIDDLE_YPOS,
770 el2gfx(new_element2));
771 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
772 DOOR_GFX_PAGEX1+ED_WIN_MB_RIGHT_XPOS,
773 DOOR_GFX_PAGEY1+ED_WIN_MB_RIGHT_YPOS,
774 el2gfx(new_element3));
775 DrawTextExt(pix[PIX_DB_DOOR],gc,
776 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS,
777 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
778 int2str(level_nr,2),FS_SMALL,FC_SPECIAL1);
779 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
780 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+3,
781 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
783 DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS,
784 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
785 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
786 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+14,
787 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
789 DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS+9,
790 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
792 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
793 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
795 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
797 /* draw bigger door */
798 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
803 /* draw new control window */
804 XCopyArea(display, pix[PIX_DOOR], drawto, gc,
805 DOOR_GFX_PAGEX8, 236,
809 redraw_mask |= REDRAW_ALL;
811 OpenDoor(DOOR_OPEN_1);
813 MapLevelEditorControlButtons();
816 OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
820 void DrawControlWindow()
826 /* Inhalt der Mampfer */
827 DrawText(ED_COUNT_GADGET_XPOS+1,SY+6,
828 "Contents of a smashed cruncher:",FS_SMALL,FC_YELLOW);
829 for(i=0;i<4;i++) for(y=0;y<4;y++) for(x=0;x<4;x++)
831 DrawMiniElement(1+5*i+x,2+y,EL_ERDREICH);
832 XFillRectangle(display,drawto,gc,
833 SX+(1+5*i)*MINI_TILEX+MINI_TILEX/2-1,
834 SY+(2)*MINI_TILEY+MINI_TILEY/2-1,
835 3*MINI_TILEX+2,3*MINI_TILEY+2);
837 XCopyArea(display,drawto,drawto,gc,
838 SX+1*MINI_TILEX,SY+2*MINI_TILEY,
839 4*5*MINI_TILEX,5*MINI_TILEY,
840 SX+1*MINI_TILEX-MINI_TILEX/2,SY+2*MINI_TILEY-MINI_TILEY/2);
843 for(y=0;y<3;y++) for(x=0;x<3;x++)
844 DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
846 DrawText(SX+MINI_TILEX+(5*i+1)*MINI_TILEX+1,
847 SY+2*MINI_TILEY+(4)*MINI_TILEY-4,
848 int2str(i+1,1),FS_SMALL,FC_YELLOW);
851 /* Inhalt der Amöbe */
852 for(y=0;y<2;y++) for(x=0;x<2;x++)
854 DrawMiniElement(29+x,26+y,EL_ERDREICH);
855 XFillRectangle(display,drawto,gc,
856 SX+29*MINI_TILEX+MINI_TILEX/2-1,
857 SY+26*MINI_TILEY+MINI_TILEY/2-1,
858 MINI_TILEX+2,MINI_TILEY+2);
860 XCopyArea(display,drawto,drawto,gc,
861 SX+29*MINI_TILEX,SY+26*MINI_TILEY,
862 3*MINI_TILEX,3*MINI_TILEY,
863 SX+29*MINI_TILEX-MINI_TILEX/2,SY+26*MINI_TILEY-MINI_TILEY/2);
864 DrawMiniElement(29,26,level.amoebe_inhalt);
866 for(i=0;i<11+3+2;i++)
868 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
869 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
870 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
871 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
872 ED_COUNT_GADGET_XPOS,
873 ED_COUNT_GADGET_YPOS+i*ED_COUNT_GADGET_YSIZE);
876 DrawText(ED_COUNT_VALUE_XPOS,
877 ED_COUNT_VALUE_YPOS+i*ED_COUNT_GADGET_YSIZE,
878 int2str(level.score[i],3),FS_SMALL,FC_YELLOW);
880 DrawText(ED_COUNT_VALUE_XPOS,
881 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
882 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
884 DrawText(ED_COUNT_VALUE_XPOS,
885 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
886 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
888 DrawText(ED_COUNT_VALUE_XPOS,
889 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
890 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
892 DrawText(ED_COUNT_VALUE_XPOS,
893 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
894 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
896 DrawText(ED_COUNT_VALUE_XPOS,
897 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
898 int2str(level.time,3),FS_SMALL,FC_YELLOW);
901 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+0*ED_COUNT_TEXT_YSIZE,
902 "Score for Emerald",FS_SMALL,FC_YELLOW);
903 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+1*ED_COUNT_TEXT_YSIZE,
904 "Score for Diamond",FS_SMALL,FC_YELLOW);
905 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+2*ED_COUNT_TEXT_YSIZE,
906 "Score for smashing a Bug",FS_SMALL,FC_YELLOW);
907 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+3*ED_COUNT_TEXT_YSIZE,
908 "Score for smashing a Spaceship",FS_SMALL,FC_YELLOW);
909 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+4*ED_COUNT_TEXT_YSIZE,
910 "Score for smashing a Cruncher",FS_SMALL,FC_YELLOW);
911 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+5*ED_COUNT_TEXT_YSIZE,
912 "Score for smashing an Alien",FS_SMALL,FC_YELLOW);
913 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+6*ED_COUNT_TEXT_YSIZE,
914 "Score for smashing a Pacman",FS_SMALL,FC_YELLOW);
915 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+7*ED_COUNT_TEXT_YSIZE,
916 "Score for cracking a nut",FS_SMALL,FC_YELLOW);
917 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+8*ED_COUNT_TEXT_YSIZE,
918 "Score for dynamite",FS_SMALL,FC_YELLOW);
919 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+9*ED_COUNT_TEXT_YSIZE,
920 "Score for key",FS_SMALL,FC_YELLOW);
921 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+10*ED_COUNT_TEXT_YSIZE,
922 "Score for each 10 seconds left",FS_SMALL,FC_YELLOW);
923 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+11*ED_COUNT_TEXT_YSIZE,
924 "Speed of the amoeba / Content",FS_SMALL,FC_YELLOW);
925 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+12*ED_COUNT_TEXT_YSIZE,
926 "Time for magic wall",FS_SMALL,FC_YELLOW);
927 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+13*ED_COUNT_TEXT_YSIZE,
928 "Time for wheel",FS_SMALL,FC_YELLOW);
929 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+14*ED_COUNT_TEXT_YSIZE,
930 "Emeralds needed in this level",FS_SMALL,FC_YELLOW);
931 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+15*ED_COUNT_TEXT_YSIZE,
932 "Time available for this level",FS_SMALL,FC_YELLOW);
934 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
935 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS,
936 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
937 ED_WIN_COUNT_XSIZE,ED_WIN_COUNT_YSIZE,
938 ED_COUNT_GADGET_XPOS,
939 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
941 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
942 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS+3+2*FONT2_XSIZE,
943 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
944 ED_WIN_COUNT_XSIZE-3-2*FONT2_XSIZE,ED_WIN_COUNT_YSIZE,
945 ED_COUNT_GADGET_XPOS+3+i*FONT2_XSIZE,
946 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
947 DrawText(ED_COUNT_GADGET_XPOS+5,
948 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
949 level.name,FS_SMALL,FC_YELLOW);
950 DrawText(ED_COUNT_GADGET_XPOS+(30+3)*FONT2_XSIZE-5,
951 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
952 "Title",FS_SMALL,FC_YELLOW);
954 DrawText(ED_SIZE_GADGET_XPOS,ED_SIZE_GADGET_YPOS-18,
955 "Playfield size:",FS_SMALL,FC_YELLOW);
956 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
957 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
958 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
959 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
961 ED_SIZE_GADGET_YPOS+0*ED_COUNT_GADGET_YSIZE);
962 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
963 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
964 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
965 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
967 ED_SIZE_GADGET_YPOS+1*ED_COUNT_GADGET_YSIZE);
968 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+0*ED_SIZE_TEXT_YSIZE,
969 "Width",FS_SMALL,FC_YELLOW);
970 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+1*ED_SIZE_TEXT_YSIZE,
971 "Height",FS_SMALL,FC_YELLOW);
972 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
973 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
974 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
975 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
978 void AdjustLevelScrollPosition()
982 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
983 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
984 if (lev_fieldx<2*SCR_FIELDX-2)
989 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
990 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
991 if (lev_fieldy<2*SCR_FIELDY-2)
995 void LevelEd(int mx, int my, int button)
997 static int last_button = 0;
998 static int in_field_pressed = FALSE;
999 static boolean use_floodfill = FALSE;
1003 int x = (mx-SX)/MINI_TILEX;
1004 int y = (my-SY)/MINI_TILEY;
1008 HandlePressedControlButtons();
1009 HandleDrawingFunction(mx, my, button);
1011 if (use_floodfill) /********** FLOOD FILL **********/
1019 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
1024 if (x>lev_fieldx || y>lev_fieldy ||
1025 (x==0 && level_xpos<0) ||
1026 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
1027 (y==0 && level_ypos<0) ||
1028 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY))
1031 from_x = x+level_xpos;
1032 from_y = y+level_ypos;
1033 fill_element = (button==1 ? new_element1 :
1034 button==2 ? new_element2 :
1035 button==3 ? new_element3 : 0);
1037 FloodFill(from_x,from_y,fill_element);
1038 DrawMiniLevel(level_xpos,level_ypos);
1041 use_floodfill = FALSE;
1042 CloseDoor(DOOR_CLOSE_1);
1043 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1052 else /********** EDIT/CTRL-FENSTER **********/
1054 static unsigned long choice_delay = 0;
1055 int choice = CheckElemButtons(mx,my,button);
1056 int elem_pos = choice-ED_BUTTON_ELEM;
1058 if (((choice == ED_BUTTON_EUP && element_shift>0) ||
1059 (choice == ED_BUTTON_EDOWN &&
1060 element_shift<elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)) &&
1061 DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
1065 step = (button==1 ? MAX_ELEM_X : button==2 ? 5*MAX_ELEM_X :
1067 element_shift += (choice==ED_BUTTON_EUP ? -step : step);
1068 if (element_shift<0)
1070 if (element_shift>elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)
1071 element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y;
1072 if (element_shift % MAX_ELEM_X)
1073 element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X);
1075 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
1076 DrawElemButton(i+2,ED_BUTTON_RELEASED);
1078 else if (elem_pos>=0 && elem_pos<MAX_ELEM_X*MAX_ELEM_Y)
1082 if (elem_pos+element_shift < elements_in_list)
1083 new_element = editor_element[elem_pos+element_shift];
1085 new_element = EL_LEERRAUM;
1088 new_element1 = new_element;
1089 else if (last_button==2)
1090 new_element2 = new_element;
1091 else if (last_button==3)
1092 new_element3 = new_element;
1094 DrawMiniGraphicExt(drawto,gc,
1095 DX+ED_WIN_MB_LEFT_XPOS,
1096 DY+ED_WIN_MB_LEFT_YPOS,
1097 el2gfx(new_element1));
1098 DrawMiniGraphicExt(drawto,gc,
1099 DX+ED_WIN_MB_MIDDLE_XPOS,
1100 DY+ED_WIN_MB_MIDDLE_YPOS,
1101 el2gfx(new_element2));
1102 DrawMiniGraphicExt(drawto,gc,
1103 DX+ED_WIN_MB_RIGHT_XPOS,
1104 DY+ED_WIN_MB_RIGHT_YPOS,
1105 el2gfx(new_element3));
1106 redraw_mask |= REDRAW_DOOR_1;
1109 if (edit_mode) /********** EDIT-FENSTER **********/
1116 switch(CheckEditButtons(mx,my,button))
1118 case ED_BUTTON_CTRL:
1119 CloseDoor(DOOR_CLOSE_2);
1120 DrawControlWindow();
1121 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1122 DOOR_GFX_PAGEX4,DOOR_GFX_PAGEY1+80,
1124 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1125 OpenDoor(DOOR_OPEN_2);
1128 case ED_BUTTON_FILL:
1129 Request("Caution ! Flood fill mode ! Choose area !",REQ_OPEN);
1130 use_floodfill = TRUE;
1133 case ED_BUTTON_LEFT:
1136 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
1138 if (lev_fieldx<2*SCR_FIELDX-2)
1141 level_xpos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
1145 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT);
1147 DrawMiniLevel(level_xpos,level_ypos);
1150 case ED_BUTTON_RIGHT:
1151 if (level_xpos<=lev_fieldx-2*SCR_FIELDX)
1153 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
1155 if (lev_fieldx<2*SCR_FIELDX-2)
1158 level_xpos += (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
1159 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
1160 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
1162 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT);
1164 DrawMiniLevel(level_xpos,level_ypos);
1170 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
1172 if (lev_fieldy<2*SCR_FIELDY-2)
1175 level_ypos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
1179 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN);
1181 DrawMiniLevel(level_xpos,level_ypos);
1184 case ED_BUTTON_DOWN:
1185 if (level_ypos<=lev_fieldy-2*SCR_FIELDY)
1187 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
1189 if (lev_fieldy<2*SCR_FIELDY-2)
1192 level_ypos += (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
1193 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
1194 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
1196 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP);
1198 DrawMiniLevel(level_xpos,level_ypos);
1211 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
1215 if (button && !motion_status)
1216 in_field_pressed = TRUE;
1218 if (!button || !in_field_pressed || button<1 || button>3 ||
1219 (y==0 && level_ypos<0) ||
1220 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY) ||
1221 (x==0 && level_xpos<0) ||
1222 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
1223 x>lev_fieldx || y>lev_fieldy)
1226 new_element = (button==1 ? new_element1 :
1227 button==2 ? new_element2 :
1228 button==3 ? new_element3 : 0);
1230 if (new_element != Feld[x+level_xpos][y+level_ypos])
1232 if (new_element==EL_SPIELFIGUR) /* Jeder nur EINE Figur bitte... */
1236 for(x=0;x<lev_fieldx;x++) for(y=0;y<lev_fieldy;y++)
1238 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
1240 Feld[x][y] = EL_LEERRAUM;
1241 if (x-level_xpos>=0 && x-level_xpos<2*SCR_FIELDX &&
1242 y-level_ypos>=0 && y-level_ypos<2*SCR_FIELDY)
1243 DrawMiniElement(x-level_xpos,y-level_ypos,EL_LEERRAUM);
1248 Feld[x+level_xpos][y+level_ypos] = new_element;
1249 DrawMiniElement(x,y,new_element);
1252 else if (!motion_status) /* Mauszeiger nicht im Level-Feld */
1253 in_field_pressed = FALSE;
1260 else /********** KONTROLL-FENSTER **********/
1262 int choice = CheckCountButtons(mx,my,button);
1263 int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0);
1265 if (choice >= 0 && choice < 36 &&
1266 DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
1275 level.score[choice] += step;
1276 if (level.score[choice]<0)
1277 level.score[choice] = 0;
1278 else if (level.score[choice]>255)
1279 level.score[choice] = 255;
1281 else if (choice==11)
1283 level.tempo_amoebe += step;
1284 if (level.tempo_amoebe<0)
1285 level.tempo_amoebe = 0;
1286 else if (level.tempo_amoebe>255)
1287 level.tempo_amoebe = 255;
1289 else if (choice==12)
1291 level.dauer_sieb += step;
1292 if (level.dauer_sieb<0)
1293 level.dauer_sieb = 0;
1294 else if (level.dauer_sieb>255)
1295 level.dauer_sieb = 255;
1297 else if (choice==13)
1299 level.dauer_ablenk += step;
1300 if (level.dauer_ablenk<0)
1301 level.dauer_ablenk = 0;
1302 else if (level.dauer_ablenk>255)
1303 level.dauer_ablenk = 255;
1305 else if (choice==14)
1307 level.edelsteine += step;
1308 if (level.edelsteine<0)
1309 level.edelsteine = 0;
1310 else if (level.edelsteine>999)
1311 level.edelsteine = 999;
1313 else if (choice==15)
1318 else if (level.time>999)
1321 else if (choice==16)
1324 if (lev_fieldx<MIN_LEV_FIELDX)
1325 lev_fieldx = MIN_LEV_FIELDX;
1326 else if (lev_fieldx>MAX_LEV_FIELDX)
1327 lev_fieldx = MAX_LEV_FIELDX;
1328 level.fieldx = lev_fieldx;
1330 else if (choice==17)
1333 if (lev_fieldy<MIN_LEV_FIELDY)
1334 lev_fieldy = MIN_LEV_FIELDY;
1335 else if (lev_fieldy>MAX_LEV_FIELDY)
1336 lev_fieldy = MAX_LEV_FIELDY;
1337 level.fieldy = lev_fieldy;
1341 DrawText(ED_COUNT_VALUE_XPOS,
1342 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1343 int2str(level.score[choice],3),FS_SMALL,FC_YELLOW);
1344 else if (choice==11)
1345 DrawText(ED_COUNT_VALUE_XPOS,
1346 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
1347 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
1348 else if (choice==12)
1349 DrawText(ED_COUNT_VALUE_XPOS,
1350 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
1351 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
1352 else if (choice==13)
1353 DrawText(ED_COUNT_VALUE_XPOS,
1354 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
1355 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
1356 else if (choice==14)
1357 DrawText(ED_COUNT_VALUE_XPOS,
1358 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
1359 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
1360 else if (choice==15)
1361 DrawText(ED_COUNT_VALUE_XPOS,
1362 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
1363 int2str(level.time,3),FS_SMALL,FC_YELLOW);
1364 else if (choice==16)
1365 DrawText(ED_SIZE_VALUE_XPOS,
1366 ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
1367 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
1368 else if (choice==17)
1369 DrawText(ED_SIZE_VALUE_XPOS,
1370 ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
1371 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
1373 redraw_mask &= ~REDRAW_FIELD;
1375 XCopyArea(display,drawto,window,gc,
1376 ED_COUNT_VALUE_XPOS,
1377 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1378 3*FONT2_XSIZE,FONT2_YSIZE,
1379 ED_COUNT_VALUE_XPOS,
1380 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE);
1382 XCopyArea(display,drawto,window,gc,
1384 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE,
1385 3*FONT2_XSIZE,FONT2_YSIZE,
1387 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE);
1395 switch(CheckCtrlButtons(mx,my,button))
1397 case ED_BUTTON_EDIT:
1398 CloseDoor(DOOR_CLOSE_2);
1399 AdjustLevelScrollPosition();
1400 DrawMiniLevel(level_xpos,level_ypos);
1401 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1402 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
1404 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1405 OpenDoor(DOOR_OPEN_2);
1408 case ED_BUTTON_CLEAR:
1409 if (Request("Are you sure to clear this level ?",REQ_ASK))
1411 for(x=0;x<MAX_LEV_FIELDX;x++)
1412 for(y=0;y<MAX_LEV_FIELDY;y++)
1413 Feld[x][y] = EL_ERDREICH;
1414 DrawMiniLevel(level_xpos,level_ypos);
1417 case ED_BUTTON_UNDO:
1418 if (leveldir[leveldir_nr].readonly ||
1419 Request("Exit without saving ?",REQ_ASK | REQ_STAY_OPEN))
1421 CloseDoor(DOOR_CLOSE_BOTH);
1422 game_status=MAINMENU;
1427 CloseDoor(DOOR_CLOSE_1);
1428 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1431 case ED_BUTTON_EXIT:
1433 int figur_vorhanden = FALSE;
1435 if (leveldir[leveldir_nr].readonly)
1437 Request("This level is read only !",REQ_CONFIRM);
1441 for(y=0;y<lev_fieldy;y++)
1442 for(x=0;x<lev_fieldx;x++)
1443 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
1444 figur_vorhanden = TRUE;
1446 if (!figur_vorhanden)
1447 Request("No Level without Gregor Mc Duffin please !",
1451 if (Request("Save this level and kill the old ?",
1452 REQ_ASK | REQ_STAY_OPEN))
1454 for(x=0;x<lev_fieldx;x++)
1455 for(y=0;y<lev_fieldy;y++)
1456 Ur[x][y]=Feld[x][y];
1457 SaveLevel(level_nr);
1459 CloseDoor(DOOR_CLOSE_BOTH);
1460 game_status=MAINMENU;
1473 if (mx>=ED_COUNT_GADGET_XPOS &&
1474 mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
1475 my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
1476 my<ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE+ED_WIN_COUNT_YSIZE)
1481 DrawText(ED_COUNT_GADGET_XPOS+5,
1482 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1483 level.name,FS_SMALL,FC_GREEN);
1484 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1485 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1486 "<",FS_SMALL,FC_RED);
1493 name_typing = FALSE;
1494 DrawText(ED_COUNT_GADGET_XPOS+5,
1495 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1496 level.name,FS_SMALL,FC_YELLOW);
1497 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1498 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1499 " ",FS_SMALL,FC_RED);
1503 if (mx>=SX+29*MINI_TILEX && mx<SX+30*MINI_TILEX &&
1504 my>=SY+26*MINI_TILEY && my<SY+27*MINI_TILEY)
1508 if (!button || button<1 || button>3)
1511 new_element = (button==1 ? new_element1 :
1512 button==2 ? new_element2 :
1513 button==3 ? new_element3 : 0);
1515 if (new_element != level.amoebe_inhalt)
1517 level.amoebe_inhalt = new_element;
1518 DrawMiniElement(29,26,new_element);
1522 if (mx>=SX+1*MINI_TILEX && mx<SX+(1+4*5)*MINI_TILEX &&
1523 my>=SY+2*MINI_TILEY && my<SY+(2+3)*MINI_TILEY)
1525 int x = (mx-SX-1*MINI_TILEX)/MINI_TILEX;
1526 int y = (my-SY-2*MINI_TILEY)/MINI_TILEY;
1531 if (i>=0 && i<43 && x>=0 && x<3 && y>=0 && y<3)
1533 if (button && !motion_status)
1534 in_field_pressed = TRUE;
1536 if (!button || !in_field_pressed || button<1 || button>3)
1539 new_element = (button==1 ? new_element1 :
1540 button==2 ? new_element2 :
1541 button==3 ? new_element3 : 0);
1543 if (new_element != level.mampfer_inhalt[i][x][y])
1545 level.mampfer_inhalt[i][x][y] = new_element;
1546 DrawMiniElement(1+5*i+x,2+y,new_element);
1549 else if (!motion_status)/* Mauszeiger nicht im Cruncher-Feld */
1550 in_field_pressed = FALSE;
1552 else if (!motion_status) /* Mauszeiger nicht im Cruncher-Feld */
1553 in_field_pressed = FALSE;
1557 last_button = button;
1562 void LevelNameTyping(KeySym key)
1564 unsigned char ascii = 0;
1565 int len = strlen(level.name);
1570 if (key>=XK_A && key<=XK_Z)
1571 ascii = 'A'+(char)(key-XK_A);
1572 else if (key>=XK_a && key<=XK_z)
1573 ascii = 'a'+(char)(key-XK_a);
1574 else if (key>=XK_0 && key<=XK_9)
1575 ascii = '0'+(char)(key-XK_0);
1577 else if (key>=XK_space && key<=XK_at)
1578 ascii = ' '+(char)(key-XK_space);
1579 else if (key==XK_Adiaeresis)
1581 else if (key==XK_Odiaeresis)
1583 else if (key==XK_Udiaeresis)
1585 else if (key==XK_adiaeresis)
1587 else if (key==XK_odiaeresis)
1589 else if (key==XK_udiaeresis)
1591 else if (key==XK_underscore)
1595 if (ascii && len<MAX_LEVNAMLEN-2)
1597 level.name[len] = ascii;
1598 level.name[len+1] = 0;
1601 DrawTextExt(drawto,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(window,gc,
1606 ED_COUNT_GADGET_XPOS+5,
1607 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1608 level.name,FS_SMALL,FC_GREEN);
1609 DrawTextExt(drawto,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);
1613 DrawTextExt(window,gc,
1614 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1615 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1616 "<",FS_SMALL,FC_RED);
1618 else if ((key==XK_Delete || key==XK_BackSpace) && len>0)
1620 level.name[len-1] = 0;
1623 DrawTextExt(drawto,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);
1627 DrawTextExt(window,gc,
1628 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1629 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1630 "< ",FS_SMALL,FC_GREEN);
1632 else if (key==XK_Return)
1634 DrawTextExt(drawto,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(window,gc,
1639 ED_COUNT_GADGET_XPOS+5,
1640 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1641 level.name,FS_SMALL,FC_YELLOW);
1642 DrawTextExt(drawto,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);
1646 DrawTextExt(window,gc,
1647 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1648 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1649 " ",FS_SMALL,FC_YELLOW);
1651 name_typing = FALSE;
1655 static void swap_numbers(int *i1, int *i2)
1663 static void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
1675 static void DrawLineElement(int sx, int sy, int element)
1677 int lx = sx + level_xpos;
1678 int ly = sy + level_ypos;
1681 DrawMiniElement(sx, sy, Feld[lx][ly]);
1684 Feld[lx][ly] = element;
1685 DrawMiniElement(sx, sy, element);
1689 void DrawLine(int from_x, int from_y, int to_x, int to_y, int element)
1691 if (from_y == to_y) /* horizontal line */
1697 swap_numbers(&from_x, &to_x);
1699 for (x=from_x; x<=to_x; x++)
1700 DrawLineElement(x, y, element);
1702 else if (from_x == to_x) /* vertical line */
1708 swap_numbers(&from_y, &to_y);
1710 for (y=from_y; y<=to_y; y++)
1711 DrawLineElement(x, y, element);
1713 else /* diagonal line */
1715 int len_x = ABS(to_x - from_x);
1716 int len_y = ABS(to_y - from_y);
1719 if (len_y < len_x) /* < 45° */
1721 float a = (float)len_y / (float)len_x;
1724 swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
1726 for (x=0; x<len_x; x++)
1728 int y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1);
1730 DrawLineElement(from_x + x, from_y + y, element);
1735 float a = (float)len_x / (float)len_y;
1738 swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
1740 for (y=0; y<len_y; y++)
1742 int x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1);
1744 DrawLineElement(from_x + x, from_y + y, element);
1750 void FloodFill(int from_x, int from_y, int fill_element)
1754 static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
1755 static int safety = 0;
1757 /* check if starting field still has the desired content */
1758 if (Feld[from_x][from_y] == fill_element)
1763 if (safety > lev_fieldx*lev_fieldy)
1764 Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
1766 old_element = Feld[from_x][from_y];
1767 Feld[from_x][from_y] = fill_element;
1771 x = from_x + check[i][0];
1772 y = from_y + check[i][1];
1774 if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
1775 FloodFill(x, y, fill_element);
1781 void HandleDrawingFunction(int mx, int my, int button)
1783 static int in_field_pressed = FALSE;
1785 int sx = (mx - SX) / MINI_TILEX;
1786 int sy = (my - SY) / MINI_TILEY;
1787 int lx = sx + level_xpos;
1788 int ly = sy + level_ypos;
1791 if (mx < SX || mx >= SX + SXSIZE || my < SY || my >= SY + SYSIZE)
1793 /* pointer ouside drawing area */
1795 if (!motion_status) /* button pressed or released outside drawing area */
1796 in_field_pressed = FALSE;
1801 if (button && !motion_status)
1802 in_field_pressed = TRUE;
1805 !in_field_pressed ||
1806 button < 1 || button > 3 ||
1807 sx > lev_fieldx || sy > lev_fieldy ||
1808 (sx == 0 && level_xpos<0) ||
1809 (sx == 2*SCR_FIELDX - 1 && level_xpos > lev_fieldx - 2*SCR_FIELDX) ||
1810 (sy == 0 && level_ypos < 0) ||
1811 (sy == 2*SCR_FIELDY - 1 && level_ypos > lev_fieldy - 2*SCR_FIELDY))
1814 new_element = (button == 1 ? new_element1 :
1815 button == 2 ? new_element2 :
1816 button == 3 ? new_element3 : 0);
1818 switch (drawing_function)
1820 case ED_CTRL_ID_SINGLE_ITEMS:
1821 if (new_element != Feld[lx][ly])
1823 if (new_element == EL_SPIELFIGUR)
1825 /* remove player at old position */
1826 for(y=0; y<lev_fieldy; y++)
1828 for(x=0; x<lev_fieldx; x++)
1830 if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1)
1832 Feld[x][y] = EL_LEERRAUM;
1833 if (x - level_xpos >= 0 && x - level_xpos < 2*SCR_FIELDX &&
1834 y - level_ypos >= 0 && y - level_ypos < 2*SCR_FIELDY)
1835 DrawMiniElement(x - level_xpos, y - level_ypos, EL_LEERRAUM);
1841 Feld[lx][ly] = new_element;
1842 DrawMiniElement(sx, sy, new_element);
1846 case ED_CTRL_ID_CONNECTED_ITEMS:
1848 static int last_x = -1;
1849 static int last_y = -1;
1853 Feld[lx][ly] = new_element;
1854 DrawMiniElement(sx, sy, new_element);
1859 else if (last_x != sx || last_y != sy)
1861 DrawLine(last_x, last_y, sx, sy, new_element);
1874 case ED_CTRL_ID_FLOOD_FILL:
1875 FloodFill(lx, ly, new_element);
1876 DrawMiniLevel(level_xpos, level_ypos);