| 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 |