rocks_n_diamonds-0.9b
[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     for(i=0;i<MAX_SC_ENTRIES;i++)
159       level.score[i]    = fgetc(file);
160     level.amoebe_inhalt = 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
169     for(i=0;i<19;i++)   /* Rest reserviert / Headergröße 80 Bytes */
170       fgetc(file);
171
172     for(y=0;y<MAX_LEV_FIELDY;y++) 
173       for(x=0;x<MAX_LEV_FIELDX;x++) 
174         Feld[x][y] = Ur[x][y] = EL_ERDREICH;
175
176     for(y=0;y<lev_fieldy;y++) 
177       for(x=0;x<lev_fieldx;x++) 
178         Feld[x][y] = Ur[x][y] = fgetc(file);
179
180     fclose(file);
181
182     if (level.time<=10) /* Mindestspieldauer */
183       level.time = 10;
184   }
185   else
186   {
187     lev_fieldx = level.fieldx = STD_LEV_FIELDX;
188     lev_fieldy = level.fieldy = STD_LEV_FIELDY;
189
190     level.time          = 100;
191     level.edelsteine    = 0;
192     strncpy(level.name,"Nameless Level",MAX_LEVNAMLEN-1);
193     for(i=0;i<MAX_SC_ENTRIES;i++)
194       level.score[i]    = 10;
195     level.amoebe_inhalt = EL_DIAMANT;
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
204     for(y=0;y<STD_LEV_FIELDY;y++) 
205       for(x=0;x<STD_LEV_FIELDX;x++) 
206         Feld[x][y] = Ur[x][y] = EL_ERDREICH;
207     Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
208     Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
209       Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
210   }
211 }
212
213 void LoadLevelTape(int level_nr)
214 {
215   int i;
216   char filename[MAX_FILENAME];
217   char cookie[MAX_FILENAME];
218   FILE *file;
219
220   sprintf(filename,"%s/%s/%d.tape",
221           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
222
223   if ((file=fopen(filename,"r")))
224   {
225     fgets(cookie,LEVELREC_COOKIE_LEN,file);
226     fgetc(file);
227     if (strcmp(cookie,LEVELREC_COOKIE)) /* ungültiges Format? */
228     {
229       fprintf(stderr,"%s: wrong format of level recording file '%s'!\n",
230               progname,filename);
231       fclose(file);
232       file = NULL;
233     }
234   }
235
236   if (!file)
237     return;
238
239   tape.random_seed =
240     (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
241   tape.date =
242     (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
243   tape.length =
244     (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
245
246   tape.level_nr = level_nr;
247   tape.counter = 0;
248   tape.recording = FALSE;
249   tape.playing = FALSE;
250   tape.pausing = FALSE;
251
252   for(i=0;i<tape.length;i++)
253   {
254     if (i>=MAX_TAPELEN)
255       break;
256     tape.pos[i].joystickdata = fgetc(file);
257     tape.pos[i].delay        = fgetc(file);
258     if (feof(file))
259       break;
260   }
261
262   if (i != tape.length)
263     fprintf(stderr,"%s: level recording file '%s' corrupted!\n",
264             progname,filename);
265
266   fclose(file);
267
268   master_tape = tape;
269 }
270
271 void LoadScore(int level_nr)
272 {
273   int i,j;
274   char filename[MAX_FILENAME];
275   char cookie[MAX_FILENAME];
276   FILE *file;
277
278   sprintf(filename,"%s/%s/%s",
279           SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
280
281   if (!(file=fopen(filename,"r")))
282   {
283     if (!CreateNewScoreFile())
284     {
285       fprintf(stderr,"%s: cannot create score file '%s'!\n",
286               progname,filename);
287     }
288     else if (!(file=fopen(filename,"r"))) 
289     {
290       fprintf(stderr,"%s: cannot load score for level %d!\n",
291               progname,level_nr);
292     }
293   }
294
295   if (file)
296   {
297     fgets(cookie,SCORE_COOKIE_LEN,file);
298     if (strcmp(cookie,SCORE_COOKIE))    /* ungültiges Format? */
299     {
300       fprintf(stderr,"%s: wrong format of score file!\n",progname);
301       fclose(file);
302       file = NULL;
303     }
304   }
305
306   if (file)
307   {
308     fseek(file,
309           SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
310           SEEK_SET);
311     for(i=0;i<MAX_SCORE_ENTRIES;i++)
312     {
313       for(j=0;j<MAX_NAMELEN;j++)
314         highscore[i].Name[j] = fgetc(file);
315       highscore[i].Score = (fgetc(file)<<8) | fgetc(file);
316     }
317     fclose(file);
318   }
319   else
320   {
321     for(i=0;i<MAX_SCORE_ENTRIES;i++)
322     {
323       strcpy(highscore[i].Name,EMPTY_ALIAS);
324       highscore[i].Score = 0;
325     }
326   }
327 }
328
329 void LoadPlayerInfo(int mode)
330 {
331   int i;
332   char filename[MAX_FILENAME];
333   char cookie[MAX_FILENAME];
334   FILE *file;
335   char *login_name = GetLoginName();
336   struct PlayerInfo default_player, new_player;
337
338   if (mode==PLAYER_LEVEL)
339     sprintf(filename,"%s/%s/%s",
340             NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
341   else
342     sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
343
344   for(i=0;i<MAX_NAMELEN;i++)
345     default_player.login_name[i] = default_player.alias_name[i] = 0;
346   strncpy(default_player.login_name,login_name,MAX_NAMELEN-1);
347   strncpy(default_player.alias_name,login_name,MAX_NAMELEN-1);
348   default_player.handicap = 0;
349   default_player.setup = DEFAULT_SETUP;
350   default_player.leveldir_nr = 0;
351
352   new_player = default_player;
353
354   if (!(file=fopen(filename,"r")))
355   {
356     if (!CreateNewNamesFile(mode))
357     {
358       fprintf(stderr,"%s: cannot create names file '%s'!\n",
359               progname,filename);
360     }
361     else if (!(file=fopen(filename,"r"))) 
362     {
363       fprintf(stderr,"%s: cannot load player information '%s'!\n",
364               progname,filename);
365     }
366   }
367
368   if (file)
369   {
370     fgets(cookie,NAMES_COOKIE_LEN,file);
371     if (strcmp(cookie,NAMES_COOKIE))    /* ungültiges Format? */
372     {
373       fprintf(stderr,"%s: wrong format of names file '%s'!\n",
374               progname,filename);
375       fclose(file);
376       file = NULL;
377     }
378   }
379
380   if (!file)
381   {
382     player = default_player;
383     level_nr = default_player.handicap;
384     return;
385   }
386
387   while(1)
388   {
389     for(i=0;i<MAX_NAMELEN;i++)
390       new_player.login_name[i] = fgetc(file);
391     for(i=0;i<MAX_NAMELEN;i++)
392       new_player.alias_name[i] = fgetc(file);
393     new_player.handicap = fgetc(file);
394     new_player.setup = (fgetc(file)<<8) | fgetc(file);
395     new_player.leveldir_nr = fgetc(file);
396
397     if (feof(file))             /* Spieler noch nicht in Liste enthalten */
398     {
399       new_player = default_player;
400
401       fclose(file);
402       if (!(file=fopen(filename,"a")))
403       {
404         fprintf(stderr,"%s: cannot append new player to names file '%s'!\n",
405                 progname,filename);
406       }
407       else
408       {
409         for(i=0;i<MAX_NAMELEN;i++)
410           fputc(new_player.login_name[i],file);
411         for(i=0;i<MAX_NAMELEN;i++)
412           fputc(new_player.alias_name[i],file);
413         fputc(new_player.handicap,file);
414         fputc(new_player.setup / 256,file);
415         fputc(new_player.setup % 256,file);
416         fputc(new_player.leveldir_nr,file);
417       }
418       break;
419     }
420     else                        /* prüfen, ob Spieler in Liste enthalten */
421       if (!strncmp(new_player.login_name,login_name,MAX_NAMELEN-1))
422         break;
423   }
424
425   if (mode==PLAYER_SETUP)
426   {
427     player = new_player;
428     if (player.leveldir_nr < num_leveldirs)
429       leveldir_nr = player.leveldir_nr;
430     else
431       leveldir_nr = 0;
432   }
433   else
434     player.handicap = new_player.handicap;
435
436   level_nr = player.handicap;
437   fclose(file);
438 }
439
440 void SaveLevel(int level_nr)
441 {
442   int i,x,y;
443   char filename[MAX_FILENAME];
444   FILE *file;
445
446   sprintf(filename,"%s/%s/%d",
447           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
448
449   if (!(file=fopen(filename,"w")))
450   {
451     fprintf(stderr,"%s: cannot save level file '%s'!\n",progname,filename);
452     return;
453   }
454
455   fputs(LEVEL_COOKIE,file);             /* Formatkennung */
456   fputc(0x0a,file);
457
458   fputc(level.fieldx,file);
459   fputc(level.fieldy,file);
460   fputc(level.time / 256,file);
461   fputc(level.time % 256,file);
462   fputc(level.edelsteine / 256,file);
463   fputc(level.edelsteine % 256,file);
464
465   for(i=0;i<MAX_LEVNAMLEN;i++)
466     fputc(level.name[i],file);
467   for(i=0;i<MAX_SC_ENTRIES;i++)
468     fputc(level.score[i],file);
469   fputc(level.amoebe_inhalt,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
478   for(i=0;i<19;i++)     /* Rest reserviert / Headergröße 80 Bytes */
479     fputc(0,file);
480
481   for(y=0;y<lev_fieldy;y++) 
482     for(x=0;x<lev_fieldx;x++) 
483       fputc(Ur[x][y],file);
484
485   fclose(file);
486
487   chmod(filename, LEVEL_PERMS);
488 }
489
490 void SaveLevelTape(int level_nr)
491 {
492   int i;
493   char filename[MAX_FILENAME];
494   FILE *file;
495   BOOL new_tape = TRUE;
496
497   sprintf(filename,"%s/%s/%d.tape",
498           LEVEL_PATH,leveldir[leveldir_nr].filename,level_nr);
499
500   /* Testen, ob bereits eine Aufnahme existiert */
501   if ((file=fopen(filename,"r")))
502   {
503     new_tape = FALSE;
504     fclose(file);
505
506     if (!AreYouSure("Replace old tape ?",AYS_ASK))
507       return;
508   }
509
510   if (!(file=fopen(filename,"w")))
511   {
512     fprintf(stderr,"%s: cannot save level recording file '%s'!\n",
513             progname,filename);
514     return;
515   }
516
517   fputs(LEVELREC_COOKIE,file);          /* Formatkennung */
518   fputc(0x0a,file);
519
520   tape = master_tape;
521
522   fputc((tape.random_seed >> 24) & 0xff,file);
523   fputc((tape.random_seed >> 16) & 0xff,file);
524   fputc((tape.random_seed >>  8) & 0xff,file);
525   fputc((tape.random_seed >>  0) & 0xff,file);
526
527   fputc((tape.date >>  24) & 0xff,file);
528   fputc((tape.date >>  16) & 0xff,file);
529   fputc((tape.date >>   8) & 0xff,file);
530   fputc((tape.date >>   0) & 0xff,file);
531
532   fputc((tape.length >>  24) & 0xff,file);
533   fputc((tape.length >>  16) & 0xff,file);
534   fputc((tape.length >>   8) & 0xff,file);
535   fputc((tape.length >>   0) & 0xff,file);
536
537   for(i=0;i<tape.length;i++)
538   {
539     fputc(tape.pos[i].joystickdata,file);
540     fputc(tape.pos[i].delay,file);
541   }
542
543   fclose(file);
544
545   chmod(filename, LEVREC_PERMS);
546
547   if (new_tape)
548     AreYouSure("tape saved !",AYS_CONFIRM);
549 }
550
551 void SaveScore(int level_nr)
552 {
553   int i,j;
554   char filename[MAX_FILENAME];
555   FILE *file;
556
557   sprintf(filename,"%s/%s/%s",
558           SCORE_PATH,leveldir[leveldir_nr].filename,SCORE_FILENAME);
559
560   if (!(file=fopen(filename,"r+")))
561   {
562     fprintf(stderr,"%s: cannot save score for level %d!\n",
563             progname,level_nr);
564     return;
565   }
566
567   fseek(file,
568         SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
569         SEEK_SET);
570   for(i=0;i<MAX_SCORE_ENTRIES;i++)
571   {
572     for(j=0;j<MAX_NAMELEN;j++)
573       fputc(highscore[i].Name[j],file);
574     fputc(highscore[i].Score / 256,file);
575     fputc(highscore[i].Score % 256,file);
576   }
577   fclose(file);
578 }
579
580 void SavePlayerInfo(int mode)
581 {
582   int i;
583   char filename[MAX_FILENAME];
584   char cookie[MAX_FILENAME];
585   FILE *file;
586   struct PlayerInfo default_player;
587
588   if (mode==PLAYER_LEVEL)
589     sprintf(filename,"%s/%s/%s",
590             NAMES_PATH,leveldir[leveldir_nr].filename,NAMES_FILENAME);
591   else
592     sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
593
594   if (!(file=fopen(filename,"r+")))
595   {
596     fprintf(stderr,"%s: cannot save player information '%s'!\n",
597             progname,filename);
598     return;
599   }
600
601   fgets(cookie,NAMES_COOKIE_LEN,file);
602   if (strcmp(cookie,NAMES_COOKIE))      /* ungültiges Format? */
603   {
604     fprintf(stderr,"%s: wrong format of names file '%s'!\n",
605             progname,filename);
606     fclose(file);
607     return;
608   }
609
610   while(1)
611   {
612     for(i=0;i<MAX_NAMELEN;i++)
613       default_player.login_name[i] = fgetc(file);
614     for(i=0;i<MAX_NAMELEN;i++)
615       default_player.alias_name[i] = fgetc(file);
616     default_player.handicap = fgetc(file);
617     default_player.setup = (fgetc(file)<<8) | fgetc(file);
618     default_player.leveldir_nr = fgetc(file);
619
620     if (feof(file))             /* Spieler noch nicht in Liste enthalten */
621       break;
622     else                        /* prüfen, ob Spieler in Liste enthalten */
623       if (!strncmp(default_player.login_name,player.login_name,MAX_NAMELEN-1))
624       {
625         fseek(file,-(2*MAX_NAMELEN+1+2+1),SEEK_CUR);
626         break;
627       }
628   }
629
630   for(i=0;i<MAX_NAMELEN;i++)
631     fputc(player.login_name[i],file);
632   for(i=0;i<MAX_NAMELEN;i++)
633     fputc(player.alias_name[i],file);
634   fputc(player.handicap,file);
635   fputc(player.setup / 256,file);
636   fputc(player.setup % 256,file);
637   fputc(player.leveldir_nr,file);
638
639   fclose(file);
640 }
641
642 void LoadJoystickData()
643 {
644   int i;
645   char cookie[256];
646   FILE *file;
647
648   if (joystick_status==JOYSTICK_OFF)
649     return;
650
651   if (!(file=fopen(JOYDAT_FILE,"r")))
652     return;
653
654   fscanf(file,"%s",cookie);
655   if (strcmp(cookie,JOYSTICK_COOKIE))   /* ungültiges Format? */
656   {
657     fprintf(stderr,"%s: wrong format of joystick file!\n",progname);
658     fclose(file);
659     return;
660   }
661
662   for(i=0;i<2;i++)
663   {
664     fscanf(file,"%s",cookie);
665     fscanf(file, "%d %d %d \n",
666            &joystick[i].xleft, &joystick[i].xmiddle, &joystick[i].xright);
667     fscanf(file, "%d %d %d \n",
668            &joystick[i].yupper, &joystick[i].ymiddle, &joystick[i].ylower);
669   }
670   fclose(file);
671
672   CheckJoystickData();
673 }
674
675 void SaveJoystickData()
676 {
677   int i;
678   FILE *file;
679
680   if (joystick_status==JOYSTICK_OFF)
681     return;
682
683   CheckJoystickData();
684
685   if (!(file=fopen(JOYDAT_FILE,"w")))
686   {
687     fprintf(stderr,"%s: cannot save joystick calibration data!\n",progname);
688     return;
689   }
690
691   fprintf(file,"%s\n",JOYSTICK_COOKIE); /* Formatkennung */
692   for(i=0;i<2;i++)
693   {
694     fprintf(file,"JOYSTICK_%d_DATA\n",i);
695     fprintf(file, "%d %d %d \n",
696             joystick[i].xleft, joystick[i].xmiddle, joystick[i].xright);
697     fprintf(file, "%d %d %d \n",
698             joystick[i].yupper, joystick[i].ymiddle, joystick[i].ylower);
699   }
700   fclose(file);
701
702   chmod(JOYDAT_FILE, JOYDAT_PERMS);
703 }