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