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];
86 sprintf(filename,"%s/%s",LEVEL_PATH,LEVDIR_FILENAME);
88 if (!(file=fopen(filename,"r")))
90 fprintf(stderr,"%s: cannot load level info '%s'!\n",progname,filename);
94 fscanf(file,"%s\n",cookie);
95 if (strcmp(cookie,LEVELDIR_COOKIE)) /* ungültiges Format? */
97 fprintf(stderr,"%s: wrong format of level info file!\n",progname);
104 for(i=0;i<MAX_LEVDIR_ENTRIES;i++)
106 fscanf(file,"%s",leveldir[i].filename);
107 fscanf(file,"%s",leveldir[i].name);
108 fscanf(file,"%d",&leveldir[i].num_ready);
109 fscanf(file,"%d",&leveldir[i].num_free);
118 fprintf(stderr,"%s: empty level info '%s'!\n",progname,filename);
123 void LoadLevel(int level_nr)
126 char filename[MAX_FILENAME];
127 char cookie[MAX_FILENAME];
130 sprintf(filename,"%s/%s/%d",
131 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
133 if (!(file=fopen(filename,"r")))
136 fprintf(stderr,"%s: cannot load level '%s'!\n",progname,filename);
141 fgets(cookie,LEVEL_COOKIE_LEN,file);
143 if (strcmp(cookie,LEVEL_COOKIE)) /* ungültiges Format? */
145 fprintf(stderr,"%s: wrong format of level file '%s'!\n",
154 lev_fieldx = level.fieldx = fgetc(file);
155 lev_fieldy = level.fieldy = fgetc(file);
157 level.time = (fgetc(file)<<8) | fgetc(file);
158 level.edelsteine = (fgetc(file)<<8) | fgetc(file);
159 for(i=0;i<MAX_LEVNAMLEN;i++)
160 level.name[i] = fgetc(file);
161 for(i=0;i<MAX_SC_ENTRIES;i++)
162 level.score[i] = fgetc(file);
166 level.mampfer_inhalt[i][x][y] = fgetc(file);
167 level.tempo_amoebe = fgetc(file);
168 level.dauer_sieb = fgetc(file);
169 level.dauer_ablenk = fgetc(file);
171 for(i=0;i<19;i++) /* Rest reserviert / Headergröße 80 Bytes */
174 for(y=0;y<lev_fieldy;y++)
175 for(x=0;x<lev_fieldx;x++)
176 Feld[x][y] = Ur[x][y] = fgetc(file);
180 if (level.time<=10) /* Mindestspieldauer */
185 lev_fieldx = level.fieldx = STD_LEV_FIELDX;
186 lev_fieldy = level.fieldy = STD_LEV_FIELDY;
189 level.edelsteine = 0;
190 strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
191 for(i=0;i<MAX_SC_ENTRIES;i++)
196 level.mampfer_inhalt[i][x][y] = EL_FELSBROCKEN;
197 level.tempo_amoebe = 10;
198 level.dauer_sieb = 10;
199 level.dauer_ablenk = 10;
201 for(y=0;y<STD_LEV_FIELDY;y++)
202 for(x=0;x<STD_LEV_FIELDX;x++)
203 Feld[x][y] = Ur[x][y] = EL_ERDREICH;
204 Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
205 Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
206 Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
210 void LoadLevelTape(int level_nr)
213 char filename[MAX_FILENAME];
214 char cookie[MAX_FILENAME];
217 sprintf(filename,"%s/%s/%d.tape",
218 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
220 if ((file=fopen(filename,"r")))
222 fgets(cookie,LEVELREC_COOKIE_LEN,file);
224 if (strcmp(cookie,LEVELREC_COOKIE)) /* ungültiges Format? */
226 fprintf(stderr,"%s: wrong format of level recording file '%s'!\n",
237 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
239 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
241 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
243 tape.level_nr = level_nr;
245 tape.recording = FALSE;
246 tape.playing = FALSE;
247 tape.pausing = FALSE;
249 for(i=0;i<tape.length;i++)
253 tape.pos[i].joystickdata = fgetc(file);
254 tape.pos[i].delay = fgetc(file);
259 if (i != tape.length)
260 fprintf(stderr,"%s: level recording file '%s' corrupted!\n",
268 void LoadScore(int level_nr)
271 char filename[MAX_FILENAME];
272 char cookie[MAX_FILENAME];
275 sprintf(filename,"%s/%s/%s",
276 SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
278 if (!(file=fopen(filename,"r")))
280 if (!CreateNewScoreFile())
282 fprintf(stderr,"%s: cannot create score file '%s'!\n",
285 else if (!(file=fopen(filename,"r")))
287 fprintf(stderr,"%s: cannot load score for level %d!\n",
294 fgets(cookie,SCORE_COOKIE_LEN,file);
295 if (strcmp(cookie,SCORE_COOKIE)) /* ungültiges Format? */
297 fprintf(stderr,"%s: wrong format of score file!\n",progname);
306 SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
308 for(i=0;i<MAX_SCORE_ENTRIES;i++)
310 for(j=0;j<MAX_NAMELEN;j++)
311 highscore[i].Name[j] = fgetc(file);
312 highscore[i].Score = (fgetc(file)<<8) | fgetc(file);
318 for(i=0;i<MAX_SCORE_ENTRIES;i++)
320 strcpy(highscore[i].Name,EMPTY_ALIAS);
321 highscore[i].Score = 0;
326 void LoadPlayerInfo(int mode)
329 char filename[MAX_FILENAME];
330 char cookie[MAX_FILENAME];
332 char *login_name = GetLoginName();
333 struct PlayerInfo default_player, new_player;
335 if (mode==PLAYER_LEVEL)
336 sprintf(filename,"%s/%s/%s",
337 NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
339 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
341 for(i=0;i<MAX_NAMELEN;i++)
342 default_player.login_name[i] = default_player.alias_name[i] = 0;
343 strncpy(default_player.login_name,login_name,MAX_NAMELEN-1);
344 strncpy(default_player.alias_name,login_name,MAX_NAMELEN-1);
345 default_player.handicap = 0;
346 default_player.setup = DEFAULT_SETUP;
347 default_player.leveldir_nr = 0;
349 new_player = default_player;
351 if (!(file=fopen(filename,"r")))
353 if (!CreateNewNamesFile(mode))
355 fprintf(stderr,"%s: cannot create names file '%s'!\n",
358 else if (!(file=fopen(filename,"r")))
360 fprintf(stderr,"%s: cannot load player information '%s'!\n",
367 fgets(cookie,NAMES_COOKIE_LEN,file);
368 if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
370 fprintf(stderr,"%s: wrong format of names file '%s'!\n",
379 player = default_player;
380 level_nr = default_player.handicap;
386 for(i=0;i<MAX_NAMELEN;i++)
387 new_player.login_name[i] = fgetc(file);
388 for(i=0;i<MAX_NAMELEN;i++)
389 new_player.alias_name[i] = fgetc(file);
390 new_player.handicap = fgetc(file);
391 new_player.setup = (fgetc(file)<<8) | fgetc(file);
392 new_player.leveldir_nr = fgetc(file);
394 if (feof(file)) /* Spieler noch nicht in Liste enthalten */
396 new_player = default_player;
399 if (!(file=fopen(filename,"a")))
401 fprintf(stderr,"%s: cannot append new player to names file '%s'!\n",
406 for(i=0;i<MAX_NAMELEN;i++)
407 fputc(new_player.login_name[i],file);
408 for(i=0;i<MAX_NAMELEN;i++)
409 fputc(new_player.alias_name[i],file);
410 fputc(new_player.handicap,file);
411 fputc(new_player.setup / 256,file);
412 fputc(new_player.setup % 256,file);
413 fputc(new_player.leveldir_nr,file);
417 else /* prüfen, ob Spieler in Liste enthalten */
418 if (!strncmp(new_player.login_name,login_name,MAX_NAMELEN-1))
422 if (mode==PLAYER_SETUP)
425 if (player.leveldir_nr < num_leveldirs)
426 leveldir_nr = player.leveldir_nr;
431 player.handicap = new_player.handicap;
433 level_nr = player.handicap;
437 void SaveLevel(int level_nr)
440 char filename[MAX_FILENAME];
443 sprintf(filename,"%s/%s/%d",
444 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
446 if (!(file=fopen(filename,"w")))
448 fprintf(stderr,"%s: cannot save level file '%s'!\n",progname,filename);
452 fputs(LEVEL_COOKIE,file); /* Formatkennung */
455 fputc(level.fieldx,file);
456 fputc(level.fieldy,file);
457 fputc(level.time / 256,file);
458 fputc(level.time % 256,file);
459 fputc(level.edelsteine / 256,file);
460 fputc(level.edelsteine % 256,file);
462 for(i=0;i<MAX_LEVNAMLEN;i++)
463 fputc(level.name[i],file);
464 for(i=0;i<MAX_SC_ENTRIES;i++)
465 fputc(level.score[i],file);
469 fputc(level.mampfer_inhalt[i][x][y],file);
470 fputc(level.tempo_amoebe,file);
471 fputc(level.dauer_sieb,file);
472 fputc(level.dauer_ablenk,file);
474 for(i=0;i<19;i++) /* Rest reserviert / Headergröße 80 Bytes */
477 for(y=0;y<lev_fieldy;y++)
478 for(x=0;x<lev_fieldx;x++)
479 fputc(Ur[x][y],file);
483 chmod(filename, LEVEL_PERMS);
486 void SaveLevelTape(int level_nr)
489 char filename[MAX_FILENAME];
491 BOOL new_tape = TRUE;
493 sprintf(filename,"%s/%s/%d.tape",
494 LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
496 /* Testen, ob bereits eine Aufnahme existiert */
497 if ((file=fopen(filename,"r")))
502 if (!AreYouSure("Replace old tape ?",AYS_ASK))
506 if (!(file=fopen(filename,"w")))
508 fprintf(stderr,"%s: cannot save level recording file '%s'!\n",
513 fputs(LEVELREC_COOKIE,file); /* Formatkennung */
518 fputc((tape.random_seed >> 24) & 0xff,file);
519 fputc((tape.random_seed >> 16) & 0xff,file);
520 fputc((tape.random_seed >> 8) & 0xff,file);
521 fputc((tape.random_seed >> 0) & 0xff,file);
523 fputc((tape.date >> 24) & 0xff,file);
524 fputc((tape.date >> 16) & 0xff,file);
525 fputc((tape.date >> 8) & 0xff,file);
526 fputc((tape.date >> 0) & 0xff,file);
528 fputc((tape.length >> 24) & 0xff,file);
529 fputc((tape.length >> 16) & 0xff,file);
530 fputc((tape.length >> 8) & 0xff,file);
531 fputc((tape.length >> 0) & 0xff,file);
533 for(i=0;i<tape.length;i++)
535 fputc(tape.pos[i].joystickdata,file);
536 fputc(tape.pos[i].delay,file);
541 chmod(filename, LEVREC_PERMS);
544 AreYouSure("tape saved !",AYS_CONFIRM);
547 void SaveScore(int level_nr)
550 char filename[MAX_FILENAME];
553 sprintf(filename,"%s/%s/%s",
554 SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
556 if (!(file=fopen(filename,"r+")))
558 fprintf(stderr,"%s: cannot save score for level %d!\n",
564 SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
566 for(i=0;i<MAX_SCORE_ENTRIES;i++)
568 for(j=0;j<MAX_NAMELEN;j++)
569 fputc(highscore[i].Name[j],file);
570 fputc(highscore[i].Score / 256,file);
571 fputc(highscore[i].Score % 256,file);
576 void SavePlayerInfo(int mode)
579 char filename[MAX_FILENAME];
580 char cookie[MAX_FILENAME];
582 struct PlayerInfo default_player;
584 if (mode==PLAYER_LEVEL)
585 sprintf(filename,"%s/%s/%s",
586 NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
588 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
590 if (!(file=fopen(filename,"r+")))
592 fprintf(stderr,"%s: cannot save player information '%s'!\n",
597 fgets(cookie,NAMES_COOKIE_LEN,file);
598 if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
600 fprintf(stderr,"%s: wrong format of names file '%s'!\n",
608 for(i=0;i<MAX_NAMELEN;i++)
609 default_player.login_name[i] = fgetc(file);
610 for(i=0;i<MAX_NAMELEN;i++)
611 default_player.alias_name[i] = fgetc(file);
612 default_player.handicap = fgetc(file);
613 default_player.setup = (fgetc(file)<<8) | fgetc(file);
614 default_player.leveldir_nr = fgetc(file);
616 if (feof(file)) /* Spieler noch nicht in Liste enthalten */
618 else /* prüfen, ob Spieler in Liste enthalten */
619 if (!strncmp(default_player.login_name,player.login_name,MAX_NAMELEN-1))
621 fseek(file,-(2*MAX_NAMELEN+1+2+1),SEEK_CUR);
626 for(i=0;i<MAX_NAMELEN;i++)
627 fputc(player.login_name[i],file);
628 for(i=0;i<MAX_NAMELEN;i++)
629 fputc(player.alias_name[i],file);
630 fputc(player.handicap,file);
631 fputc(player.setup / 256,file);
632 fputc(player.setup % 256,file);
633 fputc(player.leveldir_nr,file);
638 void GetPlayerConfig()
640 int old_joystick_nr = joystick_nr;
642 if (sound_status==SOUND_OFF)
643 player.setup &= ~SETUP_SOUND;
644 if (!sound_loops_allowed)
646 player.setup &= ~SETUP_SOUND_LOOPS;
647 player.setup &= ~SETUP_SOUND_MUSIC;
650 sound_on = SETUP_SOUND_ON(player.setup);
651 sound_loops_on = SETUP_SOUND_LOOPS_ON(player.setup);
652 sound_music_on = SETUP_SOUND_MUSIC_ON(player.setup);
653 toons_on = SETUP_TOONS_ON(player.setup);
654 direct_draw_on = SETUP_DIRECT_DRAW_ON(player.setup);
655 fading_on = SETUP_FADING_ON(player.setup);
656 autorecord_on = SETUP_RECORD_EACH_GAME_ON(player.setup);
657 joystick_nr = SETUP_2ND_JOYSTICK_ON(player.setup);
659 if (joystick_nr != old_joystick_nr)
662 close(joystick_device);
671 Dynamite = Score = 0;
672 Gems = level.edelsteine;
673 Key[0] = Key[1] = Key[2] = Key[3] = FALSE;
675 TimeLeft = level.time;
677 CheckExploding = FALSE;
678 LevelSolved = GameOver = SiebAktiv = FALSE;
683 TapeStartRecording();
684 else if (tape.playing)
687 DigField(0,0,DF_NO_PUSH);
690 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
693 MovPos[x][y]=MovDir[x][y]=MovDelay[x][y]=0;
694 Store[x][y]=Store2[x][y]=Frame[x][y]=0;
700 Feld[x][y] = EL_LEERRAUM;
705 Feld[x][y] = EL_LEERRAUM;
708 if (x<lev_fieldx-1 && Feld[x+1][y]==EL_SALZSAEURE)
709 Feld[x][y] = EL_BADEWANNE1;
710 else if (x>0 && Feld[x-1][y]==EL_SALZSAEURE)
711 Feld[x][y] = EL_BADEWANNE2;
712 else if (y>0 && Feld[x][y-1]==EL_BADEWANNE1)
713 Feld[x][y] = EL_BADEWANNE3;
714 else if (y>0 && Feld[x][y-1]==EL_SALZSAEURE)
715 Feld[x][y] = EL_BADEWANNE4;
716 else if (y>0 && Feld[x][y-1]==EL_BADEWANNE2)
717 Feld[x][y] = EL_BADEWANNE5;
743 scroll_x = scroll_y = -1;
746 (JX<=lev_fieldx-MIDPOSX ? JX-MIDPOSX : lev_fieldx-SCR_FIELDX+1);
749 (JY<=lev_fieldy-MIDPOSY ? JY-MIDPOSY : lev_fieldy-SCR_FIELDY+1);
752 DrawLevelElement(JX,JY,EL_SPIELFIGUR);
755 XCopyArea(display,pix[PIX_DOOR],pix[PIX_DB_DOOR],gc,
756 DOOR_GFX_PAGEX5,DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
757 DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY1);
758 DrawTextExt(pix[PIX_DB_DOOR],gc,
759 DOOR_GFX_PAGEX1+XX_LEVEL,DOOR_GFX_PAGEY1+YY_LEVEL,
760 int2str(level_nr,2),FS_SMALL,FC_YELLOW);
761 DrawTextExt(pix[PIX_DB_DOOR],gc,
762 DOOR_GFX_PAGEX1+XX_EMERALDS,DOOR_GFX_PAGEY1+YY_EMERALDS,
763 int2str(Gems,3),FS_SMALL,FC_YELLOW);
764 DrawTextExt(pix[PIX_DB_DOOR],gc,
765 DOOR_GFX_PAGEX1+XX_DYNAMITE,DOOR_GFX_PAGEY1+YY_DYNAMITE,
766 int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
767 DrawTextExt(pix[PIX_DB_DOOR],gc,
768 DOOR_GFX_PAGEX1+XX_SCORE,DOOR_GFX_PAGEY1+YY_SCORE,
769 int2str(Score,5),FS_SMALL,FC_YELLOW);
770 DrawTextExt(pix[PIX_DB_DOOR],gc,
771 DOOR_GFX_PAGEX1+XX_TIME,DOOR_GFX_PAGEY1+YY_TIME,
772 int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
774 DrawGameButton(BUTTON_GAME_STOP);
775 DrawGameButton(BUTTON_GAME_PAUSE);
776 DrawGameButton(BUTTON_GAME_PLAY);
777 DrawSoundDisplay(BUTTON_SOUND_MUSIC | (BUTTON_ON * sound_music_on));
778 DrawSoundDisplay(BUTTON_SOUND_LOOPS | (BUTTON_ON * sound_loops_on));
779 DrawSoundDisplay(BUTTON_SOUND_SOUND | (BUTTON_ON * sound_on));
780 XCopyArea(display,drawto,pix[PIX_DB_DOOR],gc,
781 DX+GAME_CONTROL_XPOS,DY+GAME_CONTROL_YPOS,
782 GAME_CONTROL_XSIZE,2*GAME_CONTROL_YSIZE,
783 DOOR_GFX_PAGEX1+GAME_CONTROL_XPOS,
784 DOOR_GFX_PAGEY1+GAME_CONTROL_YPOS);
786 OpenDoor(DOOR_OPEN_1);
789 PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
791 XAutoRepeatOff(display);
794 void InitMovDir(int x, int y)
796 int i, element = Feld[x][y];
797 static int xy[4][2] =
804 static int direction[2][4] =
806 MV_RIGHT, MV_UP, MV_LEFT, MV_DOWN,
807 MV_LEFT, MV_DOWN, MV_RIGHT, MV_UP
816 Feld[x][y] = EL_KAEFER;
817 MovDir[x][y] = direction[0][element-EL_KAEFER_R];
823 Feld[x][y] = EL_FLIEGER;
824 MovDir[x][y] = direction[0][element-EL_FLIEGER_R];
830 Feld[x][y] = EL_PACMAN;
831 MovDir[x][y] = direction[0][element-EL_PACMAN_R];
834 MovDir[x][y] = 1<<RND(4);
835 if (element!=EL_KAEFER && element!=EL_FLIEGER)
845 if (!IN_LEV_FIELD(x1,y1) || !IS_FREE(x1,y1))
847 if (element==EL_KAEFER)
849 MovDir[x][y] = direction[0][i];
852 else if (element==EL_FLIEGER)
854 MovDir[x][y] = direction[1][i];
866 int bumplevel = FALSE;
869 PlaySoundExt(SND_SIRR,PSND_MAX_VOLUME,PSND_MAX_RIGHT,PSND_LOOP);
873 for(;TimeLeft>=0;TimeLeft--)
876 PlaySoundStereo(SND_SIRR,PSND_MAX_RIGHT);
877 if (TimeLeft && !(TimeLeft % 10))
878 RaiseScore(level.score[SC_ZEITBONUS]);
879 DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
892 CloseDoor(DOOR_CLOSE_1);
894 if (level_nr==player.handicap &&
895 level_nr<leveldir[leveldir_nr].num_ready)
899 SavePlayerInfo(PLAYER_LEVEL);
902 if ((hi_pos=NewHiScore())>=0)
904 game_status = HALLOFFAME;
905 DrawHallOfFame(hi_pos);
906 if (bumplevel && TAPE_IS_EMPTY(tape))
911 game_status = MAINMENU;
912 if (bumplevel && TAPE_IS_EMPTY(tape))
926 if (!strcmp(player.alias_name,EMPTY_ALIAS) ||
927 Score<highscore[MAX_SCORE_ENTRIES-1].Score)
930 for(k=0;k<MAX_SCORE_ENTRIES;k++)
932 if (Score>highscore[k].Score) /* Spieler kommt in Highscore-Liste */
934 if (k<MAX_SCORE_ENTRIES-1)
936 int m = MAX_SCORE_ENTRIES-1;
939 for(l=k;l<MAX_SCORE_ENTRIES;l++)
940 if (!strcmp(player.alias_name,highscore[l].Name))
942 if (m==k) /* Spieler überschreibt seine alte Position */
948 strcpy(highscore[l].Name,highscore[l-1].Name);
949 highscore[l].Score = highscore[l-1].Score;
956 sprintf(highscore[k].Name,player.alias_name);
957 highscore[k].Score = Score;
964 else if (!strcmp(player.alias_name,highscore[k].Name))
965 break; /* Spieler schon mit besserer Punktzahl in der Liste */
974 void InitMovingField(int x, int y, int direction)
976 int newx = x + (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
977 int newy = y + (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
980 MovDir[x][y] = direction;
981 MovDir[newx][newy] = direction;
982 if (Feld[newx][newy]==EL_LEERRAUM)
983 Feld[newx][newy] = EL_BLOCKED;
986 void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
988 int direction = MovDir[x][y];
989 int newx = x + (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
990 int newy = y + (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
996 void Blocked2Moving(int x, int y, int *comes_from_x, int *comes_from_y)
998 int oldx = x, oldy = y;
999 int direction = MovDir[x][y];
1001 if (direction==MV_LEFT)
1003 else if (direction==MV_RIGHT)
1005 else if (direction==MV_UP)
1007 else if (direction==MV_DOWN)
1010 *comes_from_x = oldx;
1011 *comes_from_y = oldy;
1014 int MovingOrBlocked2Element(int x, int y)
1016 int element = Feld[x][y];
1018 if (element==EL_BLOCKED)
1022 Blocked2Moving(x,y,&oldx,&oldy);
1023 return(Feld[oldx][oldy]);
1029 void RemoveMovingField(int x, int y)
1031 int oldx=x,oldy=y, newx=x,newy=y;
1033 if (Feld[x][y]!=EL_BLOCKED && !IS_MOVING(x,y))
1038 Moving2Blocked(x,y,&newx,&newy);
1039 if (Feld[newx][newy]!=EL_BLOCKED)
1042 else if (Feld[x][y]==EL_BLOCKED)
1044 Blocked2Moving(x,y,&oldx,&oldy);
1045 if (!IS_MOVING(oldx,oldy))
1049 Feld[oldx][oldy] = EL_LEERRAUM;
1050 Feld[newx][newy] = EL_LEERRAUM;
1051 MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
1052 MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
1053 DrawLevelField(oldx,oldy);
1054 DrawLevelField(newx,newy);
1057 void DrawDynamite(int x, int y)
1059 int phase = (48-MovDelay[x][y])/6;
1061 if (!IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1069 DrawGraphic(SCROLLX(x),SCROLLY(y),el2gfx(Store[x][y]));
1071 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
1073 else if (PLAYER(x,y))
1074 DrawGraphic(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
1076 if (Store[x][y] || PLAYER(x,y))
1077 DrawGraphicThruMask(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase);
1079 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_DYNAMIT+phase);
1082 void CheckDynamite(int x, int y)
1084 CheckExploding=TRUE;
1086 if (MovDelay[x][y]) /* neues Dynamit / in Wartezustand */
1091 if (!(MovDelay[x][y] % 6))
1094 PlaySoundLevel(x,y,SND_ZISCH);
1101 StopSound(SND_ZISCH);
1105 void Explode(int ex, int ey, int phase)
1108 int num_phase = 9, delay = 1;
1109 int last_phase = num_phase*delay;
1110 int half_phase = (num_phase/2)*delay;
1112 if (phase==0) /* Feld 'Store' initialisieren */
1114 int center_element = Feld[ex][ey];
1116 if (center_element==EL_BLOCKED)
1117 center_element = MovingOrBlocked2Element(ex,ey);
1119 for(y=ey-1;y<ey+2;y++) for(x=ex-1;x<ex+2;x++)
1121 int element = Feld[x][y];
1123 if (!IN_LEV_FIELD(x,y) || IS_MASSIV(element))
1126 if (element==EL_EXPLODING)
1127 element = Store2[x][y];
1129 if (PLAYER(ex,ey) || center_element==EL_KAEFER)
1130 Store[x][y] = ((x==ex && y==ey) ? EL_DIAMANT : EL_EDELSTEIN);
1131 else if (center_element==EL_MAMPFER)
1132 Store[x][y] = level.mampfer_inhalt[MampferNr][x-ex+1][y-ey+1];
1133 else if (Feld[x][y]==EL_ERZ_1)
1134 Store[x][y] = EL_EDELSTEIN;
1135 else if (Feld[x][y]==EL_ERZ_2)
1136 Store[x][y] = EL_DIAMANT;
1137 else if (!IS_PFORTE(Store[x][y]))
1138 Store[x][y] = EL_LEERRAUM;
1141 Store2[x][y] = element;
1143 RemoveMovingField(x,y);
1144 Feld[x][y] = EL_EXPLODING;
1145 MovDir[x][y] = MovPos[x][y] = 0;
1150 if (center_element==EL_MAMPFER)
1151 MampferNr = (MampferNr+1) % 4;
1162 Frame[x][y] = (phase<last_phase ? phase+1 : 0);
1164 if (phase==half_phase)
1166 int element = Store2[x][y];
1170 else if (element==EL_BOMBE ||
1171 element==EL_DYNAMIT ||
1172 element==EL_DYNAMIT_AUS ||
1175 Feld[x][y] = Store2[x][y];
1181 if (phase==last_phase)
1185 element = Feld[x][y] = Store[x][y];
1186 Store[x][y] = Store2[x][y] = 0;
1187 MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
1188 if (CAN_MOVE(element) || COULD_MOVE(element))
1190 DrawLevelField(x,y);
1192 else if (!(phase%delay) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1195 ErdreichAnbroeckeln(SCROLLX(x),SCROLLY(y));
1197 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_EXPLOSION+(phase/delay-1));
1200 CheckExploding=TRUE;
1203 void Bang(int x, int y)
1205 int element = Feld[x][y];
1207 CheckExploding=TRUE;
1208 PlaySoundLevel(x,y,SND_ROAAAR);
1213 RaiseScore(level.score[SC_KAEFER]);
1216 RaiseScore(level.score[SC_FLIEGER]);
1219 RaiseScore(level.score[SC_MAMPFER]);
1222 RaiseScore(level.score[SC_ZOMBIE]);
1225 RaiseScore(level.score[SC_PACMAN]);
1234 void Blurb(int x, int y)
1236 int element = Feld[x][y];
1238 if (element!=EL_BLURB_LEFT && element!=EL_BLURB_RIGHT) /* Anfang */
1240 PlaySoundLevel(x,y,SND_BLURB);
1241 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y) &&
1242 (!IN_LEV_FIELD(x-1,y-1) ||
1243 !CAN_FALL(MovingOrBlocked2Element(x-1,y-1))))
1245 Feld[x-1][y] = EL_BLURB_LEFT;
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_RIGHT;
1256 int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT);
1258 CheckExploding=TRUE;
1260 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1263 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1266 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1267 DrawGraphic(SCROLLX(x),SCROLLY(y),graphic+4-MovDelay[x][y]);
1269 if (!MovDelay[x][y])
1271 Feld[x][y] = EL_LEERRAUM;
1272 DrawLevelField(x,y);
1278 void Impact(int x, int y)
1280 BOOL lastline = (y==lev_fieldy-1);
1281 BOOL object_hit = FALSE;
1282 int element = Feld[x][y];
1284 /* Element darunter berührt? */
1286 object_hit = (!IS_FREE(x,y+1) && (!IS_MOVING(x,y+1) ||
1287 MovDir[x][y+1]!=MV_DOWN ||
1288 MovPos[x][y+1]<=TILEY/2));
1290 /* Auftreffendes Element fällt in Salzsäure */
1291 if (!lastline && Feld[x][y+1]==EL_SALZSAEURE)
1297 /* Auftreffendes Element ist Bombe */
1298 if (element==EL_BOMBE && (lastline || object_hit))
1304 /* Auftreffendes Element ist Säuretropfen */
1305 if (element==EL_TROPFEN && (lastline || object_hit))
1307 if (object_hit && PLAYER(x,y+1))
1310 Feld[x][y] = EL_AMOEBING2;
1314 /* Welches Element kriegt was auf die Rübe? */
1315 if (!lastline && object_hit)
1317 int smashed = Feld[x][y+1];
1324 else if (element==EL_FELSBROCKEN)
1326 if (IS_ENEMY(MovingOrBlocked2Element(x,y+1)))
1331 else if (!IS_MOVING(x,y+1))
1333 if (smashed==EL_BOMBE)
1338 else if (smashed==EL_KOKOSNUSS)
1340 Feld[x][y+1] = EL_CRACKINGNUT;
1341 PlaySoundLevel(x,y,SND_KNACK);
1342 RaiseScore(level.score[SC_KOKOSNUSS]);
1345 else if (smashed==EL_DIAMANT)
1347 Feld[x][y+1] = EL_LEERRAUM;
1348 PlaySoundLevel(x,y,SND_QUIRK);
1355 /* Kein Geräusch beim Durchqueren des Siebes */
1356 if (!lastline && Feld[x][y+1]==EL_SIEB_LEER)
1359 /* Geräusch beim Auftreffen */
1360 if (lastline || object_hit)
1373 case EL_FELSBROCKEN:
1377 case EL_SCHLUESSEL1:
1378 case EL_SCHLUESSEL2:
1379 case EL_SCHLUESSEL3:
1380 case EL_SCHLUESSEL4:
1389 PlaySoundLevel(x,y,sound);
1393 void TurnRound(int x, int y)
1395 int element = Feld[x][y];
1396 int direction = MovDir[x][y];
1398 if (element==EL_KAEFER)
1400 TestIfBadThingHitsOtherBadThing(x,y);
1402 if (MovDir[x][y]==MV_LEFT)
1404 if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1))
1406 else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y))
1407 MovDir[x][y]=MV_DOWN;
1409 else if (MovDir[x][y]==MV_RIGHT)
1411 if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1))
1412 MovDir[x][y]=MV_DOWN;
1413 else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y))
1416 else if (MovDir[x][y]==MV_UP)
1418 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y))
1419 MovDir[x][y]=MV_RIGHT;
1420 else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1))
1421 MovDir[x][y]=MV_LEFT;
1423 else if (MovDir[x][y]==MV_DOWN)
1425 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y))
1426 MovDir[x][y]=MV_LEFT;
1427 else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1))
1428 MovDir[x][y]=MV_RIGHT;
1431 if (direction!=MovDir[x][y])
1434 else if (element==EL_FLIEGER)
1436 TestIfBadThingHitsOtherBadThing(x,y);
1438 if (MovDir[x][y]==MV_LEFT)
1440 if (IN_LEV_FIELD(x,y+1) && IS_FREE(x,y+1))
1441 MovDir[x][y]=MV_DOWN;
1442 else if (!IN_LEV_FIELD(x-1,y) || !IS_FREE(x-1,y))
1445 else if (MovDir[x][y]==MV_RIGHT)
1447 if (IN_LEV_FIELD(x,y-1) && IS_FREE(x,y-1))
1449 else if (!IN_LEV_FIELD(x+1,y) || !IS_FREE(x+1,y))
1450 MovDir[x][y]=MV_DOWN;
1452 else if (MovDir[x][y]==MV_UP)
1454 if (IN_LEV_FIELD(x-1,y) && IS_FREE(x-1,y))
1455 MovDir[x][y]=MV_LEFT;
1456 else if (!IN_LEV_FIELD(x,y-1) || !IS_FREE(x,y-1))
1457 MovDir[x][y]=MV_RIGHT;
1459 else if (MovDir[x][y]==MV_DOWN)
1461 if (IN_LEV_FIELD(x+1,y) && IS_FREE(x+1,y))
1462 MovDir[x][y]=MV_RIGHT;
1463 else if (!IN_LEV_FIELD(x,y+1) || !IS_FREE(x,y+1))
1464 MovDir[x][y]=MV_LEFT;
1467 if (direction!=MovDir[x][y])
1470 else if (element==EL_MAMPFER)
1472 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
1474 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
1475 if (IN_LEV_FIELD(x,y-1) &&
1476 (IS_FREE(x,y-1) || Feld[x][y-1]==EL_DIAMANT) &&
1479 if (IN_LEV_FIELD(x,y+1) &&
1480 (IS_FREE(x,y+1) || Feld[x][y+1]==EL_DIAMANT) &&
1482 MovDir[x][y]=MV_DOWN;
1484 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
1486 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
1487 if (IN_LEV_FIELD(x-1,y) &&
1488 (IS_FREE(x-1,y) || Feld[x-1][y]==EL_DIAMANT) &&
1490 MovDir[x][y]=MV_LEFT;
1491 if (IN_LEV_FIELD(x+1,y) &&
1492 (IS_FREE(x+1,y) || Feld[x+1][y]==EL_DIAMANT) &&
1494 MovDir[x][y]=MV_RIGHT;
1497 MovDelay[x][y]=8+8*RND(3);
1499 else if (element==EL_PACMAN)
1501 if (MovDir[x][y]==MV_LEFT || MovDir[x][y]==MV_RIGHT)
1503 MovDir[x][y]=(MovDir[x][y]==MV_LEFT ? MV_RIGHT : MV_LEFT);
1504 if (IN_LEV_FIELD(x,y-1) &&
1505 (IS_FREE(x,y-1) || IS_AMOEBOID(Feld[x][y-1])) &&
1508 if (IN_LEV_FIELD(x,y+1) &&
1509 (IS_FREE(x,y+1) || IS_AMOEBOID(Feld[x][y+1])) &&
1511 MovDir[x][y]=MV_DOWN;
1513 else if (MovDir[x][y]==MV_UP || MovDir[x][y]==MV_DOWN)
1515 MovDir[x][y]=(MovDir[x][y]==MV_UP ? MV_DOWN : MV_UP);
1516 if (IN_LEV_FIELD(x-1,y) &&
1517 (IS_FREE(x-1,y) || IS_AMOEBOID(Feld[x-1][y])) &&
1519 MovDir[x][y]=MV_LEFT;
1520 if (IN_LEV_FIELD(x+1,y) &&
1521 (IS_FREE(x+1,y) || IS_AMOEBOID(Feld[x+1][y])) &&
1523 MovDir[x][y]=MV_RIGHT;
1526 MovDelay[x][y]=3+RND(20);
1528 else if (element==EL_ZOMBIE)
1530 int attr_x = JX, attr_y = JY;
1538 MovDir[x][y]=MV_NO_MOVING;
1540 MovDir[x][y]|=MV_LEFT;
1542 MovDir[x][y]|=MV_RIGHT;
1544 MovDir[x][y]|=MV_UP;
1546 MovDir[x][y]|=MV_DOWN;
1547 if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
1548 MovDir[x][y] &= (RND(2) ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
1550 MovDelay[x][y] = 8+8*RND(2);
1554 void StartMoving(int x, int y)
1556 int element = Feld[x][y];
1561 if (CAN_FALL(element) && y<lev_fieldy-1)
1563 if (element==EL_MORAST_VOLL)
1567 InitMovingField(x,y,MV_DOWN);
1568 Feld[x][y] = EL_FELSBROCKEN;
1569 Store[x][y] = EL_MORAST_LEER;
1571 else if (Feld[x][y+1]==EL_MORAST_LEER)
1575 if (!MovDelay[x][y])
1576 MovDelay[x][y] = 16;
1585 Feld[x][y] = EL_MORAST_LEER;
1586 Feld[x][y+1] = EL_MORAST_VOLL;
1589 else if (element==EL_FELSBROCKEN && Feld[x][y+1]==EL_MORAST_LEER)
1591 InitMovingField(x,y,MV_DOWN);
1592 Store[x][y] = EL_MORAST_VOLL;
1594 else if (element==EL_SIEB_VOLL)
1598 InitMovingField(x,y,MV_DOWN);
1599 Feld[x][y] = EL_CHANGED(Store2[x][y]);
1600 Store[x][y] = EL_SIEB_LEER;
1603 else if (CAN_CHANGE(element) && Feld[x][y+1]==EL_SIEB_LEER)
1605 InitMovingField(x,y,MV_DOWN);
1606 Store[x][y] = EL_SIEB_VOLL;
1607 Store2[x][y+1] = element;
1610 else if (CAN_SMASH(element) && Feld[x][y+1]==EL_SALZSAEURE)
1613 InitMovingField(x,y,MV_DOWN);
1614 Store[x][y] = EL_SALZSAEURE;
1616 else if (CAN_SMASH(element) && Feld[x][y+1]==EL_BLOCKED)
1620 else if (IS_FREE(x,y+1))
1622 InitMovingField(x,y,MV_DOWN);
1624 else if (element==EL_TROPFEN)
1626 Feld[x][y] = EL_AMOEBING2;
1628 else if (SLIPPERY(Feld[x][y+1]) && !Store[x][y+1])
1630 int left = (x>0 && IS_FREE(x-1,y) &&
1631 (IS_FREE(x-1,y+1) || Feld[x-1][y+1]==EL_SALZSAEURE));
1632 int right = (x<lev_fieldx-1 && IS_FREE(x+1,y) &&
1633 (IS_FREE(x+1,y+1) || Feld[x+1][y+1]==EL_SALZSAEURE));
1638 left = !(right=RND(2));
1639 InitMovingField(x,y,left ? MV_LEFT : MV_RIGHT);
1643 else if (CAN_MOVE(element))
1649 if (!MovDelay[x][y]) /* neuer Schritt / noch nicht gewartet */
1651 if (element==EL_ZOMBIE || element==EL_KAEFER || element==EL_FLIEGER)
1654 if (MovDelay[x][y] && (element==EL_KAEFER || element==EL_FLIEGER))
1655 DrawLevelField(x,y);
1659 if (MovDelay[x][y]) /* neuer Schritt / in Wartezustand */
1663 if (element==EL_ZOMBIE || element==EL_MAMPFER)
1665 int phase = MovDelay[x][y] % 8;
1670 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1671 DrawGraphic(SCROLLX(x),SCROLLY(y),
1672 el2gfx(element)+phase);
1674 if (element==EL_MAMPFER && MovDelay[x][y]%4==3)
1675 PlaySoundLevel(x,y,SND_NJAM);
1682 if (element==EL_KAEFER)
1684 PlaySoundLevel(x,y,SND_KLAPPER);
1686 else if (element==EL_FLIEGER)
1688 PlaySoundLevel(x,y,SND_ROEHR);
1691 /* neuer Schritt / Wartezustand beendet */
1693 Moving2Blocked(x,y,&newx,&newy); /* wohin soll's gehen? */
1695 if (PLAYER(newx,newy)) /* Spieler erwischt */
1701 else if (element==EL_MAMPFER && IN_LEV_FIELD(newx,newy) &&
1702 Feld[newx][newy]==EL_DIAMANT)
1704 Feld[newx][newy] = EL_LEERRAUM;
1705 DrawLevelField(newx,newy);
1707 else if (element==EL_PACMAN && IN_LEV_FIELD(newx,newy) &&
1708 IS_AMOEBOID(Feld[newx][newy]))
1710 Feld[newx][newy] = EL_LEERRAUM;
1711 DrawLevelField(newx,newy);
1713 else if (element==EL_ZOMBIE && IN_LEV_FIELD(newx,newy) &&
1714 MovDir[x][y]==MV_DOWN && Feld[newx][newy]==EL_SALZSAEURE)
1717 Store[x][y] = EL_SALZSAEURE;
1719 else if (!IN_LEV_FIELD(newx,newy) || !IS_FREE(newx,newy))
1720 { /* gegen Wand gelaufen */
1722 DrawLevelField(x,y);
1726 InitMovingField(x,y,MovDir[x][y]);
1730 ContinueMoving(x,y);
1733 void ContinueMoving(int x, int y)
1735 int element = Feld[x][y];
1736 int direction = MovDir[x][y];
1737 int dx = (direction==MV_LEFT ? -1 : direction==MV_RIGHT ? +1 : 0);
1738 int dy = (direction==MV_UP ? -1 : direction==MV_DOWN ? +1 : 0);
1739 int horiz_move = (dx!=0);
1740 int newx = x + dx, newy = y + dy;
1741 int step = (horiz_move ? dx : dy)*TILEX/4;
1743 if (CAN_FALL(element) && horiz_move)
1745 else if (element==EL_TROPFEN)
1747 else if (Store[x][y]==EL_MORAST_VOLL || Store[x][y]==EL_MORAST_LEER)
1750 MovPos[x][y] += step;
1752 if (ABS(MovPos[x][y])>=TILEX) /* Zielfeld erreicht */
1754 Feld[x][y]=EL_LEERRAUM;
1755 Feld[newx][newy]=element;
1757 if (Store[x][y]==EL_MORAST_VOLL)
1760 Feld[newx][newy] = EL_MORAST_VOLL;
1761 element = EL_MORAST_VOLL;
1763 else if (Store[x][y]==EL_MORAST_LEER)
1766 Feld[x][y] = EL_MORAST_LEER;
1768 else if (Store[x][y]==EL_SIEB_VOLL)
1771 Feld[newx][newy] = EL_SIEB_VOLL;
1772 element = EL_SIEB_VOLL;
1774 else if (Store[x][y]==EL_SIEB_LEER)
1776 Store[x][y] = Store2[x][y] = 0;
1777 Feld[x][y] = EL_SIEB_LEER;
1779 else if (Store[x][y]==EL_SALZSAEURE)
1782 Feld[newx][newy] = EL_SALZSAEURE;
1783 element = EL_SALZSAEURE;
1785 else if (Store[x][y]==EL_AMOEBE2)
1788 Feld[x][y] = EL_AMOEBE2;
1791 MovPos[x][y] = MovDir[x][y] = 0;
1793 if (!CAN_MOVE(element))
1794 MovDir[newx][newy] = 0;
1796 DrawLevelField(x,y);
1797 DrawLevelField(newx,newy);
1799 Stop[newx][newy]=TRUE;
1802 if (DONT_TOUCH(element)) /* Käfer oder Flieger */
1804 TestIfBadThingHitsHero();
1805 TestIfBadThingHitsOtherBadThing(newx,newy);
1808 if (CAN_SMASH(element) && direction==MV_DOWN &&
1809 (newy==lev_fieldy-1 || !IS_FREE(x,newy+1)))
1812 else /* noch in Bewegung */
1814 DrawLevelField(x,y);
1819 void AmoebeWaechst(int x, int y)
1821 static long sound_delay = 0;
1822 static int sound_delay_value = 0;
1824 CheckExploding=TRUE;
1826 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
1830 if (DelayReached(&sound_delay,sound_delay_value))
1832 PlaySoundLevel(x,y,SND_AMOEBE);
1833 sound_delay_value = 30;
1837 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
1840 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
1841 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AMOEBING+3-MovDelay[x][y]);
1843 if (!MovDelay[x][y])
1845 Feld[x][y] = (Feld[x][y]==EL_AMOEBING2 ? EL_AMOEBE2 : EL_AMOEBE3);
1846 DrawLevelField(x,y);
1851 void AmoebeAbleger(int ax, int ay)
1854 int newax = ax, neway = ay;
1855 BOOL waiting_for_player = FALSE;
1856 static int xy[4][2] =
1864 CheckExploding=TRUE;
1866 if (!level.tempo_amoebe)
1868 Feld[ax][ay] = EL_AMOEBE1;
1869 DrawLevelField(ax,ay);
1873 if (!MovDelay[ax][ay]) /* neue Amoebe / noch nicht gewartet */
1874 MovDelay[ax][ay] = RND(33*20/(1+level.tempo_amoebe));
1876 if (MovDelay[ax][ay]) /* neue Amoebe / in Wartezustand */
1879 if (MovDelay[ax][ay])
1883 if (Feld[ax][ay]==EL_AMOEBE3)
1893 if (!IN_LEV_FIELD(x,y))
1897 Feld[x][y]==EL_ERDREICH || Feld[x][y]==EL_MORAST_LEER)
1903 else if (PLAYER(x,y))
1904 waiting_for_player = TRUE;
1907 if (newax==ax && neway==ay)
1909 if (Feld[ax][ay]==EL_AMOEBE3 && i==4 && !waiting_for_player)
1911 Feld[ax][ay] = EL_AMOEBE1;
1912 DrawLevelField(ax,ay);
1922 x = ax+xy[start][0];
1923 y = ay+xy[start][1];
1924 if (!IN_LEV_FIELD(x,y))
1928 Feld[x][y]==EL_ERDREICH || Feld[x][y]==EL_MORAST_LEER)
1934 if (newax==ax && neway==ay)
1938 if (Feld[ax][ay]==EL_AMOEBE3)
1939 Feld[newax][neway] = EL_AMOEBING3;
1940 else if (neway==lev_fieldy-1)
1941 Feld[newax][neway] = EL_AMOEBING2;
1942 else if (neway<=ay || !IS_FREE(newax,neway))
1943 Feld[newax][neway] = EL_TROPFEN;
1946 InitMovingField(ax,ay,MV_DOWN);
1947 Feld[ax][ay]=EL_TROPFEN;
1948 Store[ax][ay]=EL_AMOEBE2;
1949 ContinueMoving(ax,ay);
1953 DrawLevelField(newax,neway);
1956 void Life(int ax, int ay)
1959 static int life[4] = { 2,3,3,3 }; /* "Life"-Parameter */
1961 int element = Feld[ax][ay];
1963 CheckExploding=TRUE;
1968 if (!MovDelay[ax][ay]) /* neue Phase / noch nicht gewartet */
1969 MovDelay[ax][ay] = life_time;
1971 if (MovDelay[ax][ay]) /* neue Phase / in Wartezustand */
1974 if (MovDelay[ax][ay])
1978 for(y1=-1;y1<2;y1++) for(x1=-1;x1<2;x1++)
1980 int xx = ax+x1, yy = ay+y1;
1983 if (!IN_LEV_FIELD(xx,yy))
1986 for(y2=-1;y2<2;y2++) for(x2=-1;x2<2;x2++)
1988 int x = xx+x2, y = yy+y2;
1990 if (!IN_LEV_FIELD(x,y) || (x==xx && y==yy))
1993 if ((Feld[x][y]==element && !Stop[x][y]) ||
1994 (IS_FREE(x,y) && Stop[x][y]))
1998 if (xx==ax && yy==ay) /* mittleres Feld mit Amoebe */
2000 if (nachbarn<life[0] || nachbarn>life[1])
2002 Feld[xx][yy] = EL_LEERRAUM;
2004 DrawLevelField(xx,yy);
2005 Stop[xx][yy] = TRUE;
2008 else if (IS_FREE(xx,yy) || Feld[xx][yy]==EL_ERDREICH)
2009 { /* Randfeld ohne Amoebe */
2010 if (nachbarn>=life[2] && nachbarn<=life[3])
2012 Feld[xx][yy] = element;
2013 MovDelay[xx][yy] = (element==EL_LIFE ? 0 : life_time-1);
2015 DrawLevelField(xx,yy);
2016 Stop[xx][yy] = TRUE;
2022 void Ablenk(int x, int y)
2024 CheckExploding=TRUE;
2026 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2027 MovDelay[x][y] = 33*(level.dauer_ablenk/10);
2028 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2033 if (IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2034 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_ABLENK+MovDelay[x][y]%4);
2035 if (!(MovDelay[x][y]%4))
2036 PlaySoundLevel(x,y,SND_MIEP);
2041 Feld[x][y]=EL_ABLENK_AUS;
2042 DrawLevelField(x,y);
2047 void Birne(int x, int y)
2049 CheckExploding=TRUE;
2051 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2052 MovDelay[x][y] = 400;
2054 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2059 if (!(MovDelay[x][y]%5))
2061 if (!(MovDelay[x][y]%10))
2062 Feld[x][y]=EL_ABLENK_EIN;
2064 Feld[x][y]=EL_ABLENK_AUS;
2065 DrawLevelField(x,y);
2066 Feld[x][y]=EL_ABLENK_EIN;
2072 Feld[x][y]=EL_ABLENK_AUS;
2073 DrawLevelField(x,y);
2078 void Blubber(int x, int y)
2080 CheckExploding=TRUE;
2082 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2083 MovDelay[x][y] = 20;
2085 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2090 blubber = MovDelay[x][y]/5;
2091 if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2092 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_GEBLUBBER+3-blubber);
2096 void NussKnacken(int x, int y)
2098 CheckExploding=TRUE;
2100 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2103 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2106 if (MovDelay[x][y] && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2107 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_CRACKINGNUT+3-MovDelay[x][y]);
2109 if (!MovDelay[x][y])
2111 Feld[x][y] = EL_EDELSTEIN;
2112 DrawLevelField(x,y);
2117 void SiebAktivieren(int x, int y)
2119 CheckExploding=TRUE;
2123 if (SiebAktiv%2 && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2124 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_SIEB_VOLL+3-(SiebAktiv%8)/2);
2128 PlaySoundLevel(x,y,SND_MIEP);
2134 Feld[x][y] = EL_SIEB_TOT;
2135 DrawLevelField(x,y);
2139 void AusgangstuerPruefen(int x, int y)
2141 CheckExploding=TRUE;
2144 Feld[x][y] = EL_AUSGANG_ACT;
2147 void AusgangstuerOeffnen(int x, int y)
2149 CheckExploding=TRUE;
2151 if (!MovDelay[x][y]) /* neue Phase / noch nicht gewartet */
2152 MovDelay[x][y] = 20;
2154 if (MovDelay[x][y]) /* neue Phase / in Wartezustand */
2159 tuer = MovDelay[x][y]/5;
2160 if (!(MovDelay[x][y]%5) && IN_SCR_FIELD(SCROLLX(x),SCROLLY(y)))
2161 DrawGraphic(SCROLLX(x),SCROLLY(y),GFX_AUSGANG_ZU+3-tuer);
2163 if (!MovDelay[x][y])
2165 Feld[x][y] = EL_AUSGANG_AUF;
2166 DrawLevelField(x,y);
2171 int GameActions(int mx, int my, int button)
2173 static long time_delay=0, action_delay=0;
2176 if (TimeLeft>0 && DelayReached(&time_delay,100) && !tape.pausing)
2180 if (tape.recording || tape.playing)
2181 DrawVideoDisplay(VIDEO_STATE_TIME_ON,level.time-TimeLeft);
2184 PlaySoundStereo(SND_GONG,PSND_MAX_RIGHT);
2186 DrawText(DX_TIME,DY_TIME,int2str(TimeLeft,3),FS_SMALL,FC_YELLOW);
2193 Action = (CheckMoving || CheckExploding || SiebAktiv);
2196 if (Action && DelayReached(&action_delay,3))
2199 if (DelayReached(&action_delay,3))
2203 if (tape.pausing || (tape.playing && !TapePlayDelay()))
2205 else if (tape.recording)
2208 CheckMoving = CheckExploding = FALSE;
2209 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
2212 for(y=0;y<lev_fieldy;y++) for(x=0;x<lev_fieldx;x++)
2214 element = Feld[x][y];
2216 if (element==EL_LEERRAUM || element==EL_ERDREICH)
2219 if (!IS_MOVING(x,y) && (CAN_FALL(element) || CAN_MOVE(element)))
2221 else if (IS_MOVING(x,y))
2222 ContinueMoving(x,y);
2223 else if (element==EL_DYNAMIT)
2225 else if (element==EL_EXPLODING)
2226 Explode(x,y,Frame[x][y]);
2227 else if (element==EL_AMOEBING2 || element==EL_AMOEBING3)
2229 else if (element==EL_AMOEBE2 || element==EL_AMOEBE3)
2231 else if (element==EL_LIFE || element==EL_LIFE_ASYNC)
2233 else if (element==EL_ABLENK_EIN)
2235 else if (element==EL_SALZSAEURE)
2237 else if (element==EL_BLURB_LEFT || element==EL_BLURB_RIGHT)
2239 else if (element==EL_CRACKINGNUT)
2241 else if (element==EL_AUSGANG_ZU)
2242 AusgangstuerPruefen(x,y);
2243 else if (element==EL_AUSGANG_ACT)
2244 AusgangstuerOeffnen(x,y);
2246 if (SiebAktiv && (element==EL_SIEB_LEER ||
2247 element==EL_SIEB_VOLL ||
2248 Store[x][y]==EL_SIEB_LEER))
2249 SiebAktivieren(x,y);
2255 if (CheckMoving || CheckExploding)
2262 void ScrollLevel(int dx, int dy)
2266 XCopyArea(display,drawto_field,drawto_field,gc,
2267 SX+TILEX*(dx==-1),SY+TILEY*(dy==-1),
2268 SXSIZE-TILEX*(dx!=0),SYSIZE-TILEY*(dy!=0),
2269 SX+TILEX*(dx==1),SY+TILEY*(dy==1));
2273 x = dx==1 ? 0 : SCR_FIELDX-1;
2274 for(y=0;y<SCR_FIELDY;y++)
2275 DrawScreenField(x,y);
2279 y = dy==1 ? 0 : SCR_FIELDY-1;
2280 for(x=0;x<SCR_FIELDY;x++)
2281 DrawScreenField(x,y);
2284 redraw_mask|=REDRAW_FIELD;
2287 BOOL MoveFigureOneStep(int dx, int dy)
2289 int oldJX,oldJY, newJX=JX+dx,newJY=JY+dy;
2294 return(MF_NO_ACTION);
2295 if (!IN_LEV_FIELD(newJX,newJY))
2296 return(MF_NO_ACTION);
2298 element = MovingOrBlocked2Element(newJX,newJY);
2300 if (DONT_GO_TO(element))
2302 if (element==EL_SALZSAEURE && dx==0 && dy==1)
2305 Feld[JX][JY] = EL_SPIELFIGUR;
2306 InitMovingField(JX,JY,MV_DOWN);
2307 Store[JX][JY] = EL_SALZSAEURE;
2308 ContinueMoving(JX,JY);
2310 PlaySoundLevel(JX,JY,SND_AUTSCH);
2311 PlaySoundLevel(JX,JY,SND_LACHEN);
2321 can_move = DigField(newJX,newJY,DF_DIG);
2322 if (can_move != MF_MOVING)
2330 if (Store[oldJX][oldJY])
2332 DrawGraphic(SCROLLX(oldJX),SCROLLY(oldJY),el2gfx(Store[oldJX][oldJY]));
2333 DrawGraphicThruMask(SCROLLX(oldJX),SCROLLY(oldJY),
2334 el2gfx(Feld[oldJX][oldJY]));
2336 else if (Feld[oldJX][oldJY]==EL_DYNAMIT)
2337 DrawDynamite(oldJX,oldJY);
2339 DrawLevelField(oldJX,oldJY);
2344 BOOL MoveFigure(int dx, int dy)
2346 static long move_delay = 0;
2347 int moved = MF_NO_ACTION;
2349 if (GameOver || (!dx && !dy))
2352 if (!DelayReached(&move_delay,10) && !tape.playing)
2355 if (moved |= MoveFigureOneStep(dx,0))
2356 moved |= MoveFigureOneStep(0,dy);
2359 moved |= MoveFigureOneStep(0,dy);
2360 moved |= MoveFigureOneStep(dx,0);
2363 if (moved & MF_MOVING)
2365 int old_scroll_x=scroll_x, old_scroll_y=scroll_y;
2367 if (scroll_x!=JX-MIDPOSX && JX>=MIDPOSX-1 && JX<=lev_fieldx-MIDPOSX)
2368 scroll_x = JX-MIDPOSX;
2369 if (scroll_y!=JY-MIDPOSY && JY>=MIDPOSY-1 && JY<=lev_fieldy-MIDPOSY)
2370 scroll_y = JY-MIDPOSY;
2372 if (scroll_x!=old_scroll_x || scroll_y!=old_scroll_y)
2373 ScrollLevel(old_scroll_x-scroll_x,old_scroll_y-scroll_y);
2375 if (Feld[JX][JY]==EL_LEERRAUM)
2376 DrawLevelElement(JX,JY,EL_SPIELFIGUR);
2378 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_SPIELFIGUR);
2381 TestIfHeroHitsBadThing();
2391 void TestIfHeroHitsBadThing()
2393 int i, killx = JX,killy = JY;
2394 static int xy[4][2] =
2401 static int harmless[4] =
2415 if (!IN_LEV_FIELD(x,y))
2418 element = Feld[x][y];
2420 if (DONT_TOUCH(element))
2422 if (MovDir[x][y]==harmless[i])
2431 if (killx!=JX || killy!=JY)
2435 void TestIfBadThingHitsHero()
2437 TestIfHeroHitsBadThing();
2440 void TestIfBadThingHitsOtherBadThing(int badx, int bady)
2442 int i, killx=badx, killy=bady;
2443 static int xy[4][2] =
2457 if (!IN_LEV_FIELD(x,y))
2461 if (IS_AMOEBOID(element) || element==EL_LIFE ||
2462 element==EL_AMOEBING2 || element==EL_AMOEBING3 || element==EL_TROPFEN)
2470 if (killx!=badx || killy!=bady)
2479 if (IS_PFORTE(Feld[JX][JY]))
2480 Feld[JX][JY] = EL_LEERRAUM;
2482 PlaySoundLevel(JX,JY,SND_AUTSCH);
2483 PlaySoundLevel(JX,JY,SND_LACHEN);
2489 int DigField(int x, int y, int mode)
2491 int dx=x-JX, dy=y-JY;
2493 static long push_delay = 0;
2494 static int push_delay_value = 20;
2496 if (mode==DF_NO_PUSH)
2499 return(MF_NO_ACTION);
2503 return(MF_NO_ACTION);
2505 element = Feld[x][y];
2513 Feld[x][y]=EL_LEERRAUM;
2517 Feld[x][y]=EL_LEERRAUM;
2521 RaiseScore(level.score[SC_EDELSTEIN]);
2522 DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW);
2523 PlaySoundLevel(x,y,SND_PONG);
2526 Feld[x][y]=EL_LEERRAUM;
2531 RaiseScore(level.score[SC_DIAMANT]);
2532 DrawText(DX_EMERALDS,DY_EMERALDS,int2str(Gems,3),FS_SMALL,FC_YELLOW);
2533 PlaySoundLevel(x,y,SND_PONG);
2535 case EL_DYNAMIT_AUS:
2536 Feld[x][y]=EL_LEERRAUM;
2539 RaiseScore(level.score[SC_DYNAMIT]);
2540 DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
2541 PlaySoundLevel(x,y,SND_PONG);
2543 case EL_SCHLUESSEL1:
2544 case EL_SCHLUESSEL2:
2545 case EL_SCHLUESSEL3:
2546 case EL_SCHLUESSEL4:
2548 int key_nr = element-EL_SCHLUESSEL1;
2550 Feld[x][y] = EL_LEERRAUM;
2553 RaiseScore(level.score[SC_SCHLUESSEL]);
2554 DrawMiniGraphicExtHiRes(drawto,gc,
2555 DX_KEYS+key_nr*MINI_TILEX,DY_KEYS,
2556 GFX_SCHLUESSEL1+key_nr);
2557 DrawMiniGraphicExtHiRes(window,gc,
2558 DX_KEYS+key_nr*MINI_TILEX,DY_KEYS,
2559 GFX_SCHLUESSEL1+key_nr);
2560 PlaySoundLevel(x,y,SND_PONG);
2564 Feld[x][y]=EL_ABLENK_EIN;
2565 CheckExploding=TRUE;
2568 DrawLevelField(x,y);
2570 PlaySoundLevel(x,y,SND_DENG);
2574 case EL_FELSBROCKEN:
2578 return(MF_NO_ACTION);
2579 if (dy || !IN_LEV_FIELD(x+dx,y+dy) || Feld[x+dx][y+dy]!=EL_LEERRAUM)
2580 return(MF_NO_ACTION);
2582 if (Counter() > push_delay+4*push_delay_value)
2583 push_delay = Counter();
2584 if (!DelayReached(&push_delay,push_delay_value) && !tape.playing)
2585 return(MF_NO_ACTION);
2587 Feld[x][y] = EL_LEERRAUM;
2588 Feld[x+dx][y+dy] = element;
2589 push_delay_value = 10+RND(30);
2591 DrawLevelField(x+dx,y+dy);
2592 if (element==EL_FELSBROCKEN)
2593 PlaySoundLevel(x+dx,y+dy,SND_PUSCH);
2594 else if (element==EL_KOKOSNUSS)
2595 PlaySoundLevel(x+dx,y+dy,SND_KNURK);
2597 PlaySoundLevel(x+dx,y+dy,SND_KLOPF);
2603 if (!Key[element-EL_PFORTE1])
2604 return(MF_NO_ACTION);
2610 if (!Key[element-EL_PFORTE1X])
2611 return(MF_NO_ACTION);
2614 case EL_AUSGANG_ACT:
2615 /* Tür ist (noch) nicht offen! */
2616 return(MF_NO_ACTION);
2618 case EL_AUSGANG_AUF:
2619 if (mode==DF_SNAP || Gems>0)
2620 return(MF_NO_ACTION);
2622 PlaySoundLevel(x,y,SND_BUING);
2625 return(MF_NO_ACTION);
2632 BOOL SnapField(int dx, int dy)
2634 int x = JX+dx, y = JY+dy;
2635 static int snapped = FALSE;
2637 if (GameOver || !IN_LEV_FIELD(x,y))
2649 if (!DigField(x,y,DF_SNAP))
2653 DrawLevelField(x,y);
2659 BOOL PlaceBomb(void)
2661 if (Dynamite==0 || Feld[JX][JY]==EL_DYNAMIT)
2664 if (Feld[JX][JY]!=EL_LEERRAUM)
2665 Store[JX][JY] = Feld[JX][JY];
2666 Feld[JX][JY] = EL_DYNAMIT;
2667 MovDelay[JX][JY] = 48;
2669 DrawText(DX_DYNAMITE,DY_DYNAMITE,int2str(Dynamite,3),FS_SMALL,FC_YELLOW);
2670 DrawGraphicThruMask(SCROLLX(JX),SCROLLY(JY),GFX_DYNAMIT);
2671 CheckExploding = TRUE;
2675 void PlaySoundLevel(int x, int y, int sound_nr)
2677 int sx = SCROLLX(x), sy = SCROLLY(y);
2680 if (!sound_loops_on && IS_LOOP_SOUND(sound_nr))
2683 if (!IN_LEV_FIELD(x,y))
2686 volume = PSND_MAX_VOLUME;
2687 stereo = (sx-SCR_FIELDX/2)*12;
2689 if (!IN_SCR_FIELD(sx,sy))
2691 if (sx<0 || sx>=SCR_FIELDX)
2692 volume = PSND_MAX_VOLUME - 2*ABS(sx-SCR_FIELDX/2);
2694 volume = PSND_MAX_VOLUME - 2*ABS(sy-SCR_FIELDY/2);
2697 PlaySoundExt(sound_nr, volume, stereo, PSND_NO_LOOP);
2700 void RaiseScore(int value)
2703 DrawText(DX_SCORE,DY_SCORE,int2str(Score,5),FS_SMALL,FC_YELLOW);
2707 void TapeInitRecording()
2709 time_t zeit1 = time(NULL);
2710 struct tm *zeit2 = localtime(&zeit1);
2712 if (tape.recording || tape.playing)
2715 tape.level_nr = level_nr;
2716 tape.recording = TRUE;
2717 tape.pausing = TRUE;
2719 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday;
2721 DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_ON,0);
2722 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2723 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2726 void TapeStartRecording()
2730 tape.pos[tape.counter].delay = 0;
2731 tape.recording = TRUE;
2732 tape.playing = FALSE;
2733 tape.pausing = FALSE;
2734 tape.random_seed = InitRND(NEW_RANDOMIZE);
2735 DrawVideoDisplay(VIDEO_STATE_REC_ON | VIDEO_STATE_PAUSE_OFF,0);
2738 void TapeStopRecording()
2740 if (!tape.recording)
2743 tape.length = tape.counter;
2744 tape.recording = FALSE;
2745 tape.pausing = FALSE;
2746 DrawVideoDisplay(VIDEO_STATE_REC_OFF,0);
2751 void TapeRecordAction(int joy)
2753 if (!tape.recording || tape.pausing)
2756 if (tape.counter>=MAX_TAPELEN-1)
2758 TapeStopRecording();
2764 tape.pos[tape.counter].joystickdata = joy;
2766 tape.pos[tape.counter].delay = 0;
2770 void TapeRecordDelay()
2772 if (!tape.recording || tape.pausing)
2775 if (tape.counter>=MAX_TAPELEN)
2777 TapeStopRecording();
2781 tape.pos[tape.counter].delay++;
2783 if (tape.pos[tape.counter].delay>=255)
2785 tape.pos[tape.counter].joystickdata = 0;
2787 tape.pos[tape.counter].delay = 0;
2791 void TapeTogglePause()
2793 if (!tape.recording && !tape.playing)
2798 tape.pausing = FALSE;
2799 DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
2800 if (game_status==MAINMENU)
2801 HandleMainMenu(SX+16,SY+7*32+16,0,0,MB_MENU_CHOICE);
2805 tape.pausing = TRUE;
2806 DrawVideoDisplay(VIDEO_STATE_PAUSE_ON,0);
2810 void TapeInitPlaying()
2812 if (tape.recording || tape.playing || TAPE_IS_EMPTY(tape))
2815 tape.playing = TRUE;
2816 tape.pausing = TRUE;
2817 DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_ON,0);
2818 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2819 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2822 void TapeStartPlaying()
2827 tape.recording = FALSE;
2828 tape.playing = TRUE;
2829 tape.pausing = FALSE;
2830 InitRND(tape.random_seed);
2831 DrawVideoDisplay(VIDEO_STATE_PLAY_ON | VIDEO_STATE_PAUSE_OFF,0);
2834 void TapeStopPlaying()
2839 tape.playing = FALSE;
2840 tape.pausing = FALSE;
2841 DrawVideoDisplay(VIDEO_STATE_PLAY_OFF,0);
2844 int TapePlayAction()
2846 if (!tape.playing || tape.pausing)
2849 if (tape.counter>=tape.length)
2855 if (!tape.pos[tape.counter].delay)
2858 return(tape.pos[tape.counter-1].joystickdata);
2864 BOOL TapePlayDelay()
2866 if (!tape.playing || tape.pausing)
2869 if (tape.counter>=tape.length)
2875 if (tape.pos[tape.counter].delay)
2877 tape.pos[tape.counter].delay--;
2886 TapeStopRecording();
2888 DrawVideoDisplay(VIDEO_ALL_OFF,0);
2889 if (tape.date && tape.length)
2891 DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
2892 DrawVideoDisplay(VIDEO_STATE_TIME_ON,0);
2901 void DrawVideoDisplay(unsigned long state, unsigned long value)
2904 int part1 = 0, part2 = 1;
2905 int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
2906 static char *monatsname[12] =
2908 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
2909 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
2911 static int video_pos[10][2][4] =
2913 VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
2914 VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE,
2915 VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
2916 VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE,
2918 VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
2919 VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE,
2920 VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
2921 VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE,
2923 VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
2924 VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE,
2925 VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
2926 VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE,
2928 VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
2929 VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE,
2930 VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
2931 VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE,
2935 VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
2936 VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE,
2938 VIDEO_BUTTON_PLAY_XPOS, VIDEO_BUTTON_ANY_YPOS,
2939 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2943 VIDEO_BUTTON_REC_XPOS, VIDEO_BUTTON_ANY_YPOS,
2944 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2948 VIDEO_BUTTON_PAUSE_XPOS, VIDEO_BUTTON_ANY_YPOS,
2949 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2953 VIDEO_BUTTON_STOP_XPOS, VIDEO_BUTTON_ANY_YPOS,
2954 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2958 VIDEO_BUTTON_EJECT_XPOS, VIDEO_BUTTON_ANY_YPOS,
2959 VIDEO_BUTTON_XSIZE,VIDEO_BUTTON_YSIZE,
2968 int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
2970 if (i%2) /* i ungerade => STATE_ON / PRESS_OFF */
2971 cx = DOOR_GFX_PAGEX4;
2973 cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */
2975 if (video_pos[pos][part1][0])
2976 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
2977 cx + video_pos[pos][part1][xpos],
2978 cy + video_pos[pos][part1][ypos],
2979 video_pos[pos][part1][xsize],
2980 video_pos[pos][part1][ysize],
2981 VX + video_pos[pos][part1][xpos],
2982 VY + video_pos[pos][part1][ypos]);
2983 if (video_pos[pos][part2][0])
2984 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
2985 cx + video_pos[pos][part2][xpos],
2986 cy + video_pos[pos][part2][ypos],
2987 video_pos[pos][part2][xsize],
2988 video_pos[pos][part2][ysize],
2989 VX + video_pos[pos][part2][xpos],
2990 VY + video_pos[pos][part2][ypos]);
2994 if (state & VIDEO_STATE_DATE_ON)
2996 int tag = value % 100;
2997 int monat = (value/100) % 100;
2998 int jahr = (value/10000);
3000 DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
3001 int2str(tag,2),FS_SMALL,FC_SPECIAL1);
3002 DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
3003 monatsname[monat],FS_SMALL,FC_SPECIAL1);
3004 DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
3005 int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
3008 if (state & VIDEO_STATE_TIME_ON)
3010 int min = value / 60;
3011 int sec = value % 60;
3013 DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
3014 int2str(min,2),FS_SMALL,FC_SPECIAL1);
3015 DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
3016 int2str(sec,2),FS_SMALL,FC_SPECIAL1);
3019 if (state & VIDEO_STATE_DATE)
3020 redraw_mask |= REDRAW_VIDEO_1;
3021 if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
3022 redraw_mask |= REDRAW_VIDEO_2;
3023 if (state & VIDEO_PRESS)
3024 redraw_mask |= REDRAW_VIDEO_3;
3027 void DrawSoundDisplay(unsigned long state)
3029 int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
3031 pos = (state & BUTTON_SOUND_MUSIC ? SOUND_BUTTON_MUSIC_XPOS :
3032 state & BUTTON_SOUND_LOOPS ? SOUND_BUTTON_LOOPS_XPOS :
3033 SOUND_BUTTON_SOUND_XPOS);
3035 if (state & BUTTON_ON)
3036 cy -= SOUND_BUTTON_YSIZE;
3038 if (state & BUTTON_PRESSED)
3039 cx = DOOR_GFX_PAGEX3;
3041 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3042 cx + pos,cy + SOUND_BUTTON_ANY_YPOS,
3043 SOUND_BUTTON_XSIZE,SOUND_BUTTON_YSIZE,
3044 DX + pos,DY + SOUND_BUTTON_ANY_YPOS);
3046 redraw_mask |= REDRAW_DOOR_1;
3049 void DrawGameButton(unsigned long state)
3051 int pos, cx = DOOR_GFX_PAGEX4, cy = -GAME_BUTTON_YSIZE;
3053 pos = (state & BUTTON_GAME_STOP ? GAME_BUTTON_STOP_XPOS :
3054 state & BUTTON_GAME_PAUSE ? GAME_BUTTON_PAUSE_XPOS :
3055 GAME_BUTTON_PLAY_XPOS);
3057 if (state & BUTTON_PRESSED)
3058 cx = DOOR_GFX_PAGEX3;
3060 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3061 cx + pos,cy + GAME_BUTTON_ANY_YPOS,
3062 GAME_BUTTON_XSIZE,GAME_BUTTON_YSIZE,
3063 DX + pos,DY + GAME_BUTTON_ANY_YPOS);
3065 redraw_mask |= REDRAW_DOOR_1;
3068 void DrawChooseButton(unsigned long state)
3070 int pos, cx = DOOR_GFX_PAGEX4, cy = 0;
3072 pos = (state & BUTTON_OK ? OK_BUTTON_XPOS : NO_BUTTON_XPOS);
3074 if (state & BUTTON_PRESSED)
3075 cx = DOOR_GFX_PAGEX3;
3077 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3078 cx + pos,cy + OK_BUTTON_GFX_YPOS,
3079 OK_BUTTON_XSIZE,OK_BUTTON_YSIZE,
3080 DX + pos,DY + OK_BUTTON_YPOS);
3082 redraw_mask |= REDRAW_DOOR_1;
3085 void DrawConfirmButton(unsigned long state)
3087 int cx = DOOR_GFX_PAGEX4, cy = 0;
3089 if (state & BUTTON_PRESSED)
3090 cx = DOOR_GFX_PAGEX3;
3092 XCopyArea(display,pix[PIX_DOOR],drawto,gc,
3093 cx + CONFIRM_BUTTON_XPOS,cy + CONFIRM_BUTTON_GFX_YPOS,
3094 CONFIRM_BUTTON_XSIZE,CONFIRM_BUTTON_YSIZE,
3095 DX + CONFIRM_BUTTON_XPOS,DY + CONFIRM_BUTTON_YPOS);
3097 redraw_mask |= REDRAW_DOOR_1;