merged ppu code, added input+zapper, FDS/VS insert in menu
[fceu.git] / svga.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 1998 BERO
5  *  Copyright (C) 2002 Ben Parnell
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 /*                      SVGA High Level Routines
23                           FCE / FCE Ultra
24 */
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <math.h>
28 #include <string.h>
29
30 #include <stdarg.h>
31
32
33 #ifndef M_PI
34 #define M_PI 3.14159265358979323846
35 #endif
36
37 #include "types.h"
38 #include "svga.h"
39 #include "fce.h"
40 #include "general.h"
41 #include "video.h"
42 #include "sound.h"
43 #include "version.h"
44 #include "nsf.h"
45 #include "palette.h"
46 #include "fds.h"
47 #include "netplay.h"
48 #include "state.h"
49 #include "cart.h"
50 #include "input.h"
51
52 #include "vsuni.h"
53
54 FCEUS FSettings;
55
56 static int howlong;
57 static char errmsg[65];
58
59 void FCEU_PrintError(char *format, ...)
60 {
61  char temp[2048];
62
63  va_list ap;
64
65  va_start(ap,format);
66  vsprintf(temp,format,ap);
67  FCEUD_PrintError(temp);
68
69  va_end(ap);
70 }
71
72 void FCEU_DispMessage(char *format, ...)
73 {
74  va_list ap;
75
76  va_start(ap,format);
77  vsprintf(errmsg,format,ap);
78  va_end(ap);
79
80  howlong=180;
81  if (errmsg[0] != '|')
82   printf("%s\n", errmsg);
83 }
84
85 void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall)
86 {
87  FSettings.UsrFirstSLine[0]=ntscf;
88  FSettings.UsrLastSLine[0]=ntscl;
89  FSettings.UsrFirstSLine[1]=palf;
90  FSettings.UsrLastSLine[1]=pall;
91  if(PAL)
92  {
93   FSettings.FirstSLine=FSettings.UsrFirstSLine[1];
94   FSettings.LastSLine=FSettings.UsrLastSLine[1];
95  }
96  else
97  {
98   FSettings.FirstSLine=FSettings.UsrFirstSLine[0];
99   FSettings.LastSLine=FSettings.UsrLastSLine[0];
100  }
101
102 }
103
104 void FCEUI_SetVidSystem(int a)
105 {
106  FSettings.PAL=a?1:0;
107  FCEU_ResetVidSys();
108  FCEU_ResetPalette();
109 }
110
111 int FCEUI_GetCurrentVidSystem(int *slstart, int *slend)
112 {
113  if(slstart)
114   *slstart=FSettings.FirstSLine;
115  if(slend)
116   *slend=FSettings.LastSLine;
117  return(PAL);
118 }
119
120 #ifdef NETWORK
121 void FCEUI_SetNetworkPlay(int type)
122 {
123  FSettings.NetworkPlay=type;
124 }
125 #endif
126
127 void FCEUI_SetGameGenie(int a)
128 {
129  FSettings.GameGenie=a?1:0;
130 }
131
132 #ifndef NETWORK
133 #define netplay 0
134 #endif
135
136 uint8 Exit=0;
137
138 uint8 DIPS=0;
139
140 uint8 CommandQueue=0;
141
142 static int controlselect=0;
143 static int ntsccol=0;
144 static int ntsctint=46+10;
145 static int ntschue=72;
146 static int controllength=0;
147
148
149 void FCEUI_SetSnapName(int a)
150 {
151  FSettings.SnapName=a;
152 }
153
154 void FCEUI_SaveExtraDataUnderBase(int a)
155 {
156  FSettings.SUnderBase=a;
157 }
158
159
160 void FCEUI_SelectState(int w)
161 {
162  // if(netplay!=2 && FCEUGameInfo.type!=GIT_NSF)
163  //  CommandQueue=42+w;
164 }
165
166 void FCEUI_SaveState(void)
167 {
168  // if(netplay!=2 && FCEUGameInfo.type!=GIT_NSF)
169  //  CommandQueue=40;
170
171  //CheckStates();
172  SaveState();
173 }
174
175 void FCEUI_LoadState(void)
176 {
177  // if(netplay!=2 && FCEUGameInfo.type!=GIT_NSF)
178  //  CommandQueue=41;
179  //CheckStates();
180  LoadState();
181 }
182
183 int32 FCEUI_GetDesiredFPS(void)
184 {
185   if(PAL)
186    return(838977920); // ~50.007
187   else
188    return(1008307711);  // ~60.1
189 }
190
191 static int dosnapsave=0;
192 void FCEUI_SaveSnapshot(void)
193 {
194  dosnapsave=1;
195 }
196
197 /* I like the sounds of breaking necks. */
198 static void ReallySnap(void)
199 {
200  int x=SaveSnapshot();
201  if(!x)
202   FCEU_DispMessage("Error saving screen snapshot.");
203  else
204   FCEU_DispMessage("Screen snapshot %d saved.",x-1);
205 }
206
207 void DriverInterface(int w, void *d)
208 {
209  switch(w)
210  {
211   case DES_NTSCCOL:ntsccol=*(int *)d;FCEU_ResetPalette();break;
212   case DES_RESET:if(netplay!=2) CommandQueue=30;break;
213   case DES_POWER:if(netplay!=2) CommandQueue=31;break;
214   case DES_GETNTSCTINT:*(int*)d=ntsctint;break;
215   case DES_GETNTSCHUE:*(int*)d=ntschue;break;
216   case DES_SETNTSCTINT:ntsctint=*(int*)d;if(ntsccol)FCEU_ResetPalette();break;
217   case DES_SETNTSCHUE:ntschue=*(int*)d;if(ntsccol)FCEU_ResetPalette();break;
218
219   case DES_FDSINSERT:if(netplay!=2) CommandQueue=2;break;
220   case DES_FDSEJECT:if(netplay!=2) CommandQueue=3;break;
221   case DES_FDSSELECT:if(netplay!=2) CommandQueue=1;break;
222 /*
223   case DES_NSFINC:NSFControl(1);break;
224   case DES_NSFDEC:NSFControl(2);break;
225   case DES_NSFRES:NSFControl(0);break;
226 */
227   case DES_VSUNIDIPSET:CommandQueue=10+(int)d;break;
228   case DES_VSUNITOGGLEDIPVIEW:CommandQueue=10;break;
229   case DES_VSUNICOIN:CommandQueue=19;break;
230   case DES_NTSCSELHUE:if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF){controlselect=1;controllength=360;}break;
231   case DES_NTSCSELTINT:if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF){controlselect=2;controllength=360;}break;
232 #if 0
233   case DES_NTSCDEC:
234                   if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF)
235                   {
236                    char which;
237                    if(controlselect)
238                    {
239                     if(controllength)
240                     {
241                      which=controlselect==1?ntschue:ntsctint;
242                      which--;
243                      if(which<0) which=0;
244                          if(controlselect==1)
245                           ntschue=which;
246                          else ntsctint=which;
247                      CalculatePalette();
248                     }
249                    controllength=360;
250                     }
251                    }
252                   break;
253   case DES_NTSCINC:
254                    if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF)
255                      if(controlselect)
256                      {
257                       if(controllength)
258                       {
259                        switch(controlselect)
260                        {
261                         case 1:ntschue++;
262                                if(ntschue>128) ntschue=128;
263                                CalculatePalette();
264                                break;
265                         case 2:ntsctint++;
266                                if(ntsctint>128) ntsctint=128;
267                                CalculatePalette();
268                                break;
269                        }
270                       }
271                       controllength=360;
272                      }
273                     break;
274 #endif
275   }
276 }
277
278
279 #include "drawing.h"
280 #ifdef FRAMESKIP
281 void FCEU_PutImageDummy(void)
282 {
283  if(FCEUGameInfo.type!=GIT_NSF)
284  {
285   if(controllength) controllength--;
286  }
287  if(howlong) howlong--; /* DrawMessage() */
288  #ifdef FPS
289  {
290   extern uint64 frcount;
291   frcount++;
292  }
293  #endif
294
295 }
296 #endif
297
298 void FCEU_PutImage(void)
299 {
300         if(FCEUGameInfo.type==GIT_NSF)
301         {
302          DrawNSF(XBuf);
303          /* Save snapshot after NSF screen is drawn.  Why would we want to
304             do it before?
305          */
306          if(dosnapsave)
307          {
308           ReallySnap();
309           dosnapsave=0;
310          }
311         }
312         else
313         {
314          /* Save snapshot before overlay stuff is written. */
315          if(dosnapsave)
316          {
317           ReallySnap();
318           dosnapsave=0;
319          }
320          if(FCEUGameInfo.type==GIT_VSUNI)
321                  FCEU_VSUniDraw(XBuf);
322
323          //FCEU_DrawSaveStates(XBuf);
324          //FCEU_DrawMovies(XBuf);
325          //FCEU_DrawNTSCControlBars(XBuf);
326          //FCEU_DrawRecordingStatus(XBuf);
327
328          //if(controllength) {controllength--;DrawBars();}
329         }
330         DrawMessage();
331         #ifdef FPS
332         {
333         extern uint64 frcount;
334         frcount++;
335         }
336         #endif
337         DrawInput(XBuf+8);
338 }
339
340 #if 0
341 void DoCommand(uint8 c)
342 {
343  switch(c)
344  {
345   case 1:FDSControl(FDS_SELECT);break;
346   case 2:FDSControl(FDS_IDISK);break;
347   case 3:FDSControl(FDS_EJECT);break;
348
349   case 10:DIPS^=2;break;
350   case 11:vsdip^=1;DIPS|=2;break;
351   case 12:vsdip^=2;DIPS|=2;break;
352   case 13:vsdip^=4;DIPS|=2;break;
353   case 14:vsdip^=8;DIPS|=2;break;
354   case 15:vsdip^=0x10;DIPS|=2;break;
355   case 16:vsdip^=0x20;DIPS|=2;break;
356   case 17:vsdip^=0x40;DIPS|=2;break;
357   case 18:vsdip^=0x80;DIPS|=2;break;
358   case 19:coinon=6;break;
359   case 30:ResetNES();break;
360   case 31:PowerNES();break;
361   case 40:CheckStates();StateShow=0;SaveState();break;
362   case 41:CheckStates();StateShow=0;LoadState();break;
363   case 42: case 43: case 44: case 45: case 46: case 47: case 48: case 49:
364   case 50: case 51:StateShow=180;CurrentState=c-42;CheckStates();break;
365  }
366 }
367 #endif
368