rnd-19981017-1
[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 boolean 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 boolean 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 boolean 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   boolean 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].action[j] = MV_NO_MOVING;
271         continue;
272       }
273       tape.pos[i].action[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
463   if (file)
464     fclose(file);
465 }
466
467 void SaveLevel(int level_nr)
468 {
469   int i,x,y;
470   char filename[MAX_FILENAME_LEN];
471   FILE *file;
472
473   sprintf(filename,"%s/%s/%d",
474           level_directory,leveldir[leveldir_nr].filename,level_nr);
475
476   if (!(file=fopen(filename,"w")))
477   {
478     Error(ERR_RETURN, "cannot save level file '%s'", filename);
479     return;
480   }
481
482   fputs(LEVEL_COOKIE,file);             /* Formatkennung */
483   fputc(0x0a,file);
484
485   fputc(level.fieldx,file);
486   fputc(level.fieldy,file);
487   fputc(level.time / 256,file);
488   fputc(level.time % 256,file);
489   fputc(level.edelsteine / 256,file);
490   fputc(level.edelsteine % 256,file);
491
492   for(i=0;i<MAX_LEVNAMLEN;i++)
493     fputc(level.name[i],file);
494   for(i=0;i<MAX_LEVSCORE_ENTRIES;i++)
495     fputc(level.score[i],file);
496   for(i=0;i<4;i++)
497     for(y=0;y<3;y++)
498       for(x=0;x<3;x++)
499         fputc(level.mampfer_inhalt[i][x][y],file);
500   fputc(level.tempo_amoebe,file);
501   fputc(level.dauer_sieb,file);
502   fputc(level.dauer_ablenk,file);
503   fputc(level.amoebe_inhalt,file);
504
505   for(i=0;i<NUM_FREE_LVHD_BYTES;i++)    /* Rest frei / Headergröße 80 Bytes */
506     fputc(0,file);
507
508   for(y=0;y<lev_fieldy;y++) 
509     for(x=0;x<lev_fieldx;x++) 
510       fputc(Ur[x][y],file);
511
512   fclose(file);
513
514   chmod(filename, LEVEL_PERMS);
515 }
516
517 void SaveLevelTape(int level_nr)
518 {
519   int i;
520   char filename[MAX_FILENAME_LEN];
521   FILE *file;
522   boolean new_tape = TRUE;
523
524 #ifndef MSDOS
525   sprintf(filename,"%s/%s/%d.tape",
526           level_directory,leveldir[leveldir_nr].filename,level_nr);
527 #else
528   sprintf(filename,"%s/%s/%d.tap",
529           level_directory,leveldir[leveldir_nr].filename,level_nr);
530 #endif
531
532   /* Testen, ob bereits eine Aufnahme existiert */
533   if ((file=fopen(filename,"r")))
534   {
535     new_tape = FALSE;
536     fclose(file);
537
538     if (!Request("Replace old tape ?",REQ_ASK))
539       return;
540   }
541
542   if (!(file=fopen(filename,"w")))
543   {
544     Error(ERR_RETURN, "cannot save level recording file '%s'", filename);
545     return;
546   }
547
548   fputs(LEVELREC_COOKIE,file);          /* Formatkennung */
549   fputc(0x0a,file);
550
551   fputc((tape.random_seed >> 24) & 0xff,file);
552   fputc((tape.random_seed >> 16) & 0xff,file);
553   fputc((tape.random_seed >>  8) & 0xff,file);
554   fputc((tape.random_seed >>  0) & 0xff,file);
555
556   fputc((tape.date >>  24) & 0xff,file);
557   fputc((tape.date >>  16) & 0xff,file);
558   fputc((tape.date >>   8) & 0xff,file);
559   fputc((tape.date >>   0) & 0xff,file);
560
561   fputc((tape.length >>  24) & 0xff,file);
562   fputc((tape.length >>  16) & 0xff,file);
563   fputc((tape.length >>   8) & 0xff,file);
564   fputc((tape.length >>   0) & 0xff,file);
565
566   for(i=0;i<tape.length;i++)
567   {
568     int j;
569
570     for(j=0; j<MAX_PLAYERS; j++)
571       fputc(tape.pos[i].action[j],file);
572
573     fputc(tape.pos[i].delay,file);
574   }
575
576   fclose(file);
577
578   chmod(filename, LEVREC_PERMS);
579
580   tape.changed = FALSE;
581
582   if (new_tape)
583     Request("tape saved !",REQ_CONFIRM);
584 }
585
586 void SaveScore(int level_nr)
587 {
588   int i,j;
589   char filename[MAX_FILENAME_LEN];
590   FILE *file;
591
592   sprintf(filename,"%s/%s/%s",
593           level_directory,leveldir[leveldir_nr].filename,SCORE_FILENAME);
594
595   if (!(file=fopen(filename,"r+")))
596   {
597     Error(ERR_RETURN, "cannot save score for level %d", level_nr);
598     return;
599   }
600
601   fseek(file,
602         SCORE_COOKIE_LEN-1+level_nr*(MAX_SCORE_ENTRIES*(MAX_NAMELEN+2)),
603         SEEK_SET);
604   for(i=0;i<MAX_SCORE_ENTRIES;i++)
605   {
606     for(j=0;j<MAX_NAMELEN;j++)
607       fputc(highscore[i].Name[j],file);
608     fputc(highscore[i].Score / 256,file);
609     fputc(highscore[i].Score % 256,file);
610   }
611   fclose(file);
612 }
613
614 void SavePlayerInfo(int mode)
615 {
616   int i;
617   char filename[MAX_FILENAME_LEN];
618   char cookie[MAX_FILENAME_LEN];
619   FILE *file;
620   struct PlayerInfo default_player;
621   int version_10_file = FALSE;
622
623   if (mode==PLAYER_LEVEL)
624     sprintf(filename,"%s/%s/%s",
625             level_directory,leveldir[leveldir_nr].filename,NAMES_FILENAME);
626   else
627     sprintf(filename,"%s/%s",CONFIG_PATH,NAMES_FILENAME);
628
629   if (!(file = fopen(filename,"r+")))
630   {
631     Error(ERR_RETURN, "cannot save player information to file '%s'", filename);
632     return;
633   }
634
635   fgets(cookie,NAMES_COOKIE_LEN,file);
636   if (!strcmp(cookie,NAMES_COOKIE_10))  /* altes Format? */
637     version_10_file = TRUE;
638   else if (strcmp(cookie,NAMES_COOKIE)) /* ungültiges Format? */
639   {
640     Error(ERR_RETURN, "wrong format of names file '%s'", filename);
641     fclose(file);
642     return;
643   }
644
645   while(1)
646   {
647     for(i=0;i<MAX_NAMELEN;i++)
648       default_player.login_name[i] = fgetc(file);
649     for(i=0;i<MAX_NAMELEN;i++)
650       default_player.alias_name[i] = fgetc(file);
651     default_player.handicap = fgetc(file);
652     default_player.setup = (fgetc(file)<<8) | fgetc(file);
653     default_player.leveldir_nr = fgetc(file);
654     if (!version_10_file)
655     {
656       default_player.level_nr = fgetc(file);
657       for(i=0;i<10;i++)         /* currently unused bytes */
658         fgetc(file);
659     }
660     else
661       default_player.level_nr = default_player.handicap;
662
663     if (feof(file))             /* Spieler noch nicht in Liste enthalten */
664       break;
665     else                        /* prüfen, ob Spieler in Liste enthalten */
666       if (!strncmp(default_player.login_name,
667                    local_player->login_name, MAX_NAMELEN-1))
668       {
669         fseek(file,-(2*MAX_NAMELEN+1+2+1+(version_10_file ? 0 : 11)),SEEK_CUR);
670         break;
671       }
672   }
673
674   local_player->level_nr = level_nr;
675
676   for(i=0;i<MAX_NAMELEN;i++)
677     fputc(local_player->login_name[i],file);
678   for(i=0;i<MAX_NAMELEN;i++)
679     fputc(local_player->alias_name[i],file);
680   fputc(local_player->handicap,file);
681   fputc(local_player->setup / 256,file);
682   fputc(local_player->setup % 256,file);
683   fputc(local_player->leveldir_nr,file);
684   if (!version_10_file)
685   {
686     fputc(local_player->level_nr,file);
687     for(i=0;i<10;i++)           /* currently unused bytes */
688       fputc(0,file);
689   }
690
691   fclose(file);
692 }
693
694 void LoadJoystickData()
695 {
696   int i;
697   char cookie[256];
698   FILE *file;
699
700   if (joystick_status==JOYSTICK_OFF)
701     return;
702
703 #ifndef MSDOS
704   if (!(file=fopen(JOYDAT_FILE,"r")))
705     return;
706
707   fscanf(file,"%s",cookie);
708   if (strcmp(cookie,JOYSTICK_COOKIE))   /* ungültiges Format? */
709   {
710     Error(ERR_RETURN, "wrong format of joystick file '%s'", JOYDAT_FILE);
711     fclose(file);
712     return;
713   }
714
715   for(i=0;i<2;i++)
716   {
717     fscanf(file,"%s",cookie);
718     fscanf(file, "%d %d %d \n",
719            &joystick[i].xleft, &joystick[i].xmiddle, &joystick[i].xright);
720     fscanf(file, "%d %d %d \n",
721            &joystick[i].yupper, &joystick[i].ymiddle, &joystick[i].ylower);
722   }
723   fclose(file);
724
725   CheckJoystickData();
726 #else
727   load_joystick_data(JOYDAT_FILE);
728 #endif
729 }
730
731 void SaveJoystickData()
732 {
733   int i;
734   FILE *file;
735
736   if (joystick_status==JOYSTICK_OFF)
737     return;
738
739 #ifndef MSDOS
740   CheckJoystickData();
741
742   if (!(file=fopen(JOYDAT_FILE,"w")))
743   {
744     Error(ERR_RETURN, "cannot save joystick calibration data to file '%s'",
745           JOYDAT_FILE);
746     return;
747   }
748
749   fprintf(file,"%s\n",JOYSTICK_COOKIE); /* Formatkennung */
750   for(i=0;i<2;i++)
751   {
752     fprintf(file,"JOYSTICK_%d_DATA\n",i);
753     fprintf(file, "%d %d %d \n",
754             joystick[i].xleft, joystick[i].xmiddle, joystick[i].xright);
755     fprintf(file, "%d %d %d \n",
756             joystick[i].yupper, joystick[i].ymiddle, joystick[i].ylower);
757   }
758   fclose(file);
759
760   chmod(JOYDAT_FILE, JOYDAT_PERMS);
761 #else
762   save_joystick_data(JOYDAT_FILE);
763 #endif
764
765 }