1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
22 boolean CreateNewScoreFile()
25 char filename[MAX_FILENAME_LEN];
26 char empty_alias[MAX_NAMELEN];
29 sprintf(filename,"%s/%s/%s",
30 level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
32 if (!(file=fopen(filename,"w")))
35 for(i=0;i<MAX_NAMELEN;i++)
37 strncpy(empty_alias,EMPTY_ALIAS,MAX_NAMELEN-1);
39 fputs(SCORE_COOKIE,file); /* Formatkennung */
40 for(i=0;i<leveldir[leveldir_nr].levels;i++)
42 for(j=0;j<MAX_SCORE_ENTRIES;j++)
44 for(k=0;k<MAX_NAMELEN;k++)
45 fputc(empty_alias[k],file);
52 chmod(filename, SCORE_PERMS);
60 boolean CreateNewNamesFile(int mode)
62 char filename[MAX_FILENAME_LEN];
65 if (mode==PLAYER_LEVEL)
66 sprintf(filename,"%s/%s/%s",
67 level_directory,leveldir[leveldir_nr].filename,NAMES_FILENAME);
69 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
71 if (!(file=fopen(filename,"w")))
74 fputs(NAMES_COOKIE,file); /* Formatkennung */
77 chmod(filename, NAMES_PERMS);
84 boolean LoadLevelInfo()
87 char filename[MAX_FILENAME_LEN];
88 char cookie[MAX_FILENAME_LEN];
91 sprintf(filename,"%s/%s",level_directory,LEVDIR_FILENAME);
93 if (!(file=fopen(filename,"r")))
95 Error(ERR_WARN, "cannot read level info '%s'", filename);
99 fscanf(file,"%s\n",cookie);
100 if (strcmp(cookie,LEVELDIR_COOKIE)) /* ungültiges Format? */
102 Error(ERR_WARN, "wrong format of level info file");
109 for(i=0;i<MAX_LEVDIR_ENTRIES;i++)
111 fscanf(file,"%s",leveldir[i].filename);
112 fscanf(file,"%s",leveldir[i].name);
113 fscanf(file,"%d",&leveldir[i].levels);
114 fscanf(file,"%d",&leveldir[i].readonly);
123 Error(ERR_WARN, "empty level info '%s'", filename);
130 void LoadLevel(int level_nr)
133 char filename[MAX_FILENAME_LEN];
134 char cookie[MAX_FILENAME_LEN];
137 sprintf(filename,"%s/%s/%d",
138 level_directory,leveldir[leveldir_nr].filename,level_nr);
140 if (!(file = fopen(filename,"r")))
141 Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
144 fgets(cookie,LEVEL_COOKIE_LEN,file);
147 if (strcmp(cookie,LEVEL_COOKIE)) /* ungültiges Format? */
149 Error(ERR_WARN, "wrong format of level file '%s'", filename);
157 lev_fieldx = level.fieldx = fgetc(file);
158 lev_fieldy = level.fieldy = fgetc(file);
160 level.time = (fgetc(file)<<8) | fgetc(file);
161 level.edelsteine = (fgetc(file)<<8) | fgetc(file);
162 for(i=0;i<MAX_LEVNAMLEN;i++)
163 level.name[i] = fgetc(file);
164 level.name[MAX_LEVNAMLEN-1] = 0;
165 for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
166 level.score[i] = fgetc(file);
170 level.mampfer_inhalt[i][x][y] = fgetc(file);
171 level.tempo_amoebe = fgetc(file);
172 level.dauer_sieb = fgetc(file);
173 level.dauer_ablenk = fgetc(file);
174 level.amoebe_inhalt = fgetc(file);
176 for(i=0;i<NUM_FREE_LVHD_BYTES;i++) /* Rest frei / Headergröße 80 Bytes */
179 for(y=0;y<MAX_LEV_FIELDY;y++)
180 for(x=0;x<MAX_LEV_FIELDX;x++)
181 Feld[x][y] = Ur[x][y] = EL_ERDREICH;
183 for(y=0;y<lev_fieldy;y++)
184 for(x=0;x<lev_fieldx;x++)
185 Feld[x][y] = Ur[x][y] = fgetc(file);
189 if (level.time<=10) /* Mindestspieldauer */
194 lev_fieldx = level.fieldx = STD_LEV_FIELDX;
195 lev_fieldy = level.fieldy = STD_LEV_FIELDY;
198 level.edelsteine = 0;
199 strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
200 for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
205 level.mampfer_inhalt[i][x][y] = EL_FELSBROCKEN;
206 level.tempo_amoebe = 10;
207 level.dauer_sieb = 10;
208 level.dauer_ablenk = 10;
209 level.amoebe_inhalt = EL_DIAMANT;
211 for(y=0;y<STD_LEV_FIELDY;y++)
212 for(x=0;x<STD_LEV_FIELDX;x++)
213 Feld[x][y] = Ur[x][y] = EL_ERDREICH;
214 Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
215 Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
216 Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
220 void LoadLevelTape(int level_nr)
223 char filename[MAX_FILENAME_LEN];
224 char cookie[MAX_FILENAME_LEN];
226 boolean levelrec_10 = FALSE;
229 sprintf(filename,"%s/%s/%d.tape",
230 level_directory,leveldir[leveldir_nr].filename,level_nr);
232 sprintf(filename,"%s/%s/%d.tap",
233 level_directory,leveldir[leveldir_nr].filename,level_nr);
236 if ((file=fopen(filename,"r")))
238 fgets(cookie,LEVELREC_COOKIE_LEN,file);
240 if (!strcmp(cookie,LEVELREC_COOKIE_10)) /* old 1.0 tape format */
242 else if (strcmp(cookie,LEVELREC_COOKIE)) /* unknown tape format */
244 Error(ERR_WARN, "wrong format of level recording file '%s'", filename);
254 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
256 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
258 (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
260 tape.level_nr = level_nr;
262 tape.changed = FALSE;
264 tape.recording = FALSE;
265 tape.playing = FALSE;
266 tape.pausing = FALSE;
268 for(i=0;i<tape.length;i++)
272 if (i >= MAX_TAPELEN)
275 for(j=0; j<MAX_PLAYERS; j++)
277 if (levelrec_10 && j>0)
279 tape.pos[i].action[j] = MV_NO_MOVING;
282 tape.pos[i].action[j] = fgetc(file);
285 tape.pos[i].delay = fgetc(file);
293 if (i != tape.length)
294 Error(ERR_WARN, "level recording file '%s' corrupted", filename);
296 tape.length_seconds = GetTapeLength();
299 void LoadScore(int level_nr)
302 char filename[MAX_FILENAME_LEN];
303 char cookie[MAX_FILENAME_LEN];
306 sprintf(filename,"%s/%s/%s",
307 level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
309 if (!(file = fopen(filename,"r")))
311 if (!CreateNewScoreFile())
312 Error(ERR_WARN, "cannot create score file '%s'", filename);
313 else if (!(file = fopen(filename,"r")))
314 Error(ERR_WARN, "cannot read score for level %d", level_nr);
319 fgets(cookie,SCORE_COOKIE_LEN,file);
320 if (strcmp(cookie,SCORE_COOKIE)) /* ungültiges Format? */
322 Error(ERR_WARN, "wrong format of score file '%s'", filename);
331 SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
333 for(i=0;i<MAX_SCORE_ENTRIES;i++)
335 for(j=0;j<MAX_NAMELEN;j++)
336 highscore[i].Name[j] = fgetc(file);
337 highscore[i].Score = (fgetc(file)<<8) | fgetc(file);
343 for(i=0;i<MAX_SCORE_ENTRIES;i++)
345 strcpy(highscore[i].Name,EMPTY_ALIAS);
346 highscore[i].Score = 0;
355 void LoadPlayerInfo(int mode)
358 char filename[MAX_FILENAME_LEN];
359 char cookie[MAX_FILENAME_LEN];
361 char *login_name = GetLoginName();
362 struct PlayerInfo default_player, new_player;
363 int version_10_file = FALSE;
367 if (mode == PLAYER_SETUP)
369 else if (mode == PLAYER_LEVEL)
374 if (mode==PLAYER_LEVEL)
375 sprintf(filename,"%s/%s/%s",
376 level_directory,leveldir[leveldir_nr].filename,NAMES_FILENAME);
378 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
380 for(i=0;i<MAX_NAMELEN;i++)
381 default_player.login_name[i] = default_player.alias_name[i] = 0;
382 strncpy(default_player.login_name,login_name,MAX_NAMELEN-1);
383 strncpy(default_player.alias_name,login_name,MAX_NAMELEN-1);
384 default_player.handicap = 0;
385 default_player.setup = DEFAULT_SETUP;
386 default_player.leveldir_nr = 0;
387 default_player.level_nr = 0;
389 new_player = default_player;
391 if (!(file = fopen(filename,"r")))
393 if (!CreateNewNamesFile(mode))
394 Error(ERR_WARN, "cannot create names file '%s'", filename);
395 else if (!(file = fopen(filename,"r")))
396 Error(ERR_WARN, "cannot read player information file '%s'", filename);
401 fgets(cookie,NAMES_COOKIE_LEN,file);
402 if (!strcmp(cookie,NAMES_COOKIE_10)) /* altes Format? */
403 version_10_file = TRUE;
404 else if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
406 Error(ERR_WARN, "wrong format of names file '%s'", filename);
414 *local_player = default_player;
415 level_nr = default_player.level_nr;
421 for(i=0;i<MAX_NAMELEN;i++)
422 new_player.login_name[i] = fgetc(file);
423 for(i=0;i<MAX_NAMELEN;i++)
424 new_player.alias_name[i] = fgetc(file);
425 new_player.handicap = fgetc(file);
426 new_player.setup = (fgetc(file)<<8) | fgetc(file);
427 new_player.leveldir_nr = fgetc(file);
428 if (!version_10_file)
430 new_player.level_nr = fgetc(file);
431 for(i=0;i<10;i++) /* currently unused bytes */
435 new_player.level_nr = new_player.handicap;
437 if (feof(file)) /* Spieler noch nicht in Liste enthalten */
439 new_player = default_player;
442 if (!(file = fopen(filename,"a")))
443 Error(ERR_WARN, "cannot append new player to names file '%s'",
447 for(i=0;i<MAX_NAMELEN;i++)
448 fputc(new_player.login_name[i],file);
449 for(i=0;i<MAX_NAMELEN;i++)
450 fputc(new_player.alias_name[i],file);
451 fputc(new_player.handicap,file);
452 fputc(new_player.setup / 256,file);
453 fputc(new_player.setup % 256,file);
454 fputc(new_player.leveldir_nr,file);
455 if (!version_10_file)
457 fputc(new_player.level_nr,file);
458 for(i=0;i<10;i++) /* currently unused bytes */
464 else /* prüfen, ob Spieler in Liste enthalten */
465 if (!strncmp(new_player.login_name,login_name,MAX_NAMELEN-1))
469 if (mode==PLAYER_SETUP)
471 *local_player = new_player;
472 if (local_player->leveldir_nr < num_leveldirs)
473 leveldir_nr = local_player->leveldir_nr;
479 local_player->handicap = new_player.handicap;
480 local_player->level_nr = new_player.level_nr;
483 level_nr = local_player->level_nr;
493 void SaveLevel(int level_nr)
496 char filename[MAX_FILENAME_LEN];
499 sprintf(filename,"%s/%s/%d",
500 level_directory,leveldir[leveldir_nr].filename,level_nr);
502 if (!(file=fopen(filename,"w")))
504 Error(ERR_WARN, "cannot save level file '%s'", filename);
508 fputs(LEVEL_COOKIE,file); /* Formatkennung */
511 fputc(level.fieldx,file);
512 fputc(level.fieldy,file);
513 fputc(level.time / 256,file);
514 fputc(level.time % 256,file);
515 fputc(level.edelsteine / 256,file);
516 fputc(level.edelsteine % 256,file);
518 for(i=0;i<MAX_LEVNAMLEN;i++)
519 fputc(level.name[i],file);
520 for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
521 fputc(level.score[i],file);
525 fputc(level.mampfer_inhalt[i][x][y],file);
526 fputc(level.tempo_amoebe,file);
527 fputc(level.dauer_sieb,file);
528 fputc(level.dauer_ablenk,file);
529 fputc(level.amoebe_inhalt,file);
531 for(i=0;i<NUM_FREE_LVHD_BYTES;i++) /* Rest frei / Headergröße 80 Bytes */
534 for(y=0;y<lev_fieldy;y++)
535 for(x=0;x<lev_fieldx;x++)
536 fputc(Ur[x][y],file);
540 chmod(filename, LEVEL_PERMS);
543 void SaveLevelTape(int level_nr)
546 char filename[MAX_FILENAME_LEN];
548 boolean new_tape = TRUE;
551 sprintf(filename,"%s/%s/%d.tape",
552 level_directory,leveldir[leveldir_nr].filename,level_nr);
554 sprintf(filename,"%s/%s/%d.tap",
555 level_directory,leveldir[leveldir_nr].filename,level_nr);
558 /* Testen, ob bereits eine Aufnahme existiert */
559 if ((file=fopen(filename,"r")))
564 if (!Request("Replace old tape ?",REQ_ASK))
568 if (!(file=fopen(filename,"w")))
570 Error(ERR_WARN, "cannot save level recording file '%s'", filename);
574 fputs(LEVELREC_COOKIE,file); /* Formatkennung */
577 fputc((tape.random_seed >> 24) & 0xff,file);
578 fputc((tape.random_seed >> 16) & 0xff,file);
579 fputc((tape.random_seed >> 8) & 0xff,file);
580 fputc((tape.random_seed >> 0) & 0xff,file);
582 fputc((tape.date >> 24) & 0xff,file);
583 fputc((tape.date >> 16) & 0xff,file);
584 fputc((tape.date >> 8) & 0xff,file);
585 fputc((tape.date >> 0) & 0xff,file);
587 fputc((tape.length >> 24) & 0xff,file);
588 fputc((tape.length >> 16) & 0xff,file);
589 fputc((tape.length >> 8) & 0xff,file);
590 fputc((tape.length >> 0) & 0xff,file);
592 for(i=0;i<tape.length;i++)
596 for(j=0; j<MAX_PLAYERS; j++)
597 fputc(tape.pos[i].action[j],file);
599 fputc(tape.pos[i].delay,file);
604 chmod(filename, LEVREC_PERMS);
606 tape.changed = FALSE;
609 Request("tape saved !",REQ_CONFIRM);
612 void SaveScore(int level_nr)
615 char filename[MAX_FILENAME_LEN];
618 sprintf(filename,"%s/%s/%s",
619 level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
621 if (!(file=fopen(filename,"r+")))
623 Error(ERR_WARN, "cannot save score for level %d", level_nr);
628 SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
630 for(i=0;i<MAX_SCORE_ENTRIES;i++)
632 for(j=0;j<MAX_NAMELEN;j++)
633 fputc(highscore[i].Name[j],file);
634 fputc(highscore[i].Score / 256,file);
635 fputc(highscore[i].Score % 256,file);
644 void SavePlayerInfo(int mode)
647 char filename[MAX_FILENAME_LEN];
648 char cookie[MAX_FILENAME_LEN];
650 struct PlayerInfo default_player;
651 int version_10_file = FALSE;
655 if (mode == PLAYER_SETUP)
657 else if (mode == PLAYER_LEVEL)
662 if (mode == PLAYER_LEVEL)
663 sprintf(filename,"%s/%s/%s",
664 level_directory,leveldir[leveldir_nr].filename,NAMES_FILENAME);
666 sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
668 if (!(file = fopen(filename,"r+")))
670 Error(ERR_WARN, "cannot save player information to file '%s'", filename);
674 fgets(cookie,NAMES_COOKIE_LEN,file);
675 if (!strcmp(cookie,NAMES_COOKIE_10)) /* altes Format? */
676 version_10_file = TRUE;
677 else if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
679 Error(ERR_WARN, "wrong format of names file '%s'", filename);
686 for(i=0;i<MAX_NAMELEN;i++)
687 default_player.login_name[i] = fgetc(file);
688 for(i=0;i<MAX_NAMELEN;i++)
689 default_player.alias_name[i] = fgetc(file);
690 default_player.handicap = fgetc(file);
691 default_player.setup = (fgetc(file)<<8) | fgetc(file);
692 default_player.leveldir_nr = fgetc(file);
693 if (!version_10_file)
695 default_player.level_nr = fgetc(file);
696 for(i=0;i<10;i++) /* currently unused bytes */
700 default_player.level_nr = default_player.handicap;
702 if (feof(file)) /* Spieler noch nicht in Liste enthalten */
704 else /* prüfen, ob Spieler in Liste enthalten */
705 if (!strncmp(default_player.login_name,
706 local_player->login_name, MAX_NAMELEN-1))
708 fseek(file,-(2*MAX_NAMELEN+1+2+1+(version_10_file ? 0 : 11)),SEEK_CUR);
713 local_player->level_nr = level_nr;
715 for(i=0;i<MAX_NAMELEN;i++)
716 fputc(local_player->login_name[i],file);
717 for(i=0;i<MAX_NAMELEN;i++)
718 fputc(local_player->alias_name[i],file);
719 fputc(local_player->handicap,file);
720 fputc(local_player->setup / 256,file);
721 fputc(local_player->setup % 256,file);
722 fputc(local_player->leveldir_nr,file);
723 if (!version_10_file)
725 fputc(local_player->level_nr,file);
726 for(i=0;i<10;i++) /* currently unused bytes */
737 void LoadJoystickData()
743 if (joystick_status==JOYSTICK_OFF)
747 if (!(file=fopen(JOYDAT_FILE,"r")))
750 fscanf(file,"%s",cookie);
751 if (strcmp(cookie,JOYSTICK_COOKIE)) /* ungültiges Format? */
753 Error(ERR_WARN, "wrong format of joystick file '%s'", JOYDAT_FILE);
760 fscanf(file,"%s",cookie);
761 fscanf(file, "%d %d %d \n",
762 &joystick[i].xleft, &joystick[i].xmiddle, &joystick[i].xright);
763 fscanf(file, "%d %d %d \n",
764 &joystick[i].yupper, &joystick[i].ymiddle, &joystick[i].ylower);
770 load_joystick_data(JOYDAT_FILE);
774 void SaveJoystickData()
779 if (joystick_status==JOYSTICK_OFF)
785 if (!(file=fopen(JOYDAT_FILE,"w")))
787 Error(ERR_WARN, "cannot save joystick calibration data to file '%s'",
792 fprintf(file,"%s\n",JOYSTICK_COOKIE); /* Formatkennung */
795 fprintf(file,"JOYSTICK_%d_DATA\n",i);
796 fprintf(file, "%d %d %d \n",
797 joystick[i].xleft, joystick[i].xmiddle, joystick[i].xright);
798 fprintf(file, "%d %d %d \n",
799 joystick[i].yupper, joystick[i].ymiddle, joystick[i].ylower);
803 chmod(JOYDAT_FILE, JOYDAT_PERMS);
805 save_joystick_data(JOYDAT_FILE);
810 /* ------------------------------------------------------------------------- */
811 /* new setup functions */
812 /* ------------------------------------------------------------------------- */
814 #define TOKEN_STR_FILE_IDENTIFIER "file_identifier"
815 #define TOKEN_STR_LAST_LEVEL_SERIES "last_level_series"
816 #define TOKEN_STR_ALIAS_NAME "alias_name"
818 #define TOKEN_STR_PLAYER_PREFIX "player_"
819 #define TOKEN_VALUE_POSITION 30
820 #define TOKEN_INVALID -1
821 #define TOKEN_IGNORE -99
823 #define SETUP_TOKEN_ALIAS_NAME 100
825 #define SETUP_TOKEN_SOUND 0
826 #define SETUP_TOKEN_SOUND_LOOPS 1
827 #define SETUP_TOKEN_SOUND_MUSIC 2
828 #define SETUP_TOKEN_SOUND_SIMPLE 3
829 #define SETUP_TOKEN_TOONS 4
830 #define SETUP_TOKEN_DIRECT_DRAW 5
831 #define SETUP_TOKEN_SCROLL_DELAY 6
832 #define SETUP_TOKEN_SOFT_SCROLLING 7
833 #define SETUP_TOKEN_FADING 8
834 #define SETUP_TOKEN_AUTORECORD 9
835 #define SETUP_TOKEN_QUICK_DOORS 10
836 #define SETUP_TOKEN_USE_JOYSTICK 11
837 #define SETUP_TOKEN_JOYSTICK_NR 12
838 #define SETUP_TOKEN_JOY_SNAP 13
839 #define SETUP_TOKEN_JOY_BOMB 14
840 #define SETUP_TOKEN_KEY_LEFT 15
841 #define SETUP_TOKEN_KEY_RIGHT 16
842 #define SETUP_TOKEN_KEY_UP 17
843 #define SETUP_TOKEN_KEY_DOWN 18
844 #define SETUP_TOKEN_KEY_SNAP 19
845 #define SETUP_TOKEN_KEY_BOMB 20
847 #define NUM_SETUP_TOKENS 21
851 char *token, *value_true, *value_false;
854 { "sound", "on", "off" },
855 { "repeating_sound_loops", "on", "off" },
856 { "background_music", "on", "off" },
857 { "simple_sound_effects", "on", "off" },
858 { "toons", "on", "off" },
859 { "double_buffering", "off", "on" },
860 { "scroll_delay", "on", "off" },
861 { "soft_scrolling", "on", "off" },
862 { "screen_fading", "on", "off" },
863 { "automatic_tape_recording", "on", "off" },
864 { "quick_doors", "on", "off" },
866 /* for each player: */
867 { ".use_joystick", "true", "false" },
868 { ".joystick_device", "second", "first" },
869 { ".joy.snap_field", "", "" },
870 { ".joy.place_bomb", "", "" },
871 { ".key.move_left", "", "" },
872 { ".key.move_right", "", "" },
873 { ".key.move_up", "", "" },
874 { ".key.move_down", "", "" },
875 { ".key.snap_field", "", "" },
876 { ".key.place_bomb", "", "" }
879 static char *string_tolower(char *s)
881 static char s_lower[100];
884 if (strlen(s) >= 100)
889 for (i=0; i<strlen(s_lower); i++)
890 s_lower[i] = tolower(s_lower[i]);
895 static int get_string_integer_value(char *s)
897 static char *number_text[][3] =
899 { "0", "zero", "null", },
900 { "1", "one", "first" },
901 { "2", "two", "second" },
902 { "3", "three", "third" },
903 { "4", "four", "fourth" },
904 { "5", "five", "fifth" },
905 { "6", "six", "sixth" },
906 { "7", "seven", "seventh" },
907 { "8", "eight", "eighth" },
908 { "9", "nine", "ninth" },
909 { "10", "ten", "tenth" },
910 { "11", "eleven", "eleventh" },
911 { "12", "twelve", "twelfth" },
918 if (strcmp(string_tolower(s), number_text[i][j]) == 0)
924 static boolean get_string_boolean_value(char *s)
926 if (strcmp(string_tolower(s), "true") == 0 ||
927 strcmp(string_tolower(s), "yes") == 0 ||
928 strcmp(string_tolower(s), "on") == 0 ||
929 get_string_integer_value(s) == 1)
935 static char *getSetupToken(int token_nr)
937 return setup_info[token_nr].token;
940 static char *getSetupValue(int token_nr, boolean token_value)
942 if (token_value == TRUE)
943 return setup_info[token_nr].value_true;
945 return setup_info[token_nr].value_false;
948 static char *getFormattedSetupEntry(char *token, char *value)
951 static char entry[MAX_LINE_LEN];
953 sprintf(entry, "%s:", token);
954 for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
958 strcat(entry, value);
963 static char *getSetupEntry(char *prefix, int token_nr, int token_value)
966 static char entry[MAX_LINE_LEN];
968 sprintf(entry, "%s%s:", prefix, getSetupToken(token_nr));
969 for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
973 strcat(entry, getSetupValue(token_nr, token_value));
978 static char *getSetupEntryWithComment(char *prefix,int token_nr, KeySym keysym)
981 static char entry[MAX_LINE_LEN];
982 char *keyname = getKeyNameFromKeySym(keysym);
984 sprintf(entry, "%s%s:", prefix, getSetupToken(token_nr));
985 for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
989 strcat(entry, getX11KeyNameFromKeySym(keysym));
990 for (i=strlen(entry); i<50; i++)
994 /* add comment, if useful */
995 if (strcmp(keyname, "(undefined)") != 0 &&
996 strcmp(keyname, "(unknown)") != 0)
999 strcat(entry, keyname);
1005 static void freeSetupFileList(struct SetupFileList *setup_file_list)
1007 if (!setup_file_list)
1010 if (setup_file_list->token)
1011 free(setup_file_list->token);
1012 if (setup_file_list->value)
1013 free(setup_file_list->value);
1014 if (setup_file_list->next)
1015 freeSetupFileList(setup_file_list->next);
1016 free(setup_file_list);
1019 static struct SetupFileList *newSetupFileList(char *token, char *value)
1021 struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList));
1023 new->token = checked_malloc(strlen(token) + 1);
1024 strcpy(new->token, token);
1026 new->value = checked_malloc(strlen(value) + 1);
1027 strcpy(new->value, value);
1034 static char *getSetupFileListEntry(struct SetupFileList *setup_file_list,
1037 if (!setup_file_list)
1040 if (strcmp(setup_file_list->token, token) == 0)
1041 return setup_file_list->value;
1043 return getSetupFileListEntry(setup_file_list->next, token);
1046 boolean setSetupFileListEntry(struct SetupFileList *setup_file_list,
1047 char *token, char *value)
1049 if (!setup_file_list)
1052 if (strcmp(setup_file_list->token, token) == 0)
1054 free(setup_file_list->value);
1055 setup_file_list->value = checked_malloc(strlen(value) + 1);
1056 strcpy(setup_file_list->value, value);
1061 return setSetupFileListEntry(setup_file_list->next, token, value);
1064 void updateSetupFileListEntry(struct SetupFileList *setup_file_list,
1065 char *token, char *value)
1067 if (!setup_file_list)
1070 if (getSetupFileListEntry(setup_file_list, token) != NULL)
1071 setSetupFileListEntry(setup_file_list, token, value);
1074 struct SetupFileList *list_entry = setup_file_list;
1076 while (list_entry->next)
1077 list_entry = list_entry->next;
1079 list_entry->next = newSetupFileList(token, value);
1084 static void printSetupFileList(struct SetupFileList *setup_file_list)
1086 if (!setup_file_list)
1089 printf("token: '%s'\n", setup_file_list->token);
1090 printf("value: '%s'\n", setup_file_list->value);
1092 printSetupFileList(setup_file_list->next);
1096 static struct SetupFileList *loadSetupFileList(char *filename)
1099 char line[MAX_LINE_LEN];
1100 char *token, *value, *line_ptr;
1101 struct SetupFileList *setup_file_list = newSetupFileList("", "");
1102 struct SetupFileList *first_valid_list_entry;
1107 struct SetupFileList **next_entry = &setup_file_list;
1113 if (!(file = fopen(filename, "r")))
1115 Error(ERR_WARN, "cannot open setup file '%s'", filename);
1121 /* read next line of input file */
1122 if (!fgets(line, MAX_LINE_LEN, file))
1125 /* cut trailing comment or whitespace from input line */
1126 for (line_ptr = line; *line_ptr; line_ptr++)
1128 if (*line_ptr == '#' || *line_ptr == '\n')
1135 /* cut trailing whitespaces from input line */
1136 for (line_ptr = &line[strlen(line)]; line_ptr > line; line_ptr--)
1137 if ((*line_ptr == ' ' || *line_ptr == '\t') && line_ptr[1] == '\0')
1140 /* ignore empty lines */
1144 line_len = strlen(line);
1146 /* cut leading whitespaces from token */
1147 for (token = line; *token; token++)
1148 if (*token != ' ' && *token != '\t')
1151 /* find end of token */
1152 for (line_ptr = token; *line_ptr; line_ptr++)
1154 if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
1161 if (line_ptr < line + line_len)
1162 value = line_ptr + 1;
1166 /* cut leading whitespaces from value */
1167 for (; *value; value++)
1168 if (*value != ' ' && *value != '\t')
1171 if (*token && *value)
1172 updateSetupFileListEntry(setup_file_list, token, value);
1177 /* allocate new token/value pair */
1179 *next_entry = newSetupFileList(token, value);
1180 next_entry = &((*next_entry)->next);
1190 first_valid_list_entry = setup_file_list->next;
1192 /* free empty list header */
1193 setup_file_list->next = NULL;
1194 freeSetupFileList(setup_file_list);
1196 if (!first_valid_list_entry)
1197 Error(ERR_WARN, "setup file is empty");
1199 return first_valid_list_entry;
1202 static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
1205 if (!setup_file_list)
1208 if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0)
1210 if (strcmp(setup_file_list->value, identifier) != 0)
1212 Error(ERR_WARN, "setup file has wrong version");
1219 if (setup_file_list->next)
1220 checkSetupFileListIdentifier(setup_file_list->next, identifier);
1223 Error(ERR_WARN, "setup file has no version information");
1228 static void decodeSetupFileList(struct SetupFileList *setup_file_list)
1231 int token_nr = TOKEN_INVALID;
1235 int token_integer_value;
1236 boolean token_boolean_value;
1237 int token_player_prefix_len;
1239 if (!setup_file_list)
1242 token = setup_file_list->token;
1243 token_value = setup_file_list->value;
1244 token_integer_value = get_string_integer_value(token_value);
1245 token_boolean_value = get_string_boolean_value(token_value);
1247 token_player_prefix_len = strlen(TOKEN_STR_PLAYER_PREFIX);
1249 if (strncmp(token, TOKEN_STR_PLAYER_PREFIX,
1250 token_player_prefix_len) == 0)
1252 token += token_player_prefix_len;
1254 if (*token >= '0' && *token <= '9')
1256 player_nr = ((int)(*token - '0') - 1 + MAX_PLAYERS) % MAX_PLAYERS;
1261 for (i=0; i<NUM_SETUP_TOKENS; i++)
1263 if (strcmp(token, setup_info[i].token) == 0)
1270 if (strcmp(token, TOKEN_STR_FILE_IDENTIFIER) == 0)
1271 token_nr = TOKEN_IGNORE;
1272 else if (strcmp(token, TOKEN_STR_ALIAS_NAME) == 0)
1273 token_nr = SETUP_TOKEN_ALIAS_NAME;
1277 case SETUP_TOKEN_SOUND:
1278 setup.sound_on = token_boolean_value;
1280 case SETUP_TOKEN_SOUND_LOOPS:
1281 setup.sound_loops_on = token_boolean_value;
1283 case SETUP_TOKEN_SOUND_MUSIC:
1284 setup.sound_music_on = token_boolean_value;
1286 case SETUP_TOKEN_SOUND_SIMPLE:
1287 setup.sound_simple_on = token_boolean_value;
1289 case SETUP_TOKEN_TOONS:
1290 setup.toons_on = token_boolean_value;
1292 case SETUP_TOKEN_DIRECT_DRAW:
1293 setup.direct_draw_on = !token_boolean_value;
1295 case SETUP_TOKEN_SCROLL_DELAY:
1296 setup.scroll_delay_on = token_boolean_value;
1298 case SETUP_TOKEN_SOFT_SCROLLING:
1299 setup.soft_scrolling_on = token_boolean_value;
1301 case SETUP_TOKEN_FADING:
1302 setup.fading_on = token_boolean_value;
1304 case SETUP_TOKEN_AUTORECORD:
1305 setup.autorecord_on = token_boolean_value;
1307 case SETUP_TOKEN_QUICK_DOORS:
1308 setup.quick_doors = token_boolean_value;
1311 case SETUP_TOKEN_USE_JOYSTICK:
1312 setup.input[player_nr].use_joystick = token_boolean_value;
1314 case SETUP_TOKEN_JOYSTICK_NR:
1315 if (token_integer_value < 0 || token_integer_value > 1)
1316 token_integer_value = 1;
1317 setup.input[player_nr].joystick_nr = token_integer_value - 1;
1319 case SETUP_TOKEN_JOY_SNAP:
1320 setup.input[player_nr].joy.snap = getJoySymbolFromJoyName(token_value);
1322 case SETUP_TOKEN_JOY_BOMB :
1323 setup.input[player_nr].joy.bomb = getJoySymbolFromJoyName(token_value);
1325 case SETUP_TOKEN_KEY_LEFT:
1326 setup.input[player_nr].key.left = getKeySymFromX11KeyName(token_value);
1328 case SETUP_TOKEN_KEY_RIGHT:
1329 setup.input[player_nr].key.right = getKeySymFromX11KeyName(token_value);
1331 case SETUP_TOKEN_KEY_UP:
1332 setup.input[player_nr].key.up = getKeySymFromX11KeyName(token_value);
1334 case SETUP_TOKEN_KEY_DOWN:
1335 setup.input[player_nr].key.down = getKeySymFromX11KeyName(token_value);
1337 case SETUP_TOKEN_KEY_SNAP:
1338 setup.input[player_nr].key.snap = getKeySymFromX11KeyName(token_value);
1340 case SETUP_TOKEN_KEY_BOMB:
1341 setup.input[player_nr].key.bomb = getKeySymFromX11KeyName(token_value);
1344 case SETUP_TOKEN_ALIAS_NAME:
1345 strncpy(local_player->alias_name, token_value, MAX_NAMELEN-1);
1346 local_player->alias_name[MAX_NAMELEN-1] = '\0';
1350 Error(ERR_WARN, "unknown token '%s' not recognized", token);
1358 decodeSetupFileList(setup_file_list->next);
1364 char filename[MAX_FILENAME_LEN];
1365 struct SetupFileList *setup_file_list = NULL;
1367 /* always start with reliable default setup values */
1369 strncpy(local_player->login_name, GetLoginName(), MAX_NAMELEN-1);
1370 local_player->login_name[MAX_NAMELEN-1] = '\0';
1372 strncpy(local_player->alias_name, GetLoginName(), MAX_NAMELEN-1);
1373 local_player->alias_name[MAX_NAMELEN-1] = '\0';
1375 setup.sound_on = TRUE;
1376 setup.sound_loops_on = FALSE;
1377 setup.sound_music_on = FALSE;
1378 setup.sound_simple_on = FALSE;
1379 setup.toons_on = TRUE;
1380 setup.direct_draw_on = FALSE;
1381 setup.scroll_delay_on = FALSE;
1382 setup.soft_scrolling_on = TRUE;
1383 setup.fading_on = FALSE;
1384 setup.autorecord_on = FALSE;
1385 setup.quick_doors = FALSE;
1387 for (i=0; i<MAX_PLAYERS; i++)
1389 setup.input[i].use_joystick = FALSE;
1390 setup.input[i].joystick_nr = 0;
1391 setup.input[i].joy.snap = (i == 0 ? JOY_BUTTON_1 : 0);
1392 setup.input[i].joy.bomb = (i == 0 ? JOY_BUTTON_2 : 0);
1393 setup.input[i].key.left = (i == 0 ? DEFAULT_KEY_LEFT : KEY_UNDEFINDED);
1394 setup.input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KEY_UNDEFINDED);
1395 setup.input[i].key.up = (i == 0 ? DEFAULT_KEY_UP : KEY_UNDEFINDED);
1396 setup.input[i].key.down = (i == 0 ? DEFAULT_KEY_DOWN : KEY_UNDEFINDED);
1397 setup.input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KEY_UNDEFINDED);
1398 setup.input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KEY_UNDEFINDED);
1401 sprintf(filename, "%s/%s", SETUP_PATH, SETUP_FILENAME);
1403 setup_file_list = loadSetupFileList(filename);
1405 if (setup_file_list)
1409 printSetupFileList(setup_file_list);
1412 checkSetupFileListIdentifier(setup_file_list, SETUP_COOKIE);
1413 decodeSetupFileList(setup_file_list);
1415 freeSetupFileList(setup_file_list);
1418 Error(ERR_RETURN, "using default setup values");
1421 void LoadLevelSetup()
1423 char filename[MAX_FILENAME_LEN];
1425 /* always start with reliable default setup values */
1430 sprintf(filename, "%s/%s", SETUP_PATH, LEVELSETUP_FILENAME);
1432 if (level_setup_list)
1433 freeSetupFileList(level_setup_list);
1435 level_setup_list = loadSetupFileList(filename);
1437 if (level_setup_list)
1441 char *last_level_series =
1442 getSetupFileListEntry(level_setup_list, TOKEN_STR_LAST_LEVEL_SERIES);
1444 if (last_level_series)
1446 for (i=0; i<num_leveldirs; i++)
1448 if (strcmp(last_level_series, leveldir[i].filename) == 0)
1451 getSetupFileListEntry(level_setup_list, last_level_series);
1457 level_nr = atoi(token_value);
1461 if (level_nr > leveldir[leveldir_nr].levels - 1)
1462 level_nr = leveldir[leveldir_nr].levels - 1;
1472 printSetupFileList(level_setup_list);
1475 checkSetupFileListIdentifier(level_setup_list, LEVELSETUP_COOKIE);
1478 Error(ERR_RETURN, "using default setup values");
1484 char filename[MAX_FILENAME_LEN];
1487 sprintf(filename, "%s/%s", SETUP_PATH, SETUP_FILENAME);
1489 if (!(file = fopen(filename, "w")))
1491 Error(ERR_WARN, "cannot write setup file '%s'", filename);
1495 fprintf(file, "%s: %s\n",
1496 TOKEN_STR_FILE_IDENTIFIER, SETUP_COOKIE);
1498 fprintf(file, "\n");
1500 fprintf(file, "%s\n",
1501 getSetupEntry("", SETUP_TOKEN_SOUND,
1503 fprintf(file, "%s\n",
1504 getSetupEntry("", SETUP_TOKEN_SOUND_LOOPS,
1505 setup.sound_loops_on));
1506 fprintf(file, "%s\n",
1507 getSetupEntry("", SETUP_TOKEN_SOUND_MUSIC,
1508 setup.sound_music_on));
1509 fprintf(file, "%s\n",
1510 getSetupEntry("", SETUP_TOKEN_SOUND_SIMPLE,
1511 setup.sound_simple_on));
1512 fprintf(file, "%s\n",
1513 getSetupEntry("", SETUP_TOKEN_TOONS,
1515 fprintf(file, "%s\n",
1516 getSetupEntry("", SETUP_TOKEN_DIRECT_DRAW,
1517 setup.direct_draw_on));
1518 fprintf(file, "%s\n",
1519 getSetupEntry("", SETUP_TOKEN_SCROLL_DELAY,
1520 setup.scroll_delay_on));
1521 fprintf(file, "%s\n",
1522 getSetupEntry("", SETUP_TOKEN_SOFT_SCROLLING,
1523 setup.soft_scrolling_on));
1524 fprintf(file, "%s\n",
1525 getSetupEntry("", SETUP_TOKEN_FADING,
1527 fprintf(file, "%s\n",
1528 getSetupEntry("", SETUP_TOKEN_AUTORECORD,
1529 setup.autorecord_on));
1530 fprintf(file, "%s\n",
1531 getSetupEntry("", SETUP_TOKEN_QUICK_DOORS,
1532 setup.quick_doors));
1534 fprintf(file, "\n");
1536 fprintf(file, "%s\n",
1537 getFormattedSetupEntry(TOKEN_STR_ALIAS_NAME,
1538 local_player->alias_name));
1540 for (i=0; i<MAX_PLAYERS; i++)
1544 sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, i + 1);
1546 fprintf(file, "\n");
1548 fprintf(file, "%s\n",
1549 getSetupEntry(prefix, SETUP_TOKEN_USE_JOYSTICK,
1550 setup.input[i].use_joystick));
1551 fprintf(file, "%s\n",
1552 getSetupEntry(prefix, SETUP_TOKEN_JOYSTICK_NR,
1553 setup.input[i].joystick_nr));
1555 fprintf(file, "%s%s: %s\n", prefix,
1556 getSetupToken(SETUP_TOKEN_JOY_SNAP),
1557 getJoyNameFromJoySymbol(setup.input[i].joy.snap));
1558 fprintf(file, "%s%s: %s\n", prefix,
1559 getSetupToken(SETUP_TOKEN_JOY_BOMB),
1560 getJoyNameFromJoySymbol(setup.input[i].joy.bomb));
1562 fprintf(file, "%s\n",
1563 getSetupEntryWithComment(prefix, SETUP_TOKEN_KEY_LEFT,
1564 setup.input[i].key.left));
1565 fprintf(file, "%s\n",
1566 getSetupEntryWithComment(prefix, SETUP_TOKEN_KEY_RIGHT,
1567 setup.input[i].key.right));
1568 fprintf(file, "%s\n",
1569 getSetupEntryWithComment(prefix, SETUP_TOKEN_KEY_UP,
1570 setup.input[i].key.up));
1571 fprintf(file, "%s\n",
1572 getSetupEntryWithComment(prefix, SETUP_TOKEN_KEY_DOWN,
1573 setup.input[i].key.down));
1574 fprintf(file, "%s\n",
1575 getSetupEntryWithComment(prefix, SETUP_TOKEN_KEY_SNAP,
1576 setup.input[i].key.snap));
1577 fprintf(file, "%s\n",
1578 getSetupEntryWithComment(prefix, SETUP_TOKEN_KEY_BOMB,
1579 setup.input[i].key.bomb));
1584 chmod(filename, SETUP_PERMS);
1587 void SaveLevelSetup()
1589 char filename[MAX_FILENAME_LEN];
1590 struct SetupFileList *list_entry = level_setup_list;
1593 updateSetupFileListEntry(level_setup_list,
1594 TOKEN_STR_LAST_LEVEL_SERIES,
1595 leveldir[leveldir_nr].filename);
1597 updateSetupFileListEntry(level_setup_list,
1598 leveldir[leveldir_nr].filename,
1599 int2str(level_nr, 0));
1601 sprintf(filename, "%s/%s", SETUP_PATH, LEVELSETUP_FILENAME);
1603 if (!(file = fopen(filename, "w")))
1605 Error(ERR_WARN, "cannot write setup file '%s'", filename);
1609 fprintf(file, "%s: %s\n\n",
1610 TOKEN_STR_FILE_IDENTIFIER, LEVELSETUP_COOKIE);
1614 if (strcmp(list_entry->token, TOKEN_STR_FILE_IDENTIFIER) != 0)
1615 fprintf(file, "%s\n",
1616 getFormattedSetupEntry(list_entry->token, list_entry->value));
1618 /* just to make things nicer :) */
1619 if (strcmp(list_entry->token, TOKEN_STR_LAST_LEVEL_SERIES) == 0)
1620 fprintf(file, "\n");
1622 list_entry = list_entry->next;
1627 chmod(filename, SETUP_PERMS);