some movies fixed
[fceu.git] / state.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 /*  TODO: Add (better) file io error checking */
22 /*  TODO: Change save state file format. */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #ifdef GP2X
28 #include <unistd.h>
29 #endif
30
31 #include "types.h"
32 #include "x6502.h"
33 #include "version.h"
34 #include "fce.h"
35 #include "sound.h"
36 #define INESPRIV                // Take this out when old save state support is removed in a future version.
37 #include "ines.h"
38 #include "svga.h"
39 #include "endian.h"
40 #include "fds.h"
41 #include "general.h"
42 #include "state.h"
43 #include "memory.h"
44 #include "ppu.h"
45
46 static SFORMAT SFMDATA[64];
47 static int SFEXINDEX;
48 static int stateversion;
49
50 extern SFORMAT FCEUPPU_STATEINFO[];  // 3
51 extern SFORMAT FCEUCTRL_STATEINFO[]; // 4
52
53 SFORMAT SFCPU[]={ // 1
54  { &X.PC, 2|RLSB, "PC\0"},
55  { &X.A, 1, "A\0\0"},
56  { &X.P, 1, "P\0\0"},
57  { &X.X, 1, "X\0\0"},
58  { &X.Y, 1, "Y\0\0"},
59  { &X.S, 1, "S\0\0"},
60  { RAM, 0x800, "RAM"},
61  { 0, }
62 };
63
64 SFORMAT SFCPUC[]={ // 2
65  { &X.jammed, 1, "JAMM"},
66  { &X.IRQlow, 1, "IRQL"},
67  { &X.tcount, 4|RLSB, "ICoa"},
68  { &X.count,  4|RLSB, "ICou"},
69  { &timestamp, 4|RLSB, "TIME"},
70  { &timestampbase, 8|RLSB, "TMEB"},
71  // from 0.98.15
72  { &timestampbase, sizeof(timestampbase) | RLSB, "TSBS"}, // size seems to match?
73  { &X.mooPI, 1, "MooP"}, // alternative to the "quick and dirty hack"
74  // TODO: IQLB?
75  { 0, }
76 };
77
78 extern uint16 TempAddrT,RefreshAddrT;
79
80
81 SFORMAT SFSND[]={
82  { &fhcnt, 4|RLSB,"FHCN"},
83  { &fcnt, 1, "FCNT"},
84  { PSG, 14, "PSG"},
85  { &PSG[0x15], 1, "P15"},
86  { &PSG[0x17], 1, "P17"},
87  { decvolume, 3, "DECV"},
88  { &sqnon, 1, "SQNO"},
89  { &nreg, 2|RLSB, "NREG"},
90  { &trimode, 1, "TRIM"},
91  { &tricoop, 1, "TRIC"},
92  { sweepon, 2, "SWEE"},
93  { &curfreq[0], 4|RLSB,"CRF1"},
94  { &curfreq[1], 4|RLSB,"CRF2"},
95  { SweepCount, 2,"SWCT"},
96  { DecCountTo1, 3,"DCT1"},
97  { &PCMBitIndex, 1,"PBIN"},
98  { &PCMAddressIndex, 4|RLSB, "PAIN"},
99  { &PCMSizeIndex, 4|RLSB, "PSIN"},
100  { 0, }
101 };
102
103
104
105 int WriteStateChunk(FILE *st, int type, SFORMAT *sf)
106 {
107  int bsize, count;
108  int x;
109
110  count = x = 0;
111  while (sf[x++].v) count++;
112
113  fputc(type,st);
114
115  for(x=bsize=0;x<count;x++)
116   bsize+=sf[x].s&(~RLSB);
117  bsize+=count<<3;
118  write32(bsize,st);
119  for(x=0;x<count;x++)
120  {
121   fwrite(sf[x].desc,1,4,st);
122   write32(sf[x].s&(~RLSB),st);
123   #ifdef LSB_FIRST
124   fwrite((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
125   #else
126   {
127   int z;
128   if(sf[x].s&RLSB)
129   {
130    for(z=(sf[x].s&(~RLSB))-1;z>=0;z--)
131    {
132     fputc(*(uint8*)sf[x].v,st);
133    }
134   }
135   else
136    fwrite((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
137   }
138   #endif
139  }
140  return (bsize+5);
141 }
142
143 int ReadStateChunk(FILE *st, SFORMAT *sf, int size)
144 {
145  uint8 tmpyo[16];
146  int bsize, count;
147  int x;
148
149  // recalculate count ourselves
150  count = x = 0;
151  while (sf[x++].v) count++;
152
153  for(x=bsize=0;x<count;x++)
154   bsize+=sf[x].s&(~RLSB);
155  if(stateversion>=53)
156   bsize+=count<<3;
157  else
158  {
159   if(bsize!=size)
160   {
161    fseek(st,size,SEEK_CUR);
162    return 0;
163   }
164  }
165
166  if(stateversion<56)
167   memcpy(tmpyo,mapbyte3,16);
168
169  if(stateversion>=53)
170  {
171   int temp;
172   temp=ftell(st);
173
174   while(ftell(st)<temp+size)
175   {
176    int tsize;
177    char toa[4];
178
179    if(fread(toa,1,4,st)<=0)
180     return 0;
181    read32(&tsize,st);
182
183    for(x=0;x<count;x++)
184    {
185     if(!memcmp(toa,sf[x].desc,4))
186     {
187      if(tsize!=(sf[x].s&(~RLSB)))
188      {
189       printf("ReadStateChunk: sect \"%c%c%c%c\" has wrong size\n", toa[0], toa[1], toa[2], toa[3]);
190       goto nkayo;
191      }
192      #ifndef LSB_FIRST
193      if(sf[x].s&RLSB)
194      {
195       int z;
196        for(z=(sf[x].s&(~RLSB))-1;z>=0;z--)
197         *(uint8*)sf[x].v=fgetc(st);
198      }
199      else
200      #endif
201      {
202        fread((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
203      }
204      goto bloo;
205     }
206    }
207   printf("ReadStateChunk: sect \"%c%c%c%c\" not handled\n", toa[0], toa[1], toa[2], toa[3]);
208   nkayo:
209   fseek(st,tsize,SEEK_CUR);
210   bloo:;
211   } // while(...)
212  }  // >=53
213  else
214  {
215   for(x=0;x<count;x++)
216   {
217    #ifdef LSB_FIRST
218    fread((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
219    #else
220    int z;
221    if(sf[x].s&RLSB)
222     for(z=(sf[x].s&(~RLSB))-1;z>=0;z--)
223     {
224      *(uint8*)sf[x].v=fgetc(st);
225     }
226    else
227     fread((uint8 *)sf[x].v,1,sf[x].s&(~RLSB),st);
228    #endif
229   }
230  }
231  if(stateversion<56)
232  {
233   for(x=0;x<16;x++)
234    #ifdef LSB_FIRST
235    mapbyte1[x]=mapbyte1[x<<1];
236    #else
237    mapbyte1[x]=mapbyte1[(x<<1)+1];
238    #endif
239   memcpy(mapbyte3,tmpyo,16);
240  }
241  return 1;
242 }
243
244 static int ReadStateChunks(FILE *st)
245 {
246  int t;
247  uint32 size;
248  int ret=1;
249
250 for(;;)
251  {
252   t=fgetc(st);
253   if(t==EOF) break;
254   if(!read32(&size,st)) break;
255
256   // printf("ReadStateChunks: chunk %i\n", t);
257   switch(t)
258   {
259    case 1:if(!ReadStateChunk(st,SFCPU,size)) ret=0;
260 #ifdef ASM_6502
261           asmcpu_unpack();
262 #endif
263           break;
264    case 2:if(!ReadStateChunk(st,SFCPUC,size)) ret=0;
265           else
266           {
267            X.mooPI=X.P; // Quick and dirty hack.
268           }
269           break;
270    case 3:if(!ReadStateChunk(st,FCEUPPU_STATEINFO,size)) ret=0;break;
271    case 4:if(!ReadStateChunk(st,FCEUCTRL_STATEINFO,size)) ret=0;break;
272    case 5:if(!ReadStateChunk(st,SFSND,size)) ret=0;break;
273    case 0x10:if(!ReadStateChunk(st,SFMDATA,size)) ret=0;break;
274    default:printf("ReadStateChunks: unknown chunk: %i\n", t);
275            if(fseek(st,size,SEEK_CUR)<0) goto endo;break;
276   }
277  }
278  endo:
279  return ret;
280 }
281
282
283 int CurrentState=0;
284 extern int geniestage;
285 void SaveState(void)
286 {
287         FILE *st=NULL;
288
289         TempAddrT=TempAddr;
290         RefreshAddrT=RefreshAddr;
291
292         if(geniestage==1)
293         {
294          FCEU_DispMessage("Cannot save FCS in GG screen.");
295          return;
296         }
297
298          st=fopen(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"wb");
299
300          if(st!=NULL)
301          {
302           static uint32 totalsize;
303           static uint8 header[16]="FCS";
304           memset(header+4,0,13);
305           header[3]=VERSION_NUMERIC;
306           fwrite(header,1,16,st);
307
308 #ifdef ASM_6502
309           asmcpu_pack();
310 #endif
311           totalsize=WriteStateChunk(st,1,SFCPU);
312           totalsize+=WriteStateChunk(st,2,SFCPUC);
313           totalsize+=WriteStateChunk(st,3,FCEUPPU_STATEINFO);
314           totalsize+=WriteStateChunk(st,4,FCEUCTRL_STATEINFO);
315           totalsize+=WriteStateChunk(st,5,SFSND);
316           totalsize+=WriteStateChunk(st,0x10,SFMDATA);
317
318           fseek(st,4,SEEK_SET);
319           write32(totalsize,st);
320           SaveStateStatus[CurrentState]=1;
321           fclose(st);
322 #ifdef GP2X
323           sync();
324 #endif
325           FCEU_DispMessage("State %d saved.",CurrentState);
326          }
327          else
328           FCEU_DispMessage("State %d save error.",CurrentState);
329 }
330
331 static int LoadStateOld(FILE *st);
332 int FCEUSS_LoadFP(FILE *st, int make_backup)
333 {
334         int x;
335         if(st!=NULL)
336         {
337          uint8 header[16];
338
339          fread(&header,1,16,st);
340          if(memcmp(header,"FCS",3))
341          {
342           fseek(st,0,SEEK_SET);
343           if(!LoadStateOld(st))
344            goto lerror;
345           goto okload;
346          }
347          stateversion=header[3];
348          if(stateversion<53)
349          FixOldSaveStateSFreq();
350          x=ReadStateChunks(st);
351          if(GameStateRestore) GameStateRestore(header[3]);
352          if(x)
353          {
354           okload:
355           TempAddr=TempAddrT;
356           RefreshAddr=RefreshAddrT;
357
358           SaveStateStatus[CurrentState]=1;
359           FCEU_DispMessage("State %d loaded.",CurrentState);
360           SaveStateStatus[CurrentState]=1;
361          }
362          else
363          {
364           SaveStateStatus[CurrentState]=1;
365           FCEU_DispMessage("Error(s) reading state %d!",CurrentState);
366          }
367         }
368         else
369         {
370          lerror:
371          FCEU_DispMessage("State %d load error.",CurrentState);
372          SaveStateStatus[CurrentState]=0;
373          return 0;
374         }
375         return 1;
376 }
377
378 void LoadState(void)
379 {
380         FILE *st=NULL;
381
382         if(geniestage==1)
383         {
384          FCEU_DispMessage("Cannot load FCS in GG screen.");
385          return;
386         }
387
388         st=fopen(FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"rb");
389         if (st)
390         {
391          FCEUSS_LoadFP(st, 0);
392          fclose(st);
393         }
394 }
395
396 char SaveStateStatus[10];
397 void CheckStates(void)
398 {
399         FILE *st=NULL;
400         int ssel;
401
402         if(SaveStateStatus[0]==(char)-1)
403          for(ssel=0;ssel<10;ssel++)
404          {
405           st=fopen(FCEU_MakeFName(FCEUMKF_STATE,ssel,0),"rb");
406           if(st)
407           {
408            SaveStateStatus[ssel]=1;
409            fclose(st);
410           }
411           else
412            SaveStateStatus[ssel]=0;
413          }
414 }
415
416 void SaveStateRefresh(void)
417 {
418  SaveStateStatus[0]=-1;
419 }
420
421 void ResetExState(void)
422 {
423  int x;
424  for(x=0;x<SFEXINDEX;x++)
425   free(SFMDATA[x].desc);
426  SFEXINDEX=0;
427 }
428
429 void AddExState(void *v, uint32 s, int type, char *desc)
430 {
431  SFMDATA[SFEXINDEX].desc=FCEU_malloc(5);
432  if(SFMDATA[SFEXINDEX].desc)
433  {
434   strcpy(SFMDATA[SFEXINDEX].desc,desc);
435   SFMDATA[SFEXINDEX].v=v;
436   SFMDATA[SFEXINDEX].s=s;
437   if(type) SFMDATA[SFEXINDEX].s|=RLSB;
438   if(SFEXINDEX<63) SFEXINDEX++;
439  }
440 }
441
442 /* Old state loading code follows */
443
444 uint8 *StateBuffer;
445 unsigned int intostate;
446
447 static void afread(void *ptr, size_t _size, size_t _nelem)
448 {
449         memcpy(ptr,StateBuffer+intostate,_size*_nelem);
450         intostate+=_size*_nelem;
451 }
452
453
454 static void areadlower8of16(int8 *d)
455 {
456 #ifdef LSB_FIRST
457         *d=StateBuffer[intostate++];
458 #else
459         d[1]=StateBuffer[intostate++];
460 #endif
461 }
462
463
464 static void areadupper8of16(int8 *d)
465 {
466 #ifdef LSB_FIRST
467         d[1]=StateBuffer[intostate++];
468 #else
469         *d=StateBuffer[intostate++];
470 #endif
471 }
472
473
474 static void aread16(int8 *d)
475 {
476 #ifdef LSB_FIRST
477         *d=StateBuffer[intostate++];
478         d[1]=StateBuffer[intostate++];
479 #else
480         d[1]=StateBuffer[intostate++];
481         *d=StateBuffer[intostate++];
482 #endif
483 }
484
485
486 static void aread32(int8 *d)
487 {
488 #ifdef LSB_FIRST
489         *d=StateBuffer[intostate++];
490         d[1]=StateBuffer[intostate++];
491         d[2]=StateBuffer[intostate++];
492         d[3]=StateBuffer[intostate++];
493 #else
494         d[3]=StateBuffer[intostate++];
495         d[2]=StateBuffer[intostate++];
496         d[1]=StateBuffer[intostate++];
497         *d=StateBuffer[intostate++];
498 #endif
499 }
500
501 static int LoadStateOld(FILE *st)
502 {
503         int x;
504         int32 nada;
505         uint8 version;
506         nada=0;
507
508         printf("LoadStateOld\n");
509
510         StateBuffer=FCEU_malloc(59999);
511         if(StateBuffer==NULL)
512          return 0;
513         if(!fread(StateBuffer,59999,1,st))
514         {
515             fclose(st);
516             free(StateBuffer);
517             return 0;
518         }
519
520         intostate=0;
521
522         {
523          uint8 a[2];
524          afread(&a[0],1,1);
525          afread(&a[1],1,1);
526          X.PC=a[0]|(a[1]<<8);
527         }
528         afread(&X.A,1,1);
529         afread(&X.P,1,1);
530         afread(&X.X,1,1);
531         afread(&X.Y,1,1);
532         afread(&X.S,1,1);
533         afread(&version,1,1);
534         afread(&nada,1,1);
535         afread(&nada,1,1);
536         afread(&nada,1,1);
537         afread(&nada,1,1);
538         aread32((int8 *)&X.count);
539         afread(&nada,1,1);
540         afread(&nada,1,1);
541         afread(&nada,1,1);
542         afread(&nada,1,1);
543         aread32((int8 *)&nada);
544         afread(&nada,1,1);
545         afread(&nada,1,1);
546         afread(&nada,1,1);
547         afread(&nada,1,1);
548
549         for(x=0;x<8;x++)
550                 areadupper8of16((int8 *)&CHRBankList[x]);
551         afread(PRGBankList,4,1);
552         for(x=0;x<8;x++)
553                 areadlower8of16((int8 *)&CHRBankList[x]);
554         afread(CHRRAM,1,0x2000);
555         afread(NTARAM,1,0x400);
556         afread(ExtraNTARAM,1,0x400);
557         afread(NTARAM+0x400,1,0x400);
558         afread(ExtraNTARAM+0x400,1,0x400);
559
560         for(x=0;x<0xF00;x++)
561          afread(&nada,1,1);
562         afread(PALRAM,1,0x20);
563         for(x=0;x<256-32;x++)
564          afread(&nada,1,1);
565         for(x=0x00;x<0x20;x++)
566          PALRAM[x]&=0x3f;
567         afread(PPU,1,4);
568         afread(SPRAM,1,0x100);
569         afread(WRAM,1,8192);
570         afread(RAM,1,0x800);
571         aread16((int8 *)&scanline);
572         aread16((int8 *)&RefreshAddr);
573         afread(&VRAMBuffer,1,1);
574
575         afread(&IRQa,1,1);
576         aread32((int8 *)&IRQCount);
577         aread32((int8 *)&IRQLatch);
578         afread(&Mirroring,1,1);
579         afread(PSG,1,0x17);
580         PSG[0x11]&=0x7F;
581         afread(MapperExRAM,1,193);
582         if(version>=31)
583          PSG[0x17]=MapperExRAM[115];
584         else
585          PSG[0x17]|=0x40;
586         PSG[0x15]&=0xF;
587         sqnon=PSG[0x15];
588
589         X.IRQlow=0;
590         afread(&nada,1,1);
591         afread(&nada,1,1);
592         afread(&nada,1,1);
593         afread(&nada,1,1);
594         afread(&nada,1,1);
595         afread(&nada,1,1);
596         afread(&XOffset,1,1);
597         PPUCHRRAM=0;
598         for(x=0;x<8;x++)
599         {
600          nada=0;
601          afread(&nada,1,1);
602          PPUCHRRAM|=(nada?1:0)<<x;
603         }
604
605          afread(mapbyte1,1,8);
606          afread(mapbyte2,1,8);
607          afread(mapbyte3,1,8);
608          afread(mapbyte4,1,8);
609          for(x=0;x<4;x++)
610           aread16((int8 *)&nada);
611
612          PPUNTARAM=0;
613          for(x=0;x<4;x++)
614          {
615           nada=0;
616           aread16((int8 *)&nada);
617           PPUNTARAM|=((nada&0x800)?0:1)<<x;
618          }
619          afread(MapperExRAM,1,32768);
620          afread(&vtoggle,1,1);
621          aread16((int8 *)&TempAddrT);
622          aread16((int8 *)&RefreshAddrT);
623
624          if(GameStateRestore) GameStateRestore(version);
625          free(StateBuffer);
626          FixOldSaveStateSFreq();
627          X.mooPI=X.P;
628          return 1;
629 }
630