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 *----------------------------------------------------------*
14 * Letzte Aenderung: 15.06.1995 *
15 ***********************************************************/
24 BOOL CreateNewScoreFile()
27 char filename[MAX_FILENAME];
28 char empty_alias[MAX_NAMELEN];
31 sprintf(filename,"%s/%s/%s",
32 SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
34 if (!(file=fopen(filename,"w")))
37 for(i=0;i<MAX_NAMELEN;i++)
39 strncpy(empty_alias,EMPTY_ALIAS,MAX_NAMELEN-1);
41 fputs(SCORE_COOKIE,file); /* Formatkennung */
42 for(i=0;i<LEVELDIR_SIZE(leveldir[leveldir_nr]);i++)
44 for(j=0;j<MAX_SCORE_ENTRIES;j++)
46 for(k=0;k<MAX_NAMELEN;k++)
47 fputc(empty_alias[k],file);
54 chmod(filename, SCORE_PERMS);
58 BOOL CreateNewNamesFile(int mode)
60 char filename[MAX_FILENAME];
63 if (mode==PLAYER_LEVEL)
64 sprintf(filename,"%s/%s/%s",
65 NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
67 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
69 if (!(file=fopen(filename,"w")))
72 fputs(NAMES_COOKIE,file); /* Formatkennung */
75 chmod(filename, NAMES_PERMS);
82 char filename[MAX_FILENAME];
83 char cookie[MAX_FILENAME];
87 sprintf(filename,"%s/%s",LEVEL_PATH,LEVDIR_FILENAME);
89 if (!(file=fopen(filename,"r")))
91 fprintf(stderr,"%s: cannot load level info '%s'!\n",progname,filename);
95 ignored = fscanf(file,"%s\n",cookie);
96 if (strcmp(cookie,LEVELDIR_COOKIE)) /* ungültiges Format? */
98 fprintf(stderr,"%s: wrong format of level info file!\n",progname);
105 for(i=0;i<MAX_LEVDIR_ENTRIES;i++)
107 ignored = fscanf(file,"%s",leveldir[i].filename);
108 ignored = fscanf(file,"%s",leveldir[i].name);
109 ignored = fscanf(file,"%d",&leveldir[i].num_ready);
110 ignored = fscanf(file,"%d",&leveldir[i].num_free);
119 fprintf(stderr,"%s: empty level info '%s'!\n",progname,filename);
124 void LoadLevel(int level_nr)
127 char filename[MAX_FILENAME];
128 char cookie[MAX_FILENAME];
132 sprintf(filename,"%s/%s/%d",
133 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
135 if (!(file=fopen(filename,"r")))
138 fprintf(stderr,"%s: cannot load level '%s'!\n",progname,filename);
143 ignored = fgets(cookie,LEVEL_COOKIE_LEN,file);
145 if (strcmp(cookie,LEVEL_COOKIE)) /* ungültiges Format? */
147 fprintf(stderr,"%s: wrong format of level file '%s'!\n",
156 lev_fieldx = level.fieldx = fgetc(file);
157 lev_fieldy = level.fieldy = fgetc(file);
159 level.time = (fgetc(file)<<8) | fgetc(file);
160 level.edelsteine = (fgetc(file)<<8) | fgetc(file);
161 for(i=0;i<MAX_LEVNAMLEN;i++)
162 level.name[i] = fgetc(file);
163 for(i=0;i<MAX_SC_ENTRIES;i++)
164 level.score[i] = fgetc(file);
168 level.mampfer_inhalt[i][x][y] = fgetc(file);
169 level.tempo_amoebe = fgetc(file);
170 level.dauer_sieb = fgetc(file);
171 level.dauer_ablenk = fgetc(file);
173 for(i=0;i<19;i++) /* Rest reserviert / Headergröße 80 Bytes */
176 for(y=0;y<lev_fieldy;y++)
177 for(x=0;x<lev_fieldx;x++)
178 Feld[x][y] = Ur[x][y] = fgetc(file);
182 if (level.time<=10) /* Mindestspieldauer */
187 lev_fieldx = level.fieldx = STD_LEV_FIELDX;
188 lev_fieldy = level.fieldy = STD_LEV_FIELDY;
191 level.edelsteine = 0;
192 strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
193 for(i=0;i<MAX_SC_ENTRIES;i++)
198 level.mampfer_inhalt[i][x][y] = EL_FELSBROCKEN;
199 level.tempo_amoebe = 10;
200 level.dauer_sieb = 10;
201 level.dauer_ablenk = 10;
203 for(y=0;y<STD_LEV_FIELDY;y++)
204 for(x=0;x<STD_LEV_FIELDX;x++)
205 Feld[x][y] = Ur[x][y] = EL_ERDREICH;
206 Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
207 Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
208 Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
212 void LoadLevelTape(int level_nr)
215 char filename[MAX_FILENAME];
216 char cookie[MAX_FILENAME];
220 sprintf(filename,"%s/%s/%d.tape",
221 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
223 if ((file=fopen(filename,"r")))
225 ignored = fgets(cookie,LEVELREC_COOKIE_LEN,file);
227 if (strcmp(cookie,LEVELREC_COOKIE)) /* ungültiges Format? */
229 fprintf(stderr,"%s: wrong format of level recording file '%s'!\n",
240 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
242 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
244 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
246 tape.level_nr = level_nr;
248 tape.recording = FALSE;
249 tape.playing = FALSE;
250 tape.pausing = FALSE;
252 for(i=0;i<tape.length;i++)
256 tape.pos[i].joystickdata = fgetc(file);
257 tape.pos[i].delay = fgetc(file);
262 if (i != tape.length)
263 fprintf(stderr,"%s: level recording file '%s' corrupted!\n",
271 void LoadScore(int level_nr)
274 char filename[MAX_FILENAME];
275 char cookie[MAX_FILENAME];
279 sprintf(filename,"%s/%s/%s",
280 SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
282 if (!(file=fopen(filename,"r")))
284 if (!CreateNewScoreFile())
286 fprintf(stderr,"%s: cannot create score file '%s'!\n",
289 else if (!(file=fopen(filename,"r")))
291 fprintf(stderr,"%s: cannot load score for level %d!\n",
298 ignored = fgets(cookie,SCORE_COOKIE_LEN,file);
299 if (strcmp(cookie,SCORE_COOKIE)) /* ungültiges Format? */
301 fprintf(stderr,"%s: wrong format of score file!\n",progname);
310 SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
312 for(i=0;i<MAX_SCORE_ENTRIES;i++)
314 for(j=0;j<MAX_NAMELEN;j++)
315 highscore[i].Name[j] = fgetc(file);
316 highscore[i].Score = (fgetc(file)<<8) | fgetc(file);
322 for(i=0;i<MAX_SCORE_ENTRIES;i++)
324 strcpy(highscore[i].Name,EMPTY_ALIAS);
325 highscore[i].Score = 0;
330 void LoadPlayerInfo(int mode)
333 char filename[MAX_FILENAME];
334 char cookie[MAX_FILENAME];
336 char *login_name = GetLoginName();
337 struct PlayerInfo default_player, new_player;
340 if (mode==PLAYER_LEVEL)
341 sprintf(filename,"%s/%s/%s",
342 NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
344 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
346 for(i=0;i<MAX_NAMELEN;i++)
347 default_player.login_name[i] = default_player.alias_name[i] = 0;
348 strncpy(default_player.login_name,login_name,MAX_NAMELEN-1);
349 strncpy(default_player.alias_name,login_name,MAX_NAMELEN-1);
350 default_player.handicap = 0;
351 default_player.setup = DEFAULT_SETUP;
352 default_player.leveldir_nr = 0;
354 new_player = default_player;
356 if (!(file=fopen(filename,"r")))
358 if (!CreateNewNamesFile(mode))
360 fprintf(stderr,"%s: cannot create names file '%s'!\n",
363 else if (!(file=fopen(filename,"r")))
365 fprintf(stderr,"%s: cannot load player information '%s'!\n",
372 ignored = fgets(cookie,NAMES_COOKIE_LEN,file);
373 if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
375 fprintf(stderr,"%s: wrong format of names file '%s'!\n",
384 player = default_player;
385 level_nr = default_player.handicap;
391 for(i=0;i<MAX_NAMELEN;i++)
392 new_player.login_name[i] = fgetc(file);
393 for(i=0;i<MAX_NAMELEN;i++)
394 new_player.alias_name[i] = fgetc(file);
395 new_player.handicap = fgetc(file);
396 new_player.setup = (fgetc(file)<<8) | fgetc(file);
397 new_player.leveldir_nr = fgetc(file);
399 if (feof(file)) /* Spieler noch nicht in Liste enthalten */
401 new_player = default_player;
404 if (!(file=fopen(filename,"a")))
406 fprintf(stderr,"%s: cannot append new player to names file '%s'!\n",
411 for(i=0;i<MAX_NAMELEN;i++)
412 fputc(new_player.login_name[i],file);
413 for(i=0;i<MAX_NAMELEN;i++)
414 fputc(new_player.alias_name[i],file);
415 fputc(new_player.handicap,file);
416 fputc(new_player.setup / 256,file);
417 fputc(new_player.setup % 256,file);
418 fputc(new_player.leveldir_nr,file);
422 else /* prüfen, ob Spieler in Liste enthalten */
423 if (!strncmp(new_player.login_name,login_name,MAX_NAMELEN-1))
427 if (mode==PLAYER_SETUP)
430 if (player.leveldir_nr < num_leveldirs)
431 leveldir_nr = player.leveldir_nr;
436 player.handicap = new_player.handicap;
438 level_nr = player.handicap;
442 void SaveLevel(int level_nr)
445 char filename[MAX_FILENAME];
448 sprintf(filename,"%s/%s/%d",
449 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
451 if (!(file=fopen(filename,"w")))
453 fprintf(stderr,"%s: cannot save level file '%s'!\n",progname,filename);
457 fputs(LEVEL_COOKIE,file); /* Formatkennung */
460 fputc(level.fieldx,file);
461 fputc(level.fieldy,file);
462 fputc(level.time / 256,file);
463 fputc(level.time % 256,file);
464 fputc(level.edelsteine / 256,file);
465 fputc(level.edelsteine % 256,file);
467 for(i=0;i<MAX_LEVNAMLEN;i++)
468 fputc(level.name[i],file);
469 for(i=0;i<MAX_SC_ENTRIES;i++)
470 fputc(level.score[i],file);
474 fputc(level.mampfer_inhalt[i][x][y],file);
475 fputc(level.tempo_amoebe,file);
476 fputc(level.dauer_sieb,file);
477 fputc(level.dauer_ablenk,file);
479 for(i=0;i<19;i++) /* Rest reserviert / Headergröße 80 Bytes */
482 for(y=0;y<lev_fieldy;y++)
483 for(x=0;x<lev_fieldx;x++)
484 fputc(Ur[x][y],file);
488 chmod(filename, LEVEL_PERMS);
491 void SaveLevelTape(int level_nr)
494 char filename[MAX_FILENAME];
496 BOOL new_tape = TRUE;
498 sprintf(filename,"%s/%s/%d.tape",
499 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
501 /* Testen, ob bereits eine Aufnahme existiert */
502 if ((file=fopen(filename,"r")))
507 if (!AreYouSure("Replace old tape ?",AYS_ASK))
511 if (!(file=fopen(filename,"w")))
513 fprintf(stderr,"%s: cannot save level recording file '%s'!\n",
518 fputs(LEVELREC_COOKIE,file); /* Formatkennung */
523 fputc((tape.random_seed >> 24) & 0xff,file);
524 fputc((tape.random_seed >> 16) & 0xff,file);
525 fputc((tape.random_seed >> 8) & 0xff,file);
526 fputc((tape.random_seed >> 0) & 0xff,file);
528 fputc((tape.date >> 24) & 0xff,file);
529 fputc((tape.date >> 16) & 0xff,file);
530 fputc((tape.date >> 8) & 0xff,file);
531 fputc((tape.date >> 0) & 0xff,file);
533 fputc((tape.length >> 24) & 0xff,file);
534 fputc((tape.length >> 16) & 0xff,file);
535 fputc((tape.length >> 8) & 0xff,file);
536 fputc((tape.length >> 0) & 0xff,file);
538 for(i=0;i<tape.length;i++)
540 fputc(tape.pos[i].joystickdata,file);
541 fputc(tape.pos[i].delay,file);
546 chmod(filename, LEVREC_PERMS);
549 AreYouSure("tape saved !",AYS_CONFIRM);
552 void SaveScore(int level_nr)
555 char filename[MAX_FILENAME];
558 sprintf(filename,"%s/%s/%s",
559 SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
561 if (!(file=fopen(filename,"r+")))
563 fprintf(stderr,"%s: cannot save score for level %d!\n",
569 SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
571 for(i=0;i<MAX_SCORE_ENTRIES;i++)
573 for(j=0;j<MAX_NAMELEN;j++)
574 fputc(highscore[i].Name[j],file);
575 fputc(highscore[i].Score / 256,file);
576 fputc(highscore[i].Score % 256,file);
581 void SavePlayerInfo(int mode)
584 char filename[MAX_FILENAME];
585 char cookie[MAX_FILENAME];
587 struct PlayerInfo default_player;
590 if (mode==PLAYER_LEVEL)
591 sprintf(filename,"%s/%s/%s",
592 NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
594 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
596 if (!(file=fopen(filename,"r+")))
598 fprintf(stderr,"%s: cannot save player information '%s'!\n",
603 ignored = fgets(cookie,NAMES_COOKIE_LEN,file);
604 if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
606 fprintf(stderr,"%s: wrong format of names file '%s'!\n",
614 for(i=0;i<MAX_NAMELEN;i++)
615 default_player.login_name[i] = fgetc(file);
616 for(i=0;i<MAX_NAMELEN;i++)
617 default_player.alias_name[i] = fgetc(file);
618 default_player.handicap = fgetc(file);
619 default_player.setup = (fgetc(file)<<8) | fgetc(file);
620 default_player.leveldir_nr = fgetc(file);
622 if (feof(file)) /* Spieler noch nicht in Liste enthalten */
624 else /* prüfen, ob Spieler in Liste enthalten */
625 if (!strncmp(default_player.login_name,player.login_name,MAX_NAMELEN-1))
627 fseek(file,-(2*MAX_NAMELEN+1+2+1),SEEK_CUR);
632 for(i=0;i<MAX_NAMELEN;i++)
633 fputc(player.login_name[i],file);
634 for(i=0;i<MAX_NAMELEN;i++)
635 fputc(player.alias_name[i],file);
636 fputc(player.handicap,file);
637 fputc(player.setup / 256,file);
638 fputc(player.setup % 256,file);
639 fputc(player.leveldir_nr,file);
644 void GetPlayerConfig()
646 int old_joystick_nr = joystick_nr;
648 if (sound_status==SOUND_OFF)
649 player.setup &= ~SETUP_SOUND;
650 if (!sound_loops_allowed)
652 player.setup &= ~SETUP_SOUND_LOOPS;
653 player.setup &= ~SETUP_SOUND_MUSIC;
656 sound_on = SETUP_SOUND_ON(player.setup);
657 sound_loops_on = SETUP_SOUND_LOOPS_ON(player.setup);
658 sound_music_on = SETUP_SOUND_MUSIC_ON(player.setup);
659 toons_on = SETUP_TOONS_ON(player.setup);
660 direct_draw_on = SETUP_DIRECT_DRAW_ON(player.setup);
661 fading_on = SETUP_FADING_ON(player.setup);
662 autorecord_on = SETUP_RECORD_EACH_GAME_ON(player.setup);
663 joystick_nr = SETUP_2ND_JOYSTICK_ON(player.setup);
665 if (joystick_nr != old_joystick_nr)
668 close(joystick_device);
677 Dynamite = Score = 0;
678 Gems = level.edelsteine;
679 Key[0] = Key[1] = Key[2] = Key[3] = FALSE;
681 TimeLeft = level.time;
683 CheckExploding = FALSE;
684 LevelSolved = GameOver = SiebAktiv = FALSE;
689 TapeStartRecording();
690 else if (tape.playing)
693 DigField(0,0,DF_NO_PUSH);
696 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
699 MovPos[x][y]=MovDir[x][y]=MovDelay[x][y]=0;
700 Store[x][y]=Store2[x][y]=Frame[x][y]=0;
706 Feld[x][y] = EL_LEERRAUM;
711 Feld[x][y] = EL_LEERRAUM;
714 if (x<lev_fieldx-1 && Feld[x+1][y]==EL_SALZSAEURE)
715 Feld[x][y] = EL_BADEWANNE1;
716 else if (x>0 && Feld[x-1][y]==EL_SALZSAEURE)
717 Feld[x][y] = EL_BADEWANNE2;
718 else if (y>0 && Feld[x][y-1]==EL_BADEWANNE1)
719 Feld[x][y] = EL_BADEWANNE3;
720 else if (y>0 && Feld[x][y-1]==EL_SALZSAEURE)
721 Feld[x][y] = EL_BADEWANNE4;
722 else if (y>0 && Feld[x][y-1]==EL_BADEWANNE2)
723 Feld[x][y] = EL_BADEWANNE5;
749 scroll_x = scroll_y = -1;
752 (JX<=lev_fieldx-MIDPOSX ? JX-MIDPOSX : lev_fieldx-SCR_FIELDX+1);
755 (JY<=lev_fieldy-MIDPOSY ? JY-MIDPOSY : lev_fieldy-SCR_FIELDY+1);
758 DrawLevelElement(JX,JY,EL_SPIELFIGUR);
761 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
762 DOOR_GFX_PAGEX5,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
763 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
764 DrawTextExt(pix[PIX_DB_DOOR],gc,
765 DOOR_GFX_PAGEX1+XX_LEVEL,DOOR_GFX_PAGEY1+YY_LEVEL,
766 int2str(level_nr,2),FS_SMALL,FC_YELLOW);
767 DrawTextExt(pix[PIX_DB_DOOR],gc,
768 DOOR_GFX_PAGEX1+XX_EMERALDS,DOOR_GFX_PAGEY1+YY_EMERALDS,
769 int2str(Gems,3),FS_SMALL,FC_YELLOW);
770 DrawTextExt(pix[PIX_DB_DOOR],gc,
771 DOOR_GFX_PAGEX1+XX_DYNAMITE,DOOR_GFX_PAGEY1+YY_DYNAMITE,
772 int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
773 DrawTextExt(pix[PIX_DB_DOOR],gc,
774 DOOR_GFX_PAGEX1+XX_SCORE,DOOR_GFX_PAGEY1+YY_SCORE,
775 int2str(Score,5),FS_SMALL,FC_YELLOW);
776 DrawTextExt(pix[PIX_DB_DOOR],gc,
777 DOOR_GFX_PAGEX1+XX_TIME,DOOR_GFX_PAGEY1+YY_TIME,
778 int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
780 DrawGameButton(BUTTON_GAME_STOP);
781 DrawGameButton(BUTTON_GAME_PAUSE);
782 DrawGameButton(BUTTON_GAME_PLAY);
783 DrawSoundDisplay(BUTTON_SOUND_MUSIC | (BUTTON_ON * sound_music_on));
784 DrawSoundDisplay(BUTTON_SOUND_LOOPS | (BUTTON_ON * sound_loops_on));
785 DrawSoundDisplay(BUTTON_SOUND_SOUND | (BUTTON_ON * sound_on));
786 XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
787 DX+GAME_CONTROL_XPOS,DY+GAME_CONTROL_YPOS,
788 GAME_CONTROL_XSIZE,2*GAME_CONTROL_YSIZE,
789 DOOR_GFX_PAGEX1+GAME_CONTROL_XPOS,
790 DOOR_GFX_PAGEY1+GAME_CONTROL_YPOS);
792 OpenDoor(DOOR_OPEN_1);
795 PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
797 XAutoRepeatOff(display);
800 void InitMovDir(int x, int y)
802 int i, element = Feld[x][y];
803 static int xy[4][2] =
810 static int direction[2][4] =
812 MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN,
813 MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP
822 Feld[x][y] = EL_KAEFER;
823 MovDir[x][y] = direction[0][element-EL_KAEFER_R];
829 Feld[x][y] = EL_FLIEGER;
830 MovDir[x][y] = direction[0][element-EL_FLIEGER_R];
836 Feld[x][y] = EL_PACMAN;
837 MovDir[x][y] = direction[0][element-EL_PACMAN_R];
840 MovDir[x][y] = 1<<RND(4);
841 if (element!=EL_KAEFER && element!=EL_FLIEGER)
851 if (!IN_LEV_FIELD(x1,y1) || !IS_FREE(x1,y1))
853 if (element==EL_KAEFER)
855 MovDir[x][y] = direction[0][i];
858 else if (element==EL_FLIEGER)
860 MovDir[x][y] = direction[1][i];
872 int bumplevel = FALSE;
875 PlaySoundExt(SND_SIRR,PSND_MAX_VOLUME,PSND_MAX_RIGHT,PSND_LOOP);
879 for(;TimeLeft>=0;TimeLeft--)
882 PlaySoundStereo(SND_SIRR,PSND_MAX_RIGHT);
883 if (TimeLeft && !(TimeLeft % 10))
884 RaiseScore(level.score[SC_ZEITBONUS]);
885 DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
898 CloseDoor(DOOR_CLOSE_1);
900 if (level_nr==player.handicap &&
901 level_nr<leveldir[leveldir_nr].num_ready)
905 SavePlayerInfo(PLAYER_LEVEL);
908 if ((hi_pos=NewHiScore())>=0)
910 game_status = HALLOFFAME;
911 DrawHallOfFame(hi_pos);
912 if (bumplevel && TAPE_IS_EMPTY(tape))
917 game_status = MAINMENU;
918 if (bumplevel && TAPE_IS_EMPTY(tape))
932 if (!strcmp(player.alias_name,EMPTY_ALIAS) ||
933 Score<highscore[MAX_SCORE_ENTRIES-1].Score)
936 for(k=0;k<MAX_SCORE_ENTRIES;k++)
938 if (Score>highscore[k].Score) /* Spieler kommt in Highscore-Liste */
940 if (k<MAX_SCORE_ENTRIES-1)
942 int m = MAX_SCORE_ENTRIES-1;
945 for(l=k;l<MAX_SCORE_ENTRIES;l++)
946 if (!strcmp(player.alias_name,highscore[l].Name))
948 if (m==k) /* Spieler überschreibt seine alte Position */
954 strcpy(highscore[l].Name,highscore[l-1].Name);
955 highscore[l].Score = highscore[l-1].Score;
962 sprintf(highscore[k].Name,"%s",player.alias_name);
963 highscore[k].Score = Score;
970 else if (!strcmp(player.alias_name,highscore[k].Name))
971 break; /* Spieler schon mit besserer Punktzahl in der Liste */
980 void InitMovingField(int x, int y, int direction)
982 int newx = x + (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
983 int newy = y + (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
986 MovDir[x][y] = direction;
987 MovDir[newx][newy] = direction;
988 if (Feld[newx][newy]==EL_LEERRAUM)
989 Feld[newx][newy] = EL_BLOCKED;
992 void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
994 int direction = MovDir[x][y];
995 int newx = x + (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
996 int newy = y + (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
1002 void Blocked2Moving(int x, int y, int *comes_from_x, int *comes_from_y)
1004 int oldx = x, oldy = y;
1005 int direction = MovDir[x][y];
1007 if (direction==MV_LEFT)
1009 else if (direction==MV_RIGHT)
1011 else if (direction==MV_UP)
1013 else if (direction==MV_DOWN)
1016 *comes_from_x = oldx;
1017 *comes_from_y = oldy;
1020 int MovingOrBlocked2Element(int x, int y)
1022 int element = Feld[x][y];
1024 if (element==EL_BLOCKED)
1028 Blocked2Moving(x,y,&oldx,&oldy);
1029 return(Feld[oldx][oldy]);
1035 void RemoveMovingField(int x, int y)
1037 int oldx=x,oldy=y, newx=x,newy=y;
1039 if (Feld[x][y]!=EL_BLOCKED && !IS_MOVING(x,y))
1044 Moving2Blocked(x,y,&newx,&newy);
1045 if (Feld[newx][newy]!=EL_BLOCKED)
1048 else if (Feld[x][y]==EL_BLOCKED)
1050 Blocked2Moving(x,y,&oldx,&oldy);
1051 if (!IS_MOVING(oldx,oldy))
1055 Feld[oldx][oldy] = EL_LEERRAUM;
1056 Feld[newx][newy] = EL_LEERRAUM;
1057 MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
1058 MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
1059 DrawLevelField(oldx,oldy);
1060 DrawLevelField(newx,newy);
1063 void DrawDynamite(int x, int y)
1065 int phase = (48-MovDelay[x][y])/6;
1067 if (!IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1075 DrawGraphic(SCROLLX(x),SCROLLY(y),el2gfx(Store[x][y]));
1077 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
1079 else if (PLAYER(x,y))
1080 DrawGraphic(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
1082 if (Store[x][y] || PLAYER(x,y))
1083 DrawGraphicThruMask(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase);
1085 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase);
1088 void CheckDynamite(int x, int y)
1090 CheckExploding=TRUE;
1092 if (MovDelay[x][y]) /* neues Dynamit / in Wartezustand */
1097 if (!(MovDelay[x][y] % 6))
1100 PlaySoundLevel(x,y,SND_ZISCH);
1107 StopSound(SND_ZISCH);
1111 void Explode(int ex, int ey, int phase)
1114 int num_phase = 9, delay = 1;
1115 int last_phase = num_phase*delay;
1116 int half_phase = (num_phase/2)*delay;
1118 if (phase==0) /* Feld 'Store' initialisieren */
1120 int center_element = Feld[ex][ey];
1122 if (center_element==EL_BLOCKED)
1123 center_element = MovingOrBlocked2Element(ex,ey);
1125 for(y=ey-1;y<ey+2;y++) for(x=ex-1;x<ex+2;x++)
1127 int element = Feld[x][y];
1129 if (!IN_LEV_FIELD(x,y) || IS_MASSIV(element))
1132 if (element==EL_EXPLODING)
1133 element = Store2[x][y];
1135 if (PLAYER(ex,ey) || center_element==EL_KAEFER)
1136 Store[x][y] = ((x==ex && y==ey) ? EL_DIAMANT : EL_EDELSTEIN);
1137 else if (center_element==EL_MAMPFER)
1138 Store[x][y] = level.mampfer_inhalt[MampferNr][x-ex+1][y-ey+1];
1139 else if (Feld[x][y]==EL_ERZ_1)
1140 Store[x][y] = EL_EDELSTEIN;
1141 else if (Feld[x][y]==EL_ERZ_2)
1142 Store[x][y] = EL_DIAMANT;
1143 else if (!IS_PFORTE(Store[x][y]))
1144 Store[x][y] = EL_LEERRAUM;
1147 Store2[x][y] = element;
1149 RemoveMovingField(x,y);
1150 Feld[x][y] = EL_EXPLODING;
1151 MovDir[x][y] = MovPos[x][y] = 0;
1156 if (center_element==EL_MAMPFER)
1157 MampferNr = (MampferNr+1) % 4;
1168 Frame[x][y] = (phase<last_phase ? phase+1 : 0);
1170 if (phase==half_phase)
1172 int element = Store2[x][y];
1176 else if (element==EL_BOMBE ||
1177 element==EL_DYNAMIT ||
1178 element==EL_DYNAMIT_AUS ||
1181 Feld[x][y] = Store2[x][y];
1187 if (phase==last_phase)
1191 element = Feld[x][y] = Store[x][y];
1192 Store[x][y] = Store2[x][y] = 0;
1193 MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
1194 if (CAN_MOVE(element) || COULD_MOVE(element))
1196 DrawLevelField(x,y);
1198 else if (!(phase%delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1201 ErdreichAnbroeckeln(SCROLLX(x),SCROLLY(y));
1203 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EXPLOSION+(phase/delay-1));
1206 CheckExploding=TRUE;
1209 void Bang(int x, int y)
1211 int element = Feld[x][y];
1213 CheckExploding=TRUE;
1214 PlaySoundLevel(x,y,SND_ROAAAR);
1219 RaiseScore(level.score[SC_KAEFER]);
1222 RaiseScore(level.score[SC_FLIEGER]);
1225 RaiseScore(level.score[SC_MAMPFER]);
1228 RaiseScore(level.score[SC_ZOMBIE]);
1231 RaiseScore(level.score[SC_PACMAN]);
1240 void Blurb(int x, int y)
1242 int element = Feld[x][y];
1244 if (element!=EL_BLURB_LEFT && element!=EL_BLURB_RIGHT) /* Anfang */
1246 PlaySoundLevel(x,y,SND_BLURB);
1247 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y) &&
1248 (!IN_LEV_FIELD(x-1,y-1) ||
1249 !CAN_FALL(MovingOrBlocked2Element(x-1,y-1))))
1251 Feld[x-1][y] = EL_BLURB_LEFT;
1253 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y) &&
1254 (!IN_LEV_FIELD(x+1,y-1) ||
1255 !CAN_FALL(MovingOrBlocked2Element(x+1,y-1))))
1257 Feld[x+1][y] = EL_BLURB_RIGHT;
1262 int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT);
1264 CheckExploding=TRUE;
1266 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1269 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1272 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1273 DrawGraphic(SCROLLX(x),SCROLLY(y),graphic+4-MovDelay[x][y]);
1275 if (!MovDelay[x][y])
1277 Feld[x][y] = EL_LEERRAUM;
1278 DrawLevelField(x,y);
1284 void Impact(int x, int y)
1286 BOOL lastline = (y==lev_fieldy-1);
1287 BOOL object_hit = FALSE;
1288 int element = Feld[x][y];
1290 /* Element darunter berührt? */
1292 object_hit = (!IS_FREE(x,y+1) && (!IS_MOVING(x,y+1) ||
1293 MovDir[x][y+1]!=MV_DOWN ||
1294 MovPos[x][y+1]<=TILEY/2));
1296 /* Auftreffendes Element fällt in Salzsäure */
1297 if (!lastline && Feld[x][y+1]==EL_SALZSAEURE)
1303 /* Auftreffendes Element ist Bombe */
1304 if (element==EL_BOMBE && (lastline || object_hit))
1310 /* Auftreffendes Element ist Säuretropfen */
1311 if (element==EL_TROPFEN && (lastline || object_hit))
1313 if (object_hit && PLAYER(x,y+1))
1316 Feld[x][y] = EL_AMOEBING2;
1320 /* Welches Element kriegt was auf die Rübe? */
1321 if (!lastline && object_hit)
1323 int smashed = Feld[x][y+1];
1330 else if (element==EL_FELSBROCKEN)
1332 if (IS_ENEMY(MovingOrBlocked2Element(x,y+1)))
1337 else if (!IS_MOVING(x,y+1))
1339 if (smashed==EL_BOMBE)
1344 else if (smashed==EL_KOKOSNUSS)
1346 Feld[x][y+1] = EL_CRACKINGNUT;
1347 PlaySoundLevel(x,y,SND_KNACK);
1348 RaiseScore(level.score[SC_KOKOSNUSS]);
1351 else if (smashed==EL_DIAMANT)
1353 Feld[x][y+1] = EL_LEERRAUM;
1354 PlaySoundLevel(x,y,SND_QUIRK);
1361 /* Kein Geräusch beim Durchqueren des Siebes */
1362 if (!lastline && Feld[x][y+1]==EL_SIEB_LEER)
1365 /* Geräusch beim Auftreffen */
1366 if (lastline || object_hit)
1379 case EL_FELSBROCKEN:
1383 case EL_SCHLUESSEL1:
1384 case EL_SCHLUESSEL2:
1385 case EL_SCHLUESSEL3:
1386 case EL_SCHLUESSEL4:
1395 PlaySoundLevel(x,y,sound);
1399 void TurnRound(int x, int y)
1401 int element = Feld[x][y];
1402 int direction = MovDir[x][y];
1404 if (element==EL_KAEFER)
1406 TestIfBadThingHitsOtherBadThing(x,y);
1408 if (MovDir[x][y]==MV_LEFT)
1410 if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1))
1412 else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y))
1413 MovDir[x][y]=MV_DOWN;
1415 else if (MovDir[x][y]==MV_RIGHT)
1417 if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1))
1418 MovDir[x][y]=MV_DOWN;
1419 else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y))
1422 else if (MovDir[x][y]==MV_UP)
1424 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y))
1425 MovDir[x][y]=MV_RIGHT;
1426 else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1))
1427 MovDir[x][y]=MV_LEFT;
1429 else if (MovDir[x][y]==MV_DOWN)
1431 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y))
1432 MovDir[x][y]=MV_LEFT;
1433 else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1))
1434 MovDir[x][y]=MV_RIGHT;
1437 if (direction!=MovDir[x][y])
1440 else if (element==EL_FLIEGER)
1442 TestIfBadThingHitsOtherBadThing(x,y);
1444 if (MovDir[x][y]==MV_LEFT)
1446 if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1))
1447 MovDir[x][y]=MV_DOWN;
1448 else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y))
1451 else if (MovDir[x][y]==MV_RIGHT)
1453 if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1))
1455 else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y))
1456 MovDir[x][y]=MV_DOWN;
1458 else if (MovDir[x][y]==MV_UP)
1460 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y))
1461 MovDir[x][y]=MV_LEFT;
1462 else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1))
1463 MovDir[x][y]=MV_RIGHT;
1465 else if (MovDir[x][y]==MV_DOWN)
1467 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y))
1468 MovDir[x][y]=MV_RIGHT;
1469 else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1))
1470 MovDir[x][y]=MV_LEFT;
1473 if (direction!=MovDir[x][y])
1476 else if (element==EL_MAMPFER)
1478 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
1480 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
1481 if (IN_LEV_FIELD(x,y-1) &&
1482 (IS_FREE(x,y-1) || Feld[x][y-1]==EL_DIAMANT) &&
1485 if (IN_LEV_FIELD(x,y+1) &&
1486 (IS_FREE(x,y+1) || Feld[x][y+1]==EL_DIAMANT) &&
1488 MovDir[x][y]=MV_DOWN;
1490 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
1492 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
1493 if (IN_LEV_FIELD(x-1,y) &&
1494 (IS_FREE(x-1,y) || Feld[x-1][y]==EL_DIAMANT) &&
1496 MovDir[x][y]=MV_LEFT;
1497 if (IN_LEV_FIELD(x+1,y) &&
1498 (IS_FREE(x+1,y) || Feld[x+1][y]==EL_DIAMANT) &&
1500 MovDir[x][y]=MV_RIGHT;
1503 MovDelay[x][y]=8+8*RND(3);
1505 else if (element==EL_PACMAN)
1507 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
1509 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
1510 if (IN_LEV_FIELD(x,y-1) &&
1511 (IS_FREE(x,y-1) || IS_AMOEBOID(Feld[x][y-1])) &&
1514 if (IN_LEV_FIELD(x,y+1) &&
1515 (IS_FREE(x,y+1) || IS_AMOEBOID(Feld[x][y+1])) &&
1517 MovDir[x][y]=MV_DOWN;
1519 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
1521 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
1522 if (IN_LEV_FIELD(x-1,y) &&
1523 (IS_FREE(x-1,y) || IS_AMOEBOID(Feld[x-1][y])) &&
1525 MovDir[x][y]=MV_LEFT;
1526 if (IN_LEV_FIELD(x+1,y) &&
1527 (IS_FREE(x+1,y) || IS_AMOEBOID(Feld[x+1][y])) &&
1529 MovDir[x][y]=MV_RIGHT;
1532 MovDelay[x][y]=3+RND(20);
1534 else if (element==EL_ZOMBIE)
1536 int attr_x = JX, attr_y = JY;
1544 MovDir[x][y]=MV_NO_MOVING;
1546 MovDir[x][y]|=MV_LEFT;
1548 MovDir[x][y]|=MV_RIGHT;
1550 MovDir[x][y]|=MV_UP;
1552 MovDir[x][y]|=MV_DOWN;
1553 if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
1554 MovDir[x][y] &= (RND(2) ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
1556 MovDelay[x][y] = 8+8*RND(2);
1560 void StartMoving(int x, int y)
1562 int element = Feld[x][y];
1567 if (CAN_FALL(element) && y<lev_fieldy-1)
1569 if (element==EL_MORAST_VOLL)
1573 InitMovingField(x,y,MV_DOWN);
1574 Feld[x][y] = EL_FELSBROCKEN;
1575 Store[x][y] = EL_MORAST_LEER;
1577 else if (Feld[x][y+1]==EL_MORAST_LEER)
1581 if (!MovDelay[x][y])
1582 MovDelay[x][y] = 16;
1591 Feld[x][y] = EL_MORAST_LEER;
1592 Feld[x][y+1] = EL_MORAST_VOLL;
1595 else if (element==EL_FELSBROCKEN && Feld[x][y+1]==EL_MORAST_LEER)
1597 InitMovingField(x,y,MV_DOWN);
1598 Store[x][y] = EL_MORAST_VOLL;
1600 else if (element==EL_SIEB_VOLL)
1604 InitMovingField(x,y,MV_DOWN);
1605 Feld[x][y] = EL_CHANGED(Store2[x][y]);
1606 Store[x][y] = EL_SIEB_LEER;
1609 else if (CAN_CHANGE(element) && Feld[x][y+1]==EL_SIEB_LEER)
1611 InitMovingField(x,y,MV_DOWN);
1612 Store[x][y] = EL_SIEB_VOLL;
1613 Store2[x][y+1] = element;
1616 else if (CAN_SMASH(element) && Feld[x][y+1]==EL_SALZSAEURE)
1619 InitMovingField(x,y,MV_DOWN);
1620 Store[x][y] = EL_SALZSAEURE;
1622 else if (CAN_SMASH(element) && Feld[x][y+1]==EL_BLOCKED)
1626 else if (IS_FREE(x,y+1))
1628 InitMovingField(x,y,MV_DOWN);
1630 else if (element==EL_TROPFEN)
1632 Feld[x][y] = EL_AMOEBING2;
1634 else if (SLIPPERY(Feld[x][y+1]) && !Store[x][y+1])
1636 int left = (x>0 && IS_FREE(x-1,y) &&
1637 (IS_FREE(x-1,y+1) || Feld[x-1][y+1]==EL_SALZSAEURE));
1638 int right = (x<lev_fieldx-1 && IS_FREE(x+1,y) &&
1639 (IS_FREE(x+1,y+1) || Feld[x+1][y+1]==EL_SALZSAEURE));
1644 left = !(right=RND(2));
1645 InitMovingField(x,y,left ? MV_LEFT : MV_RIGHT);
1649 else if (CAN_MOVE(element))
1655 if (!MovDelay[x][y]) /* neuer Schritt / noch nicht gewartet */
1657 if (element==EL_ZOMBIE || element==EL_KAEFER || element==EL_FLIEGER)
1660 if (MovDelay[x][y] && (element==EL_KAEFER || element==EL_FLIEGER))
1661 DrawLevelField(x,y);
1665 if (MovDelay[x][y]) /* neuer Schritt / in Wartezustand */
1669 if (element==EL_ZOMBIE || element==EL_MAMPFER)
1671 int phase = MovDelay[x][y] % 8;
1676 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1677 DrawGraphic(SCROLLX(x),SCROLLY(y),
1678 el2gfx(element)+phase);
1680 if (element==EL_MAMPFER && MovDelay[x][y]%4==3)
1681 PlaySoundLevel(x,y,SND_NJAM);
1688 if (element==EL_KAEFER)
1690 PlaySoundLevel(x,y,SND_KLAPPER);
1692 else if (element==EL_FLIEGER)
1694 PlaySoundLevel(x,y,SND_ROEHR);
1697 /* neuer Schritt / Wartezustand beendet */
1699 Moving2Blocked(x,y,&newx,&newy); /* wohin soll's gehen? */
1701 if (PLAYER(newx,newy)) /* Spieler erwischt */
1707 else if (element==EL_MAMPFER && IN_LEV_FIELD(newx,newy) &&
1708 Feld[newx][newy]==EL_DIAMANT)
1710 Feld[newx][newy] = EL_LEERRAUM;
1711 DrawLevelField(newx,newy);
1713 else if (element==EL_PACMAN && IN_LEV_FIELD(newx,newy) &&
1714 IS_AMOEBOID(Feld[newx][newy]))
1716 Feld[newx][newy] = EL_LEERRAUM;
1717 DrawLevelField(newx,newy);
1719 else if (element==EL_ZOMBIE && IN_LEV_FIELD(newx,newy) &&
1720 MovDir[x][y]==MV_DOWN && Feld[newx][newy]==EL_SALZSAEURE)
1723 Store[x][y] = EL_SALZSAEURE;
1725 else if (!IN_LEV_FIELD(newx,newy) || !IS_FREE(newx,newy))
1726 { /* gegen Wand gelaufen */
1728 DrawLevelField(x,y);
1732 InitMovingField(x,y,MovDir[x][y]);
1736 ContinueMoving(x,y);
1739 void ContinueMoving(int x, int y)
1741 int element = Feld[x][y];
1742 int direction = MovDir[x][y];
1743 int dx = (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
1744 int dy = (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
1745 int horiz_move = (dx!=0);
1746 int newx = x + dx, newy = y + dy;
1747 int step = (horiz_move ? dx : dy)*TILEX/4;
1749 if (CAN_FALL(element) && horiz_move)
1751 else if (element==EL_TROPFEN)
1753 else if (Store[x][y]==EL_MORAST_VOLL || Store[x][y]==EL_MORAST_LEER)
1756 MovPos[x][y] += step;
1758 if (ABS(MovPos[x][y])>=TILEX) /* Zielfeld erreicht */
1760 Feld[x][y]=EL_LEERRAUM;
1761 Feld[newx][newy]=element;
1763 if (Store[x][y]==EL_MORAST_VOLL)
1766 Feld[newx][newy] = EL_MORAST_VOLL;
1767 element = EL_MORAST_VOLL;
1769 else if (Store[x][y]==EL_MORAST_LEER)
1772 Feld[x][y] = EL_MORAST_LEER;
1774 else if (Store[x][y]==EL_SIEB_VOLL)
1777 Feld[newx][newy] = EL_SIEB_VOLL;
1778 element = EL_SIEB_VOLL;
1780 else if (Store[x][y]==EL_SIEB_LEER)
1782 Store[x][y] = Store2[x][y] = 0;
1783 Feld[x][y] = EL_SIEB_LEER;
1785 else if (Store[x][y]==EL_SALZSAEURE)
1788 Feld[newx][newy] = EL_SALZSAEURE;
1789 element = EL_SALZSAEURE;
1791 else if (Store[x][y]==EL_AMOEBE2)
1794 Feld[x][y] = EL_AMOEBE2;
1797 MovPos[x][y] = MovDir[x][y] = 0;
1799 if (!CAN_MOVE(element))
1800 MovDir[newx][newy] = 0;
1802 DrawLevelField(x,y);
1803 DrawLevelField(newx,newy);
1805 Stop[newx][newy]=TRUE;
1808 if (DONT_TOUCH(element)) /* Käfer oder Flieger */
1810 TestIfBadThingHitsHero();
1811 TestIfBadThingHitsOtherBadThing(newx,newy);
1814 if (CAN_SMASH(element) && direction==MV_DOWN &&
1815 (newy==lev_fieldy-1 || !IS_FREE(x,newy+1)))
1818 else /* noch in Bewegung */
1820 DrawLevelField(x,y);
1825 void AmoebeWaechst(int x, int y)
1827 static int sound_delay = 0;
1828 static int sound_delay_value = 0;
1830 CheckExploding=TRUE;
1832 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1836 if (DelayReached(&sound_delay,sound_delay_value))
1838 PlaySoundLevel(x,y,SND_AMOEBE);
1839 sound_delay_value = 30;
1843 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1846 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1847 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AMOEBING+3-MovDelay[x][y]);
1849 if (!MovDelay[x][y])
1851 Feld[x][y] = (Feld[x][y]==EL_AMOEBING2 ? EL_AMOEBE2 : EL_AMOEBE3);
1852 DrawLevelField(x,y);
1857 void AmoebeAbleger(int ax, int ay)
1860 int newax = ax, neway = ay;
1861 BOOL waiting_for_player = FALSE;
1862 static int xy[4][2] =
1870 CheckExploding=TRUE;
1872 if (!level.tempo_amoebe)
1874 Feld[ax][ay] = EL_AMOEBE1;
1875 DrawLevelField(ax,ay);
1879 if (!MovDelay[ax][ay]) /* neue Amoebe / noch nicht gewartet */
1880 MovDelay[ax][ay] = RND(33*20/(1+level.tempo_amoebe));
1882 if (MovDelay[ax][ay]) /* neue Amoebe / in Wartezustand */
1885 if (MovDelay[ax][ay])
1889 if (Feld[ax][ay]==EL_AMOEBE3)
1899 if (!IN_LEV_FIELD(x,y))
1903 Feld[x][y]==EL_ERDREICH || Feld[x][y]==EL_MORAST_LEER)
1909 else if (PLAYER(x,y))
1910 waiting_for_player = TRUE;
1913 if (newax==ax && neway==ay)
1915 if (Feld[ax][ay]==EL_AMOEBE3 && i==4 && !waiting_for_player)
1917 Feld[ax][ay] = EL_AMOEBE1;
1918 DrawLevelField(ax,ay);
1928 x = ax+xy[start][0];
1929 y = ay+xy[start][1];
1930 if (!IN_LEV_FIELD(x,y))
1934 Feld[x][y]==EL_ERDREICH || Feld[x][y]==EL_MORAST_LEER)
1940 if (newax==ax && neway==ay)
1944 if (Feld[ax][ay]==EL_AMOEBE3)
1945 Feld[newax][neway] = EL_AMOEBING3;
1946 else if (neway==lev_fieldy-1)
1947 Feld[newax][neway] = EL_AMOEBING2;
1948 else if (neway<=ay || !IS_FREE(newax,neway))
1949 Feld[newax][neway] = EL_TROPFEN;
1952 InitMovingField(ax,ay,MV_DOWN);
1953 Feld[ax][ay]=EL_TROPFEN;
1954 Store[ax][ay]=EL_AMOEBE2;
1955 ContinueMoving(ax,ay);
1959 DrawLevelField(newax,neway);
1962 void Life(int ax, int ay)
1965 static int life[4] = { 2,3,3,3 }; /* "Life"-Parameter */
1967 int element = Feld[ax][ay];
1969 CheckExploding=TRUE;
1974 if (!MovDelay[ax][ay]) /* neue Phase / noch nicht gewartet */
1975 MovDelay[ax][ay] = life_time;
1977 if (MovDelay[ax][ay]) /* neue Phase / in Wartezustand */
1980 if (MovDelay[ax][ay])
1984 for(y1=-1;y1<2;y1++) for(x1=-1;x1<2;x1++)
1986 int xx = ax+x1, yy = ay+y1;
1989 if (!IN_LEV_FIELD(xx,yy))
1992 for(y2=-1;y2<2;y2++) for(x2=-1;x2<2;x2++)
1994 int x = xx+x2, y = yy+y2;
1996 if (!IN_LEV_FIELD(x,y) || (x==xx && y==yy))
1999 if ((Feld[x][y]==element && !Stop[x][y]) ||
2000 (IS_FREE(x,y) && Stop[x][y]))
2004 if (xx==ax && yy==ay) /* mittleres Feld mit Amoebe */
2006 if (nachbarn<life[0] || nachbarn>life[1])
2008 Feld[xx][yy] = EL_LEERRAUM;
2010 DrawLevelField(xx,yy);
2011 Stop[xx][yy] = TRUE;
2014 else if (IS_FREE(xx,yy) || Feld[xx][yy]==EL_ERDREICH)
2015 { /* Randfeld ohne Amoebe */
2016 if (nachbarn>=life[2] && nachbarn<=life[3])
2018 Feld[xx][yy] = element;
2019 MovDelay[xx][yy] = (element==EL_LIFE ? 0 : life_time-1);
2021 DrawLevelField(xx,yy);
2022 Stop[xx][yy] = TRUE;
2028 void Ablenk(int x, int y)
2030 CheckExploding=TRUE;
2032 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2033 MovDelay[x][y] = 33*(level.dauer_ablenk/10);
2034 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2039 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2040 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_ABLENK+MovDelay[x][y]%4);
2041 if (!(MovDelay[x][y]%4))
2042 PlaySoundLevel(x,y,SND_MIEP);
2047 Feld[x][y]=EL_ABLENK_AUS;
2048 DrawLevelField(x,y);
2053 void Birne(int x, int y)
2055 CheckExploding=TRUE;
2057 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2058 MovDelay[x][y] = 400;
2060 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2065 if (!(MovDelay[x][y]%5))
2067 if (!(MovDelay[x][y]%10))
2068 Feld[x][y]=EL_ABLENK_EIN;
2070 Feld[x][y]=EL_ABLENK_AUS;
2071 DrawLevelField(x,y);
2072 Feld[x][y]=EL_ABLENK_EIN;
2078 Feld[x][y]=EL_ABLENK_AUS;
2079 DrawLevelField(x,y);
2084 void Blubber(int x, int y)
2086 CheckExploding=TRUE;
2088 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2089 MovDelay[x][y] = 20;
2091 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2096 blubber = MovDelay[x][y]/5;
2097 if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2098 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_GEBLUBBER+3-blubber);
2102 void NussKnacken(int x, int y)
2104 CheckExploding=TRUE;
2106 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2109 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2112 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2113 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_CRACKINGNUT+3-MovDelay[x][y]);
2115 if (!MovDelay[x][y])
2117 Feld[x][y] = EL_EDELSTEIN;
2118 DrawLevelField(x,y);
2123 void SiebAktivieren(int x, int y)
2125 CheckExploding=TRUE;
2129 if (SiebAktiv%2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2130 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_SIEB_VOLL+3-(SiebAktiv%8)/2);
2134 PlaySoundLevel(x,y,SND_MIEP);
2140 Feld[x][y] = EL_SIEB_TOT;
2141 DrawLevelField(x,y);
2145 void AusgangstuerPruefen(int x, int y)
2147 CheckExploding=TRUE;
2150 Feld[x][y] = EL_AUSGANG_ACT;
2153 void AusgangstuerOeffnen(int x, int y)
2155 CheckExploding=TRUE;
2157 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2158 MovDelay[x][y] = 20;
2160 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2165 tuer = MovDelay[x][y]/5;
2166 if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2167 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_ZU+3-tuer);
2169 if (!MovDelay[x][y])
2171 Feld[x][y] = EL_AUSGANG_AUF;
2172 DrawLevelField(x,y);
2177 int GameActions(int mx, int my, int button)
2179 static int time_delay=0, action_delay=0;
2182 if (TimeLeft>0 && DelayReached(&time_delay,100) && !tape.pausing)
2186 if (tape.recording || tape.playing)
2187 DrawVideoDisplay(VIDEO_STATE_TIME_ON,level.time-TimeLeft);
2190 PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT);
2192 DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
2199 Action = (CheckMoving || CheckExploding || SiebAktiv);
2202 if (Action && DelayReached(&action_delay,3))
2205 if (DelayReached(&action_delay,3))
2209 if (tape.pausing || (tape.playing && !TapePlayDelay()))
2211 else if (tape.recording)
2214 CheckMoving = CheckExploding = FALSE;
2215 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
2218 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
2220 element = Feld[x][y];
2222 if (element==EL_LEERRAUM || element==EL_ERDREICH)
2225 if (!IS_MOVING(x,y) && (CAN_FALL(element) || CAN_MOVE(element)))
2227 else if (IS_MOVING(x,y))
2228 ContinueMoving(x,y);
2229 else if (element==EL_DYNAMIT)
2231 else if (element==EL_EXPLODING)
2232 Explode(x,y,Frame[x][y]);
2233 else if (element==EL_AMOEBING2 || element==EL_AMOEBING3)
2235 else if (element==EL_AMOEBE2 || element==EL_AMOEBE3)
2237 else if (element==EL_LIFE || element==EL_LIFE_ASYNC)
2239 else if (element==EL_ABLENK_EIN)
2241 else if (element==EL_SALZSAEURE)
2243 else if (element==EL_BLURB_LEFT || element==EL_BLURB_RIGHT)
2245 else if (element==EL_CRACKINGNUT)
2247 else if (element==EL_AUSGANG_ZU)
2248 AusgangstuerPruefen(x,y);
2249 else if (element==EL_AUSGANG_ACT)
2250 AusgangstuerOeffnen(x,y);
2252 if (SiebAktiv && (element==EL_SIEB_LEER ||
2253 element==EL_SIEB_VOLL ||
2254 Store[x][y]==EL_SIEB_LEER))
2255 SiebAktivieren(x,y);
2261 if (CheckMoving || CheckExploding)
2268 void ScrollLevel(int dx, int dy)
2272 XCopyArea(display,drawto_field,drawto_field,gc,
2273 SX+TILEX*(dx==-1),SY+TILEY*(dy==-1),
2274 SXSIZE-TILEX*(dx!=0),SYSIZE-TILEY*(dy!=0),
2275 SX+TILEX*(dx==1),SY+TILEY*(dy==1));
2279 x = dx==1 ? 0 : SCR_FIELDX-1;
2280 for(y=0;y<SCR_FIELDY;y++)
2281 DrawScreenField(x,y);
2285 y = dy==1 ? 0 : SCR_FIELDY-1;
2286 for(x=0;x<SCR_FIELDY;x++)
2287 DrawScreenField(x,y);
2290 redraw_mask|=REDRAW_FIELD;
2293 BOOL MoveFigureOneStep(int dx, int dy)
2295 int oldJX,oldJY, newJX=JX+dx,newJY=JY+dy;
2300 return(MF_NO_ACTION);
2301 if (!IN_LEV_FIELD(newJX,newJY))
2302 return(MF_NO_ACTION);
2304 element = MovingOrBlocked2Element(newJX,newJY);
2306 if (DONT_GO_TO(element))
2308 if (element==EL_SALZSAEURE && dx==0 && dy==1)
2311 Feld[JX][JY] = EL_SPIELFIGUR;
2312 InitMovingField(JX,JY,MV_DOWN);
2313 Store[JX][JY] = EL_SALZSAEURE;
2314 ContinueMoving(JX,JY);
2316 PlaySoundLevel(JX,JY,SND_AUTSCH);
2317 PlaySoundLevel(JX,JY,SND_LACHEN);
2327 can_move = DigField(newJX,newJY,DF_DIG);
2328 if (can_move != MF_MOVING)
2336 if (Store[oldJX][oldJY])
2338 DrawGraphic(SCROLLX(oldJX),SCROLLY(oldJY),el2gfx(Store[oldJX][oldJY]));
2339 DrawGraphicThruMask(SCROLLX(oldJX),SCROLLY(oldJY),
2340 el2gfx(Feld[oldJX][oldJY]));
2342 else if (Feld[oldJX][oldJY]==EL_DYNAMIT)
2343 DrawDynamite(oldJX,oldJY);
2345 DrawLevelField(oldJX,oldJY);
2350 BOOL MoveFigure(int dx, int dy)
2352 static int move_delay = 0;
2353 int moved = MF_NO_ACTION;
2355 if (GameOver || (!dx && !dy))
2358 if (!DelayReached(&move_delay,10) && !tape.playing)
2361 if (moved |= MoveFigureOneStep(dx,0))
2362 moved |= MoveFigureOneStep(0,dy);
2365 moved |= MoveFigureOneStep(0,dy);
2366 moved |= MoveFigureOneStep(dx,0);
2369 if (moved & MF_MOVING)
2371 int old_scroll_x=scroll_x, old_scroll_y=scroll_y;
2373 if (scroll_x!=JX-MIDPOSX && JX>=MIDPOSX-1 && JX<=lev_fieldx-MIDPOSX)
2374 scroll_x = JX-MIDPOSX;
2375 if (scroll_y!=JY-MIDPOSY && JY>=MIDPOSY-1 && JY<=lev_fieldy-MIDPOSY)
2376 scroll_y = JY-MIDPOSY;
2378 if (scroll_x!=old_scroll_x || scroll_y!=old_scroll_y)
2379 ScrollLevel(old_scroll_x-scroll_x,old_scroll_y-scroll_y);
2381 if (Feld[JX][JY]==EL_LEERRAUM)
2382 DrawLevelElement(JX,JY,EL_SPIELFIGUR);
2384 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
2387 TestIfHeroHitsBadThing();
2397 void TestIfHeroHitsBadThing()
2399 int i, killx = JX,killy = JY;
2400 static int xy[4][2] =
2407 static int harmless[4] =
2421 if (!IN_LEV_FIELD(x,y))
2424 element = Feld[x][y];
2426 if (DONT_TOUCH(element))
2428 if (MovDir[x][y]==harmless[i])
2437 if (killx!=JX || killy!=JY)
2441 void TestIfBadThingHitsHero()
2443 TestIfHeroHitsBadThing();
2446 void TestIfBadThingHitsOtherBadThing(int badx, int bady)
2448 int i, killx=badx, killy=bady;
2449 static int xy[4][2] =
2463 if (!IN_LEV_FIELD(x,y))
2467 if (IS_AMOEBOID(element) || element==EL_LIFE ||
2468 element==EL_AMOEBING2 || element==EL_AMOEBING3 || element==EL_TROPFEN)
2476 if (killx!=badx || killy!=bady)
2485 if (IS_PFORTE(Feld[JX][JY]))
2486 Feld[JX][JY] = EL_LEERRAUM;
2488 PlaySoundLevel(JX,JY,SND_AUTSCH);
2489 PlaySoundLevel(JX,JY,SND_LACHEN);
2495 int DigField(int x, int y, int mode)
2497 int dx=x-JX, dy=y-JY;
2499 static int push_delay = 0;
2500 static int push_delay_value = 20;
2502 if (mode==DF_NO_PUSH)
2505 return(MF_NO_ACTION);
2509 return(MF_NO_ACTION);
2511 element = Feld[x][y];
2519 Feld[x][y]=EL_LEERRAUM;
2523 Feld[x][y]=EL_LEERRAUM;
2527 RaiseScore(level.score[SC_EDELSTEIN]);
2528 DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW);
2529 PlaySoundLevel(x,y,SND_PONG);
2532 Feld[x][y]=EL_LEERRAUM;
2537 RaiseScore(level.score[SC_DIAMANT]);
2538 DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW);
2539 PlaySoundLevel(x,y,SND_PONG);
2541 case EL_DYNAMIT_AUS:
2542 Feld[x][y]=EL_LEERRAUM;
2545 RaiseScore(level.score[SC_DYNAMIT]);
2546 DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
2547 PlaySoundLevel(x,y,SND_PONG);
2549 case EL_SCHLUESSEL1:
2550 case EL_SCHLUESSEL2:
2551 case EL_SCHLUESSEL3:
2552 case EL_SCHLUESSEL4:
2554 int key_nr = element-EL_SCHLUESSEL1;
2556 Feld[x][y] = EL_LEERRAUM;
2559 RaiseScore(level.score[SC_SCHLUESSEL]);
2560 DrawMiniGraphicExtHiRes(drawto,gc,
2561 DX_KEYS+key_nr*MINI_TILEX,DY_KEYS,
2562 GFX_SCHLUESSEL1+key_nr);
2563 DrawMiniGraphicExtHiRes(window,gc,
2564 DX_KEYS+key_nr*MINI_TILEX,DY_KEYS,
2565 GFX_SCHLUESSEL1+key_nr);
2566 PlaySoundLevel(x,y,SND_PONG);
2570 Feld[x][y]=EL_ABLENK_EIN;
2571 CheckExploding=TRUE;
2574 DrawLevelField(x,y);
2576 PlaySoundLevel(x,y,SND_DENG);
2580 case EL_FELSBROCKEN:
2584 return(MF_NO_ACTION);
2585 if (dy || !IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy]!=EL_LEERRAUM)
2586 return(MF_NO_ACTION);
2588 if (Counter() > push_delay+4*push_delay_value)
2589 push_delay = Counter();
2590 if (!DelayReached(&push_delay,push_delay_value) && !tape.playing)
2591 return(MF_NO_ACTION);
2593 Feld[x][y] = EL_LEERRAUM;
2594 Feld[x+dx][y+dy] = element;
2595 push_delay_value = 10+RND(30);
2597 DrawLevelField(x+dx,y+dy);
2598 if (element==EL_FELSBROCKEN)
2599 PlaySoundLevel(x+dx,y+dy,SND_PUSCH);
2600 else if (element==EL_KOKOSNUSS)
2601 PlaySoundLevel(x+dx,y+dy,SND_KNURK);
2603 PlaySoundLevel(x+dx,y+dy,SND_KLOPF);
2609 if (!Key[element-EL_PFORTE1])
2610 return(MF_NO_ACTION);
2616 if (!Key[element-EL_PFORTE1X])
2617 return(MF_NO_ACTION);
2620 case EL_AUSGANG_ACT:
2621 /* Tür ist (noch) nicht offen! */
2622 return(MF_NO_ACTION);
2624 case EL_AUSGANG_AUF:
2625 if (mode==DF_SNAP || Gems>0)
2626 return(MF_NO_ACTION);
2628 PlaySoundLevel(x,y,SND_BUING);
2631 return(MF_NO_ACTION);
2638 BOOL SnapField(int dx, int dy)
2640 int x = JX+dx, y = JY+dy;
2641 static int snapped = FALSE;
2643 if (GameOver || !IN_LEV_FIELD(x,y))
2655 if (!DigField(x,y,DF_SNAP))
2659 DrawLevelField(x,y);
2665 BOOL PlaceBomb(void)
2667 if (Dynamite==0 || Feld[JX][JY]==EL_DYNAMIT)
2670 if (Feld[JX][JY]!=EL_LEERRAUM)
2671 Store[JX][JY] = Feld[JX][JY];
2672 Feld[JX][JY] = EL_DYNAMIT;
2673 MovDelay[JX][JY] = 48;
2675 DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
2676 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
2677 CheckExploding = TRUE;
2681 void PlaySoundLevel(int x, int y, int sound_nr)
2683 int sx = SCROLLX(x), sy = SCROLLY(y);
2686 if (!sound_loops_on && IS_LOOP_SOUND(sound_nr))
2689 if (!IN_LEV_FIELD(x,y))
2692 volume = PSND_MAX_VOLUME;
2693 stereo = (sx-SCR_FIELDX/2)*12;
2695 if (!IN_SCR_FIELD(sx,sy))
2697 if (sx<0 || sx>=SCR_FIELDX)
2698 volume = PSND_MAX_VOLUME - 2*ABS(sx-SCR_FIELDX/2);
2700 volume = PSND_MAX_VOLUME - 2*ABS(sy-SCR_FIELDY/2);
2703 PlaySoundExt(sound_nr, volume, stereo, PSND_NO_LOOP);
2706 void RaiseScore(int value)
2709 DrawText(DX_SCORE,DY_SCORE,int2str(Score,5),FS_SMALL,FC_YELLOW);
2713 void TapeInitRecording()
2715 time_t zeit1 = time(NULL);
2716 struct tm *zeit2 = localtime(&zeit1);
2718 if (tape.recording || tape.playing)
2721 tape.level_nr = level_nr;
2722 tape.recording = TRUE;
2723 tape.pausing = TRUE;
2725 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday;
2727 DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_ON,0);
2728 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2729 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2732 void TapeStartRecording()
2736 tape.pos[tape.counter].delay = 0;
2737 tape.recording = TRUE;
2738 tape.playing = FALSE;
2739 tape.pausing = FALSE;
2740 tape.random_seed = InitRND(NEW_RANDOMIZE);
2741 DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_OFF,0);
2744 void TapeStopRecording()
2746 if (!tape.recording)
2749 tape.length = tape.counter;
2750 tape.recording = FALSE;
2751 tape.pausing = FALSE;
2752 DrawVideoDisplay(VIDEO_STATE_REC_OFF,0);
2757 void TapeRecordAction(int joy)
2759 if (!tape.recording || tape.pausing)
2762 if (tape.counter>=MAX_TAPELEN-1)
2764 TapeStopRecording();
2770 tape.pos[tape.counter].joystickdata = joy;
2772 tape.pos[tape.counter].delay = 0;
2776 void TapeRecordDelay()
2778 if (!tape.recording || tape.pausing)
2781 if (tape.counter>=MAX_TAPELEN)
2783 TapeStopRecording();
2787 tape.pos[tape.counter].delay++;
2789 if (tape.pos[tape.counter].delay>=255)
2791 tape.pos[tape.counter].joystickdata = 0;
2793 tape.pos[tape.counter].delay = 0;
2797 void TapeTogglePause()
2799 if (!tape.recording && !tape.playing)
2804 tape.pausing = FALSE;
2805 DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
2806 if (game_status==MAINMENU)
2807 HandleMainMenu(SX+16,SY+7*32+16,0,0,MB_MENU_CHOICE);
2811 tape.pausing = TRUE;
2812 DrawVideoDisplay(VIDEO_STATE_PAUSE_ON,0);
2816 void TapeInitPlaying()
2818 if (tape.recording || tape.playing || TAPE_IS_EMPTY(tape))
2821 tape.playing = TRUE;
2822 tape.pausing = TRUE;
2823 DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_ON,0);
2824 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2825 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2828 void TapeStartPlaying()
2833 tape.recording = FALSE;
2834 tape.playing = TRUE;
2835 tape.pausing = FALSE;
2836 InitRND(tape.random_seed);
2837 DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_OFF,0);
2840 void TapeStopPlaying()
2845 tape.playing = FALSE;
2846 tape.pausing = FALSE;
2847 DrawVideoDisplay(VIDEO_STATE_PLAY_OFF,0);
2850 int TapePlayAction()
2852 if (!tape.playing || tape.pausing)
2855 if (tape.counter>=tape.length)
2861 if (!tape.pos[tape.counter].delay)
2864 return(tape.pos[tape.counter-1].joystickdata);
2870 BOOL TapePlayDelay()
2872 if (!tape.playing || tape.pausing)
2875 if (tape.counter>=tape.length)
2881 if (tape.pos[tape.counter].delay)
2883 tape.pos[tape.counter].delay--;
2892 TapeStopRecording();
2894 DrawVideoDisplay(VIDEO_ALL_OFF,0);
2895 if (tape.date && tape.length)
2897 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2898 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2907 void DrawVideoDisplay(unsigned int state, unsigned int value)
2910 int part1 = 0, part2 = 1;
2911 int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
2912 static char *monatsname[12] =
2914 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
2915 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
2917 static int video_pos[10][2][4] =
2919 VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
2920 VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE,
2921 VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
2922 VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE,
2924 VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
2925 VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE,
2926 VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
2927 VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE,
2929 VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
2930 VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE,
2931 VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
2932 VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE,
2934 VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
2935 VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE,
2936 VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
2937 VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE,
2941 VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
2942 VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE,
2944 VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS,
2945 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2949 VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS,
2950 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2954 VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS,
2955 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2959 VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS,
2960 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2964 VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS,
2965 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2974 int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
2976 if (i%2) /* i ungerade => STATE_ON / PRESS_OFF */
2977 cx = DOOR_GFX_PAGEX4;
2979 cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */
2981 if (video_pos[pos][part1][0])
2982 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
2983 cx + video_pos[pos][part1][xpos],
2984 cy + video_pos[pos][part1][ypos],
2985 video_pos[pos][part1][xsize],
2986 video_pos[pos][part1][ysize],
2987 VX + video_pos[pos][part1][xpos],
2988 VY + video_pos[pos][part1][ypos]);
2989 if (video_pos[pos][part2][0])
2990 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
2991 cx + video_pos[pos][part2][xpos],
2992 cy + video_pos[pos][part2][ypos],
2993 video_pos[pos][part2][xsize],
2994 video_pos[pos][part2][ysize],
2995 VX + video_pos[pos][part2][xpos],
2996 VY + video_pos[pos][part2][ypos]);
3000 if (state & VIDEO_STATE_DATE_ON)
3002 int tag = value % 100;
3003 int monat = (value/100) % 100;
3004 int jahr = (value/10000);
3006 DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
3007 int2str(tag,2),FS_SMALL,FC_SPECIAL1);
3008 DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
3009 monatsname[monat],FS_SMALL,FC_SPECIAL1);
3010 DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
3011 int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
3014 if (state & VIDEO_STATE_TIME_ON)
3016 int min = value / 60;
3017 int sec = value % 60;
3019 DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
3020 int2str(min,2),FS_SMALL,FC_SPECIAL1);
3021 DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
3022 int2str(sec,2),FS_SMALL,FC_SPECIAL1);
3025 if (state & VIDEO_STATE_DATE)
3026 redraw_mask |= REDRAW_VIDEO_1;
3027 if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
3028 redraw_mask |= REDRAW_VIDEO_2;
3029 if (state & VIDEO_PRESS)
3030 redraw_mask |= REDRAW_VIDEO_3;
3033 void DrawSoundDisplay(unsigned int state)
3035 int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
3037 pos = (state & BUTTON_SOUND_MUSIC ? SOUND_BUTTON_MUSIC_XPOS :
3038 state & BUTTON_SOUND_LOOPS ? SOUND_BUTTON_LOOPS_XPOS :
3039 SOUND_BUTTON_SOUND_XPOS);
3041 if (state & BUTTON_ON)
3042 cy -= SOUND_BUTTON_YSIZE;
3044 if (state & BUTTON_PRESSED)
3045 cx = DOOR_GFX_PAGEX3;
3047 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3048 cx + pos,cy + SOUND_BUTTON_ANY_YPOS,
3049 SOUND_BUTTON_XSIZE,SOUND_BUTTON_YSIZE,
3050 DX + pos,DY + SOUND_BUTTON_ANY_YPOS);
3052 redraw_mask |= REDRAW_DOOR_1;
3055 void DrawGameButton(unsigned int state)
3057 int pos, cx = DOOR_GFX_PAGEX4, cy = -GAME_BUTTON_YSIZE;
3059 pos = (state & BUTTON_GAME_STOP ? GAME_BUTTON_STOP_XPOS :
3060 state & BUTTON_GAME_PAUSE ? GAME_BUTTON_PAUSE_XPOS :
3061 GAME_BUTTON_PLAY_XPOS);
3063 if (state & BUTTON_PRESSED)
3064 cx = DOOR_GFX_PAGEX3;
3066 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3067 cx + pos,cy + GAME_BUTTON_ANY_YPOS,
3068 GAME_BUTTON_XSIZE,GAME_BUTTON_YSIZE,
3069 DX + pos,DY + GAME_BUTTON_ANY_YPOS);
3071 redraw_mask |= REDRAW_DOOR_1;
3074 void DrawChooseButton(unsigned int state)
3076 int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
3078 pos = (state & BUTTON_OK ? OK_BUTTON_XPOS : NO_BUTTON_XPOS);
3080 if (state & BUTTON_PRESSED)
3081 cx = DOOR_GFX_PAGEX3;
3083 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3084 cx + pos,cy + OK_BUTTON_GFX_YPOS,
3085 OK_BUTTON_XSIZE,OK_BUTTON_YSIZE,
3086 DX + pos,DY + OK_BUTTON_YPOS);
3088 redraw_mask |= REDRAW_DOOR_1;
3091 void DrawConfirmButton(unsigned int state)
3093 int cx = DOOR_GFX_PAGEX4, cy = 0;
3095 if (state & BUTTON_PRESSED)
3096 cx = DOOR_GFX_PAGEX3;
3098 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3099 cx + CONFIRM_BUTTON_XPOS,cy + CONFIRM_BUTTON_GFX_YPOS,
3100 CONFIRM_BUTTON_XSIZE,CONFIRM_BUTTON_YSIZE,
3101 DX + CONFIRM_BUTTON_XPOS,DY + CONFIRM_BUTTON_YPOS);
3103 redraw_mask |= REDRAW_DOOR_1;