initial fce ultra 0.81 import
[fceu.git] / drivers / win / main.c
CommitLineData
c62d2810 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
59static int eoptions=EO_BGRUN;
60
61void ResetVideo(void);
62void ShowCursorAbs(int w);
63void HideFWindow(int h);
64int SetMainWindowStuff(void);
65int GetClientAbsRect(LPRECT lpRect);
66void UpdateFCEUWindow(void);
67
68
69HWND hAppWnd=0;
70HINSTANCE fceu_hInstance;
71
72HRESULT ddrval;
73
74FCEUGI *GI=0;
75
76// cheats, misc, nonvol, states, snaps, base
77static char *DOvers[6]={0,0,0,0,0,0};
78static char *defaultds[5]={"cheats","gameinfo","sav","fcs","snaps"};
79
80static char TempArray[2048];
81static char BaseDirectory[2048];
82
83void 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. */
98void 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
110void 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
122static char *gfsdir=0;
123void 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
136static int exiting=0;
137int 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
154int NoWaiting=0;
155static int fullscreen=0;
156static int soundflush=0;
157static int soundsleep=0;
158static int genie=0;
159static int palyo=0;
160static int windowedfailed;
161static int winsizemul=1;
162static int winwidth,winheight;
163
164static volatile int nofocus=0;
165static 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
172static int soundrate=44100;
173static int soundbuftime=46;
174static int soundbufsize;
175static int soundoptions=0;
176static int soundvolume=100;
177
178static unsigned int srendline,erendline;
179static unsigned int srendlinen=8;
180static unsigned int erendlinen=239;
181static unsigned int srendlinep=0;
182static unsigned int erendlinep=239;
183
184
185static unsigned int totallines;
186
187static void FixFL(void)
188{
189 FCEUI_GetCurrentVidSystem(&srendline,&erendline);
190 totallines=erendline-srendline+1;
191}
192
193static void UpdateRendBounds(void)
194{
195 FCEUI_SetRenderedLines(srendlinen,erendlinen,srendlinep,erendlinep);
196 FixFL();
197}
198
199static uint8 cpalette[192];
200static int vmod=1;
201static int soundo=1;
202static int ntsccol=0,ntsctint,ntschue;
203
204void 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
211void 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
217void DoFCEUExit(void)
218{
219 exiting=1;
220 if(GI)
221 {
222 FCEUI_CloseGame();
223 GI=0;
224 }
225}
226
227static 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
238int 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
252static 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
264int 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
331void 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