rocks_n_diamonds-0.9b2
[rocksndiamonds.git] / src / files.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  ©1995 Artsoft Development                               *
5 *        Holger Schemel                                    *
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 *----------------------------------------------------------*
12 *  files.h                                                 *
13 ***********************************************************/
14
15 #include "files.h"
16 #include "tools.h"
17 #include "misc.h"
18
19 BOOL CreateNewScoreFile()
20 {
21   int i,j,k;
22   char filename[MAX_FILENAME];
23   char empty_alias[MAX_NAMELEN];
24   FILE *file;
25
26   sprintf(filename,"%s/%s/%s",
27           SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
28
29   if (!(file=fopen(filename,"w")))
30     return(FALSE);
31
32   for(i=0;i<MAX_NAMELEN;i++)
33     empty_alias[i] = 0;
34   strncpy(empty_alias,EMPTY_ALIAS,MAX_NAMELEN-1);
35
36   fputs(SCORE_COOKIE,file);             /* Formatkennung */
37   for(i=0;i<LEVELDIR_SIZE(leveldir[leveldir_nr]);i++)
38   {
39     for(j=0;j<MAX_SCORE_ENTRIES;j++)
40     {
41       for(k=0;k<MAX_NAMELEN;k++)
42         fputc(empty_alias[k],file);
43       fputc(0,file);
44       fputc(0,file);
45     }
46   }
47   fclose(file);
48
49   chmod(filename, SCORE_PERMS);
50   return(TRUE);
51 }
52
53 BOOL CreateNewNamesFile(int mode)
54 {
55   char filename[MAX_FILENAME];
56   FILE *file;
57
58   if (mode==PLAYER_LEVEL)
59     sprintf(filename,"%s/%s/%s",
60             NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
61   else
62     sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
63
64   if (!(file=fopen(filename,"w")))
65     return(FALSE);
66
67   fputs(NAMES_COOKIE,file);             /* Formatkennung */
68   fclose(file);
69
70   chmod(filename, NAMES_PERMS);
71   return(TRUE);
72 }
73
74 BOOL LoadLevelInfo()
75 {
76   int i;
77   char filename[MAX_FILENAME];
78   char cookie[MAX_FILENAME];
79   FILE *file;
80
81   sprintf(filename,"%s/%s",LEVEL_PATH,LEVDIR_FILENAME);
82
83   if (!(file=fopen(filename,"r")))
84   {
85     fprintf(stderr,"%s: cannot load level info '%s'!\n",progname,filename);
86     return(FALSE);
87   }
88
89   fscanf(file,"%s\n",cookie);
90   if (strcmp(cookie,LEVELDIR_COOKIE))   /* ungültiges Format? */
91   {
92     fprintf(stderr,"%s: wrong format of level info file!\n",progname);
93     fclose(file);
94     return(FALSE);
95   }
96
97   num_leveldirs = 0;
98   leveldir_nr = 0;
99   for(i=0;i<MAX_LEVDIR_ENTRIES;i++)
100   {
101     fscanf(file,"%s",leveldir[i].filename);
102     fscanf(file,"%s",leveldir[i].name);
103     fscanf(file,"%d",&leveldir[i].num_ready);
104     fscanf(file,"%d",&leveldir[i].num_free);
105     if (feof(file))
106       break;
107
108     num_leveldirs++;
109   }
110
111   if (!num_leveldirs)
112   {
113     fprintf(stderr,"%s: empty level info '%s'!\n",progname,filename);
114     return(FALSE);
115   }
116
117   return(TRUE);
118 }
119
120 void LoadLevel(int level_nr)
121 {
122   int i,x,y;
123   char filename[MAX_FILENAME];
124   char cookie[MAX_FILENAME];
125   FILE *file;
126
127   sprintf(filename,"%s/%s/%d",
128           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
129
130   if (!(file=fopen(filename,"r")))
131   {
132 /*
133     fprintf(stderr,"%s: cannot load level '%s'!\n",progname,filename);
134 */
135   }
136   else
137   {
138     fgets(cookie,LEVEL_COOKIE_LEN,file);
139     fgetc(file);
140     if (strcmp(cookie,LEVEL_COOKIE))    /* ungültiges Format? */
141     {
142       fprintf(stderr,"%s: wrong format of level file '%s'!\n",
143               progname,filename);
144       fclose(file);
145       file = NULL;
146     }
147   }
148
149   if (file)
150   {
151     lev_fieldx = level.fieldx = fgetc(file);
152     lev_fieldy = level.fieldy = fgetc(file);
153
154     level.time          = (fgetc(file)<<8) | fgetc(file);
155     level.edelsteine    = (fgetc(file)<<8) | fgetc(file);
156     for(i=0;i<MAX_LEVNAMLEN;i++)
157       level.name[i]     = fgetc(file);
158     level.name[MAX_LEVNAMLEN-1] = 0;
159     for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
160       level.score[i]    = fgetc(file);
161     for(i=0;i<4;i++)
162       for(y=0;y<3;y++)
163         for(x=0;x<3;x++)
164           level.mampfer_inhalt[i][x][y] = fgetc(file);
165     level.tempo_amoebe  = fgetc(file);
166     level.dauer_sieb    = fgetc(file);
167     level.dauer_ablenk  = fgetc(file);
168     level.amoebe_inhalt = fgetc(file);
169
170     for(i=0;i<NUM_FREE_LVHD_BYTES;i++)  /* Rest frei / Headergröße 80 Bytes */
171       fgetc(file);
172
173     for(y=0;y<MAX_LEV_FIELDY;y++) 
174       for(x=0;x<MAX_LEV_FIELDX;x++) 
175         Feld[x][y] = Ur[x][y] = EL_ERDREICH;
176
177     for(y=0;y<lev_fieldy;y++) 
178       for(x=0;x<lev_fieldx;x++) 
179         Feld[x][y] = Ur[x][y] = fgetc(file);
180
181     fclose(file);
182
183     if (level.time<=10) /* Mindestspieldauer */
184       level.time = 10;
185   }
186   else
187   {
188     lev_fieldx = level.fieldx = STD_LEV_FIELDX;
189     lev_fieldy = level.fieldy = STD_LEV_FIELDY;
190
191     level.time          = 100;
192     level.edelsteine    = 0;
193     strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
194     for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
195       level.score[i]    = 10;
196     for(i=0;i<4;i++)
197       for(y=0;y<3;y++)
198         for(x=0;x<3;x++)
199           level.mampfer_inhalt[i][x][y] = EL_FELSBROCKEN;
200     level.tempo_amoebe  = 10;
201     level.dauer_sieb    = 10;
202     level.dauer_ablenk  = 10;
203     level.amoebe_inhalt = EL_DIAMANT;
204
205     for(y=0;y<STD_LEV_FIELDY;y++) 
206       for(x=0;x<STD_LEV_FIELDX;x++) 
207         Feld[x][y] = Ur[x][y] = EL_ERDREICH;
208     Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
209     Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
210       Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
211   }
212 }
213
214 void LoadLevelTape(int level_nr)
215 {
216   int i;
217   char filename[MAX_FILENAME];
218   char cookie[MAX_FILENAME];
219   FILE *file;
220
221   sprintf(filename,"%s/%s/%d.tape",
222           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
223
224   if ((file=fopen(filename,"r")))
225   {
226     fgets(cookie,LEVELREC_COOKIE_LEN,file);
227     fgetc(file);
228     if (strcmp(cookie,LEVELREC_COOKIE)) /* ungültiges Format? */
229     {
230       fprintf(stderr,"%s: wrong format of level recording file '%s'!\n",
231               progname,filename);
232       fclose(file);
233       file = NULL;
234     }
235   }
236
237   if (!file)
238     return;
239
240   tape.random_seed =
241     (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
242   tape.date =
243     (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
244   tape.length =
245     (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
246
247   tape.level_nr = level_nr;
248   tape.counter = 0;
249   tape.recording = FALSE;
250   tape.playing = FALSE;
251   tape.pausing = FALSE;
252
253   for(i=0;i<tape.length;i++)
254   {
255     if (i>=MAX_TAPELEN)
256       break;
257     tape.pos[i].joystickdata = fgetc(file);
258     tape.pos[i].delay        = fgetc(file);
259     if (feof(file))
260       break;
261   }
262
263   if (i != tape.length)
264     fprintf(stderr,"%s: level recording file '%s' corrupted!\n",
265             progname,filename);
266
267   fclose(file);
268
269   master_tape = tape;
270 }
271
272 void LoadScore(int level_nr)
273 {
274   int i,j;
275   char filename[MAX_FILENAME];
276   char cookie[MAX_FILENAME];
277   FILE *file;
278
279   sprintf(filename,"%s/%s/%s",
280           SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
281
282   if (!(file=fopen(filename,"r")))
283   {
284     if (!CreateNewScoreFile())
285     {
286       fprintf(stderr,"%s: cannot create score file '%s'!\n",
287               progname,filename);
288     }
289     else if (!(file=fopen(filename,"r"))) 
290     {
291       fprintf(stderr,"%s: cannot load score for level %d!\n",
292               progname,level_nr);
293     }
294   }
295
296   if (file)
297   {
298     fgets(cookie,SCORE_COOKIE_LEN,file);
299     if (strcmp(cookie,SCORE_COOKIE))    /* ungültiges Format? */
300     {
301       fprintf(stderr,"%s: wrong format of score file!\n",progname);
302       fclose(file);
303       file = NULL;
304     }
305   }
306
307   if (file)
308   {
309     fseek(file,
310           SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
311           SEEK_SET);
312     for(i=0;i<MAX_SCORE_ENTRIES;i++)
313     {
314       for(j=0;j<MAX_NAMELEN;j++)
315         highscore[i].Name[j] = fgetc(file);
316       highscore[i].Score = (fgetc(file)<<8) | fgetc(file);
317     }
318     fclose(file);
319   }
320   else
321   {
322     for(i=0;i<MAX_SCORE_ENTRIES;i++)
323     {
324       strcpy(highscore[i].Name,EMPTY_ALIAS);
325       highscore[i].Score = 0;
326     }
327   }
328 }
329
330 void LoadPlayerInfo(int mode)
331 {
332   int i;
333   char filename[MAX_FILENAME];
334   char cookie[MAX_FILENAME];
335   FILE *file;
336   char *login_name = GetLoginName();
337   struct PlayerInfo default_player, new_player;
338
339   if (mode==PLAYER_LEVEL)
340     sprintf(filename,"%s/%s/%s",
341             NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
342   else
343     sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
344
345   for(i=0;i<MAX_NAMELEN;i++)
346     default_player.login_name[i] = default_player.alias_name[i] = 0;
347   strncpy(default_player.login_name,login_name,MAX_NAMELEN-1);
348   strncpy(default_player.alias_name,login_name,MAX_NAMELEN-1);
349   default_player.handicap = 0;
350   default_player.setup = DEFAULT_SETUP;
351   default_player.leveldir_nr = 0;
352
353   new_player = default_player;
354
355   if (!(file=fopen(filename,"r")))
356   {
357     if (!CreateNewNamesFile(mode))
358     {
359       fprintf(stderr,"%s: cannot create names file '%s'!\n",
360               progname,filename);
361     }
362     else if (!(file=fopen(filename,"r"))) 
363     {
364       fprintf(stderr,"%s: cannot load player information '%s'!\n",
365               progname,filename);
366     }
367   }
368
369   if (file)
370   {
371     fgets(cookie,NAMES_COOKIE_LEN,file);
372     if (strcmp(cookie,NAMES_COOKIE))    /* ungültiges Format? */
373     {
374       fprintf(stderr,"%s: wrong format of names file '%s'!\n",
375               progname,filename);
376       fclose(file);
377       file = NULL;
378     }
379   }
380
381   if (!file)
382   {
383     player = default_player;
384     level_nr = default_player.handicap;
385     return;
386   }
387
388   while(1)
389   {
390     for(i=0;i<MAX_NAMELEN;i++)
391       new_player.login_name[i] = fgetc(file);
392     for(i=0;i<MAX_NAMELEN;i++)
393       new_player.alias_name[i] = fgetc(file);
394     new_player.handicap = fgetc(file);
395     new_player.setup = (fgetc(file)<<8) | fgetc(file);
396     new_player.leveldir_nr = fgetc(file);
397
398     if (feof(file))             /* Spieler noch nicht in Liste enthalten */
399     {
400       new_player = default_player;
401
402       fclose(file);
403       if (!(file=fopen(filename,"a")))
404       {
405         fprintf(stderr,"%s: cannot append new player to names file '%s'!\n",
406                 progname,filename);
407       }
408       else
409       {
410         for(i=0;i<MAX_NAMELEN;i++)
411           fputc(new_player.login_name[i],file);
412         for(i=0;i<MAX_NAMELEN;i++)
413           fputc(new_player.alias_name[i],file);
414         fputc(new_player.handicap,file);
415         fputc(new_player.setup / 256,file);
416         fputc(new_player.setup % 256,file);
417         fputc(new_player.leveldir_nr,file);
418       }
419       break;
420     }
421     else                        /* prüfen, ob Spieler in Liste enthalten */
422       if (!strncmp(new_player.login_name,login_name,MAX_NAMELEN-1))
423         break;
424   }
425
426   if (mode==PLAYER_SETUP)
427   {
428     player = new_player;
429     if (player.leveldir_nr < num_leveldirs)
430       leveldir_nr = player.leveldir_nr;
431     else
432       leveldir_nr = 0;
433   }
434   else
435     player.handicap = new_player.handicap;
436
437   level_nr = player.handicap;
438   fclose(file);
439 }
440
441 void SaveLevel(int level_nr)
442 {
443   int i,x,y;
444   char filename[MAX_FILENAME];
445   FILE *file;
446
447   sprintf(filename,"%s/%s/%d",
448           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
449
450   if (!(file=fopen(filename,"w")))
451   {
452     fprintf(stderr,"%s: cannot save level file '%s'!\n",progname,filename);
453     return;
454   }
455
456   fputs(LEVEL_COOKIE,file);             /* Formatkennung */
457   fputc(0x0a,file);
458
459   fputc(level.fieldx,file);
460   fputc(level.fieldy,file);
461   fputc(level.time / 256,file);
462   fputc(level.time % 256,file);
463   fputc(level.edelsteine / 256,file);
464   fputc(level.edelsteine % 256,file);
465
466   for(i=0;i<MAX_LEVNAMLEN;i++)
467     fputc(level.name[i],file);
468   for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
469     fputc(level.score[i],file);
470   for(i=0;i<4;i++)
471     for(y=0;y<3;y++)
472       for(x=0;x<3;x++)
473         fputc(level.mampfer_inhalt[i][x][y],file);
474   fputc(level.tempo_amoebe,file);
475   fputc(level.dauer_sieb,file);
476   fputc(level.dauer_ablenk,file);
477   fputc(level.amoebe_inhalt,file);
478
479   for(i=0;i<NUM_FREE_LVHD_BYTES;i++)    /* Rest frei / Headergröße 80 Bytes */
480     fputc(0,file);
481
482   for(y=0;y<lev_fieldy;y++) 
483     for(x=0;x<lev_fieldx;x++) 
484       fputc(Ur[x][y],file);
485
486   fclose(file);
487
488   chmod(filename, LEVEL_PERMS);
489 }
490
491 void SaveLevelTape(int level_nr)
492 {
493   int i;
494   char filename[MAX_FILENAME];
495   FILE *file;
496   BOOL new_tape = TRUE;
497
498   sprintf(filename,"%s/%s/%d.tape",
499           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
500
501   /* Testen, ob bereits eine Aufnahme existiert */
502   if ((file=fopen(filename,"r")))
503   {
504     new_tape = FALSE;
505     fclose(file);
506
507     if (!AreYouSure("Replace old tape ?",AYS_ASK))
508       return;
509   }
510
511   if (!(file=fopen(filename,"w")))
512   {
513     fprintf(stderr,"%s: cannot save level recording file '%s'!\n",
514             progname,filename);
515     return;
516   }
517
518   fputs(LEVELREC_COOKIE,file);          /* Formatkennung */
519   fputc(0x0a,file);
520
521   tape = master_tape;
522
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);
527
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);
532
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);
537
538   for(i=0;i<tape.length;i++)
539   {
540     fputc(tape.pos[i].joystickdata,file);
541     fputc(tape.pos[i].delay,file);
542   }
543
544   fclose(file);
545
546   chmod(filename, LEVREC_PERMS);
547
548   if (new_tape)
549     AreYouSure("tape saved !",AYS_CONFIRM);
550 }
551
552 void SaveScore(int level_nr)
553 {
554   int i,j;
555   char filename[MAX_FILENAME];
556   FILE *file;
557
558   sprintf(filename,"%s/%s/%s",
559           SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
560
561   if (!(file=fopen(filename,"r+")))
562   {
563     fprintf(stderr,"%s: cannot save score for level %d!\n",
564             progname,level_nr);
565     return;
566   }
567
568   fseek(file,
569         SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
570         SEEK_SET);
571   for(i=0;i<MAX_SCORE_ENTRIES;i++)
572   {
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);
577   }
578   fclose(file);
579 }
580
581 void SavePlayerInfo(int mode)
582 {
583   int i;
584   char filename[MAX_FILENAME];
585   char cookie[MAX_FILENAME];
586   FILE *file;
587   struct PlayerInfo default_player;
588
589   if (mode==PLAYER_LEVEL)
590     sprintf(filename,"%s/%s/%s",
591             NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
592   else
593     sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
594
595   if (!(file=fopen(filename,"r+")))
596   {
597     fprintf(stderr,"%s: cannot save player information '%s'!\n",
598             progname,filename);
599     return;
600   }
601
602   fgets(cookie,NAMES_COOKIE_LEN,file);
603   if (strcmp(cookie,NAMES_COOKIE))      /* ungültiges Format? */
604   {
605     fprintf(stderr,"%s: wrong format of names file '%s'!\n",
606             progname,filename);
607     fclose(file);
608     return;
609   }
610
611   while(1)
612   {
613     for(i=0;i<MAX_NAMELEN;i++)
614       default_player.login_name[i] = fgetc(file);
615     for(i=0;i<MAX_NAMELEN;i++)
616       default_player.alias_name[i] = fgetc(file);
617     default_player.handicap = fgetc(file);
618     default_player.setup = (fgetc(file)<<8) | fgetc(file);
619     default_player.leveldir_nr = fgetc(file);
620
621     if (feof(file))             /* Spieler noch nicht in Liste enthalten */
622       break;
623     else                        /* prüfen, ob Spieler in Liste enthalten */
624       if (!strncmp(default_player.login_name,player.login_name,MAX_NAMELEN-1))
625       {
626         fseek(file,-(2*MAX_NAMELEN+1+2+1),SEEK_CUR);
627         break;
628       }
629   }
630
631   for(i=0;i<MAX_NAMELEN;i++)
632     fputc(player.login_name[i],file);
633   for(i=0;i<MAX_NAMELEN;i++)
634     fputc(player.alias_name[i],file);
635   fputc(player.handicap,file);
636   fputc(player.setup / 256,file);
637   fputc(player.setup % 256,file);
638   fputc(player.leveldir_nr,file);
639
640   fclose(file);
641 }
642
643 void LoadJoystickData()
644 {
645   int i;
646   char cookie[256];
647   FILE *file;
648
649   if (joystick_status==JOYSTICK_OFF)
650     return;
651
652   if (!(file=fopen(JOYDAT_FILE,"r")))
653     return;
654
655   fscanf(file,"%s",cookie);
656   if (strcmp(cookie,JOYSTICK_COOKIE))   /* ungültiges Format? */
657   {
658     fprintf(stderr,"%s: wrong format of joystick file!\n",progname);
659     fclose(file);
660     return;
661   }
662
663   for(i=0;i<2;i++)
664   {
665     fscanf(file,"%s",cookie);
666     fscanf(file, "%d %d %d \n",
667            &joystick[i].xleft, &joystick[i].xmiddle, &joystick[i].xright);
668     fscanf(file, "%d %d %d \n",
669            &joystick[i].yupper, &joystick[i].ymiddle, &joystick[i].ylower);
670   }
671   fclose(file);
672
673   CheckJoystickData();
674 }
675
676 void SaveJoystickData()
677 {
678   int i;
679   FILE *file;
680
681   if (joystick_status==JOYSTICK_OFF)
682     return;
683
684   CheckJoystickData();
685
686   if (!(file=fopen(JOYDAT_FILE,"w")))
687   {
688     fprintf(stderr,"%s: cannot save joystick calibration data!\n",progname);
689     return;
690   }
691
692   fprintf(file,"%s\n",JOYSTICK_COOKIE); /* Formatkennung */
693   for(i=0;i<2;i++)
694   {
695     fprintf(file,"JOYSTICK_%d_DATA\n",i);
696     fprintf(file, "%d %d %d \n",
697             joystick[i].xleft, joystick[i].xmiddle, joystick[i].xright);
698     fprintf(file, "%d %d %d \n",
699             joystick[i].yupper, joystick[i].ymiddle, joystick[i].ylower);
700   }
701   fclose(file);
702
703   chmod(JOYDAT_FILE, JOYDAT_PERMS);
704 }