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);
422 void DrawControlWindow()
428 /* Inhalt der Mampfer */
429 DrawText(ED_COUNT_GADGET_XPOS+1,SY+6,
430 "Contents of a smashed cruncher:",FS_SMALL,FC_YELLOW);
431 for(i=0;i<4;i++) for(y=0;y<4;y++) for(x=0;x<4;x++)
433 DrawMiniElement(1+5*i+x,2+y,EL_ERDREICH);
434 XFillRectangle(display,drawto,gc,
435 SX+(1+5*i)*MINI_TILEX+MINI_TILEX/2-1,
436 SY+(2)*MINI_TILEY+MINI_TILEY/2-1,
437 3*MINI_TILEX+2,3*MINI_TILEY+2);
439 XCopyArea(display,drawto,drawto,gc,
440 SX+1*MINI_TILEX,SY+2*MINI_TILEY,
441 4*5*MINI_TILEX,5*MINI_TILEY,
442 SX+1*MINI_TILEX-MINI_TILEX/2,SY+2*MINI_TILEY-MINI_TILEY/2);
445 for(y=0;y<3;y++) for(x=0;x<3;x++)
446 DrawMiniElement(1+5*i+x,2+y,level.mampfer_inhalt[i][x][y]);
448 DrawText(SX+MINI_TILEX+(5*i+1)*MINI_TILEX+1,
449 SY+2*MINI_TILEY+(4)*MINI_TILEY-4,
450 int2str(i+1,1),FS_SMALL,FC_YELLOW);
453 /* Inhalt der Amöbe */
454 for(y=0;y<2;y++) for(x=0;x<2;x++)
456 DrawMiniElement(29+x,26+y,EL_ERDREICH);
457 XFillRectangle(display,drawto,gc,
458 SX+29*MINI_TILEX+MINI_TILEX/2-1,
459 SY+26*MINI_TILEY+MINI_TILEY/2-1,
460 MINI_TILEX+2,MINI_TILEY+2);
462 XCopyArea(display,drawto,drawto,gc,
463 SX+29*MINI_TILEX,SY+26*MINI_TILEY,
464 3*MINI_TILEX,3*MINI_TILEY,
465 SX+29*MINI_TILEX-MINI_TILEX/2,SY+26*MINI_TILEY-MINI_TILEY/2);
466 DrawMiniElement(29,26,level.amoebe_inhalt);
468 for(i=0;i<11+3+2;i++)
470 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
471 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
472 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
473 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
474 ED_COUNT_GADGET_XPOS,
475 ED_COUNT_GADGET_YPOS+i*ED_COUNT_GADGET_YSIZE);
478 DrawText(ED_COUNT_VALUE_XPOS,
479 ED_COUNT_VALUE_YPOS+i*ED_COUNT_GADGET_YSIZE,
480 int2str(level.score[i],3),FS_SMALL,FC_YELLOW);
482 DrawText(ED_COUNT_VALUE_XPOS,
483 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
484 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
486 DrawText(ED_COUNT_VALUE_XPOS,
487 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
488 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
490 DrawText(ED_COUNT_VALUE_XPOS,
491 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
492 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
494 DrawText(ED_COUNT_VALUE_XPOS,
495 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
496 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
498 DrawText(ED_COUNT_VALUE_XPOS,
499 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
500 int2str(level.time,3),FS_SMALL,FC_YELLOW);
503 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+0*ED_COUNT_TEXT_YSIZE,
504 "Score for Emerald",FS_SMALL,FC_YELLOW);
505 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+1*ED_COUNT_TEXT_YSIZE,
506 "Score for Diamond",FS_SMALL,FC_YELLOW);
507 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+2*ED_COUNT_TEXT_YSIZE,
508 "Score for smashing a Bug",FS_SMALL,FC_YELLOW);
509 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+3*ED_COUNT_TEXT_YSIZE,
510 "Score for smashing a Spaceship",FS_SMALL,FC_YELLOW);
511 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+4*ED_COUNT_TEXT_YSIZE,
512 "Score for smashing a Cruncher",FS_SMALL,FC_YELLOW);
513 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+5*ED_COUNT_TEXT_YSIZE,
514 "Score for smashing an Alien",FS_SMALL,FC_YELLOW);
515 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+6*ED_COUNT_TEXT_YSIZE,
516 "Score for smashing a Pacman",FS_SMALL,FC_YELLOW);
517 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+7*ED_COUNT_TEXT_YSIZE,
518 "Score for cracking a nut",FS_SMALL,FC_YELLOW);
519 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+8*ED_COUNT_TEXT_YSIZE,
520 "Score for dynamite",FS_SMALL,FC_YELLOW);
521 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+9*ED_COUNT_TEXT_YSIZE,
522 "Score for key",FS_SMALL,FC_YELLOW);
523 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+10*ED_COUNT_TEXT_YSIZE,
524 "Score for each 10 seconds left",FS_SMALL,FC_YELLOW);
525 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+11*ED_COUNT_TEXT_YSIZE,
526 "Speed of the amoeba / Content",FS_SMALL,FC_YELLOW);
527 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+12*ED_COUNT_TEXT_YSIZE,
528 "Time for magic wall",FS_SMALL,FC_YELLOW);
529 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+13*ED_COUNT_TEXT_YSIZE,
530 "Time for wheel",FS_SMALL,FC_YELLOW);
531 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+14*ED_COUNT_TEXT_YSIZE,
532 "Emeralds needed in this level",FS_SMALL,FC_YELLOW);
533 DrawText(ED_COUNT_TEXT_XPOS,ED_COUNT_TEXT_YPOS+15*ED_COUNT_TEXT_YSIZE,
534 "Time available for this level",FS_SMALL,FC_YELLOW);
536 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
537 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS,
538 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
539 ED_WIN_COUNT_XSIZE,ED_WIN_COUNT_YSIZE,
540 ED_COUNT_GADGET_XPOS,
541 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
543 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
544 DOOR_GFX_PAGEX4+ED_WIN_COUNT_XPOS+3+2*FONT2_XSIZE,
545 DOOR_GFX_PAGEY1+ED_WIN_COUNT_YPOS,
546 ED_WIN_COUNT_XSIZE-3-2*FONT2_XSIZE,ED_WIN_COUNT_YSIZE,
547 ED_COUNT_GADGET_XPOS+3+i*FONT2_XSIZE,
548 ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE);
549 DrawText(ED_COUNT_GADGET_XPOS+5,
550 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
551 level.name,FS_SMALL,FC_YELLOW);
552 DrawText(ED_COUNT_GADGET_XPOS+(30+3)*FONT2_XSIZE-5,
553 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
554 "Title",FS_SMALL,FC_YELLOW);
556 DrawText(ED_SIZE_GADGET_XPOS,ED_SIZE_GADGET_YPOS-18,
557 "Playfield size:",FS_SMALL,FC_YELLOW);
558 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
559 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
560 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
561 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
563 ED_SIZE_GADGET_YPOS+0*ED_COUNT_GADGET_YSIZE);
564 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
565 DOOR_GFX_PAGEX4+ED_BUTTON_MINUS_XPOS,
566 DOOR_GFX_PAGEY1+ED_BUTTON_MINUS_YPOS,
567 DXSIZE-4,ED_BUTTON_MINUS_YSIZE,
569 ED_SIZE_GADGET_YPOS+1*ED_COUNT_GADGET_YSIZE);
570 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+0*ED_SIZE_TEXT_YSIZE,
571 "Width",FS_SMALL,FC_YELLOW);
572 DrawText(ED_SIZE_TEXT_XPOS,ED_SIZE_TEXT_YPOS+1*ED_SIZE_TEXT_YSIZE,
573 "Height",FS_SMALL,FC_YELLOW);
574 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
575 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
576 DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
577 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
580 void ScrollMiniLevel(int from_x, int from_y, int scroll)
583 int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
584 int dy = (scroll==ED_SCROLL_UP ? -1 : scroll==ED_SCROLL_DOWN ? 1 : 0);
586 XCopyArea(display,drawto,drawto,gc,
587 SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
588 SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
589 SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
592 x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
593 for(y=0;y<2*SCR_FIELDY;y++)
594 DrawMiniElementOrWall(x,y,from_x,from_y);
598 y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
599 for(x=0;x<2*SCR_FIELDX;x++)
600 DrawMiniElementOrWall(x,y,from_x,from_y);
603 redraw_mask |= REDRAW_FIELD;
607 void AdjustLevelScrollPosition()
611 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
612 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
613 if (lev_fieldx<2*SCR_FIELDX-2)
618 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
619 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
620 if (lev_fieldy<2*SCR_FIELDY-2)
624 void FloodFill(int from_x, int from_y, int fill_element)
628 static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
629 static int safety = 0;
631 /* check if starting field still has the desired content */
632 if (Feld[from_x][from_y] == fill_element)
637 if (safety > lev_fieldx*lev_fieldy)
638 Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
640 old_element = Feld[from_x][from_y];
641 Feld[from_x][from_y] = fill_element;
645 x = from_x + check[i][0];
646 y = from_y + check[i][1];
648 if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
649 FloodFill(x, y, fill_element);
655 void LevelEd(int mx, int my, int button)
657 static int last_button = 0;
658 static int in_field_pressed = FALSE;
659 static boolean use_floodfill = FALSE;
660 int x = (mx-SX)/MINI_TILEX;
661 int y = (my-SY)/MINI_TILEY;
663 if (use_floodfill) /********** FLOOD FILL **********/
667 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
672 if (x>lev_fieldx || y>lev_fieldy ||
673 (x==0 && level_xpos<0) ||
674 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
675 (y==0 && level_ypos<0) ||
676 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY))
679 from_x = x+level_xpos;
680 from_y = y+level_ypos;
681 fill_element = (button==1 ? new_element1 :
682 button==2 ? new_element2 :
683 button==3 ? new_element3 : 0);
685 FloodFill(from_x,from_y,fill_element);
686 DrawMiniLevel(level_xpos,level_ypos);
689 use_floodfill = FALSE;
690 CloseDoor(DOOR_CLOSE_1);
691 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
695 else /********** EDIT/CTRL-FENSTER **********/
697 static unsigned long choice_delay = 0;
698 int choice = CheckElemButtons(mx,my,button);
699 int elem_pos = choice-ED_BUTTON_ELEM;
701 if (((choice == ED_BUTTON_EUP && element_shift>0) ||
702 (choice == ED_BUTTON_EDOWN &&
703 element_shift<elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)) &&
704 DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
708 step = (button==1 ? MAX_ELEM_X : button==2 ? 5*MAX_ELEM_X :
710 element_shift += (choice==ED_BUTTON_EUP ? -step : step);
713 if (element_shift>elements_in_list-MAX_ELEM_X*MAX_ELEM_Y)
714 element_shift = elements_in_list-MAX_ELEM_X*MAX_ELEM_Y;
715 if (element_shift % MAX_ELEM_X)
716 element_shift += MAX_ELEM_X-(element_shift % MAX_ELEM_X);
718 for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
719 DrawElemButton(i+2,ED_BUTTON_RELEASED);
721 else if (elem_pos>=0 && elem_pos<MAX_ELEM_X*MAX_ELEM_Y)
725 if (elem_pos+element_shift < elements_in_list)
726 new_element = editor_element[elem_pos+element_shift];
728 new_element = EL_LEERRAUM;
731 new_element1 = new_element;
732 else if (last_button==2)
733 new_element2 = new_element;
734 else if (last_button==3)
735 new_element3 = new_element;
737 DrawMiniGraphicExt(drawto,gc,
738 DX+ED_WIN_MB_LEFT_XPOS,
739 DY+ED_WIN_MB_LEFT_YPOS,
740 el2gfx(new_element1));
741 DrawMiniGraphicExt(drawto,gc,
742 DX+ED_WIN_MB_MIDDLE_XPOS,
743 DY+ED_WIN_MB_MIDDLE_YPOS,
744 el2gfx(new_element2));
745 DrawMiniGraphicExt(drawto,gc,
746 DX+ED_WIN_MB_RIGHT_XPOS,
747 DY+ED_WIN_MB_RIGHT_YPOS,
748 el2gfx(new_element3));
749 redraw_mask |= REDRAW_DOOR_1;
752 if (edit_mode) /********** EDIT-FENSTER **********/
754 switch(CheckEditButtons(mx,my,button))
757 CloseDoor(DOOR_CLOSE_2);
759 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
760 DOOR_GFX_PAGEX4,DOOR_GFX_PAGEY1+80,
762 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
763 OpenDoor(DOOR_OPEN_2);
767 Request("Caution ! Flood fill mode ! Choose area !",REQ_OPEN);
768 use_floodfill = TRUE;
774 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
776 if (lev_fieldx<2*SCR_FIELDX-2)
779 level_xpos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
783 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_RIGHT);
785 DrawMiniLevel(level_xpos,level_ypos);
788 case ED_BUTTON_RIGHT:
789 if (level_xpos<=lev_fieldx-2*SCR_FIELDX)
791 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
793 if (lev_fieldx<2*SCR_FIELDX-2)
796 level_xpos += (button==1 ? 1 : button==2 ? 5 : lev_fieldx);
797 if (level_xpos>lev_fieldx-2*SCR_FIELDX+1)
798 level_xpos = lev_fieldx-2*SCR_FIELDX+1;
800 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_LEFT);
802 DrawMiniLevel(level_xpos,level_ypos);
808 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
810 if (lev_fieldy<2*SCR_FIELDY-2)
813 level_ypos -= (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
817 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_DOWN);
819 DrawMiniLevel(level_xpos,level_ypos);
823 if (level_ypos<=lev_fieldy-2*SCR_FIELDY)
825 if (!DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
827 if (lev_fieldy<2*SCR_FIELDY-2)
830 level_ypos += (button==1 ? 1 : button==2 ? 5 : lev_fieldy);
831 if (level_ypos>lev_fieldy-2*SCR_FIELDY+1)
832 level_ypos = lev_fieldy-2*SCR_FIELDY+1;
834 ScrollMiniLevel(level_xpos,level_ypos,ED_SCROLL_UP);
836 DrawMiniLevel(level_xpos,level_ypos);
843 if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
847 if (button && !motion_status)
848 in_field_pressed = TRUE;
850 if (!button || !in_field_pressed || button<1 || button>3 ||
851 (y==0 && level_ypos<0) ||
852 (y==2*SCR_FIELDY-1 && level_ypos>lev_fieldy-2*SCR_FIELDY) ||
853 (x==0 && level_xpos<0) ||
854 (x==2*SCR_FIELDX-1 && level_xpos>lev_fieldx-2*SCR_FIELDX) ||
855 x>lev_fieldx || y>lev_fieldy)
858 new_element = (button==1 ? new_element1 :
859 button==2 ? new_element2 :
860 button==3 ? new_element3 : 0);
862 if (new_element != Feld[x+level_xpos][y+level_ypos])
864 if (new_element==EL_SPIELFIGUR) /* Jeder nur EINE Figur bitte... */
868 for(x=0;x<lev_fieldx;x++) for(y=0;y<lev_fieldy;y++)
870 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
872 Feld[x][y] = EL_LEERRAUM;
873 if (x-level_xpos>=0 && x-level_xpos<2*SCR_FIELDX &&
874 y-level_ypos>=0 && y-level_ypos<2*SCR_FIELDY)
875 DrawMiniElement(x-level_xpos,y-level_ypos,EL_LEERRAUM);
880 Feld[x+level_xpos][y+level_ypos] = new_element;
881 DrawMiniElement(x,y,new_element);
884 else if (!motion_status) /* Mauszeiger nicht im Level-Feld */
885 in_field_pressed = FALSE;
887 else /********** KONTROLL-FENSTER **********/
889 int choice = CheckCountButtons(mx,my,button);
890 int step = (button==1 ? 1 : button==2 ? 5 : button==3 ? 10 : 0);
892 if (choice >= 0 && choice < 36 &&
893 DelayReached(&choice_delay, CHOICE_DELAY_VALUE))
902 level.score[choice] += step;
903 if (level.score[choice]<0)
904 level.score[choice] = 0;
905 else if (level.score[choice]>255)
906 level.score[choice] = 255;
910 level.tempo_amoebe += step;
911 if (level.tempo_amoebe<0)
912 level.tempo_amoebe = 0;
913 else if (level.tempo_amoebe>255)
914 level.tempo_amoebe = 255;
918 level.dauer_sieb += step;
919 if (level.dauer_sieb<0)
920 level.dauer_sieb = 0;
921 else if (level.dauer_sieb>255)
922 level.dauer_sieb = 255;
926 level.dauer_ablenk += step;
927 if (level.dauer_ablenk<0)
928 level.dauer_ablenk = 0;
929 else if (level.dauer_ablenk>255)
930 level.dauer_ablenk = 255;
934 level.edelsteine += step;
935 if (level.edelsteine<0)
936 level.edelsteine = 0;
937 else if (level.edelsteine>999)
938 level.edelsteine = 999;
945 else if (level.time>999)
951 if (lev_fieldx<MIN_LEV_FIELDX)
952 lev_fieldx = MIN_LEV_FIELDX;
953 else if (lev_fieldx>MAX_LEV_FIELDX)
954 lev_fieldx = MAX_LEV_FIELDX;
955 level.fieldx = lev_fieldx;
960 if (lev_fieldy<MIN_LEV_FIELDY)
961 lev_fieldy = MIN_LEV_FIELDY;
962 else if (lev_fieldy>MAX_LEV_FIELDY)
963 lev_fieldy = MAX_LEV_FIELDY;
964 level.fieldy = lev_fieldy;
968 DrawText(ED_COUNT_VALUE_XPOS,
969 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
970 int2str(level.score[choice],3),FS_SMALL,FC_YELLOW);
972 DrawText(ED_COUNT_VALUE_XPOS,
973 ED_COUNT_VALUE_YPOS+11*ED_COUNT_GADGET_YSIZE,
974 int2str(level.tempo_amoebe,3),FS_SMALL,FC_YELLOW);
976 DrawText(ED_COUNT_VALUE_XPOS,
977 ED_COUNT_VALUE_YPOS+12*ED_COUNT_GADGET_YSIZE,
978 int2str(level.dauer_sieb,3),FS_SMALL,FC_YELLOW);
980 DrawText(ED_COUNT_VALUE_XPOS,
981 ED_COUNT_VALUE_YPOS+13*ED_COUNT_GADGET_YSIZE,
982 int2str(level.dauer_ablenk,3),FS_SMALL,FC_YELLOW);
984 DrawText(ED_COUNT_VALUE_XPOS,
985 ED_COUNT_VALUE_YPOS+14*ED_COUNT_GADGET_YSIZE,
986 int2str(level.edelsteine,3),FS_SMALL,FC_YELLOW);
988 DrawText(ED_COUNT_VALUE_XPOS,
989 ED_COUNT_VALUE_YPOS+15*ED_COUNT_GADGET_YSIZE,
990 int2str(level.time,3),FS_SMALL,FC_YELLOW);
992 DrawText(ED_SIZE_VALUE_XPOS,
993 ED_SIZE_VALUE_YPOS+0*ED_SIZE_GADGET_YSIZE,
994 int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
996 DrawText(ED_SIZE_VALUE_XPOS,
997 ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
998 int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
1000 redraw_mask &= ~REDRAW_FIELD;
1002 XCopyArea(display,drawto,window,gc,
1003 ED_COUNT_VALUE_XPOS,
1004 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE,
1005 3*FONT2_XSIZE,FONT2_YSIZE,
1006 ED_COUNT_VALUE_XPOS,
1007 ED_COUNT_VALUE_YPOS+choice*ED_COUNT_GADGET_YSIZE);
1009 XCopyArea(display,drawto,window,gc,
1011 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE,
1012 3*FONT2_XSIZE,FONT2_YSIZE,
1014 ED_SIZE_VALUE_YPOS+(choice-16)*ED_SIZE_GADGET_YSIZE);
1018 switch(CheckCtrlButtons(mx,my,button))
1020 case ED_BUTTON_EDIT:
1021 CloseDoor(DOOR_CLOSE_2);
1022 AdjustLevelScrollPosition();
1023 DrawMiniLevel(level_xpos,level_ypos);
1024 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
1025 DOOR_GFX_PAGEX6,DOOR_GFX_PAGEY2,
1027 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
1028 OpenDoor(DOOR_OPEN_2);
1031 case ED_BUTTON_CLEAR:
1032 if (Request("Are you sure to clear this level ?",REQ_ASK))
1034 for(x=0;x<MAX_LEV_FIELDX;x++)
1035 for(y=0;y<MAX_LEV_FIELDY;y++)
1036 Feld[x][y] = EL_ERDREICH;
1037 DrawMiniLevel(level_xpos,level_ypos);
1040 case ED_BUTTON_UNDO:
1041 if (leveldir[leveldir_nr].readonly ||
1042 Request("Exit without saving ?",REQ_ASK | REQ_STAY_OPEN))
1044 CloseDoor(DOOR_CLOSE_BOTH);
1045 game_status=MAINMENU;
1050 CloseDoor(DOOR_CLOSE_1);
1051 OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
1054 case ED_BUTTON_EXIT:
1056 int figur_vorhanden = FALSE;
1058 if (leveldir[leveldir_nr].readonly)
1060 Request("This level is read only !",REQ_CONFIRM);
1064 for(y=0;y<lev_fieldy;y++)
1065 for(x=0;x<lev_fieldx;x++)
1066 if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1)
1067 figur_vorhanden = TRUE;
1069 if (!figur_vorhanden)
1070 Request("No Level without Gregor Mc Duffin please !",
1074 if (Request("Save this level and kill the old ?",
1075 REQ_ASK | REQ_STAY_OPEN))
1077 for(x=0;x<lev_fieldx;x++)
1078 for(y=0;y<lev_fieldy;y++)
1079 Ur[x][y]=Feld[x][y];
1080 SaveLevel(level_nr);
1082 CloseDoor(DOOR_CLOSE_BOTH);
1083 game_status=MAINMENU;
1092 if (mx>=ED_COUNT_GADGET_XPOS &&
1093 mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
1094 my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
1095 my<ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE+ED_WIN_COUNT_YSIZE)
1100 DrawText(ED_COUNT_GADGET_XPOS+5,
1101 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1102 level.name,FS_SMALL,FC_GREEN);
1103 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1104 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1105 "<",FS_SMALL,FC_RED);
1112 name_typing = FALSE;
1113 DrawText(ED_COUNT_GADGET_XPOS+5,
1114 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1115 level.name,FS_SMALL,FC_YELLOW);
1116 DrawText(ED_COUNT_GADGET_XPOS+5+strlen(level.name)*FONT2_XSIZE,
1117 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1118 " ",FS_SMALL,FC_RED);
1122 if (mx>=SX+29*MINI_TILEX && mx<SX+30*MINI_TILEX &&
1123 my>=SY+26*MINI_TILEY && my<SY+27*MINI_TILEY)
1127 if (!button || button<1 || button>3)
1130 new_element = (button==1 ? new_element1 :
1131 button==2 ? new_element2 :
1132 button==3 ? new_element3 : 0);
1134 if (new_element != level.amoebe_inhalt)
1136 level.amoebe_inhalt = new_element;
1137 DrawMiniElement(29,26,new_element);
1141 if (mx>=SX+1*MINI_TILEX && mx<SX+(1+4*5)*MINI_TILEX &&
1142 my>=SY+2*MINI_TILEY && my<SY+(2+3)*MINI_TILEY)
1144 int x = (mx-SX-1*MINI_TILEX)/MINI_TILEX;
1145 int y = (my-SY-2*MINI_TILEY)/MINI_TILEY;
1150 if (i>=0 && i<43 && x>=0 && x<3 && y>=0 && y<3)
1152 if (button && !motion_status)
1153 in_field_pressed = TRUE;
1155 if (!button || !in_field_pressed || button<1 || button>3)
1158 new_element = (button==1 ? new_element1 :
1159 button==2 ? new_element2 :
1160 button==3 ? new_element3 : 0);
1162 if (new_element != level.mampfer_inhalt[i][x][y])
1164 level.mampfer_inhalt[i][x][y] = new_element;
1165 DrawMiniElement(1+5*i+x,2+y,new_element);
1168 else if (!motion_status)/* Mauszeiger nicht im Cruncher-Feld */
1169 in_field_pressed = FALSE;
1171 else if (!motion_status) /* Mauszeiger nicht im Cruncher-Feld */
1172 in_field_pressed = FALSE;
1176 last_button = button;
1181 void LevelNameTyping(KeySym key)
1183 unsigned char ascii = 0;
1184 int len = strlen(level.name);
1189 if (key>=XK_A && key<=XK_Z)
1190 ascii = 'A'+(char)(key-XK_A);
1191 else if (key>=XK_a && key<=XK_z)
1192 ascii = 'a'+(char)(key-XK_a);
1193 else if (key>=XK_0 && key<=XK_9)
1194 ascii = '0'+(char)(key-XK_0);
1196 else if (key>=XK_space && key<=XK_at)
1197 ascii = ' '+(char)(key-XK_space);
1198 else if (key==XK_Adiaeresis)
1200 else if (key==XK_Odiaeresis)
1202 else if (key==XK_Udiaeresis)
1204 else if (key==XK_adiaeresis)
1206 else if (key==XK_odiaeresis)
1208 else if (key==XK_udiaeresis)
1210 else if (key==XK_underscore)
1214 if (ascii && len<MAX_LEVNAMLEN-2)
1216 level.name[len] = ascii;
1217 level.name[len+1] = 0;
1220 DrawTextExt(drawto,gc,
1221 ED_COUNT_GADGET_XPOS+5,
1222 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1223 level.name,FS_SMALL,FC_GREEN);
1224 DrawTextExt(window,gc,
1225 ED_COUNT_GADGET_XPOS+5,
1226 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1227 level.name,FS_SMALL,FC_GREEN);
1228 DrawTextExt(drawto,gc,
1229 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1230 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1231 "<",FS_SMALL,FC_RED);
1232 DrawTextExt(window,gc,
1233 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1234 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1235 "<",FS_SMALL,FC_RED);
1237 else if ((key==XK_Delete || key==XK_BackSpace) && len>0)
1239 level.name[len-1] = 0;
1242 DrawTextExt(drawto,gc,
1243 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1244 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1245 "< ",FS_SMALL,FC_GREEN);
1246 DrawTextExt(window,gc,
1247 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1248 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1249 "< ",FS_SMALL,FC_GREEN);
1251 else if (key==XK_Return)
1253 DrawTextExt(drawto,gc,
1254 ED_COUNT_GADGET_XPOS+5,
1255 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1256 level.name,FS_SMALL,FC_YELLOW);
1257 DrawTextExt(window,gc,
1258 ED_COUNT_GADGET_XPOS+5,
1259 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1260 level.name,FS_SMALL,FC_YELLOW);
1261 DrawTextExt(drawto,gc,
1262 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1263 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1264 " ",FS_SMALL,FC_YELLOW);
1265 DrawTextExt(window,gc,
1266 ED_COUNT_GADGET_XPOS+5+len*FONT2_XSIZE,
1267 ED_COUNT_TEXT_YPOS+16*ED_COUNT_TEXT_YSIZE,
1268 " ",FS_SMALL,FC_YELLOW);
1270 name_typing = FALSE;