initial fce ultra 0.81 import
[fceu.git] / drivers / win / window.c
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