gpfce patch
[fceu.git] / drivers / win / main.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
22 #include "common.h"
23
24 #include <winsock.h>
25 #include <mmsystem.h>
26 #include <ddraw.h>
27 #include <dsound.h>
28 #include <dinput.h>
29 #include <dir.h>
30 #include <commctrl.h>
31 #include <shlobj.h>     // For directories configuration dialog.
32
33 #include "input.h"
34 #include "joystick.h"
35 #include "keyboard.h"
36 #include "cheat.h"
37
38
39 #define EO_BGRUN          1
40
41 #define EO_CPALETTE       4
42 #define EO_NOSPRLIM       8
43 #define EO_BSAV          16
44 #define EO_FSAFTERLOAD   32
45 #define EO_FOAFTERSTART  64
46 #define EO_NOTHROTTLE   128
47 #define EO_CLIPSIDES    256
48 #define EO_SNAPNAME     512
49
50 /* EO_USERFORCE is something I've been playing with.
51    The code for it isn't finished.
52 */
53 #define EO_USERFORCE   1024
54
55
56 #define VNSCLIP  ((eoptions&EO_CLIPSIDES)?8:0)
57 #define VNSWID   ((eoptions&EO_CLIPSIDES)?240:256)
58
59 static int eoptions=EO_BGRUN;
60
61 void ResetVideo(void);
62 void ShowCursorAbs(int w);
63 void HideFWindow(int h);
64 int SetMainWindowStuff(void);
65 int GetClientAbsRect(LPRECT lpRect);
66 void UpdateFCEUWindow(void);
67
68
69 HWND hAppWnd=0;
70 HINSTANCE fceu_hInstance;
71
72 HRESULT  ddrval;
73
74 FCEUGI *GI=0;
75
76 // cheats, misc, nonvol, states, snaps, base
77 static char *DOvers[6]={0,0,0,0,0,0};
78 static char *defaultds[5]={"cheats","gameinfo","sav","fcs","snaps"};
79
80 static char TempArray[2048];
81 static char BaseDirectory[2048];
82
83 void SetDirs(void)
84 {
85  int x;
86  static int jlist[5]=
87   {FCEUIOD_CHEATS,FCEUIOD_MISC,FCEUIOD_NV,FCEUIOD_STATE,FCEUIOD_SNAPS};
88
89  for(x=0;x<5;x++)
90   FCEUI_SetDirOverride(jlist[x], DOvers[x]);  
91  if(DOvers[5])
92   FCEUI_SetBaseDirectory(DOvers[5]);
93  else
94   FCEUI_SetBaseDirectory(BaseDirectory);
95  FCEUI_SaveExtraDataUnderBase(eoptions&EO_BSAV);
96 }
97 /* Remove empty, unused directories. */
98 void RemoveDirs(void)
99 {
100  int x;
101
102  for(x=0;x<5;x++)
103   if(!DOvers[x])
104   {
105    sprintf(TempArray,"%s\\%s",DOvers[5]?DOvers[5]:BaseDirectory,defaultds[x]);
106    RemoveDirectory(TempArray);
107   }
108 }
109
110 void CreateDirs(void)
111 {
112  int x;
113
114  for(x=0;x<5;x++)
115   if(!DOvers[x])
116   {
117    sprintf(TempArray,"%s\\%s",DOvers[5]?DOvers[5]:BaseDirectory,defaultds[x]);
118    CreateDirectory(TempArray,0);
119   }
120 }
121
122 static char *gfsdir=0;
123 void GetBaseDirectory(void)
124 {
125  int x;
126  BaseDirectory[0]=0;
127  GetModuleFileName(0,(LPTSTR)BaseDirectory,2047);
128
129  for(x=strlen(BaseDirectory);x>=0;x--)
130  {
131   if(BaseDirectory[x]=='\\' || BaseDirectory[x]=='/')
132    {BaseDirectory[x]=0;break;}
133  }
134 }
135
136 static int exiting=0;
137 int BlockingCheck(void)
138 {
139   MSG msg;
140
141   while( PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ) ) {
142      if( GetMessage( &msg, 0,  0, 0)>0 )
143      {
144      TranslateMessage(&msg);
145      DispatchMessage(&msg);
146      }
147    }
148
149  if(exiting) return(0);
150
151  return(1);
152 }
153
154 int NoWaiting=0;
155 static int fullscreen=0;
156 static int soundflush=0;
157 static int soundsleep=0;
158 static int genie=0;
159 static int palyo=0;
160 static int windowedfailed;
161 static int winsizemul=1;
162 static int winwidth,winheight;
163
164 static volatile int nofocus=0;
165 static volatile int userpause=0;
166
167 #define SO_FORCE8BIT  1
168 #define SO_SECONDARY  2
169 #define SO_GFOCUS     4
170 #define SO_D16VOL     8
171
172 static int soundrate=44100;
173 static int soundbuftime=46;
174 static int soundbufsize;
175 static int soundoptions=0;
176 static int soundvolume=100;
177
178 static unsigned int srendline,erendline;
179 static unsigned int srendlinen=8;
180 static unsigned int erendlinen=239;
181 static unsigned int srendlinep=0;
182 static unsigned int erendlinep=239;
183
184
185 static unsigned int totallines;
186
187 static void FixFL(void)
188 {
189  FCEUI_GetCurrentVidSystem(&srendline,&erendline);
190  totallines=erendline-srendline+1;
191 }
192
193 static void UpdateRendBounds(void)
194
195  FCEUI_SetRenderedLines(srendlinen,erendlinen,srendlinep,erendlinep);
196  FixFL(); 
197 }
198
199 static uint8 cpalette[192];
200 static int vmod=1;
201 static int soundo=1;
202 static int ntsccol=0,ntsctint,ntschue;
203
204 void FCEUD_PrintError(char *s)
205 {
206  if(fullscreen) ShowCursorAbs(1);
207  MessageBox(0,s,"FCE Ultra Error",MB_ICONERROR|MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
208  if(fullscreen)ShowCursorAbs(0);
209 }
210
211 void ShowAboutBox(void)
212 {
213  sprintf(TempArray,"FCE Ultra "VERSION_STRING"\n\nhttp://fceultra.sourceforge.net\n\n"__TIME__"\n"__DATE__"\n""gcc "__VERSION__);
214  MessageBox(hAppWnd,TempArray,"About FCE Ultra",MB_OK);
215 }
216
217 void DoFCEUExit(void)
218 {
219  exiting=1;
220  if(GI)
221  {
222   FCEUI_CloseGame();
223   GI=0;
224  }
225 }
226
227 static int changerecursive=0;
228
229 #include "throttle.c"
230
231 #include "netplay.c"
232 #include "sound.c"
233 #include "video.c"
234 #include "window.c"
235 #include "config.c"
236
237
238 int DriverInitialize(void)
239 {
240   if(!InitializeDDraw())
241    return(0);
242
243   if(soundo)
244    soundo=InitSound();
245
246   SetVideoMode(fullscreen);
247   InitInputStuff();             /* Initialize DInput interfaces. */
248   CreateInputStuff();           /* Create and set virtual NES/FC devices. */
249   return 1;
250 }
251
252 static void DriverKill(void)
253
254  sprintf(TempArray,"%s/fceu.cfg",BaseDirectory);
255  SaveConfig(TempArray);
256  DestroyInput();
257  ResetVideo();
258  if(soundo) TrashSound();
259  CloseWave();
260  ByebyeWindow();
261 }
262
263
264 int main(int argc,char *argv[])
265 {
266   char *t;
267
268   if(!FCEUI_Initialize())
269    goto doexito;
270
271   fceu_hInstance=GetModuleHandle(0);
272
273   GetBaseDirectory();
274
275   sprintf(TempArray,"%s\\fceu.cfg",BaseDirectory);
276   LoadConfig(TempArray);
277   FixGIGO();      /* Since a game doesn't have to be
278                      loaded before the GUI can be used, make
279                      sure the temporary input type variables
280                      are set.
281                   */
282
283
284   CreateDirs();
285   SetDirs();
286
287   DoVideoConfigFix();
288   DoMiscConfigFix();
289
290   if(eoptions&EO_CPALETTE)
291    FCEUI_SetPaletteArray(cpalette);
292
293   t=0;
294   if(argc>1)
295    t=argv[1];
296   if(!t) fullscreen=0;
297
298   CreateMainWindow();
299
300   if(!InitDInput())
301    goto doexito;
302
303   if(!DriverInitialize())
304    goto doexito;
305  
306   InitSpeedThrottle();
307   UpdateMenu();
308
309   if(t)
310    ALoad(t);
311   else if(eoptions&EO_FOAFTERSTART)
312    LoadNewGamey(hAppWnd);
313
314   doloopy:
315   UpdateFCEUWindow();
316   if(GI)
317   {
318    FCEUI_Emulate();
319    RedrawWindow(hAppWnd,0,0,RDW_ERASE|RDW_INVALIDATE);
320    StopSound();
321   }
322   Sleep(50);
323   if(!exiting)
324    goto doloopy;
325
326   doexito:
327   DriverKill();
328   return(0);
329 }
330
331 void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count)
332 {
333  FCEUD_BlitScreen(XBuf);
334  if(Count)
335   FCEUD_WriteSoundData(Buffer,Count);
336  FCEUD_UpdateInput();
337 }
338