c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator\r |
2 | *\r |
3 | * Copyright notice for this file:\r |
4 | * Copyright (C) 2002 Ben Parnell\r |
5 | *\r |
6 | * This program is free software; you can redistribute it and/or modify\r |
7 | * it under the terms of the GNU General Public License as published by\r |
8 | * the Free Software Foundation; either version 2 of the License, or\r |
9 | * (at your option) any later version.\r |
10 | *\r |
11 | * This program is distributed in the hope that it will be useful,\r |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of\r |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r |
14 | * GNU General Public License for more details.\r |
15 | *\r |
16 | * You should have received a copy of the GNU General Public License\r |
17 | * along with this program; if not, write to the Free Software\r |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r |
19 | */\r |
20 | \r |
21 | static void ConfigMisc(void);\r |
22 | static void ConfigPalette(void);\r |
23 | static void ConfigDirectories(void);\r |
24 | \r |
25 | static HMENU fceumenu=0;\r |
26 | static HMENU recentmenu;\r |
27 | \r |
28 | static int tog=0;\r |
29 | \r |
30 | void ShowCursorAbs(int w)\r |
31 | {\r |
32 | static int stat=0;\r |
33 | if(w)\r |
34 | {\r |
35 | if(stat==-1) {stat++; ShowCursor(1);}\r |
36 | }\r |
37 | else\r |
38 | {\r |
39 | if(stat==0) {stat--; ShowCursor(0);}\r |
40 | }\r |
41 | }\r |
42 | \r |
43 | \r |
44 | RECT *CalcWindowSize(void)\r |
45 | {\r |
46 | static RECT al;\r |
47 | al.left=0;\r |
48 | al.right=VNSWID*winsizemul;\r |
49 | al.top=0;\r |
50 | al.bottom=totallines*winsizemul;\r |
51 | \r |
52 | AdjustWindowRectEx(&al,GetWindowLong(hAppWnd,GWL_STYLE),GetMenu(hAppWnd)!=NULL,GetWindowLong(hAppWnd,GWL_EXSTYLE));\r |
53 | \r |
54 | al.right-=al.left;\r |
55 | al.left=0;\r |
56 | al.bottom-=al.top;\r |
57 | al.top=0;\r |
58 | \r |
59 | return(&al);\r |
60 | }\r |
61 | \r |
62 | void UpdateMenu(void)\r |
63 | {\r |
64 | static int *polo[2]={&genie,&palyo};\r |
65 | static int polo2[2]={310,311};\r |
66 | int x;\r |
67 | \r |
68 | for(x=0;x<2;x++)\r |
69 | CheckMenuItem(fceumenu,polo2[x],*polo[x]?MF_CHECKED:MF_UNCHECKED);\r |
70 | if(eoptions&EO_BGRUN)\r |
71 | CheckMenuItem(fceumenu,301,MF_CHECKED);\r |
72 | else\r |
73 | CheckMenuItem(fceumenu,301,MF_UNCHECKED);\r |
74 | }\r |
75 | \r |
76 | char *rfiles[10]={0,0,0,0,0,0,0,0,0,0};\r |
77 | \r |
78 | void UpdateRMenu(void)\r |
79 | {\r |
80 | MENUITEMINFO moo;\r |
81 | int x;\r |
82 | \r |
83 | moo.cbSize=sizeof(moo);\r |
84 | moo.fMask=MIIM_SUBMENU|MIIM_STATE;\r |
85 | \r |
86 | GetMenuItemInfo(GetSubMenu(fceumenu,0),102,FALSE,&moo);\r |
87 | moo.hSubMenu=recentmenu;\r |
88 | moo.fState=rfiles[0]?MFS_ENABLED:MFS_GRAYED;\r |
89 | \r |
90 | SetMenuItemInfo(GetSubMenu(fceumenu,0),102,FALSE,&moo);\r |
91 | \r |
92 | for(x=0;x<10;x++)\r |
93 | RemoveMenu(recentmenu,600+x,MF_BYCOMMAND);\r |
94 | for(x=9;x>=0;x--)\r |
95 | { \r |
96 | char tmp[128+5];\r |
97 | if(!rfiles[x]) continue;\r |
98 | \r |
99 | moo.cbSize=sizeof(moo);\r |
100 | moo.fMask=MIIM_DATA|MIIM_ID|MIIM_TYPE;\r |
101 | \r |
102 | if(strlen(rfiles[x])<128)\r |
103 | {\r |
104 | sprintf(tmp,"&%d. %s",(x+1)%10,rfiles[x]);\r |
105 | }\r |
106 | else\r |
107 | sprintf(tmp,"&%d. %s",(x+1)%10,rfiles[x]+strlen(rfiles[x])-127);\r |
108 | \r |
109 | moo.cch=strlen(tmp);\r |
110 | moo.fType=0;\r |
111 | moo.wID=600+x;\r |
112 | moo.dwTypeData=tmp;\r |
113 | InsertMenuItem(recentmenu,0,1,&moo);\r |
114 | }\r |
115 | DrawMenuBar(hAppWnd);\r |
116 | }\r |
117 | \r |
118 | void AddRecent(char *fn)\r |
119 | {\r |
120 | int x;\r |
121 | \r |
122 | for(x=0;x<10;x++)\r |
123 | if(rfiles[x])\r |
124 | if(!strcmp(rfiles[x],fn)) // Item is already in list.\r |
125 | {\r |
126 | int y;\r |
127 | char *tmp;\r |
128 | \r |
129 | tmp=rfiles[x]; // Save pointer.\r |
130 | for(y=x;y;y--)\r |
131 | rfiles[y]=rfiles[y-1]; // Move items down.\r |
132 | \r |
133 | rfiles[0]=tmp; // Put item on top.\r |
134 | UpdateRMenu();\r |
135 | return;\r |
136 | }\r |
137 | \r |
138 | if(rfiles[9]) free(rfiles[9]);\r |
139 | for(x=9;x;x--) rfiles[x]=rfiles[x-1];\r |
140 | rfiles[0]=malloc(strlen(fn)+1);\r |
141 | strcpy(rfiles[0],fn);\r |
142 | UpdateRMenu();\r |
143 | }\r |
144 | \r |
145 | void HideMenu(int h)\r |
146 | {\r |
147 | if(h)\r |
148 | {\r |
149 | SetMenu(hAppWnd,0); \r |
150 | }\r |
151 | else\r |
152 | {\r |
153 | SetMenu(hAppWnd,fceumenu);\r |
154 | }\r |
155 | }\r |
156 | \r |
157 | static LONG WindowXC=1<<30,WindowYC;\r |
158 | void HideFWindow(int h)\r |
159 | {\r |
160 | LONG desa;\r |
161 | \r |
162 | if(h)\r |
163 | {\r |
164 | RECT bo;\r |
165 | GetWindowRect(hAppWnd,&bo);\r |
166 | WindowXC=bo.left;\r |
167 | WindowYC=bo.top;\r |
168 | \r |
169 | SetMenu(hAppWnd,0);\r |
170 | desa=WS_POPUP|WS_CLIPSIBLINGS;\r |
171 | }\r |
172 | else\r |
173 | {\r |
174 | desa=WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS;\r |
175 | HideMenu(tog);\r |
176 | }\r |
177 | \r |
178 | SetWindowLong(hAppWnd,GWL_STYLE,desa|(GetWindowLong(hAppWnd,GWL_STYLE)&WS_VISIBLE));\r |
179 | SetWindowPos(hAppWnd,0,0,0,0,0,SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOSIZE|SWP_NOZORDER);\r |
180 | }\r |
181 | \r |
182 | void ToggleHideMenu(void)\r |
183 | { \r |
184 | if(!fullscreen)\r |
185 | {\r |
186 | tog^=1;\r |
187 | HideMenu(tog);\r |
188 | SetMainWindowStuff();\r |
189 | }\r |
190 | }\r |
191 | \r |
192 | static void ALoad(char *nameo)\r |
193 | {\r |
194 | if((GI=FCEUI_LoadGame(nameo)))\r |
195 | {\r |
196 | FixFL();\r |
197 | FixGIGO();\r |
198 | SetMainWindowStuff();\r |
199 | AddRecent(nameo);\r |
200 | RefreshThrottleFPS();\r |
201 | if(eoptions&EO_FSAFTERLOAD)\r |
202 | SetFSVideoMode();\r |
203 | }\r |
204 | else\r |
205 | StopSound();\r |
206 | }\r |
207 | \r |
208 | void LoadNewGamey(HWND hParent)\r |
209 | {\r |
210 | const char filter[]="All usable files(*.nes,*.nsf,*.fds,*.unf,*.zip,*.gz)\0*.nes;*.nsf;*.fds;*.unf;*.zip;*.gz\0All non-compressed usable files(*.nes,*.nsf,*.fds,*.unf)\0*.nes;*.nsf;*.fds;*.unf\0All files (*.*)\0*.*\0";\r |
211 | char nameo[2048];\r |
212 | OPENFILENAME ofn;\r |
213 | memset(&ofn,0,sizeof(ofn));\r |
214 | ofn.lStructSize=sizeof(ofn);\r |
215 | ofn.hInstance=fceu_hInstance;\r |
216 | ofn.lpstrTitle="FCE Ultra Open File...";\r |
217 | ofn.lpstrFilter=filter;\r |
218 | nameo[0]=0;\r |
219 | ofn.hwndOwner=hParent;\r |
220 | ofn.lpstrFile=nameo;\r |
221 | ofn.nMaxFile=256;\r |
222 | ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY; //OFN_EXPLORER|OFN_ENABLETEMPLATE|OFN_ENABLEHOOK;\r |
223 | ofn.lpstrInitialDir=gfsdir;\r |
224 | if(GetOpenFileName(&ofn))\r |
225 | {\r |
226 | if(gfsdir) free(gfsdir);\r |
227 | if((gfsdir=malloc(ofn.nFileOffset+1)))\r |
228 | {\r |
229 | strncpy(gfsdir,ofn.lpstrFile,ofn.nFileOffset);\r |
230 | gfsdir[ofn.nFileOffset]=0;\r |
231 | }\r |
232 | ALoad(nameo);\r |
233 | }\r |
234 | }\r |
235 | \r |
236 | static uint32 mousex,mousey,mouseb;\r |
237 | void GetMouseData(uint32 *x, uint32 *y, uint32 *b)\r |
238 | {\r |
239 | *x=mousex;\r |
240 | *y=mousey;\r |
241 | if(!fullscreen)\r |
242 | {\r |
243 | if(eoptions&EO_USERFORCE)\r |
244 | {\r |
245 | RECT t;\r |
246 | GetClientRect(hAppWnd,&t);\r |
247 | \r |
248 | *x=*x*VNSWID/(t.right?t.right:1);\r |
249 | *y=*y*totallines/(t.bottom?t.bottom:1);\r |
250 | }\r |
251 | else\r |
252 | {\r |
253 | *x/=winsizemul;\r |
254 | *y/=winsizemul;\r |
255 | }\r |
256 | *x+=VNSCLIP;\r |
257 | }\r |
258 | \r |
259 | *y+=srendline;\r |
260 | *b=((mouseb==MK_LBUTTON)?1:0)|((mouseb==MK_RBUTTON)?2:0);\r |
261 | }\r |
262 | \r |
263 | static int sizchange=0;\r |
264 | static int vchanged=0;\r |
265 | \r |
266 | LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)\r |
267 | {\r |
268 | switch(msg) { \r |
269 | case WM_LBUTTONDOWN:\r |
270 | case WM_LBUTTONUP:\r |
271 | case WM_RBUTTONDOWN:\r |
272 | case WM_RBUTTONUP:\r |
273 | mouseb=wParam;\r |
274 | goto proco;\r |
275 | case WM_MOUSEMOVE:\r |
276 | {\r |
277 | mousex=LOWORD(lParam);\r |
278 | mousey=HIWORD(lParam);\r |
279 | }\r |
280 | goto proco;\r |
281 | case WM_SIZING:\r |
282 | sizchange=1;\r |
283 | goto proco;\r |
284 | case WM_DISPLAYCHANGE:\r |
285 | if(!fullscreen && !changerecursive)\r |
286 | vchanged=1;\r |
287 | goto proco;\r |
288 | case WM_DROPFILES:\r |
289 | {\r |
290 | UINT len;\r |
291 | char *ftmp;\r |
292 | \r |
293 | len=DragQueryFile((HANDLE)wParam,0,0,0)+1;\r |
294 | if((ftmp=malloc(len)))\r |
295 | {\r |
296 | DragQueryFile((HANDLE)wParam,0,ftmp,len);\r |
297 | ALoad(ftmp);\r |
298 | free(ftmp);\r |
299 | } \r |
300 | }\r |
301 | break;\r |
302 | case WM_COMMAND:\r |
303 | if(!(wParam>>16))\r |
304 | {\r |
305 | wParam&=0xFFFF;\r |
306 | if(wParam>=600 && wParam<=609)\r |
307 | {\r |
308 | if(rfiles[wParam-600]) ALoad(rfiles[wParam-600]);\r |
309 | }\r |
310 | switch(wParam)\r |
311 | {\r |
312 | case 300:ToggleHideMenu();break;\r |
313 | case 301:eoptions^=EO_BGRUN;UpdateMenu();break;\r |
314 | \r |
315 | case 310:genie^=1;FCEUI_SetGameGenie(genie);UpdateMenu();break;\r |
316 | case 311:palyo^=1;\r |
317 | FCEUI_SetVidSystem(palyo);\r |
318 | RefreshThrottleFPS();\r |
319 | UpdateMenu();\r |
320 | FixFL();\r |
321 | SetMainWindowStuff();\r |
322 | break;\r |
323 | \r |
324 | case 320:StopSound();ConfigDirectories();break;\r |
325 | case 321:StopSound();ConfigInput(hWnd);break;\r |
326 | case 322:ConfigMisc();break;\r |
327 | case 323:StopSound();ConfigNetplay();break;\r |
328 | case 324:StopSound();ConfigPalette();break;\r |
329 | case 325:StopSound();ConfigSound();break;\r |
330 | case 326:ConfigVideo();break;\r |
331 | \r |
332 | case 200:DriverInterface(DES_RESET,0);break;\r |
333 | case 201:DriverInterface(DES_POWER,0);break;\r |
334 | case 202:ConfigCheats(hWnd);break;\r |
335 | \r |
336 | case 100:StopSound();\r |
337 | LoadNewGamey(hWnd);\r |
338 | break;\r |
339 | case 101:if(GI)\r |
340 | {\r |
341 | FCEUI_CloseGame(); \r |
342 | GI=0;\r |
343 | }\r |
344 | break;\r |
345 | case 110:FCEUI_SaveState();break;\r |
346 | case 111:FCEUI_LoadState();break;\r |
347 | \r |
348 | case 120:\r |
349 | {\r |
350 | MENUITEMINFO mi;\r |
351 | char *str;\r |
352 | \r |
353 | StopSound();\r |
354 | if(CreateSoundSave())\r |
355 | str="Stop Sound Logging";\r |
356 | else\r |
357 | str="Log Sound As...";\r |
358 | memset(&mi,0,sizeof(mi));\r |
359 | mi.fMask=MIIM_DATA|MIIM_TYPE;\r |
360 | mi.cbSize=sizeof(mi);\r |
361 | GetMenuItemInfo(fceumenu,120,0,&mi); \r |
362 | mi.fMask=MIIM_DATA|MIIM_TYPE;\r |
363 | mi.cbSize=sizeof(mi);\r |
364 | mi.dwTypeData=str;\r |
365 | mi.cch=strlen(str);\r |
366 | SetMenuItemInfo(fceumenu,120,0,&mi);\r |
367 | }\r |
368 | break;\r |
369 | case 130:DoFCEUExit();break;\r |
370 | \r |
371 | case 400:StopSound();ShowAboutBox();break;\r |
372 | } \r |
373 | }\r |
374 | break;\r |
375 | \r |
376 | \r |
377 | case WM_SYSCOMMAND:\r |
378 | if(wParam==SC_KEYMENU)\r |
379 | if(GI && InputTypeFC==SIFC_FKB && cidisabled)\r |
380 | break;\r |
381 | goto proco;\r |
382 | case WM_SYSKEYDOWN:\r |
383 | if(GI && InputTypeFC==SIFC_FKB && cidisabled)\r |
384 | break; /* Hopefully this won't break DInput... */\r |
385 | \r |
386 | if(fullscreen || tog)\r |
387 | {\r |
388 | if(wParam==VK_MENU)\r |
389 | break;\r |
390 | }\r |
391 | if(wParam==VK_F10)\r |
392 | {\r |
393 | if(!(lParam&0x40000000))\r |
394 | DriverInterface(DES_RESET,0);\r |
395 | break;\r |
396 | }\r |
397 | goto proco;\r |
398 | \r |
399 | case WM_KEYDOWN:\r |
400 | if(GI)\r |
401 | {\r |
402 | /* Only disable command keys if a game is loaded(and the other\r |
403 | conditions are right, of course). */\r |
404 | if(InputTypeFC==SIFC_FKB)\r |
405 | {\r |
406 | if(wParam==VK_SCROLL)\r |
407 | {\r |
408 | cidisabled^=1;\r |
409 | FCEUI_DispMessage("Family Keyboard %sabled.",cidisabled?"en":"dis");\r |
410 | }\r |
411 | if(cidisabled)\r |
412 | break; /* Hopefully this won't break DInput... */\r |
413 | }\r |
414 | if(GI->type==GIT_NSF)\r |
415 | switch(wParam)\r |
416 | {\r |
417 | case VK_UP:DriverInterface(DES_NSFINC,0);break;\r |
418 | case VK_DOWN:DriverInterface(DES_NSFDEC,0);break;\r |
419 | case VK_RETURN:DriverInterface(DES_NSFRES,0);break;\r |
420 | \r |
421 | case VK_LEFT:if(!(lParam&0x40000000))\r |
422 | DriverInterface(DES_NSFDEC,0); break;\r |
423 | case VK_RIGHT:if(!(lParam&0x40000000))\r |
424 | DriverInterface(DES_NSFINC,0); break;\r |
425 | }\r |
426 | \r |
427 | }\r |
428 | if(!(lParam&0x40000000))\r |
429 | switch( wParam )\r |
430 | {\r |
431 | case VK_F11:DriverInterface(DES_POWER,0);break;\r |
432 | case VK_F12:DoFCEUExit();break;\r |
433 | case VK_F2:userpause^=1;break;\r |
434 | case VK_F3:ToggleHideMenu();break;\r |
435 | case VK_F4: UpdateMenu();\r |
436 | changerecursive=1;\r |
437 | if(!SetVideoMode(fullscreen^1))\r |
438 | SetVideoMode(fullscreen);\r |
439 | changerecursive=0;\r |
440 | break;\r |
441 | }\r |
442 | goto proco;\r |
443 | \r |
444 | \r |
445 | case WM_NCRBUTTONDOWN:\r |
446 | case WM_NCMBUTTONDOWN:StopSound();goto proco;\r |
447 | case WM_NCLBUTTONDOWN:StopSound();goto proco;\r |
448 | \r |
449 | case WM_ENTERMENULOOP:StopSound();goto proco;\r |
450 | case WM_CLOSE:\r |
451 | case WM_DESTROY:\r |
452 | case WM_QUIT:DoFCEUExit();break;\r |
453 | case WM_ACTIVATEAPP: \r |
454 | if((BOOL)wParam)\r |
455 | {\r |
456 | nofocus=0;\r |
457 | }\r |
458 | else\r |
459 | {\r |
460 | nofocus=1;\r |
461 | }\r |
462 | default:\r |
463 | proco:\r |
464 | return DefWindowProc(hWnd,msg,wParam,lParam);\r |
465 | }\r |
466 | return 0;\r |
467 | }\r |
468 | \r |
469 | void UpdateFCEUWindow(void)\r |
470 | {\r |
471 | int w,h;\r |
472 | RECT wrect;\r |
473 | \r |
474 | if(vchanged && !fullscreen && !changerecursive && !nofocus)\r |
475 | {\r |
476 | SetVideoMode(0);\r |
477 | vchanged=0;\r |
478 | }\r |
479 | \r |
480 | if(sizchange && !fullscreen && !(eoptions&EO_USERFORCE))\r |
481 | { \r |
482 | GetWindowRect(hAppWnd,&wrect);\r |
483 | h=wrect.bottom-wrect.top;\r |
484 | w=wrect.right-wrect.left;\r |
485 | if(w!=winwidth)\r |
486 | winsizemul=(w-(winwidth-VNSWID*winsizemul)+(VNSWID>>1))>>8;\r |
487 | else\r |
488 | if(h!=winheight)\r |
489 | winsizemul=(h-(winheight-totallines*winsizemul)+(totallines>>1))>>8;\r |
490 | \r |
491 | if(winsizemul<1)\r |
492 | winsizemul=1;\r |
493 | SetMainWindowStuff();\r |
494 | }\r |
495 | sizchange=0;\r |
496 | \r |
497 | BlockingCheck();\r |
498 | }\r |
499 | \r |
500 | void ByebyeWindow(void)\r |
501 | {\r |
502 | SetMenu(hAppWnd,0);\r |
503 | DestroyMenu(fceumenu);\r |
504 | DestroyWindow(hAppWnd);\r |
505 | }\r |
506 | \r |
507 | int CreateMainWindow(void)\r |
508 | {\r |
509 | WNDCLASSEX winclass;\r |
510 | RECT tmp;\r |
511 | \r |
512 | memset(&winclass,0,sizeof(winclass));\r |
513 | winclass.cbSize=sizeof(WNDCLASSEX);\r |
514 | winclass.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS;\r |
515 | winclass.lpfnWndProc=AppWndProc;\r |
516 | winclass.cbClsExtra=0;\r |
517 | winclass.cbWndExtra=0;\r |
518 | winclass.hInstance=fceu_hInstance;\r |
519 | winclass.hIcon=LoadIcon(fceu_hInstance, "ICON_1");\r |
520 | winclass.hIconSm=LoadIcon(fceu_hInstance, "ICON_1");\r |
521 | winclass.hCursor=LoadCursor(NULL, IDC_ARROW);\r |
522 | winclass.hbrBackground=GetStockObject(BLACK_BRUSH);\r |
523 | //winclass.lpszMenuName="FCEUMENU";\r |
524 | winclass.lpszClassName="FCEULTRA";\r |
525 | \r |
526 | if(!RegisterClassEx(&winclass))\r |
527 | return FALSE;\r |
528 | \r |
529 | AdjustWindowRectEx(&tmp,WS_OVERLAPPEDWINDOW,1,0);\r |
530 | \r |
531 | fceumenu=LoadMenu(fceu_hInstance,"FCEUMENU");\r |
532 | recentmenu=CreateMenu();\r |
533 | UpdateRMenu();\r |
534 | \r |
535 | hAppWnd = CreateWindowEx(0,"FCEULTRA","FCE Ultra",\r |
536 | WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS, /* Style */\r |
537 | CW_USEDEFAULT,CW_USEDEFAULT,256,240, /* X,Y ; Width, Height */\r |
538 | NULL,fceumenu,fceu_hInstance,NULL ); \r |
539 | DragAcceptFiles(hAppWnd, 1);\r |
540 | SetMainWindowStuff();\r |
541 | return 1;\r |
542 | }\r |
543 | \r |
544 | \r |
545 | int SetMainWindowStuff(void)\r |
546 | {\r |
547 | RECT *srect;\r |
548 | RECT tmp;\r |
549 | \r |
550 | GetWindowRect(hAppWnd,&tmp);\r |
551 | \r |
552 | if(WindowXC!=(1<<30))\r |
553 | {\r |
554 | /* Subtracting and adding for if(eoptions&EO_USERFORCE) below. */\r |
555 | tmp.bottom-=tmp.top;\r |
556 | tmp.bottom+=WindowYC;\r |
557 | \r |
558 | tmp.right-=tmp.left;\r |
559 | tmp.right+=WindowXC;\r |
560 | \r |
561 | \r |
562 | tmp.left=WindowXC;\r |
563 | tmp.top=WindowYC;\r |
564 | WindowXC=1<<30;\r |
565 | }\r |
566 | \r |
567 | if(eoptions&EO_USERFORCE)\r |
568 | {\r |
569 | SetWindowPos(hAppWnd,HWND_TOP,tmp.left,tmp.top,0,0,SWP_NOSIZE|SWP_SHOWWINDOW);\r |
570 | winwidth=tmp.right-tmp.left;\r |
571 | winheight=tmp.bottom-tmp.top;\r |
572 | }\r |
573 | else\r |
574 | {\r |
575 | srect=CalcWindowSize();\r |
576 | SetWindowPos(hAppWnd,HWND_TOP,tmp.left,tmp.top,srect->right,srect->bottom,SWP_SHOWWINDOW);\r |
577 | winwidth=srect->right;\r |
578 | winheight=srect->bottom;\r |
579 | }\r |
580 | \r |
581 | \r |
582 | ShowWindow(hAppWnd, SW_SHOWNORMAL);\r |
583 | return 1;\r |
584 | }\r |
585 | \r |
586 | int GetClientAbsRect(LPRECT lpRect)\r |
587 | {\r |
588 | POINT point;\r |
589 | point.x=point.y=0;\r |
590 | if(!ClientToScreen(hAppWnd,&point)) return 0;\r |
591 | \r |
592 | lpRect->top=point.y;\r |
593 | lpRect->left=point.x;\r |
594 | \r |
595 | if(eoptions&EO_USERFORCE)\r |
596 | {\r |
597 | RECT al;\r |
598 | \r |
599 | GetClientRect(hAppWnd,&al);\r |
600 | \r |
601 | lpRect->right=point.x+al.right;\r |
602 | lpRect->bottom=point.y+al.bottom;\r |
603 | }\r |
604 | else\r |
605 | {\r |
606 | lpRect->right=point.x+VNSWID*winsizemul;\r |
607 | lpRect->bottom=point.y+totallines*winsizemul;\r |
608 | }\r |
609 | return 1;\r |
610 | }\r |
611 | \r |
612 | \r |
613 | void LoadPaletteFile(void)\r |
614 | {\r |
615 | FILE *fp;\r |
616 | const char filter[]="All usable files(*.pal)\0*.pal\0All files (*.*)\0*.*\0";\r |
617 | char nameo[2048];\r |
618 | OPENFILENAME ofn;\r |
619 | memset(&ofn,0,sizeof(ofn));\r |
620 | ofn.lStructSize=sizeof(ofn);\r |
621 | ofn.hInstance=fceu_hInstance;\r |
622 | ofn.lpstrTitle="FCE Ultra Open Palette File...";\r |
623 | ofn.lpstrFilter=filter;\r |
624 | nameo[0]=0;\r |
625 | ofn.lpstrFile=nameo;\r |
626 | ofn.nMaxFile=256;\r |
627 | ofn.Flags=OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;\r |
628 | ofn.lpstrInitialDir=0;\r |
629 | if(GetOpenFileName(&ofn))\r |
630 | {\r |
631 | if((fp=fopen(nameo,"rb")))\r |
632 | {\r |
633 | fread(cpalette,1,192,fp);\r |
634 | fclose(fp);\r |
635 | FCEUI_SetPaletteArray(cpalette);\r |
636 | eoptions|=EO_CPALETTE;\r |
637 | }\r |
638 | else\r |
639 | FCEUD_PrintError("Error opening palette file!");\r |
640 | }\r |
641 | }\r |
642 | \r |
643 | BOOL CALLBACK PaletteConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r |
644 | {\r |
645 | switch(uMsg) {\r |
646 | case WM_INITDIALOG: \r |
647 | if(ntsccol)\r |
648 | CheckDlgButton(hwndDlg,100,BST_CHECKED);\r |
649 | SendDlgItemMessage(hwndDlg,500,TBM_SETRANGE,1,MAKELONG(0,128));\r |
650 | SendDlgItemMessage(hwndDlg,501,TBM_SETRANGE,1,MAKELONG(0,128));\r |
651 | DriverInterface(DES_GETNTSCTINT,&ntsctint);\r |
652 | DriverInterface(DES_GETNTSCHUE,&ntschue);\r |
653 | SendDlgItemMessage(hwndDlg,500,TBM_SETPOS,1,ntsctint);\r |
654 | SendDlgItemMessage(hwndDlg,501,TBM_SETPOS,1,ntschue);\r |
655 | break;\r |
656 | case WM_CLOSE:\r |
657 | case WM_QUIT: goto gornk;\r |
658 | case WM_COMMAND:\r |
659 | if(!(wParam>>16))\r |
660 | switch(wParam&0xFFFF)\r |
661 | {\r |
662 | case 100:ntsccol^=1;DriverInterface(DES_NTSCCOL,&ntsccol);break;\r |
663 | case 200:\r |
664 | LoadPaletteFile();\r |
665 | break;\r |
666 | case 201:FCEUI_SetPaletteArray(0);\r |
667 | eoptions&=~EO_CPALETTE;\r |
668 | break;\r |
669 | case 1:\r |
670 | gornk:\r |
671 | ntsctint=SendDlgItemMessage(hwndDlg,500,TBM_GETPOS,0,(LPARAM)(LPSTR)0);\r |
672 | ntschue=SendDlgItemMessage(hwndDlg,501,TBM_GETPOS,0,(LPARAM)(LPSTR)0);\r |
673 | EndDialog(hwndDlg,0);\r |
674 | break;\r |
675 | }\r |
676 | }\r |
677 | return 0;\r |
678 | }\r |
679 | \r |
680 | static void ConfigPalette(void)\r |
681 | {\r |
682 | DialogBox(fceu_hInstance,"PALCONFIG",hAppWnd,PaletteConCallB);\r |
683 | DriverInterface(DES_SETNTSCTINT,&ntsctint);\r |
684 | DriverInterface(DES_SETNTSCHUE,&ntschue);\r |
685 | }\r |
686 | \r |
687 | \r |
688 | static BOOL CALLBACK MiscConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r |
689 | {\r |
690 | switch(uMsg) {\r |
691 | case WM_INITDIALOG: \r |
692 | if(eoptions&EO_NOSPRLIM)\r |
693 | CheckDlgButton(hwndDlg,100,BST_CHECKED);\r |
694 | if(eoptions&EO_FOAFTERSTART)\r |
695 | CheckDlgButton(hwndDlg,102,BST_CHECKED);\r |
696 | if(eoptions&EO_SNAPNAME)\r |
697 | CheckDlgButton(hwndDlg,103,BST_CHECKED);\r |
698 | if(eoptions&EO_NOTHROTTLE)\r |
699 | CheckDlgButton(hwndDlg,101,BST_CHECKED);\r |
700 | break;\r |
701 | case WM_CLOSE:\r |
702 | case WM_QUIT: goto gornk;\r |
703 | case WM_COMMAND:\r |
704 | if(!(wParam>>16))\r |
705 | switch(wParam&0xFFFF)\r |
706 | {\r |
707 | case 1:\r |
708 | gornk:\r |
709 | if(IsDlgButtonChecked(hwndDlg,100)==BST_CHECKED)\r |
710 | eoptions|=EO_NOSPRLIM;\r |
711 | else\r |
712 | eoptions&=~EO_NOSPRLIM;\r |
713 | if(IsDlgButtonChecked(hwndDlg,102)==BST_CHECKED)\r |
714 | eoptions|=EO_FOAFTERSTART;\r |
715 | else\r |
716 | eoptions&=~EO_FOAFTERSTART;\r |
717 | if(IsDlgButtonChecked(hwndDlg,103)==BST_CHECKED)\r |
718 | eoptions|=EO_SNAPNAME;\r |
719 | else\r |
720 | eoptions&=~EO_SNAPNAME;\r |
721 | if(IsDlgButtonChecked(hwndDlg,101)==BST_CHECKED)\r |
722 | eoptions|=EO_NOTHROTTLE;\r |
723 | else\r |
724 | eoptions&=~EO_NOTHROTTLE;\r |
725 | EndDialog(hwndDlg,0);\r |
726 | break;\r |
727 | }\r |
728 | }\r |
729 | return 0;\r |
730 | }\r |
731 | \r |
732 | void DoMiscConfigFix(void)\r |
733 | {\r |
734 | FCEUI_DisableSpriteLimitation(eoptions&EO_NOSPRLIM);\r |
735 | FCEUI_SetSnapName(eoptions&EO_SNAPNAME);\r |
736 | }\r |
737 | \r |
738 | static void ConfigMisc(void)\r |
739 | {\r |
740 | DialogBox(fceu_hInstance,"MISCCONFIG",hAppWnd,MiscConCallB); \r |
741 | DoMiscConfigFix();\r |
742 | }\r |
743 | \r |
744 | static int BrowseForFolder(HWND hParent, char *htext, char *buf)\r |
745 | {\r |
746 | BROWSEINFO bi;\r |
747 | LPCITEMIDLIST pidl;\r |
748 | int ret=1;\r |
749 | \r |
750 | buf[0]=0;\r |
751 | \r |
752 | memset(&bi,0,sizeof(bi));\r |
753 | \r |
754 | bi.hwndOwner=hParent;\r |
755 | bi.lpszTitle=htext;\r |
756 | bi.ulFlags=BIF_RETURNONLYFSDIRS; \r |
757 | \r |
758 | if(FAILED(CoInitialize(0)))\r |
759 | return(0);\r |
760 | \r |
761 | if(!(pidl=SHBrowseForFolder(&bi)))\r |
762 | {\r |
763 | ret=0;\r |
764 | goto end1;\r |
765 | }\r |
766 | \r |
767 | if(!SHGetPathFromIDList(pidl,buf))\r |
768 | {\r |
769 | ret=0;\r |
770 | goto end2;\r |
771 | }\r |
772 | \r |
773 | end2:\r |
774 | /* This probably isn't the best way to free the memory... */\r |
775 | CoTaskMemFree((PVOID)pidl);\r |
776 | \r |
777 | end1:\r |
778 | CoUninitialize();\r |
779 | return(ret);\r |
780 | }\r |
781 | \r |
782 | static BOOL CALLBACK DirConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r |
783 | {\r |
784 | int x;\r |
785 | \r |
786 | switch(uMsg){\r |
787 | case WM_INITDIALOG: \r |
788 | for(x=0;x<6;x++)\r |
789 | SetDlgItemText(hwndDlg,100+x,DOvers[x]);\r |
790 | \r |
791 | if(eoptions&EO_BSAV)\r |
792 | CheckDlgButton(hwndDlg,300,BST_CHECKED);\r |
793 | break;\r |
794 | case WM_CLOSE:\r |
795 | case WM_QUIT: goto gornk;\r |
796 | case WM_COMMAND:\r |
797 | if(!(wParam>>16))\r |
798 | {\r |
799 | if((wParam&0xFFFF)>=200 && (wParam&0xFFFF)<=205)\r |
800 | {\r |
801 | static char *helpert[6]={"Cheats","Miscellaneous","Nonvolatile Game Data","Save States","Screen Snapshots","Base Directory"};\r |
802 | char name[MAX_PATH];\r |
803 | \r |
804 | if(BrowseForFolder(hwndDlg,helpert[((wParam&0xFFFF)-200)],name))\r |
805 | SetDlgItemText(hwndDlg,100+((wParam&0xFFFF)-200),name);\r |
806 | }\r |
807 | else switch(wParam&0xFFFF)\r |
808 | {\r |
809 | case 1:\r |
810 | gornk:\r |
811 | \r |
812 | RemoveDirs(); // Remove empty directories.\r |
813 | \r |
814 | for(x=0;x<6;x++)\r |
815 | {\r |
816 | LONG len;\r |
817 | len=SendDlgItemMessage(hwndDlg,100+x,WM_GETTEXTLENGTH,0,0);\r |
818 | if(len<=0)\r |
819 | {\r |
820 | if(DOvers[x]) free(DOvers[x]);\r |
821 | DOvers[x]=0;\r |
822 | continue;\r |
823 | }\r |
824 | len++; // Add 1 for null character.\r |
825 | if(!(DOvers[x]=malloc(len)))\r |
826 | continue;\r |
827 | if(!GetDlgItemText(hwndDlg,100+x,DOvers[x],len))\r |
828 | {\r |
829 | free(DOvers[x]);\r |
830 | DOvers[x]=0;\r |
831 | continue;\r |
832 | }\r |
833 | \r |
834 | }\r |
835 | if(IsDlgButtonChecked(hwndDlg,300)==BST_CHECKED)\r |
836 | eoptions|=EO_BSAV;\r |
837 | else\r |
838 | eoptions&=~EO_BSAV;\r |
839 | \r |
840 | CreateDirs(); // Create needed directories.\r |
841 | SetDirs(); // Set the directories in the core.\r |
842 | EndDialog(hwndDlg,0);\r |
843 | break;\r |
844 | }\r |
845 | }\r |
846 | }\r |
847 | return 0;\r |
848 | }\r |
849 | \r |
850 | \r |
851 | \r |
852 | static void ConfigDirectories(void)\r |
853 | {\r |
854 | DialogBox(fceu_hInstance,"DIRCONFIG",hAppWnd,DirConCallB);\r |
855 | }\r |