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 static int level_xpos,level_ypos;
42 static boolean edit_mode;
43 static boolean name_typing;
44 static int new_element1 = EL_MAUERWERK;
45 static int new_element2 = EL_LEERRAUM;
46 static int new_element3 = EL_ERDREICH;
49 int editor_element[] =
51 EL_CHAR_A + ('B' - 'A'),
52 EL_CHAR_A + ('O' - 'A'),
53 EL_CHAR_A + ('U' - 'A'),
54 EL_CHAR_A + ('L' - 'A'),
57 EL_CHAR_A + ('D' - 'A'),
58 EL_CHAR_A + ('E' - 'A'),
59 EL_CHAR_A + ('R' - 'A'),
61 EL_CHAR_A + ('D' - 'A'),
62 EL_CHAR_A + ('A' - 'A'),
63 EL_CHAR_A + ('S' - 'A'),
64 EL_CHAR_A + ('H' - 'A'),
91 EL_CHAR_A + ('E' - 'A'),
92 EL_CHAR_A + ('M' - 'A'),
93 EL_CHAR_A + ('E' - 'A'),
96 EL_CHAR_A + ('R' - 'A'),
97 EL_CHAR_A + ('A' - 'A'),
98 EL_CHAR_A + ('L' - 'A'),
99 EL_CHAR_A + ('D' - 'A'),
101 EL_CHAR_A + ('M' - 'A'),
102 EL_CHAR_A + ('I' - 'A'),
103 EL_CHAR_A + ('N' - 'A'),
104 EL_CHAR_A + ('E' - 'A'),
181 EL_CHAR_A + ('M' - 'A'),
182 EL_CHAR_A + ('O' - 'A'),
183 EL_CHAR_A + ('R' - 'A'),
184 EL_CHAR_A + ('E' - 'A'),
231 EL_CHAR_A + ('S' - 'A'),
232 EL_CHAR_A + ('O' - 'A'),
233 EL_CHAR_A + ('K' - 'A'),
234 EL_CHAR_A + ('O' - 'A'),
237 EL_CHAR_A + ('B' - 'A'),
238 EL_CHAR_A + ('A' - 'A'),
239 EL_CHAR_A + ('N' - 'A'),
242 EL_SOKOBAN_FELD_LEER,
243 EL_SOKOBAN_FELD_VOLL,
247 EL_CHAR_A + ('D' - 'A'),
248 EL_CHAR_A + ('Y' - 'A'),
249 EL_CHAR_A + ('N' - 'A'),
250 EL_CHAR_A + ('A' - 'A'),
252 EL_CHAR_A + ('B' - 'A'),
253 EL_CHAR_A + ('L' - 'A'),
254 EL_CHAR_A + ('A' - 'A'),
255 EL_CHAR_A + ('S' - 'A'),
258 EL_CHAR_A + ('T' - 'A'),
259 EL_CHAR_A + ('E' - 'A'),
260 EL_CHAR_A + ('R' - 'A'),
342 int elements_in_list = sizeof(editor_element)/sizeof(int);
354 CloseDoor(DOOR_CLOSE_2);
356 DrawMiniLevel(level_xpos,level_ypos);
359 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
360 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY1,
362 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
363 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
364 DOOR_GFX_PAGEX6+ED_BUTTON_ELEM_XPOS,
365 DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS,
366 4*ED_BUTTON_ELEM_XSIZE,5*ED_BUTTON_ELEM_YSIZE,
367 DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS,
368 DOOR_GFX_PAGEY1+ED_BUTTON_EUP_Y2POS);
370 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
372 if (i < elements_in_list)
373 graphic = el2gfx(editor_element[i]);
375 graphic = GFX_LEERRAUM;
377 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
378 DOOR_GFX_PAGEX1+ED_BUTTON_ELEM_XPOS+3 +
379 (i%MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
380 DOOR_GFX_PAGEY1+ED_BUTTON_ELEM_YPOS+3 +
381 (i/MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
385 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
386 DOOR_GFX_PAGEX1+ED_WIN_MB_LEFT_XPOS,
387 DOOR_GFX_PAGEY1+ED_WIN_MB_LEFT_YPOS,
388 el2gfx(new_element1));
389 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
390 DOOR_GFX_PAGEX1+ED_WIN_MB_MIDDLE_XPOS,
391 DOOR_GFX_PAGEY1+ED_WIN_MB_MIDDLE_YPOS,
392 el2gfx(new_element2));
393 DrawMiniGraphicExt(pix[PIX_DB_DOOR],gc,
394 DOOR_GFX_PAGEX1+ED_WIN_MB_RIGHT_XPOS,
395 DOOR_GFX_PAGEY1+ED_WIN_MB_RIGHT_YPOS,
396 el2gfx(new_element3));
397 DrawTextExt(pix[PIX_DB_DOOR],gc,
398 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS,
399 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
400 int2str(level_nr,2),FS_SMALL,FC_SPECIAL1);
401 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
402 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+3,
403 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
405 DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS,
406 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
407 XCopyArea(display,pix[PIX_DB_DOOR],pix[PIX_DB_DOOR],gc,
408 DOOR_GFX_PAGEX2+ED_WIN_LEVELNR_XPOS+14,
409 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS,
411 DOOR_GFX_PAGEX1+ED_WIN_LEVELNR_XPOS+9,
412 DOOR_GFX_PAGEY1+ED_WIN_LEVELNR_YPOS);
414 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
415 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
417 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
419 OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
424 void test_func(struct GadgetInfo *gi)
426 if (gi->event == GD_EVENT_PRESSED)
427 printf("test_func: GD_EVENT_PRESSED\n");
428 else if (gi->event == GD_EVENT_RELEASED)
429 printf("test_func: GD_EVENT_RELEASED\n");
431 printf("test_func: ?\n");
438 void DrawControlWindow()
444 /* Inhalt der Mampfer */
445 DrawText(ED_COUNT_GADGET_XPOS+1,SY+6,
446 "Contents of a smashed cruncher:",FS_SMALL,FC_YELLOW);
447 for(i=0;i<4;i++) for(y=0;y<4;y++) for(x=0;x<4;x++)
449 DrawMiniElement(1+5*i+x,2+y,EL_ERDREICH);
450 XFillRectangle(display,drawto,gc,
451 SX+(1+5*i)*MINI_TILEX+MINI_TILEX/2-1,
452 SY+(2)*MINI_TILEY+MINI_TILEY/2-1,
453 3*MINI_TILEX+2,3*MINI_TILEY+2);
455 XCopyArea(display,drawto,drawto,gc,
456 SX+1*MINI_TILEX,SY+2*MINI_TILEY,
457 4*5*MINI_TILEX,5*MINI_TILEY,
458 SX+1*MINI_TILEX-MINI_TILEX/2,SY+2*MINI_TILEY-MINI_TILEY/2);
461 for(y=0;y<3;y++) for(x=0;x<3;x++)
462 DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
464 DrawText(SX+MINI_TILEX+(5*i+1)*MINI_TILEX+1,
465 SY+2*MINI_TILEY+(4)*MINI_TILEY-4,
466 int2str(i+1,1),FS_SMALL,FC_YELLOW);
469 /* Inhalt der Amöbe */
470 for(y=0;y<2;y++) for(x=0;x<2;x++)
472 DrawMiniElement(29+x,26+y,EL_ERDREICH);
473 XFillRectangle(display,drawto,gc,
474 SX+29*MINI_TILEX+MINI_TILEX/2-1,
475 SY+26*MINI_TILEY+MINI_TILEY/2-1,
476 MINI_TILEX+2,MINI_TILEY+2);
478 XCopyArea(display,drawto,drawto,gc,
479 SX+29*MINI_TILEX,SY+26*MINI_TILEY,
480 3*MINI_TILEX,3*MINI_TILEY,
481 SX+29*MINI_TILEX-MINI_TILEX/2,SY+26*MINI_TILEY-MINI_TILEY/2);
482 DrawMiniElement(29,26,level.amoebe_inhalt);
484 for(i=0;i<11+3+2;i++)
486 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
487 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
488 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
489 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
490 ED_COUNT_GADGET_XPOS,
491 ED_COUNT_GADGET_YPOS+i*ED_COUNT_GADGET_YSIZE);
494 DrawText(ED_COUNT_VALUE_XPOS,
495 ED_COUNT_VALUE_YPOS+i*ED_COUNT_GADGET_YSIZE,
496 int2str(level.score[i],3),FS_SMALL,FC_YELLOW);
498 DrawText(ED_COUNT_VALUE_XPOS,
499 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
500 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
502 DrawText(ED_COUNT_VALUE_XPOS,
503 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
504 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
506 DrawText(ED_COUNT_VALUE_XPOS,
507 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
508 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
510 DrawText(ED_COUNT_VALUE_XPOS,
511 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
512 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
514 DrawText(ED_COUNT_VALUE_XPOS,
515 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
516 int2str(level.time,3),FS_SMALL,FC_YELLOW);
519 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+0*ED_COUNT_TEXT_YSIZE,
520 "Score for Emerald",FS_SMALL,FC_YELLOW);
521 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+1*ED_COUNT_TEXT_YSIZE,
522 "Score for Diamond",FS_SMALL,FC_YELLOW);
523 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+2*ED_COUNT_TEXT_YSIZE,
524 "Score for smashing a Bug",FS_SMALL,FC_YELLOW);
525 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+3*ED_COUNT_TEXT_YSIZE,
526 "Score for smashing a Spaceship",FS_SMALL,FC_YELLOW);
527 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+4*ED_COUNT_TEXT_YSIZE,
528 "Score for smashing a Cruncher",FS_SMALL,FC_YELLOW);
529 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+5*ED_COUNT_TEXT_YSIZE,
530 "Score for smashing an Alien",FS_SMALL,FC_YELLOW);
531 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+6*ED_COUNT_TEXT_YSIZE,
532 "Score for smashing a Pacman",FS_SMALL,FC_YELLOW);
533 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+7*ED_COUNT_TEXT_YSIZE,
534 "Score for cracking a nut",FS_SMALL,FC_YELLOW);
535 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+8*ED_COUNT_TEXT_YSIZE,
536 "Score for dynamite",FS_SMALL,FC_YELLOW);
537 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+9*ED_COUNT_TEXT_YSIZE,
538 "Score for key",FS_SMALL,FC_YELLOW);
539 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+10*ED_COUNT_TEXT_YSIZE,
540 "Score for each 10 seconds left",FS_SMALL,FC_YELLOW);
541 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+11*ED_COUNT_TEXT_YSIZE,
542 "Speed of the amoeba / Content",FS_SMALL,FC_YELLOW);
543 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+12*ED_COUNT_TEXT_YSIZE,
544 "Time for magic wall",FS_SMALL,FC_YELLOW);
545 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+13*ED_COUNT_TEXT_YSIZE,
546 "Time for wheel",FS_SMALL,FC_YELLOW);
547 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+14*ED_COUNT_TEXT_YSIZE,
548 "Emeralds needed in this level",FS_SMALL,FC_YELLOW);
549 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+15*ED_COUNT_TEXT_YSIZE,
550 "Time available for this level",FS_SMALL,FC_YELLOW);
552 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
553 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS,
554 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
555 ED_WIN_COUNT_XSIZE,ED_WIN_COUNT_YSIZE,
556 ED_COUNT_GADGET_XPOS,
557 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
559 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
560 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS+3+2*FONT2_XSIZE,
561 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
562 ED_WIN_COUNT_XSIZE-3-2*FONT2_XSIZE,ED_WIN_COUNT_YSIZE,
563 ED_COUNT_GADGET_XPOS+3+i*FONT2_XSIZE,
564 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
565 DrawText(ED_COUNT_GADGET_XPOS+5,
566 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
567 level.name,FS_SMALL,FC_YELLOW);
568 DrawText(ED_COUNT_GADGET_XPOS+(30+3)*FONT2_XSIZE-5,
569 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
570 "Title",FS_SMALL,FC_YELLOW);
572 DrawText(ED_SIZE_GADGET_XPOS,ED_SIZE_GADGET_YPOS-18,
573 "Playfield size:",FS_SMALL,FC_YELLOW);
574 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
575 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
576 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
577 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
579 ED_SIZE_GADGET_YPOS+0*ED_COUNT_GADGET_YSIZE);
580 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
581 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
582 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
583 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
585 ED_SIZE_GADGET_YPOS+1*ED_COUNT_GADGET_YSIZE);
586 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+0*ED_SIZE_TEXT_YSIZE,
587 "Width",FS_SMALL,FC_YELLOW);
588 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+1*ED_SIZE_TEXT_YSIZE,
589 "Height",FS_SMALL,FC_YELLOW);
590 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
591 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
592 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
593 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
596 Pixmap gd_pixmap = pix[PIX_DOOR];
597 int gd_x1 = DOOR_GFX_PAGEX4 + ED_BUTTON_MINUS_XPOS;
598 int gd_x2 = DOOR_GFX_PAGEX3 + ED_BUTTON_MINUS_XPOS;
599 int gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
600 struct GadgetInfo *gi;
602 gi = CreateGadget(GDI_X, 100,
604 GDI_WIDTH, ED_BUTTON_MINUS_XSIZE,
605 GDI_HEIGHT, ED_BUTTON_MINUS_YSIZE,
606 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
607 GDI_STATE, GD_BUTTON_UNPRESSED,
608 GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
609 GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
610 GDI_CALLBACK, test_func,
614 Error(ERR_EXIT, "cannot create gadget");
622 void ScrollMiniLevel(int from_x, int from_y, int scroll)
625 int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
626 int dy = (scroll==ED_SCROLL_UP ? -1 : scroll==ED_SCROLL_DOWN ? 1 : 0);
628 XCopyArea(display,drawto,drawto,gc,
629 SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
630 SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
631 SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
634 x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
635 for(y=0;y<2*SCR_FIELDY;y++)
636 DrawMiniElementOrWall(x,y,from_x,from_y);
640 y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
641 for(x=0;x<2*SCR_FIELDX;x++)
642 DrawMiniElementOrWall(x,y,from_x,from_y);
645 redraw_mask |= REDRAW_FIELD;
649 void AdjustLevelScrollPosition()
653 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
654 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
655 if (lev_fieldx<2*SCR_FIELDX-2)
660 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
661 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
662 if (lev_fieldy<2*SCR_FIELDY-2)
666 void FloodFill(int from_x, int from_y, int fill_element)
670 static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
671 static int safety = 0;
673 /* check if starting field still has the desired content */
674 if (Feld[from_x][from_y] == fill_element)
679 if (safety > lev_fieldx*lev_fieldy)
680 Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
682 old_element = Feld[from_x][from_y];
683 Feld[from_x][from_y] = fill_element;
687 x = from_x + check[i][0];
688 y = from_y + check[i][1];
690 if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
691 FloodFill(x, y, fill_element);
697 void LevelEd(int mx, int my, int button)
699 static int last_button = 0;
700 static int in_field_pressed = FALSE;
701 static boolean use_floodfill = FALSE;
702 int x = (mx-SX)/MINI_TILEX;
703 int y = (my-SY)/MINI_TILEY;
705 if (use_floodfill) /********** FLOOD FILL **********/
709 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
714 if (x>lev_fieldx || y>lev_fieldy ||
715 (x==0 && level_xpos<0) ||
716 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
717 (y==0 && level_ypos<0) ||
718 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY))
721 from_x = x+level_xpos;
722 from_y = y+level_ypos;
723 fill_element = (button==1 ? new_element1 :
724 button==2 ? new_element2 :
725 button==3 ? new_element3 : 0);
727 FloodFill(from_x,from_y,fill_element);
728 DrawMiniLevel(level_xpos,level_ypos);
731 use_floodfill = FALSE;
732 CloseDoor(DOOR_CLOSE_1);
733 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
737 else /********** EDIT/CTRL-FENSTER **********/
739 static unsigned long choice_delay = 0;
740 int choice = CheckElemButtons(mx,my,button);
741 int elem_pos = choice-ED_BUTTON_ELEM;
743 if (((choice == ED_BUTTON_EUP && element_shift>0) ||
744 (choice == ED_BUTTON_EDOWN &&
745 element_shift<elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)) &&
746 DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
750 step = (button==1 ? MAX_ELEM_X : button==2 ? 5*MAX_ELEM_X :
752 element_shift += (choice==ED_BUTTON_EUP ? -step : step);
755 if (element_shift>elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)
756 element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y;
757 if (element_shift % MAX_ELEM_X)
758 element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X);
760 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
761 DrawElemButton(i+2,ED_BUTTON_RELEASED);
763 else if (elem_pos>=0 && elem_pos<MAX_ELEM_X*MAX_ELEM_Y)
767 if (elem_pos+element_shift < elements_in_list)
768 new_element = editor_element[elem_pos+element_shift];
770 new_element = EL_LEERRAUM;
773 new_element1 = new_element;
774 else if (last_button==2)
775 new_element2 = new_element;
776 else if (last_button==3)
777 new_element3 = new_element;
779 DrawMiniGraphicExt(drawto,gc,
780 DX+ED_WIN_MB_LEFT_XPOS,
781 DY+ED_WIN_MB_LEFT_YPOS,
782 el2gfx(new_element1));
783 DrawMiniGraphicExt(drawto,gc,
784 DX+ED_WIN_MB_MIDDLE_XPOS,
785 DY+ED_WIN_MB_MIDDLE_YPOS,
786 el2gfx(new_element2));
787 DrawMiniGraphicExt(drawto,gc,
788 DX+ED_WIN_MB_RIGHT_XPOS,
789 DY+ED_WIN_MB_RIGHT_YPOS,
790 el2gfx(new_element3));
791 redraw_mask |= REDRAW_DOOR_1;
794 if (edit_mode) /********** EDIT-FENSTER **********/
796 switch(CheckEditButtons(mx,my,button))
799 CloseDoor(DOOR_CLOSE_2);
801 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
802 DOOR_GFX_PAGEX4,DOOR_GFX_PAGEY1+80,
804 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
805 OpenDoor(DOOR_OPEN_2);
809 Request("Caution ! Flood fill mode ! Choose area !",REQ_OPEN);
810 use_floodfill = TRUE;
816 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
818 if (lev_fieldx<2*SCR_FIELDX-2)
821 level_xpos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
825 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT);
827 DrawMiniLevel(level_xpos,level_ypos);
830 case ED_BUTTON_RIGHT:
831 if (level_xpos<=lev_fieldx-2*SCR_FIELDX)
833 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
835 if (lev_fieldx<2*SCR_FIELDX-2)
838 level_xpos += (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
839 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
840 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
842 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT);
844 DrawMiniLevel(level_xpos,level_ypos);
850 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
852 if (lev_fieldy<2*SCR_FIELDY-2)
855 level_ypos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
859 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN);
861 DrawMiniLevel(level_xpos,level_ypos);
865 if (level_ypos<=lev_fieldy-2*SCR_FIELDY)
867 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
869 if (lev_fieldy<2*SCR_FIELDY-2)
872 level_ypos += (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
873 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
874 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
876 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP);
878 DrawMiniLevel(level_xpos,level_ypos);
885 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
889 if (button && !motion_status)
890 in_field_pressed = TRUE;
892 if (!button || !in_field_pressed || button<1 || button>3 ||
893 (y==0 && level_ypos<0) ||
894 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY) ||
895 (x==0 && level_xpos<0) ||
896 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
897 x>lev_fieldx || y>lev_fieldy)
900 new_element = (button==1 ? new_element1 :
901 button==2 ? new_element2 :
902 button==3 ? new_element3 : 0);
904 if (new_element != Feld[x+level_xpos][y+level_ypos])
906 if (new_element==EL_SPIELFIGUR) /* Jeder nur EINE Figur bitte... */
910 for(x=0;x<lev_fieldx;x++) for(y=0;y<lev_fieldy;y++)
912 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
914 Feld[x][y] = EL_LEERRAUM;
915 if (x-level_xpos>=0 && x-level_xpos<2*SCR_FIELDX &&
916 y-level_ypos>=0 && y-level_ypos<2*SCR_FIELDY)
917 DrawMiniElement(x-level_xpos,y-level_ypos,EL_LEERRAUM);
922 Feld[x+level_xpos][y+level_ypos] = new_element;
923 DrawMiniElement(x,y,new_element);
926 else if (!motion_status) /* Mauszeiger nicht im Level-Feld */
927 in_field_pressed = FALSE;
929 else /********** KONTROLL-FENSTER **********/
931 int choice = CheckCountButtons(mx,my,button);
932 int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0);
934 if (choice >= 0 && choice < 36 &&
935 DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
944 level.score[choice] += step;
945 if (level.score[choice]<0)
946 level.score[choice] = 0;
947 else if (level.score[choice]>255)
948 level.score[choice] = 255;
952 level.tempo_amoebe += step;
953 if (level.tempo_amoebe<0)
954 level.tempo_amoebe = 0;
955 else if (level.tempo_amoebe>255)
956 level.tempo_amoebe = 255;
960 level.dauer_sieb += step;
961 if (level.dauer_sieb<0)
962 level.dauer_sieb = 0;
963 else if (level.dauer_sieb>255)
964 level.dauer_sieb = 255;
968 level.dauer_ablenk += step;
969 if (level.dauer_ablenk<0)
970 level.dauer_ablenk = 0;
971 else if (level.dauer_ablenk>255)
972 level.dauer_ablenk = 255;
976 level.edelsteine += step;
977 if (level.edelsteine<0)
978 level.edelsteine = 0;
979 else if (level.edelsteine>999)
980 level.edelsteine = 999;
987 else if (level.time>999)
993 if (lev_fieldx<MIN_LEV_FIELDX)
994 lev_fieldx = MIN_LEV_FIELDX;
995 else if (lev_fieldx>MAX_LEV_FIELDX)
996 lev_fieldx = MAX_LEV_FIELDX;
997 level.fieldx = lev_fieldx;
1002 if (lev_fieldy<MIN_LEV_FIELDY)
1003 lev_fieldy = MIN_LEV_FIELDY;
1004 else if (lev_fieldy>MAX_LEV_FIELDY)
1005 lev_fieldy = MAX_LEV_FIELDY;
1006 level.fieldy = lev_fieldy;
1010 DrawText(ED_COUNT_VALUE_XPOS,
1011 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1012 int2str(level.score[choice],3),FS_SMALL,FC_YELLOW);
1013 else if (choice==11)
1014 DrawText(ED_COUNT_VALUE_XPOS,
1015 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
1016 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
1017 else if (choice==12)
1018 DrawText(ED_COUNT_VALUE_XPOS,
1019 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
1020 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
1021 else if (choice==13)
1022 DrawText(ED_COUNT_VALUE_XPOS,
1023 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
1024 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
1025 else if (choice==14)
1026 DrawText(ED_COUNT_VALUE_XPOS,
1027 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
1028 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
1029 else if (choice==15)
1030 DrawText(ED_COUNT_VALUE_XPOS,
1031 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
1032 int2str(level.time,3),FS_SMALL,FC_YELLOW);
1033 else if (choice==16)
1034 DrawText(ED_SIZE_VALUE_XPOS,
1035 ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
1036 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
1037 else if (choice==17)
1038 DrawText(ED_SIZE_VALUE_XPOS,
1039 ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
1040 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
1042 redraw_mask &= ~REDRAW_FIELD;
1044 XCopyArea(display,drawto,window,gc,
1045 ED_COUNT_VALUE_XPOS,
1046 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1047 3*FONT2_XSIZE,FONT2_YSIZE,
1048 ED_COUNT_VALUE_XPOS,
1049 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE);
1051 XCopyArea(display,drawto,window,gc,
1053 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE,
1054 3*FONT2_XSIZE,FONT2_YSIZE,
1056 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE);
1060 switch(CheckCtrlButtons(mx,my,button))
1062 case ED_BUTTON_EDIT:
1063 CloseDoor(DOOR_CLOSE_2);
1064 AdjustLevelScrollPosition();
1065 DrawMiniLevel(level_xpos,level_ypos);
1066 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1067 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
1069 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1070 OpenDoor(DOOR_OPEN_2);
1073 case ED_BUTTON_CLEAR:
1074 if (Request("Are you sure to clear this level ?",REQ_ASK))
1076 for(x=0;x<MAX_LEV_FIELDX;x++)
1077 for(y=0;y<MAX_LEV_FIELDY;y++)
1078 Feld[x][y] = EL_ERDREICH;
1079 DrawMiniLevel(level_xpos,level_ypos);
1082 case ED_BUTTON_UNDO:
1083 if (leveldir[leveldir_nr].readonly ||
1084 Request("Exit without saving ?",REQ_ASK | REQ_STAY_OPEN))
1086 CloseDoor(DOOR_CLOSE_BOTH);
1087 game_status=MAINMENU;
1092 CloseDoor(DOOR_CLOSE_1);
1093 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1096 case ED_BUTTON_EXIT:
1098 int figur_vorhanden = FALSE;
1100 if (leveldir[leveldir_nr].readonly)
1102 Request("This level is read only !",REQ_CONFIRM);
1106 for(y=0;y<lev_fieldy;y++)
1107 for(x=0;x<lev_fieldx;x++)
1108 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
1109 figur_vorhanden = TRUE;
1111 if (!figur_vorhanden)
1112 Request("No Level without Gregor Mc Duffin please !",
1116 if (Request("Save this level and kill the old ?",
1117 REQ_ASK | REQ_STAY_OPEN))
1119 for(x=0;x<lev_fieldx;x++)
1120 for(y=0;y<lev_fieldy;y++)
1121 Ur[x][y]=Feld[x][y];
1122 SaveLevel(level_nr);
1124 CloseDoor(DOOR_CLOSE_BOTH);
1125 game_status=MAINMENU;
1134 if (mx>=ED_COUNT_GADGET_XPOS &&
1135 mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
1136 my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
1137 my<ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE+ED_WIN_COUNT_YSIZE)
1142 DrawText(ED_COUNT_GADGET_XPOS+5,
1143 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1144 level.name,FS_SMALL,FC_GREEN);
1145 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1146 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1147 "<",FS_SMALL,FC_RED);
1154 name_typing = FALSE;
1155 DrawText(ED_COUNT_GADGET_XPOS+5,
1156 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1157 level.name,FS_SMALL,FC_YELLOW);
1158 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1159 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1160 " ",FS_SMALL,FC_RED);
1164 if (mx>=SX+29*MINI_TILEX && mx<SX+30*MINI_TILEX &&
1165 my>=SY+26*MINI_TILEY && my<SY+27*MINI_TILEY)
1169 if (!button || button<1 || button>3)
1172 new_element = (button==1 ? new_element1 :
1173 button==2 ? new_element2 :
1174 button==3 ? new_element3 : 0);
1176 if (new_element != level.amoebe_inhalt)
1178 level.amoebe_inhalt = new_element;
1179 DrawMiniElement(29,26,new_element);
1183 if (mx>=SX+1*MINI_TILEX && mx<SX+(1+4*5)*MINI_TILEX &&
1184 my>=SY+2*MINI_TILEY && my<SY+(2+3)*MINI_TILEY)
1186 int x = (mx-SX-1*MINI_TILEX)/MINI_TILEX;
1187 int y = (my-SY-2*MINI_TILEY)/MINI_TILEY;
1192 if (i>=0 && i<43 && x>=0 && x<3 && y>=0 && y<3)
1194 if (button && !motion_status)
1195 in_field_pressed = TRUE;
1197 if (!button || !in_field_pressed || button<1 || button>3)
1200 new_element = (button==1 ? new_element1 :
1201 button==2 ? new_element2 :
1202 button==3 ? new_element3 : 0);
1204 if (new_element != level.mampfer_inhalt[i][x][y])
1206 level.mampfer_inhalt[i][x][y] = new_element;
1207 DrawMiniElement(1+5*i+x,2+y,new_element);
1210 else if (!motion_status)/* Mauszeiger nicht im Cruncher-Feld */
1211 in_field_pressed = FALSE;
1213 else if (!motion_status) /* Mauszeiger nicht im Cruncher-Feld */
1214 in_field_pressed = FALSE;
1218 last_button = button;
1223 void LevelNameTyping(KeySym key)
1225 unsigned char ascii = 0;
1226 int len = strlen(level.name);
1231 if (key>=XK_A && key<=XK_Z)
1232 ascii = 'A'+(char)(key-XK_A);
1233 else if (key>=XK_a && key<=XK_z)
1234 ascii = 'a'+(char)(key-XK_a);
1235 else if (key>=XK_0 && key<=XK_9)
1236 ascii = '0'+(char)(key-XK_0);
1238 else if (key>=XK_space && key<=XK_at)
1239 ascii = ' '+(char)(key-XK_space);
1240 else if (key==XK_Adiaeresis)
1242 else if (key==XK_Odiaeresis)
1244 else if (key==XK_Udiaeresis)
1246 else if (key==XK_adiaeresis)
1248 else if (key==XK_odiaeresis)
1250 else if (key==XK_udiaeresis)
1252 else if (key==XK_underscore)
1256 if (ascii && len<MAX_LEVNAMLEN-2)
1258 level.name[len] = ascii;
1259 level.name[len+1] = 0;
1262 DrawTextExt(drawto,gc,
1263 ED_COUNT_GADGET_XPOS+5,
1264 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1265 level.name,FS_SMALL,FC_GREEN);
1266 DrawTextExt(window,gc,
1267 ED_COUNT_GADGET_XPOS+5,
1268 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1269 level.name,FS_SMALL,FC_GREEN);
1270 DrawTextExt(drawto,gc,
1271 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1272 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1273 "<",FS_SMALL,FC_RED);
1274 DrawTextExt(window,gc,
1275 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1276 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1277 "<",FS_SMALL,FC_RED);
1279 else if ((key==XK_Delete || key==XK_BackSpace) && len>0)
1281 level.name[len-1] = 0;
1284 DrawTextExt(drawto,gc,
1285 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1286 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1287 "< ",FS_SMALL,FC_GREEN);
1288 DrawTextExt(window,gc,
1289 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1290 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1291 "< ",FS_SMALL,FC_GREEN);
1293 else if (key==XK_Return)
1295 DrawTextExt(drawto,gc,
1296 ED_COUNT_GADGET_XPOS+5,
1297 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1298 level.name,FS_SMALL,FC_YELLOW);
1299 DrawTextExt(window,gc,
1300 ED_COUNT_GADGET_XPOS+5,
1301 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1302 level.name,FS_SMALL,FC_YELLOW);
1303 DrawTextExt(drawto,gc,
1304 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1305 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1306 " ",FS_SMALL,FC_YELLOW);
1307 DrawTextExt(window,gc,
1308 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1309 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1310 " ",FS_SMALL,FC_YELLOW);
1312 name_typing = FALSE;