1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * ©1995 Artsoft Development *
6 * 33659 Bielefeld-Senne *
7 * Telefon: (0521) 493245 *
8 * eMail: aeglos@valinor.owl.de *
9 * aeglos@uni-paderborn.de *
10 * q99492@pbhrzx.uni-paderborn.de *
11 *----------------------------------------------------------*
13 ***********************************************************/
24 void GetPlayerConfig()
26 int old_joystick_nr = joystick_nr;
28 if (sound_status==SOUND_OFF)
29 player.setup &= ~SETUP_SOUND;
30 if (!sound_loops_allowed)
32 player.setup &= ~SETUP_SOUND_LOOPS;
33 player.setup &= ~SETUP_SOUND_MUSIC;
36 sound_on = SETUP_SOUND_ON(player.setup);
37 sound_loops_on = SETUP_SOUND_LOOPS_ON(player.setup);
38 sound_music_on = SETUP_SOUND_MUSIC_ON(player.setup);
39 toons_on = SETUP_TOONS_ON(player.setup);
40 direct_draw_on = SETUP_DIRECT_DRAW_ON(player.setup);
41 fading_on = SETUP_FADING_ON(player.setup);
42 autorecord_on = SETUP_RECORD_EACH_GAME_ON(player.setup);
43 joystick_nr = SETUP_2ND_JOYSTICK_ON(player.setup);
44 quick_doors = SETUP_QUICK_DOORS_ON(player.setup);
46 if (joystick_nr != old_joystick_nr)
49 close(joystick_device);
59 Gems = level.edelsteine;
60 DynaBombCount = DynaBombSize = DynaBombsLeft = 0;
61 Key[0] = Key[1] = Key[2] = Key[3] = FALSE;
63 TimeLeft = level.time;
65 CheckExploding = FALSE;
66 LevelSolved = GameOver = SiebAktiv = FALSE;
72 else if (tape.playing)
75 DigField(0,0,DF_NO_PUSH);
78 for(i=0;i<MAX_NUM_AMOEBA;i++)
81 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
83 Feld[x][y] = Ur[x][y];
84 MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
85 Store[x][y] = Store2[x][y] = Frame[x][y] = AmoebaNr[x][y] = 0;
92 Feld[x][y] = EL_LEERRAUM;
97 Feld[x][y] = EL_LEERRAUM;
100 if (x<lev_fieldx-1 && Feld[x+1][y]==EL_SALZSAEURE)
101 Feld[x][y] = EL_BADEWANNE1;
102 else if (x>0 && Feld[x-1][y]==EL_SALZSAEURE)
103 Feld[x][y] = EL_BADEWANNE2;
104 else if (y>0 && Feld[x][y-1]==EL_BADEWANNE1)
105 Feld[x][y] = EL_BADEWANNE3;
106 else if (y>0 && Feld[x][y-1]==EL_SALZSAEURE)
107 Feld[x][y] = EL_BADEWANNE4;
108 else if (y>0 && Feld[x][y-1]==EL_BADEWANNE2)
109 Feld[x][y] = EL_BADEWANNE5;
137 Feld[x][y] = EL_AMOEBING;
138 Store[x][y] = EL_AMOEBE_NASS;
146 scroll_x = scroll_y = -1;
149 (JX<=lev_fieldx-MIDPOSX ? JX-MIDPOSX : lev_fieldx-SCR_FIELDX+1);
152 (JY<=lev_fieldy-MIDPOSY ? JY-MIDPOSY : lev_fieldy-SCR_FIELDY+1);
155 DrawLevelElement(JX,JY,EL_SPIELFIGUR);
158 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
159 DOOR_GFX_PAGEX5,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
160 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
161 DrawTextExt(pix[PIX_DB_DOOR],gc,
162 DOOR_GFX_PAGEX1+XX_LEVEL,DOOR_GFX_PAGEY1+YY_LEVEL,
163 int2str(level_nr,2),FS_SMALL,FC_YELLOW);
164 DrawTextExt(pix[PIX_DB_DOOR],gc,
165 DOOR_GFX_PAGEX1+XX_EMERALDS,DOOR_GFX_PAGEY1+YY_EMERALDS,
166 int2str(Gems,3),FS_SMALL,FC_YELLOW);
167 DrawTextExt(pix[PIX_DB_DOOR],gc,
168 DOOR_GFX_PAGEX1+XX_DYNAMITE,DOOR_GFX_PAGEY1+YY_DYNAMITE,
169 int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
170 DrawTextExt(pix[PIX_DB_DOOR],gc,
171 DOOR_GFX_PAGEX1+XX_SCORE,DOOR_GFX_PAGEY1+YY_SCORE,
172 int2str(Score,5),FS_SMALL,FC_YELLOW);
173 DrawTextExt(pix[PIX_DB_DOOR],gc,
174 DOOR_GFX_PAGEX1+XX_TIME,DOOR_GFX_PAGEY1+YY_TIME,
175 int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
177 DrawGameButton(BUTTON_GAME_STOP);
178 DrawGameButton(BUTTON_GAME_PAUSE);
179 DrawGameButton(BUTTON_GAME_PLAY);
180 DrawSoundDisplay(BUTTON_SOUND_MUSIC | (BUTTON_ON * sound_music_on));
181 DrawSoundDisplay(BUTTON_SOUND_LOOPS | (BUTTON_ON * sound_loops_on));
182 DrawSoundDisplay(BUTTON_SOUND_SOUND | (BUTTON_ON * sound_on));
183 XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
184 DX+GAME_CONTROL_XPOS,DY+GAME_CONTROL_YPOS,
185 GAME_CONTROL_XSIZE,2*GAME_CONTROL_YSIZE,
186 DOOR_GFX_PAGEX1+GAME_CONTROL_XPOS,
187 DOOR_GFX_PAGEY1+GAME_CONTROL_YPOS);
189 OpenDoor(DOOR_OPEN_1);
192 PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
194 XAutoRepeatOff(display);
197 void InitMovDir(int x, int y)
199 int i, element = Feld[x][y];
200 static int xy[4][2] =
207 static int direction[2][4] =
209 MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN,
210 MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP
219 Feld[x][y] = EL_KAEFER;
220 MovDir[x][y] = direction[0][element-EL_KAEFER_R];
226 Feld[x][y] = EL_FLIEGER;
227 MovDir[x][y] = direction[0][element-EL_FLIEGER_R];
233 Feld[x][y] = EL_PACMAN;
234 MovDir[x][y] = direction[0][element-EL_PACMAN_R];
237 MovDir[x][y] = 1<<RND(4);
238 if (element!=EL_KAEFER && element!=EL_FLIEGER)
248 if (!IN_LEV_FIELD(x1,y1) || !IS_FREE(x1,y1))
250 if (element==EL_KAEFER)
252 MovDir[x][y] = direction[0][i];
255 else if (element==EL_FLIEGER)
257 MovDir[x][y] = direction[1][i];
266 void InitAmoebaNr(int x, int y)
269 int group_nr = AmoebeNachbarNr(x,y);
273 for(i=1;i<MAX_NUM_AMOEBA;i++)
283 AmoebaNr[x][y] = group_nr;
284 AmoebaCnt[group_nr]++;
290 int bumplevel = FALSE;
293 PlaySoundExt(SND_SIRR,PSND_MAX_VOLUME,PSND_MAX_RIGHT,PSND_LOOP);
297 for(;TimeLeft>=0;TimeLeft--)
300 PlaySoundStereo(SND_SIRR,PSND_MAX_RIGHT);
301 if (TimeLeft && !(TimeLeft % 10))
302 RaiseScore(level.score[SC_ZEITBONUS]);
303 DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
316 CloseDoor(DOOR_CLOSE_1);
318 if (level_nr==player.handicap &&
319 level_nr<leveldir[leveldir_nr].num_ready-1)
323 SavePlayerInfo(PLAYER_LEVEL);
326 if ((hi_pos=NewHiScore())>=0)
328 game_status = HALLOFFAME;
329 DrawHallOfFame(hi_pos);
330 if (bumplevel && TAPE_IS_EMPTY(tape))
335 game_status = MAINMENU;
336 if (bumplevel && TAPE_IS_EMPTY(tape))
350 if (!strcmp(player.alias_name,EMPTY_ALIAS) ||
351 Score<highscore[MAX_SCORE_ENTRIES-1].Score)
354 for(k=0;k<MAX_SCORE_ENTRIES;k++)
356 if (Score>highscore[k].Score) /* Spieler kommt in Highscore-Liste */
358 if (k<MAX_SCORE_ENTRIES-1)
360 int m = MAX_SCORE_ENTRIES-1;
363 for(l=k;l<MAX_SCORE_ENTRIES;l++)
364 if (!strcmp(player.alias_name,highscore[l].Name))
366 if (m==k) /* Spieler überschreibt seine alte Position */
372 strcpy(highscore[l].Name,highscore[l-1].Name);
373 highscore[l].Score = highscore[l-1].Score;
380 sprintf(highscore[k].Name,player.alias_name);
381 highscore[k].Score = Score;
387 else if (!strcmp(player.alias_name,highscore[k].Name))
388 break; /* Spieler schon mit besserer Punktzahl in der Liste */
399 void InitMovingField(int x, int y, int direction)
401 int newx = x + (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
402 int newy = y + (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
405 MovDir[x][y] = direction;
406 MovDir[newx][newy] = direction;
407 if (Feld[newx][newy]==EL_LEERRAUM)
408 Feld[newx][newy] = EL_BLOCKED;
411 void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
413 int direction = MovDir[x][y];
414 int newx = x + (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
415 int newy = y + (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
421 void Blocked2Moving(int x, int y, int *comes_from_x, int *comes_from_y)
423 int oldx = x, oldy = y;
424 int direction = MovDir[x][y];
426 if (direction==MV_LEFT)
428 else if (direction==MV_RIGHT)
430 else if (direction==MV_UP)
432 else if (direction==MV_DOWN)
435 *comes_from_x = oldx;
436 *comes_from_y = oldy;
439 int MovingOrBlocked2Element(int x, int y)
441 int element = Feld[x][y];
443 if (element==EL_BLOCKED)
447 Blocked2Moving(x,y,&oldx,&oldy);
448 return(Feld[oldx][oldy]);
454 void RemoveMovingField(int x, int y)
456 int oldx=x,oldy=y, newx=x,newy=y;
458 if (Feld[x][y]!=EL_BLOCKED && !IS_MOVING(x,y))
463 Moving2Blocked(x,y,&newx,&newy);
464 if (Feld[newx][newy]!=EL_BLOCKED)
467 else if (Feld[x][y]==EL_BLOCKED)
469 Blocked2Moving(x,y,&oldx,&oldy);
470 if (!IS_MOVING(oldx,oldy))
474 Feld[oldx][oldy] = EL_LEERRAUM;
475 Feld[newx][newy] = EL_LEERRAUM;
476 MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
477 MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
478 DrawLevelField(oldx,oldy);
479 DrawLevelField(newx,newy);
482 void DrawDynamite(int x, int y)
484 int phase = (48-MovDelay[x][y])/6;
486 if (!IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
494 DrawGraphic(SCROLLX(x),SCROLLY(y),el2gfx(Store[x][y]));
496 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
498 else if (PLAYER(x,y))
499 DrawGraphic(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
501 if (Store[x][y] || PLAYER(x,y))
502 DrawGraphicThruMask(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase);
504 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase);
507 void CheckDynamite(int x, int y)
509 CheckExploding = TRUE;
511 if (MovDelay[x][y]) /* neues Dynamit / in Wartezustand */
516 if (!(MovDelay[x][y] % 6))
519 PlaySoundLevel(x,y,SND_ZISCH);
526 StopSound(SND_ZISCH);
530 void Explode(int ex, int ey, int phase, int mode)
533 int num_phase = 9, delay = 1;
534 int last_phase = num_phase*delay;
535 int half_phase = (num_phase/2)*delay;
537 if (phase==0) /* Feld 'Store' initialisieren */
539 int center_element = Feld[ex][ey];
541 if (center_element==EL_BLOCKED)
542 center_element = MovingOrBlocked2Element(ex,ey);
544 for(y=ey-1;y<ey+2;y++) for(x=ex-1;x<ex+2;x++)
546 int element = Feld[x][y];
548 if (!IN_LEV_FIELD(x,y) || IS_MASSIV(element))
551 if ((mode!=EX_NORMAL || center_element==EL_AMOEBA2DIAM) &&
555 if (element==EL_EXPLODING)
556 element = Store2[x][y];
558 if (PLAYER(ex,ey) || center_element==EL_KAEFER)
559 Store[x][y] = ((x==ex && y==ey) ? EL_DIAMANT : EL_EDELSTEIN);
560 else if (center_element==EL_MAMPFER)
561 Store[x][y] = level.mampfer_inhalt[MampferNr][x-ex+1][y-ey+1];
562 else if (center_element==EL_AMOEBA2DIAM)
563 Store[x][y] = level.amoebe_inhalt;
564 else if (element==EL_ERZ_EDEL)
565 Store[x][y] = EL_EDELSTEIN;
566 else if (element==EL_ERZ_DIAM)
567 Store[x][y] = EL_DIAMANT;
568 else if (element==EL_ERZ_EDEL2)
569 Store[x][y] = EL_EDELSTEIN2;
570 else if (element==EL_ERZ_EDEL3)
571 Store[x][y] = EL_EDELSTEIN3;
572 else if (!IS_PFORTE(Store[x][y]))
573 Store[x][y] = EL_LEERRAUM;
575 if (x!=ex || y!=ey || center_element==EL_AMOEBA2DIAM || mode==EX_BORDER)
576 Store2[x][y] = element;
578 if (AmoebaNr[x][y] && (element==EL_AMOEBE_VOLL || element==EL_AMOEBING))
579 AmoebaCnt[AmoebaNr[x][y]]--;
581 RemoveMovingField(x,y);
582 Feld[x][y] = EL_EXPLODING;
583 MovDir[x][y] = MovPos[x][y] = 0;
589 if (center_element==EL_MAMPFER)
590 MampferNr = (MampferNr+1) % 4;
601 Frame[x][y] = (phase<last_phase ? phase+1 : 0);
603 if (phase==half_phase)
605 int element = Store2[x][y];
609 else if (element==EL_BOMBE ||
610 element==EL_DYNAMIT ||
611 element==EL_DYNAMIT_AUS ||
612 element==EL_DYNABOMB ||
615 Feld[x][y] = Store2[x][y];
619 else if (element==EL_AMOEBA2DIAM)
620 AmoebeUmwandeln(x,y);
623 if (phase==last_phase)
627 element = Feld[x][y] = Store[x][y];
628 Store[x][y] = Store2[x][y] = 0;
629 MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
630 if (CAN_MOVE(element) || COULD_MOVE(element))
634 else if (!(phase%delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
637 ErdreichAnbroeckeln(SCROLLX(x),SCROLLY(y));
639 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EXPLOSION+(phase/delay-1));
642 CheckExploding = TRUE;
645 void DynaExplode(int ex, int ey, int size)
648 static int xy[4][2] =
656 Explode(ex,ey,0,EX_CENTER);
662 int x = ex+j*xy[i%4][0];
663 int y = ey+j*xy[i%4][1];
665 if (!IN_LEV_FIELD(x,y) || IS_MASSIV(Feld[x][y]))
668 Explode(x,y,0,EX_BORDER);
675 void Bang(int x, int y)
677 int element = Feld[x][y];
679 CheckExploding = TRUE;
680 PlaySoundLevel(x,y,SND_ROAAAR);
685 RaiseScore(level.score[SC_KAEFER]);
688 RaiseScore(level.score[SC_FLIEGER]);
692 RaiseScore(level.score[SC_MAMPFER]);
695 RaiseScore(level.score[SC_ZOMBIE]);
698 RaiseScore(level.score[SC_PACMAN]);
704 if (element==EL_DYNABOMB)
705 DynaExplode(x,y,DynaBombSize);
707 Explode(x,y,0,EX_NORMAL);
710 void Blurb(int x, int y)
712 int element = Feld[x][y];
714 if (element!=EL_BLURB_LEFT && element!=EL_BLURB_RIGHT) /* Anfang */
716 PlaySoundLevel(x,y,SND_BLURB);
717 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y) &&
718 (!IN_LEV_FIELD(x-1,y-1) ||
719 !CAN_FALL(MovingOrBlocked2Element(x-1,y-1))))
721 Feld[x-1][y] = EL_BLURB_LEFT;
723 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y) &&
724 (!IN_LEV_FIELD(x+1,y-1) ||
725 !CAN_FALL(MovingOrBlocked2Element(x+1,y-1))))
727 Feld[x+1][y] = EL_BLURB_RIGHT;
732 int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT);
734 CheckExploding = TRUE;
736 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
739 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
742 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
743 DrawGraphic(SCROLLX(x),SCROLLY(y),graphic+4-MovDelay[x][y]);
747 Feld[x][y] = EL_LEERRAUM;
754 void Impact(int x, int y)
756 BOOL lastline = (y==lev_fieldy-1);
757 BOOL object_hit = FALSE;
758 int element = Feld[x][y];
760 /* Element darunter berührt? */
762 object_hit = (!IS_FREE(x,y+1) && (!IS_MOVING(x,y+1) ||
763 MovDir[x][y+1]!=MV_DOWN ||
764 MovPos[x][y+1]<=TILEY/2));
766 /* Auftreffendes Element fällt in Salzsäure */
767 if (!lastline && Feld[x][y+1]==EL_SALZSAEURE)
773 /* Auftreffendes Element ist Bombe */
774 if (element==EL_BOMBE && (lastline || object_hit))
780 /* Auftreffendes Element ist Säuretropfen */
781 if (element==EL_TROPFEN && (lastline || object_hit))
783 if (object_hit && PLAYER(x,y+1))
787 Feld[x][y] = EL_AMOEBING;
788 Store[x][y] = EL_AMOEBE_NASS;
793 /* Welches Element kriegt was auf die Rübe? */
794 if (!lastline && object_hit)
796 int smashed = Feld[x][y+1];
803 else if (element==EL_FELSBROCKEN ||
804 element==EL_EDELSTEIN2 || element==EL_EDELSTEIN3)
806 if (IS_ENEMY(MovingOrBlocked2Element(x,y+1)))
811 else if (!IS_MOVING(x,y+1))
813 if (smashed==EL_BOMBE)
818 else if (smashed==EL_KOKOSNUSS)
820 Feld[x][y+1] = EL_CRACKINGNUT;
821 PlaySoundLevel(x,y,SND_KNACK);
822 RaiseScore(level.score[SC_KOKOSNUSS]);
825 else if (smashed==EL_DIAMANT)
827 Feld[x][y+1] = EL_LEERRAUM;
828 PlaySoundLevel(x,y,SND_QUIRK);
835 /* Kein Geräusch beim Durchqueren des Siebes */
836 if (!lastline && (Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER))
839 /* Geräusch beim Auftreffen */
840 if (lastline || object_hit)
875 PlaySoundLevel(x,y,sound);
879 void TurnRound(int x, int y)
881 int element = Feld[x][y];
882 int direction = MovDir[x][y];
884 if (element==EL_KAEFER)
886 TestIfBadThingHitsOtherBadThing(x,y);
888 if (MovDir[x][y]==MV_LEFT)
890 if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1))
892 else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y))
893 MovDir[x][y]=MV_DOWN;
895 else if (MovDir[x][y]==MV_RIGHT)
897 if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1))
898 MovDir[x][y]=MV_DOWN;
899 else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y))
902 else if (MovDir[x][y]==MV_UP)
904 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y))
905 MovDir[x][y]=MV_RIGHT;
906 else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1))
907 MovDir[x][y]=MV_LEFT;
909 else if (MovDir[x][y]==MV_DOWN)
911 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y))
912 MovDir[x][y]=MV_LEFT;
913 else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1))
914 MovDir[x][y]=MV_RIGHT;
917 if (direction!=MovDir[x][y])
920 else if (element==EL_FLIEGER)
922 TestIfBadThingHitsOtherBadThing(x,y);
924 if (MovDir[x][y]==MV_LEFT)
926 if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1))
927 MovDir[x][y]=MV_DOWN;
928 else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y))
931 else if (MovDir[x][y]==MV_RIGHT)
933 if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1))
935 else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y))
936 MovDir[x][y]=MV_DOWN;
938 else if (MovDir[x][y]==MV_UP)
940 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y))
941 MovDir[x][y]=MV_LEFT;
942 else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1))
943 MovDir[x][y]=MV_RIGHT;
945 else if (MovDir[x][y]==MV_DOWN)
947 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y))
948 MovDir[x][y]=MV_RIGHT;
949 else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1))
950 MovDir[x][y]=MV_LEFT;
953 if (direction!=MovDir[x][y])
956 else if (element==EL_MAMPFER)
958 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
960 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
961 if (IN_LEV_FIELD(x,y-1) &&
962 (IS_FREE(x,y-1) || Feld[x][y-1]==EL_DIAMANT) &&
965 if (IN_LEV_FIELD(x,y+1) &&
966 (IS_FREE(x,y+1) || Feld[x][y+1]==EL_DIAMANT) &&
968 MovDir[x][y]=MV_DOWN;
970 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
972 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
973 if (IN_LEV_FIELD(x-1,y) &&
974 (IS_FREE(x-1,y) || Feld[x-1][y]==EL_DIAMANT) &&
976 MovDir[x][y]=MV_LEFT;
977 if (IN_LEV_FIELD(x+1,y) &&
978 (IS_FREE(x+1,y) || Feld[x+1][y]==EL_DIAMANT) &&
980 MovDir[x][y]=MV_RIGHT;
983 MovDelay[x][y]=8+8*RND(3);
985 else if (element==EL_MAMPFER2)
987 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
989 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
990 if (IN_LEV_FIELD(x,y-1) &&
991 (IS_FREE(x,y-1) || IS_MAMPF2(Feld[x][y-1])) && RND(2))
993 if (IN_LEV_FIELD(x,y+1) &&
994 (IS_FREE(x,y+1) || IS_MAMPF2(Feld[x][y+1])) && RND(2))
995 MovDir[x][y]=MV_DOWN;
997 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
999 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
1000 if (IN_LEV_FIELD(x-1,y) &&
1001 (IS_FREE(x-1,y) || IS_MAMPF2(Feld[x-1][y])) && RND(2))
1002 MovDir[x][y]=MV_LEFT;
1003 if (IN_LEV_FIELD(x+1,y) &&
1004 (IS_FREE(x+1,y) || IS_MAMPF2(Feld[x+1][y])) && RND(2))
1005 MovDir[x][y]=MV_RIGHT;
1008 MovDelay[x][y]=8+8*RND(3);
1010 else if (element==EL_PACMAN)
1012 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
1014 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
1015 if (IN_LEV_FIELD(x,y-1) &&
1016 (IS_FREE(x,y-1) || IS_AMOEBOID(Feld[x][y-1])) &&
1019 if (IN_LEV_FIELD(x,y+1) &&
1020 (IS_FREE(x,y+1) || IS_AMOEBOID(Feld[x][y+1])) &&
1022 MovDir[x][y]=MV_DOWN;
1024 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
1026 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
1027 if (IN_LEV_FIELD(x-1,y) &&
1028 (IS_FREE(x-1,y) || IS_AMOEBOID(Feld[x-1][y])) &&
1030 MovDir[x][y]=MV_LEFT;
1031 if (IN_LEV_FIELD(x+1,y) &&
1032 (IS_FREE(x+1,y) || IS_AMOEBOID(Feld[x+1][y])) &&
1034 MovDir[x][y]=MV_RIGHT;
1037 MovDelay[x][y]=3+RND(20);
1039 else if (element==EL_ZOMBIE)
1041 int attr_x = JX, attr_y = JY;
1049 MovDir[x][y]=MV_NO_MOVING;
1051 MovDir[x][y]|=MV_LEFT;
1053 MovDir[x][y]|=MV_RIGHT;
1055 MovDir[x][y]|=MV_UP;
1057 MovDir[x][y]|=MV_DOWN;
1058 if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
1059 MovDir[x][y] &= (RND(2) ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
1061 MovDelay[x][y] = 8+8*RND(2);
1065 void StartMoving(int x, int y)
1067 int element = Feld[x][y];
1072 if (CAN_FALL(element) && y<lev_fieldy-1)
1074 if (element==EL_MORAST_VOLL)
1078 InitMovingField(x,y,MV_DOWN);
1079 Feld[x][y] = EL_FELSBROCKEN;
1080 Store[x][y] = EL_MORAST_LEER;
1082 else if (Feld[x][y+1]==EL_MORAST_LEER)
1086 if (!MovDelay[x][y])
1087 MovDelay[x][y] = 16;
1096 Feld[x][y] = EL_MORAST_LEER;
1097 Feld[x][y+1] = EL_MORAST_VOLL;
1100 else if (element==EL_FELSBROCKEN && Feld[x][y+1]==EL_MORAST_LEER)
1102 InitMovingField(x,y,MV_DOWN);
1103 Store[x][y] = EL_MORAST_VOLL;
1105 else if (element==EL_SIEB_VOLL)
1109 InitMovingField(x,y,MV_DOWN);
1110 Feld[x][y] = EL_CHANGED(Store2[x][y]);
1111 Store[x][y] = EL_SIEB_LEER;
1114 else if (element==EL_SIEB2_VOLL)
1118 InitMovingField(x,y,MV_DOWN);
1119 Feld[x][y] = EL_CHANGED2(Store2[x][y]);
1120 Store[x][y] = EL_SIEB2_LEER;
1123 else if (CAN_CHANGE(element) &&
1124 (Feld[x][y+1]==EL_SIEB_LEER || Feld[x][y+1]==EL_SIEB2_LEER))
1126 InitMovingField(x,y,MV_DOWN);
1128 (Feld[x][y+1]==EL_SIEB_LEER ? EL_SIEB_VOLL : EL_SIEB2_VOLL);
1129 Store2[x][y+1] = element;
1132 else if (CAN_SMASH(element) && Feld[x][y+1]==EL_SALZSAEURE)
1135 InitMovingField(x,y,MV_DOWN);
1136 Store[x][y] = EL_SALZSAEURE;
1138 else if (CAN_SMASH(element) && Feld[x][y+1]==EL_BLOCKED && JustHit[x][y])
1142 else if (IS_FREE(x,y+1))
1144 InitMovingField(x,y,MV_DOWN);
1146 else if (element==EL_TROPFEN)
1148 Feld[x][y] = EL_AMOEBING;
1149 Store[x][y] = EL_AMOEBE_NASS;
1151 else if (IS_SLIPPERY(Feld[x][y+1]) && !Store[x][y+1])
1153 int left = (x>0 && IS_FREE(x-1,y) &&
1154 (IS_FREE(x-1,y+1) || Feld[x-1][y+1]==EL_SALZSAEURE));
1155 int right = (x<lev_fieldx-1 && IS_FREE(x+1,y) &&
1156 (IS_FREE(x+1,y+1) || Feld[x+1][y+1]==EL_SALZSAEURE));
1161 left = !(right=RND(2));
1162 InitMovingField(x,y,left ? MV_LEFT : MV_RIGHT);
1166 else if (CAN_MOVE(element))
1172 if (!MovDelay[x][y]) /* neuer Schritt / noch nicht gewartet */
1174 if (element==EL_ZOMBIE || element==EL_KAEFER || element==EL_FLIEGER)
1177 if (MovDelay[x][y] && (element==EL_KAEFER || element==EL_FLIEGER))
1178 DrawLevelField(x,y);
1182 if (MovDelay[x][y]) /* neuer Schritt / in Wartezustand */
1186 if (element==EL_ZOMBIE || element==EL_MAMPFER || element==EL_MAMPFER2)
1188 int phase = MovDelay[x][y] % 8;
1193 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1194 DrawGraphic(SCROLLX(x),SCROLLY(y),
1195 el2gfx(element)+phase);
1197 if ((element==EL_MAMPFER || element==EL_MAMPFER2)
1198 && MovDelay[x][y]%4==3)
1199 PlaySoundLevel(x,y,SND_NJAM);
1206 if (element==EL_KAEFER)
1208 PlaySoundLevel(x,y,SND_KLAPPER);
1210 else if (element==EL_FLIEGER)
1212 PlaySoundLevel(x,y,SND_ROEHR);
1215 /* neuer Schritt / Wartezustand beendet */
1217 Moving2Blocked(x,y,&newx,&newy); /* wohin soll's gehen? */
1219 if (PLAYER(newx,newy)) /* Spieler erwischt */
1225 else if (element==EL_MAMPFER && IN_LEV_FIELD(newx,newy) &&
1226 Feld[newx][newy]==EL_DIAMANT)
1228 if (IS_MOVING(newx,newy))
1229 RemoveMovingField(newx,newy);
1232 Feld[newx][newy] = EL_LEERRAUM;
1233 DrawLevelField(newx,newy);
1236 else if (element==EL_MAMPFER2 && IN_LEV_FIELD(newx,newy) &&
1237 IS_MAMPF2(Feld[newx][newy]))
1239 if (AmoebaNr[newx][newy] && Feld[newx][newy]==EL_AMOEBE_VOLL)
1240 AmoebaCnt[AmoebaNr[newx][newy]]--;
1242 if (IS_MOVING(newx,newy))
1243 RemoveMovingField(newx,newy);
1246 Feld[newx][newy] = EL_LEERRAUM;
1247 DrawLevelField(newx,newy);
1250 else if (element==EL_PACMAN && IN_LEV_FIELD(newx,newy) &&
1251 IS_AMOEBOID(Feld[newx][newy]))
1253 if (AmoebaNr[newx][newy] && Feld[newx][newy]==EL_AMOEBE_VOLL)
1254 AmoebaCnt[AmoebaNr[newx][newy]]--;
1256 Feld[newx][newy] = EL_LEERRAUM;
1257 DrawLevelField(newx,newy);
1259 else if (element==EL_ZOMBIE && IN_LEV_FIELD(newx,newy) &&
1260 MovDir[x][y]==MV_DOWN && Feld[newx][newy]==EL_SALZSAEURE)
1263 Store[x][y] = EL_SALZSAEURE;
1265 else if (!IN_LEV_FIELD(newx,newy) || !IS_FREE(newx,newy))
1266 { /* gegen Wand gelaufen */
1268 DrawLevelField(x,y);
1272 InitMovingField(x,y,MovDir[x][y]);
1276 ContinueMoving(x,y);
1279 void ContinueMoving(int x, int y)
1281 int element = Feld[x][y];
1282 int direction = MovDir[x][y];
1283 int dx = (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
1284 int dy = (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
1285 int horiz_move = (dx!=0);
1286 int newx = x + dx, newy = y + dy;
1287 int step = (horiz_move ? dx : dy)*TILEX/4;
1289 if (CAN_FALL(element) && horiz_move)
1291 else if (element==EL_TROPFEN)
1293 else if (Store[x][y]==EL_MORAST_VOLL || Store[x][y]==EL_MORAST_LEER)
1296 MovPos[x][y] += step;
1298 if (ABS(MovPos[x][y])>=TILEX) /* Zielfeld erreicht */
1300 Feld[x][y] = EL_LEERRAUM;
1301 Feld[newx][newy] = element;
1303 if (Store[x][y]==EL_MORAST_VOLL)
1306 Feld[newx][newy] = EL_MORAST_VOLL;
1307 element = EL_MORAST_VOLL;
1309 else if (Store[x][y]==EL_MORAST_LEER)
1312 Feld[x][y] = EL_MORAST_LEER;
1314 else if (Store[x][y]==EL_SIEB_VOLL)
1317 Feld[newx][newy] = EL_SIEB_VOLL;
1318 element = EL_SIEB_VOLL;
1320 else if (Store[x][y]==EL_SIEB_LEER)
1322 Store[x][y] = Store2[x][y] = 0;
1323 Feld[x][y] = EL_SIEB_LEER;
1325 else if (Store[x][y]==EL_SIEB2_VOLL)
1328 Feld[newx][newy] = EL_SIEB2_VOLL;
1329 element = EL_SIEB2_VOLL;
1331 else if (Store[x][y]==EL_SIEB2_LEER)
1333 Store[x][y] = Store2[x][y] = 0;
1334 Feld[x][y] = EL_SIEB2_LEER;
1336 else if (Store[x][y]==EL_SALZSAEURE)
1339 Feld[newx][newy] = EL_SALZSAEURE;
1340 element = EL_SALZSAEURE;
1342 else if (Store[x][y]==EL_AMOEBE_NASS)
1345 Feld[x][y] = EL_AMOEBE_NASS;
1348 MovPos[x][y] = MovDir[x][y] = 0;
1350 if (!CAN_MOVE(element))
1351 MovDir[newx][newy] = 0;
1353 DrawLevelField(x,y);
1354 DrawLevelField(newx,newy);
1356 Stop[newx][newy] = TRUE;
1357 JustHit[x][newy] = 3;
1360 if (DONT_TOUCH(element)) /* Käfer oder Flieger */
1362 TestIfBadThingHitsHero();
1363 TestIfBadThingHitsOtherBadThing(newx,newy);
1366 if (CAN_SMASH(element) && direction==MV_DOWN &&
1367 (newy==lev_fieldy-1 || !IS_FREE(x,newy+1)))
1370 else /* noch in Bewegung */
1372 DrawLevelField(x,y);
1377 int AmoebeNachbarNr(int ax, int ay)
1380 int element = Feld[ax][ay];
1382 static int xy[4][2] =
1392 int x = ax+xy[i%4][0];
1393 int y = ay+xy[i%4][1];
1395 if (!IN_LEV_FIELD(x,y))
1398 if (Feld[x][y]==element && AmoebaNr[x][y]>0)
1399 group_nr = AmoebaNr[x][y];
1405 void AmoebenVereinigen(int ax, int ay)
1408 int new_group_nr = AmoebaNr[ax][ay];
1409 static int xy[4][2] =
1425 if (!IN_LEV_FIELD(x,y))
1428 if ((Feld[x][y]==EL_AMOEBE_VOLL || Feld[x][y]==EL_AMOEBE_TOT) &&
1429 AmoebaNr[x][y] != new_group_nr)
1431 int old_group_nr = AmoebaNr[x][y];
1433 AmoebaCnt[new_group_nr] += AmoebaCnt[old_group_nr];
1434 AmoebaCnt[old_group_nr] = 0;
1436 for(yy=0;yy<lev_fieldy;yy++) for(xx=0;xx<lev_fieldx;xx++)
1437 if (AmoebaNr[xx][yy]==old_group_nr)
1438 AmoebaNr[xx][yy] = new_group_nr;
1443 void AmoebeUmwandeln(int ax, int ay)
1446 int group_nr = AmoebaNr[ax][ay];
1447 static int xy[4][2] =
1455 if (Feld[ax][ay]==EL_AMOEBE_TOT)
1457 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
1459 if (Feld[x][y]==EL_AMOEBE_TOT && AmoebaNr[x][y]==group_nr)
1462 Feld[x][y] = EL_AMOEBA2DIAM;
1474 if (!IN_LEV_FIELD(x,y))
1477 if (Feld[x][y]==EL_AMOEBA2DIAM)
1483 void AmoebeWaechst(int x, int y)
1485 static long sound_delay = 0;
1486 static int sound_delay_value = 0;
1488 CheckExploding = TRUE;
1490 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1494 if (DelayReached(&sound_delay,sound_delay_value))
1496 PlaySoundLevel(x,y,SND_AMOEBE);
1497 sound_delay_value = 30;
1501 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1504 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1505 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AMOEBING+3-MovDelay[x][y]);
1507 if (!MovDelay[x][y])
1509 Feld[x][y] = Store[x][y];
1511 DrawLevelField(x,y);
1516 void AmoebeAbleger(int ax, int ay)
1519 int element = Feld[ax][ay];
1520 int newax = ax, neway = ay;
1521 static int xy[4][2] =
1529 CheckExploding = TRUE;
1531 if (!level.tempo_amoebe)
1533 Feld[ax][ay] = EL_AMOEBE_TOT;
1534 DrawLevelField(ax,ay);
1538 if (!MovDelay[ax][ay]) /* neue Amoebe / noch nicht gewartet */
1539 MovDelay[ax][ay] = RND(33*20/(1+level.tempo_amoebe));
1541 if (MovDelay[ax][ay]) /* neue Amoebe / in Wartezustand */
1544 if (MovDelay[ax][ay])
1548 if (element==EL_AMOEBE_NASS) /* tropfende Amöbe */
1551 int x = ax+xy[start][0];
1552 int y = ay+xy[start][1];
1554 if (!IN_LEV_FIELD(x,y))
1558 Feld[x][y]==EL_ERDREICH || Feld[x][y]==EL_MORAST_LEER)
1564 if (newax==ax && neway==ay)
1567 else /* normale oder "gefüllte" Amöbe */
1570 BOOL waiting_for_player = FALSE;
1574 int j = (start+i)%4;
1575 int x = ax+xy[j][0];
1576 int y = ay+xy[j][1];
1578 if (!IN_LEV_FIELD(x,y))
1582 Feld[x][y]==EL_ERDREICH || Feld[x][y]==EL_MORAST_LEER)
1588 else if (PLAYER(x,y))
1589 waiting_for_player = TRUE;
1592 if (newax==ax && neway==ay)
1594 if (i==4 && !waiting_for_player)
1596 Feld[ax][ay] = EL_AMOEBE_TOT;
1597 DrawLevelField(ax,ay);
1599 if (element==EL_AMOEBE_VOLL && --AmoebaCnt[AmoebaNr[ax][ay]]<=0)
1600 AmoebeUmwandeln(ax,ay);
1604 else if (element==EL_AMOEBE_VOLL)
1606 int new_group_nr = AmoebaNr[ax][ay];
1608 AmoebaNr[newax][neway] = new_group_nr;
1609 AmoebaCnt[new_group_nr]++;
1610 AmoebenVereinigen(newax,neway);
1614 if (element!=EL_AMOEBE_NASS || neway<ay || !IS_FREE(newax,neway) ||
1615 (neway==lev_fieldy-1 && newax!=ax))
1617 Feld[newax][neway] = EL_AMOEBING;
1618 Store[newax][neway] = element;
1621 Feld[newax][neway] = EL_TROPFEN;
1624 InitMovingField(ax,ay,MV_DOWN);
1625 Feld[ax][ay] = EL_TROPFEN;
1626 Store[ax][ay] = EL_AMOEBE_NASS;
1627 ContinueMoving(ax,ay);
1631 DrawLevelField(newax,neway);
1634 void Life(int ax, int ay)
1637 static int life[4] = { 2,3,3,3 }; /* "Life"-Parameter */
1639 int element = Feld[ax][ay];
1641 CheckExploding = TRUE;
1646 if (!MovDelay[ax][ay]) /* neue Phase / noch nicht gewartet */
1647 MovDelay[ax][ay] = life_time;
1649 if (MovDelay[ax][ay]) /* neue Phase / in Wartezustand */
1652 if (MovDelay[ax][ay])
1656 for(y1=-1;y1<2;y1++) for(x1=-1;x1<2;x1++)
1658 int xx = ax+x1, yy = ay+y1;
1661 if (!IN_LEV_FIELD(xx,yy))
1664 for(y2=-1;y2<2;y2++) for(x2=-1;x2<2;x2++)
1666 int x = xx+x2, y = yy+y2;
1668 if (!IN_LEV_FIELD(x,y) || (x==xx && y==yy))
1671 if (((Feld[x][y]==element || (element==EL_LIFE && PLAYER(x,y))) &&
1673 (IS_FREE(x,y) && Stop[x][y]))
1677 if (xx==ax && yy==ay) /* mittleres Feld mit Amoebe */
1679 if (nachbarn<life[0] || nachbarn>life[1])
1681 Feld[xx][yy] = EL_LEERRAUM;
1683 DrawLevelField(xx,yy);
1684 Stop[xx][yy] = TRUE;
1687 else if (IS_FREE(xx,yy) || Feld[xx][yy]==EL_ERDREICH)
1688 { /* Randfeld ohne Amoebe */
1689 if (nachbarn>=life[2] && nachbarn<=life[3])
1691 Feld[xx][yy] = element;
1692 MovDelay[xx][yy] = (element==EL_LIFE ? 0 : life_time-1);
1694 DrawLevelField(xx,yy);
1695 Stop[xx][yy] = TRUE;
1701 void Ablenk(int x, int y)
1703 CheckExploding = TRUE;
1705 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1706 MovDelay[x][y] = 33*(level.dauer_ablenk/10);
1707 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1712 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1713 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_ABLENK+MovDelay[x][y]%4);
1714 if (!(MovDelay[x][y]%4))
1715 PlaySoundLevel(x,y,SND_MIEP);
1720 Feld[x][y]=EL_ABLENK_AUS;
1721 DrawLevelField(x,y);
1726 void Birne(int x, int y)
1728 CheckExploding = TRUE;
1730 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1731 MovDelay[x][y] = 400;
1733 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1738 if (!(MovDelay[x][y]%5))
1740 if (!(MovDelay[x][y]%10))
1741 Feld[x][y]=EL_ABLENK_EIN;
1743 Feld[x][y]=EL_ABLENK_AUS;
1744 DrawLevelField(x,y);
1745 Feld[x][y]=EL_ABLENK_EIN;
1751 Feld[x][y]=EL_ABLENK_AUS;
1752 DrawLevelField(x,y);
1757 void Blubber(int x, int y)
1759 CheckExploding = TRUE;
1761 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1762 MovDelay[x][y] = 20;
1764 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1769 blubber = MovDelay[x][y]/5;
1770 if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1771 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_GEBLUBBER+3-blubber);
1775 void NussKnacken(int x, int y)
1777 CheckExploding = TRUE;
1779 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1782 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1785 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1786 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_CRACKINGNUT+3-MovDelay[x][y]);
1788 if (!MovDelay[x][y])
1790 Feld[x][y] = EL_EDELSTEIN;
1791 DrawLevelField(x,y);
1796 void SiebAktivieren(int x, int y, int typ)
1798 CheckExploding = TRUE;
1802 if (SiebAktiv%2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1803 DrawGraphic(SCROLLX(x),SCROLLY(y),
1804 (typ==1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL)+3-(SiebAktiv%8)/2);
1808 PlaySoundLevel(x,y,SND_MIEP);
1814 Feld[x][y] = (typ==1 ? EL_SIEB_TOT : EL_SIEB2_TOT);
1815 DrawLevelField(x,y);
1819 void AusgangstuerPruefen(int x, int y)
1821 CheckExploding = TRUE;
1825 Feld[x][y] = EL_AUSGANG_ACT;
1826 PlaySoundLevel(x,y,SND_OEFFNEN);
1830 void AusgangstuerOeffnen(int x, int y)
1834 CheckExploding = TRUE;
1836 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1837 MovDelay[x][y] = 5*speed;
1839 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1844 tuer = MovDelay[x][y]/speed;
1845 if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1846 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_AUF-tuer);
1848 if (!MovDelay[x][y])
1850 Feld[x][y] = EL_AUSGANG_AUF;
1851 DrawLevelField(x,y);
1856 void AusgangstuerBlinken(int x, int y)
1858 CheckExploding = TRUE;
1860 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1861 MovDelay[x][y] = 16;
1863 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1868 phase = (MovDelay[x][y] % 16)/2;
1871 if (!(MovDelay[x][y]%2) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1872 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_AUF+phase);
1876 void EdelsteinFunkeln(int x, int y)
1880 CheckExploding = TRUE;
1885 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1886 MovDelay[x][y] = 4*speed;
1888 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1893 phase = MovDelay[x][y]/speed;
1894 if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1895 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EDELSTEIN2-phase);
1899 void MauerWaechst(int x, int y)
1903 CheckExploding = TRUE;
1905 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1906 MovDelay[x][y] = 3*speed;
1908 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1913 phase = 2-MovDelay[x][y]/speed;
1914 if (!(MovDelay[x][y]%speed) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1915 DrawGraphic(SCROLLX(x),SCROLLY(y),
1916 (Store[x][y]==MV_LEFT ? GFX_MAUER_L1 : GFX_MAUER_R1)+phase);
1918 if (!MovDelay[x][y])
1920 if (Store[x][y]==MV_LEFT)
1922 if (IN_LEV_FIELD(x-1,y) && IS_MAUER(Feld[x-1][y]))
1923 DrawLevelField(x-1,y);
1927 if (IN_LEV_FIELD(x+1,y) && IS_MAUER(Feld[x+1][y]))
1928 DrawLevelField(x+1,y);
1931 Feld[x][y] = EL_MAUER_LEBT;
1933 DrawLevelField(x,y);
1938 void MauerAbleger(int ax, int ay)
1940 BOOL links_frei = FALSE, rechts_frei = FALSE;
1941 BOOL links_massiv = FALSE, rechts_massiv = FALSE;
1943 CheckExploding = TRUE;
1945 if (!MovDelay[ax][ay]) /* neue Mauer / noch nicht gewartet */
1946 MovDelay[ax][ay] = 3;
1948 if (MovDelay[ax][ay]) /* neue Mauer / in Wartezustand */
1951 if (MovDelay[ax][ay])
1955 if (IN_LEV_FIELD(ax-1,ay) && IS_FREE(ax-1,ay))
1957 if (IN_LEV_FIELD(ax+1,ay) && IS_FREE(ax+1,ay))
1962 Feld[ax-1][ay] = EL_MAUERND;
1963 Store[ax-1][ay] = MV_LEFT;
1964 if (IN_SCR_FIELD(SCROLLX(ax-1),SCROLLY(ay)))
1965 DrawGraphic(SCROLLX(ax-1),SCROLLY(ay),GFX_MAUER_L1);
1969 Feld[ax+1][ay] = EL_MAUERND;
1970 Store[ax+1][ay] = MV_RIGHT;
1971 if (IN_SCR_FIELD(SCROLLX(ax+1),SCROLLY(ay)))
1972 DrawGraphic(SCROLLX(ax+1),SCROLLY(ay),GFX_MAUER_R1);
1975 if (links_frei || rechts_frei)
1976 DrawLevelField(ax,ay);
1978 if (!IN_LEV_FIELD(ax-1,ay) || IS_MAUER(Feld[ax-1][ay]))
1979 links_massiv = TRUE;
1980 if (!IN_LEV_FIELD(ax+1,ay) || IS_MAUER(Feld[ax+1][ay]))
1981 rechts_massiv = TRUE;
1983 if (links_massiv && rechts_massiv)
1984 Feld[ax][ay] = EL_MAUERWERK;
1987 int GameActions(int mx, int my, int button)
1989 static long time_delay=0, action_delay=0;
1992 if (TimeLeft>0 && DelayReached(&time_delay,100) && !tape.pausing)
1996 if (tape.recording || tape.playing)
1997 DrawVideoDisplay(VIDEO_STATE_TIME_ON,level.time-TimeLeft);
2000 PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT);
2002 DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
2009 Action = (CheckMoving || CheckExploding || SiebAktiv);
2012 if (Action && DelayReached(&action_delay,3))
2015 if (DelayReached(&action_delay,3))
2019 if (tape.pausing || (tape.playing && !TapePlayDelay()))
2021 else if (tape.recording)
2024 CheckMoving = CheckExploding = FALSE;
2025 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
2028 if (JustHit[x][y]>0)
2032 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
2034 element = Feld[x][y];
2036 if (element==EL_LEERRAUM || element==EL_ERDREICH)
2039 if (!IS_MOVING(x,y) && (CAN_FALL(element) || CAN_MOVE(element)))
2042 if (Feld[x][y]==EL_EDELSTEIN2)
2043 EdelsteinFunkeln(x,y);
2045 else if (IS_MOVING(x,y))
2046 ContinueMoving(x,y);
2047 else if (element==EL_DYNAMIT || element==EL_DYNABOMB)
2049 else if (element==EL_EXPLODING)
2050 Explode(x,y,Frame[x][y],EX_NORMAL);
2051 else if (element==EL_AMOEBING)
2053 else if (IS_AMOEBALIVE(element))
2055 else if (element==EL_LIFE || element==EL_LIFE_ASYNC)
2057 else if (element==EL_ABLENK_EIN)
2059 else if (element==EL_SALZSAEURE)
2061 else if (element==EL_BLURB_LEFT || element==EL_BLURB_RIGHT)
2063 else if (element==EL_CRACKINGNUT)
2065 else if (element==EL_AUSGANG_ZU)
2066 AusgangstuerPruefen(x,y);
2067 else if (element==EL_AUSGANG_ACT)
2068 AusgangstuerOeffnen(x,y);
2069 else if (element==EL_AUSGANG_AUF)
2070 AusgangstuerBlinken(x,y);
2071 else if (element==EL_MAUERND)
2073 else if (element==EL_MAUER_LEBT)
2078 if (element==EL_SIEB_LEER || element==EL_SIEB_VOLL ||
2079 Store[x][y]==EL_SIEB_LEER)
2080 SiebAktivieren(x,y,1);
2081 else if (element==EL_SIEB2_LEER || element==EL_SIEB2_VOLL ||
2082 Store[x][y]==EL_SIEB2_LEER)
2083 SiebAktivieren(x,y,2);
2090 if (CheckMoving || CheckExploding)
2097 void ScrollLevel(int dx, int dy)
2101 XCopyArea(display,drawto_field,drawto_field,gc,
2102 SX+TILEX*(dx==-1),SY+TILEY*(dy==-1),
2103 SXSIZE-TILEX*(dx!=0),SYSIZE-TILEY*(dy!=0),
2104 SX+TILEX*(dx==1),SY+TILEY*(dy==1));
2108 x = dx==1 ? 0 : SCR_FIELDX-1;
2109 for(y=0;y<SCR_FIELDY;y++)
2110 DrawScreenField(x,y);
2114 y = dy==1 ? 0 : SCR_FIELDY-1;
2115 for(x=0;x<SCR_FIELDY;x++)
2116 DrawScreenField(x,y);
2119 redraw_mask|=REDRAW_FIELD;
2122 BOOL MoveFigureOneStep(int dx, int dy)
2124 int oldJX,oldJY, newJX = JX+dx,newJY = JY+dy;
2129 return(MF_NO_ACTION);
2130 if (!IN_LEV_FIELD(newJX,newJY))
2131 return(MF_NO_ACTION);
2133 element = MovingOrBlocked2Element(newJX,newJY);
2135 if (DONT_GO_TO(element))
2137 if (element==EL_SALZSAEURE && dx==0 && dy==1)
2140 Feld[JX][JY] = EL_SPIELFIGUR;
2141 InitMovingField(JX,JY,MV_DOWN);
2142 Store[JX][JY] = EL_SALZSAEURE;
2143 ContinueMoving(JX,JY);
2145 PlaySoundLevel(JX,JY,SND_AUTSCH);
2146 PlaySoundLevel(JX,JY,SND_LACHEN);
2156 can_move = DigField(newJX,newJY,DF_DIG);
2157 if (can_move != MF_MOVING)
2165 if (Store[oldJX][oldJY])
2167 DrawGraphic(SCROLLX(oldJX),SCROLLY(oldJY),el2gfx(Store[oldJX][oldJY]));
2168 DrawGraphicThruMask(SCROLLX(oldJX),SCROLLY(oldJY),
2169 el2gfx(Feld[oldJX][oldJY]));
2171 else if (Feld[oldJX][oldJY]==EL_DYNAMIT)
2172 DrawDynamite(oldJX,oldJY);
2174 DrawLevelField(oldJX,oldJY);
2179 BOOL MoveFigure(int dx, int dy)
2181 static long move_delay = 0;
2182 int moved = MF_NO_ACTION;
2184 if (GameOver || (!dx && !dy))
2187 if (!DelayReached(&move_delay,10) && !tape.playing)
2190 if (moved |= MoveFigureOneStep(dx,0))
2191 moved |= MoveFigureOneStep(0,dy);
2194 moved |= MoveFigureOneStep(0,dy);
2195 moved |= MoveFigureOneStep(dx,0);
2198 if (moved & MF_MOVING)
2200 int old_scroll_x=scroll_x, old_scroll_y=scroll_y;
2202 if (scroll_x!=JX-MIDPOSX && JX>=MIDPOSX-1 && JX<=lev_fieldx-MIDPOSX)
2203 scroll_x = JX-MIDPOSX;
2204 if (scroll_y!=JY-MIDPOSY && JY>=MIDPOSY-1 && JY<=lev_fieldy-MIDPOSY)
2205 scroll_y = JY-MIDPOSY;
2207 if (scroll_x!=old_scroll_x || scroll_y!=old_scroll_y)
2208 ScrollLevel(old_scroll_x-scroll_x,old_scroll_y-scroll_y);
2210 if (Feld[JX][JY]==EL_LEERRAUM)
2211 DrawLevelElement(JX,JY,EL_SPIELFIGUR);
2213 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
2216 TestIfHeroHitsBadThing();
2226 void TestIfHeroHitsBadThing()
2228 int i, killx = JX,killy = JY;
2229 static int xy[4][2] =
2236 static int harmless[4] =
2250 if (!IN_LEV_FIELD(x,y))
2253 element = Feld[x][y];
2255 if (DONT_TOUCH(element))
2257 if (MovDir[x][y]==harmless[i])
2266 if (killx!=JX || killy!=JY)
2270 void TestIfBadThingHitsHero()
2272 TestIfHeroHitsBadThing();
2275 void TestIfBadThingHitsOtherBadThing(int badx, int bady)
2277 int i, killx=badx, killy=bady;
2278 static int xy[4][2] =
2292 if (!IN_LEV_FIELD(x,y))
2296 if (IS_AMOEBOID(element) || element==EL_LIFE ||
2297 element==EL_AMOEBING || element==EL_TROPFEN)
2305 if (killx!=badx || killy!=bady)
2314 if (IS_PFORTE(Feld[JX][JY]))
2315 Feld[JX][JY] = EL_LEERRAUM;
2317 PlaySoundLevel(JX,JY,SND_AUTSCH);
2318 PlaySoundLevel(JX,JY,SND_LACHEN);
2324 int DigField(int x, int y, int mode)
2326 int dx = x-JX, dy = y-JY;
2328 static long push_delay = 0;
2329 static int push_delay_value = 20;
2331 if (mode==DF_NO_PUSH)
2334 return(MF_NO_ACTION);
2338 return(MF_NO_ACTION);
2340 element = Feld[x][y];
2348 Feld[x][y] = EL_LEERRAUM;
2354 Feld[x][y] = EL_LEERRAUM;
2358 RaiseScore(level.score[SC_EDELSTEIN]);
2359 DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW);
2360 PlaySoundLevel(x,y,SND_PONG);
2363 Feld[x][y] = EL_LEERRAUM;
2368 RaiseScore(level.score[SC_DIAMANT]);
2369 DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW);
2370 PlaySoundLevel(x,y,SND_PONG);
2372 case EL_DYNAMIT_AUS:
2373 Feld[x][y] = EL_LEERRAUM;
2376 RaiseScore(level.score[SC_DYNAMIT]);
2377 DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
2378 PlaySoundLevel(x,y,SND_PONG);
2380 case EL_DYNABOMB_NR:
2381 Feld[x][y] = EL_LEERRAUM;
2385 RaiseScore(level.score[SC_DYNAMIT]);
2386 PlaySoundLevel(x,y,SND_PONG);
2388 case EL_DYNABOMB_SZ:
2389 Feld[x][y] = EL_LEERRAUM;
2392 RaiseScore(level.score[SC_DYNAMIT]);
2393 PlaySoundLevel(x,y,SND_PONG);
2395 case EL_SCHLUESSEL1:
2396 case EL_SCHLUESSEL2:
2397 case EL_SCHLUESSEL3:
2398 case EL_SCHLUESSEL4:
2400 int key_nr = element-EL_SCHLUESSEL1;
2402 Feld[x][y] = EL_LEERRAUM;
2405 RaiseScore(level.score[SC_SCHLUESSEL]);
2406 DrawMiniGraphicExtHiRes(drawto,gc,
2407 DX_KEYS+key_nr*MINI_TILEX,DY_KEYS,
2408 GFX_SCHLUESSEL1+key_nr);
2409 DrawMiniGraphicExtHiRes(window,gc,
2410 DX_KEYS+key_nr*MINI_TILEX,DY_KEYS,
2411 GFX_SCHLUESSEL1+key_nr);
2412 PlaySoundLevel(x,y,SND_PONG);
2416 Feld[x][y] = EL_ABLENK_EIN;
2417 CheckExploding = TRUE;
2420 DrawLevelField(x,y);
2423 case EL_FELSBROCKEN:
2428 return(MF_NO_ACTION);
2429 if (dy || !IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy]!=EL_LEERRAUM)
2430 return(MF_NO_ACTION);
2432 if (Counter() > push_delay+4*push_delay_value)
2433 push_delay = Counter();
2434 if (!DelayReached(&push_delay,push_delay_value) && !tape.playing)
2435 return(MF_NO_ACTION);
2437 Feld[x][y] = EL_LEERRAUM;
2438 Feld[x+dx][y+dy] = element;
2439 push_delay_value = 10+RND(30);
2441 DrawLevelField(x+dx,y+dy);
2442 if (element==EL_FELSBROCKEN)
2443 PlaySoundLevel(x+dx,y+dy,SND_PUSCH);
2444 else if (element==EL_KOKOSNUSS)
2445 PlaySoundLevel(x+dx,y+dy,SND_KNURK);
2447 PlaySoundLevel(x+dx,y+dy,SND_KLOPF);
2453 if (!Key[element-EL_PFORTE1])
2454 return(MF_NO_ACTION);
2460 if (!Key[element-EL_PFORTE1X])
2461 return(MF_NO_ACTION);
2464 case EL_AUSGANG_ACT:
2465 /* Tür ist (noch) nicht offen! */
2466 return(MF_NO_ACTION);
2468 case EL_AUSGANG_AUF:
2470 if (mode==DF_SNAP || Gems>0)
2471 return(MF_NO_ACTION);
2474 return(MF_NO_ACTION);
2475 LevelSolved = GameOver = TRUE;
2476 PlaySoundLevel(x,y,SND_BUING);
2479 Feld[x][y] = EL_BIRNE_EIN;
2480 DrawLevelField(x,y);
2481 PlaySoundLevel(x,y,SND_DENG);
2485 Feld[x][y] = EL_ZEIT_LEER;
2486 DrawLevelField(x,y);
2487 PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT);
2491 return(MF_NO_ACTION);
2498 BOOL SnapField(int dx, int dy)
2500 int x = JX+dx, y = JY+dy;
2501 static int snapped = FALSE;
2503 if (GameOver || !IN_LEV_FIELD(x,y))
2515 if (!DigField(x,y,DF_SNAP))
2519 DrawLevelField(x,y);
2525 BOOL PlaceBomb(void)
2527 if ((Dynamite==0 && DynaBombsLeft==0) ||
2528 Feld[JX][JY]==EL_DYNAMIT || Feld[JX][JY]==EL_DYNABOMB)
2531 if (Feld[JX][JY]!=EL_LEERRAUM)
2532 Store[JX][JY] = Feld[JX][JY];
2536 Feld[JX][JY] = EL_DYNAMIT;
2537 MovDelay[JX][JY] = 48;
2539 DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
2540 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
2544 Feld[JX][JY] = EL_DYNABOMB;
2545 MovDelay[JX][JY] = 48;
2548 /* ändern, wenn Maske für DYNABOMB vorliegt! */
2550 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
2553 CheckExploding = TRUE;
2557 void PlaySoundLevel(int x, int y, int sound_nr)
2559 int sx = SCROLLX(x), sy = SCROLLY(y);
2562 if (!sound_loops_on && IS_LOOP_SOUND(sound_nr))
2565 if (!IN_LEV_FIELD(x,y))
2568 volume = PSND_MAX_VOLUME;
2569 stereo = (sx-SCR_FIELDX/2)*12;
2571 if (!IN_SCR_FIELD(sx,sy))
2573 if (sx<0 || sx>=SCR_FIELDX)
2574 volume = PSND_MAX_VOLUME - 2*ABS(sx-SCR_FIELDX/2);
2576 volume = PSND_MAX_VOLUME - 2*ABS(sy-SCR_FIELDY/2);
2579 PlaySoundExt(sound_nr, volume, stereo, PSND_NO_LOOP);
2582 void RaiseScore(int value)
2585 DrawText(DX_SCORE,DY_SCORE,int2str(Score,5),FS_SMALL,FC_YELLOW);
2589 void TapeInitRecording()
2591 time_t zeit1 = time(NULL);
2592 struct tm *zeit2 = localtime(&zeit1);
2594 if (tape.recording || tape.playing)
2597 tape.level_nr = level_nr;
2598 tape.recording = TRUE;
2599 tape.pausing = TRUE;
2601 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday;
2603 DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_ON,0);
2604 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2605 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2608 void TapeStartRecording()
2612 tape.pos[tape.counter].delay = 0;
2613 tape.recording = TRUE;
2614 tape.playing = FALSE;
2615 tape.pausing = FALSE;
2616 tape.random_seed = InitRND(NEW_RANDOMIZE);
2617 DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_OFF,0);
2620 void TapeStopRecording()
2622 if (!tape.recording)
2625 tape.length = tape.counter;
2626 tape.recording = FALSE;
2627 tape.pausing = FALSE;
2628 DrawVideoDisplay(VIDEO_STATE_REC_OFF,0);
2633 void TapeRecordAction(int joy)
2635 if (!tape.recording || tape.pausing)
2638 if (tape.counter>=MAX_TAPELEN-1)
2640 TapeStopRecording();
2646 tape.pos[tape.counter].joystickdata = joy;
2648 tape.pos[tape.counter].delay = 0;
2652 void TapeRecordDelay()
2654 if (!tape.recording || tape.pausing)
2657 if (tape.counter>=MAX_TAPELEN)
2659 TapeStopRecording();
2663 tape.pos[tape.counter].delay++;
2665 if (tape.pos[tape.counter].delay>=255)
2667 tape.pos[tape.counter].joystickdata = 0;
2669 tape.pos[tape.counter].delay = 0;
2673 void TapeTogglePause()
2675 if (!tape.recording && !tape.playing)
2680 tape.pausing = FALSE;
2681 DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
2682 if (game_status==MAINMENU)
2683 HandleMainMenu(SX+16,SY+7*32+16,0,0,MB_MENU_CHOICE);
2687 tape.pausing = TRUE;
2688 DrawVideoDisplay(VIDEO_STATE_PAUSE_ON,0);
2692 void TapeInitPlaying()
2694 if (tape.recording || tape.playing || TAPE_IS_EMPTY(tape))
2697 tape.playing = TRUE;
2698 tape.pausing = TRUE;
2699 DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_ON,0);
2700 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2701 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2704 void TapeStartPlaying()
2709 tape.recording = FALSE;
2710 tape.playing = TRUE;
2711 tape.pausing = FALSE;
2712 InitRND(tape.random_seed);
2713 DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_OFF,0);
2716 void TapeStopPlaying()
2721 tape.playing = FALSE;
2722 tape.pausing = FALSE;
2723 DrawVideoDisplay(VIDEO_STATE_PLAY_OFF,0);
2726 int TapePlayAction()
2728 if (!tape.playing || tape.pausing)
2731 if (tape.counter>=tape.length)
2737 if (!tape.pos[tape.counter].delay)
2740 return(tape.pos[tape.counter-1].joystickdata);
2746 BOOL TapePlayDelay()
2748 if (!tape.playing || tape.pausing)
2751 if (tape.counter>=tape.length)
2757 if (tape.pos[tape.counter].delay)
2759 tape.pos[tape.counter].delay--;
2768 TapeStopRecording();
2770 DrawVideoDisplay(VIDEO_ALL_OFF,0);
2771 if (tape.date && tape.length)
2773 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2774 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);