1 /*  Pcsx - Pc Psx Emulator
2  *  Copyright (C) 1999-2003  Pcsx Team
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <windows.h>
20 #include <windowsx.h>
21 #include <commctrl.h>
22 #include <time.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdarg.h>
26 
27 #include "resource.h"
28 #include "AboutDlg.h"
29 
30 #include "psxcommon.h"
31 #include "plugin.h"
32 #include "debug.h"
33 #include "Win32.h"
34 #include "sio.h"
35 #include "misc.h"
36 #include "cheat.h"
37 
38 #ifdef __MINGW32__
39 #ifndef LVM_GETSELECTIONMARK
40 #define LVM_GETSELECTIONMARK (LVM_FIRST+66)
41 #endif
42 #ifndef ListView_GetSelectionMark
43 #define ListView_GetSelectionMark(w) (INT)SNDMSG((w),LVM_GETSELECTIONMARK,0,0)
44 #endif
45 #endif
46 
47 int AccBreak = 0;
48 int ConfPlug = 0;
49 int StatesC = 0;
50 int CancelQuit = 0;
51 char cfgfile[256];
52 int Running = 0;
53 boolean UseGui = TRUE;
54 char PcsxrDir[256];
55 
56 static HDC          hDC;
57 static HDC          hdcmem;
58 static HBITMAP      hBm;
59 static BITMAP       bm;
60 
61 #ifdef ENABLE_NLS
62 
63 unsigned int langsMax;
64 
65 typedef struct {
66 	char lang[256];
67 } _langs;
68 _langs *langs = NULL;
69 
70 typedef struct {
71 	char			id[8];
72 	char			name[64];
73 	LANGID			langid;
74 } LangDef;
75 
76 LangDef sLangs[] = {
77 	{ "ar",		N_("Arabic"),				0x0401 },
78 	{ "ca",		N_("Catalan"),				0x0403 },
79 	{ "de",		N_("German"),				0x0407 },
80 	{ "el",		N_("Greek"),				0x0408 },
81 	{ "en",		N_("English"),				0x0409 },
82 	{ "es",		N_("Spanish"),				0x040a },
83 	{ "fr_FR",	N_("French"),				0x040c },
84 	{ "hu_HU",	N_("Hungarian"),			0x040e },
85 	{ "it",		N_("Italian"),				0x0410 },
86 	{ "pt",		N_("Portuguese"),			0x0816 },
87 	{ "pt_BR",	N_("Portuguese (Brazilian)"),		0x0416 },
88 	{ "ro",		N_("Romanian"),				0x0418 },
89 	{ "ru_RU",	N_("Russian"),				0x0419 },
90 	{ "zh_CN",	N_("Simplified Chinese"),	0x0804 },
91 	{ "zh_TW",	N_("Traditional Chinese"),	0x0404 },
92 	{ "ja",		N_("Japanese"),				0x0411 },
93 	{ "ko_KR",	N_("Korean"),				0x0412 },
94 	{ "", "", 0xFFFF },
95 };
96 
ParseLang(char * id)97 char *ParseLang(char *id) {
98 	int i=0;
99 
100 	while (sLangs[i].id[0] != '\0') {
101 		if (!strcmp(id, sLangs[i].id))
102 			return _(sLangs[i].name);
103 		i++;
104 	}
105 
106 	return id;
107 }
108 
SetDefaultLang(void)109 static void SetDefaultLang(void) {
110 	LANGID langid;
111 	int i;
112 
113 	langid = GetSystemDefaultLangID();
114 
115 	i = 0;
116 	while (sLangs[i].id[0] != '\0') {
117 		if (langid == sLangs[i].langid) {
118 			strcpy(Config.Lang, sLangs[i].id);
119 			return;
120 		}
121 		i++;
122 	}
123 
124 	strcpy(Config.Lang, "English");
125 }
126 
127 #endif
128 
strcatz(char * dst,char * src)129 void strcatz(char *dst, char *src) {
130 	int len = strlen(dst) + 1;
131 	strcpy(dst + len, src);
132 }
133 
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)134 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
135 	char *arg = NULL;
136 	char cdfile[MAXPATHLEN] = "", buf[4096];
137 	char exfile[MAXPATHLEN] = { '\0' };
138 	char appath[MAXPATHLEN] = { '\0' };		//Application base path access for load Memorycard/Bios.
139 	char ldfile[MAXPATHLEN] = { '\0' };
140 	int loadstatenum = -1;
141 	unsigned char is_exfile = 0;
142 	unsigned char is_appath = 0;
143 	unsigned char is_ldfile = 0;
144 
145 	strcpy(cfgfile, "Software\\Pcsxr");
146 
147 	gApp.hInstance = hInstance;
148 
149 #ifdef ENABLE_NLS
150 	bindtextdomain(PACKAGE, "Langs\\");
151 	textdomain(PACKAGE);
152 #endif
153 
154 	Running = 0;
155 
156 	GetCurrentDirectory(256, PcsxrDir);
157 
158 	memset(&Config, 0, sizeof(PcsxConfig));
159 	strcpy(Config.Net, "Disabled");
160 	if (LoadConfig() == -1) {
161 		Config.PsxAuto = 1;
162 		strcpy(Config.PluginsDir, "Plugins\\");
163 		strcpy(Config.BiosDir,    "Bios\\");
164 
165 		strcpy(Config.Mcd1, "memcards\\Mcd001.mcr");
166 		strcpy(Config.Mcd2, "memcards\\Mcd002.mcr");
167 
168 		ConfPlug = 1;
169 
170 #ifdef ENABLE_NLS
171 		{
172 			char text[256];
173 			SetDefaultLang();
174 			sprintf(text, "LANGUAGE=%s", Config.Lang);
175 			gettext_putenv(text);
176 		}
177 #endif
178 
179 		ConfigurePlugins(gApp.hWnd);
180 
181 		if (LoadConfig() == -1) {
182 			return 0;
183 		}
184 	}
185 
186 	strcpy(Config.PatchesDir, "Patches\\");
187 
188 #ifdef ENABLE_NLS
189 	if (Config.Lang[0] == 0) {
190 		SetDefaultLang();
191 		SaveConfig();
192 		LoadConfig();
193 	}
194 #endif
195 
196 	// Parse command-line
197 	strncpy(buf, lpCmdLine, 4096);
198 
199 	for (arg = strtok(buf, " "); arg != NULL; arg = strtok(NULL, " ")) {
200 		if (strcmp(arg, "-nogui") == 0) {
201 			UseGui = FALSE;
202 		} else if (strcmp(arg, "-runcd") == 0) {
203 			cdfile[0] = '\0';
204 			exfile[0] = '\0';
205 			appath[0] = '\0';
206 			ldfile[0] = '\0';
207 		} else if (strcmp(arg, "-cdfile") == 0) {
208 			arg = strtok(NULL, " ");
209 			if (arg != NULL) {
210 				if (arg[0] == '"') {
211 					strncpy(buf, lpCmdLine + (arg - buf), 4096);
212 					arg = strtok(buf, "\"");
213 					if (arg != NULL) strcpy(cdfile, arg);
214 				} else {
215 					strcpy(cdfile, arg);
216 				}
217 				UseGui = FALSE;
218 			}
219 		} else if (strcmp(arg, "-exfile") == 0) {
220 			arg = strtok(NULL, " ");
221 			if (arg != NULL) {
222 				if (arg[0] == '"') {
223 					strncpy(buf, lpCmdLine + (arg - buf), 4096);
224 					arg = strtok(buf, "\"");
225 					if (arg != NULL) strcpy(exfile, arg);
226 				} else {
227 					strcpy(exfile, arg);
228 				}
229 				UseGui = FALSE;
230 				is_exfile = 1;
231 			}
232 		} else if (strcmp(arg, "-appath") == 0) {
233 			arg = strtok(NULL, " ");
234 			if (arg != NULL) {
235 				if (arg[0] == '"') {
236 					strncpy(buf, lpCmdLine + (arg - buf), 4096);
237 					arg = strtok(buf, "\"");
238 					if (arg != NULL) strcpy(appath, arg);
239 				} else {
240 					strcpy(appath, arg);
241 				}
242 				UseGui = FALSE;
243 				is_appath = 1;
244 			}
245 		} else if (strcmp(arg, "-ldfile") == 0) {
246 			arg = strtok(NULL, " ");
247 			if (arg != NULL) {
248 				if (arg[0] == '"') {
249 					strncpy(buf, lpCmdLine + (arg - buf), 4096);
250 					arg = strtok(buf, "\"");
251 					if (arg != NULL) strcpy(ldfile, arg);
252 				} else {
253 					strcpy(ldfile, arg);
254 				}
255 				UseGui = FALSE;
256 				is_ldfile = 1;
257 			}
258 		} else if (strcmp(arg, "-psxout") == 0) {
259 			Config.PsxOut = TRUE;
260 		} else if (strcmp(arg, "-slowboot") == 0) {
261 			Config.SlowBoot = TRUE;
262 		} else if (strcmp(arg, "-help") == 0) {
263 			MessageBox(gApp.hWnd, _(
264 				"Usage: pcsxr [options]\n"
265 				"\toptions:\n"
266 				"\t-nogui\t\tDon't open the GUI\n"
267 				"\t-psxout\t\tEnable PSX output\n"
268 				"\t-slowboot\t\tEnable BIOS logo\n"
269 				"\t-runcd\t\tRuns CD-ROM (requires -nogui)\n"
270 				"\t-appath PATH\tLoad memorycard/bios files this path (requires -nogui)\n"
271 				"\t-cdfile FILE\tRuns a CD image file (requires -nogui)\n"
272 				"\t-exfile FILE\tRuns a PS-EXE file (requires -nogui)\n"
273 				"\t-ldfile FILE\tLoads binary file to psx-memory (requires -nogui)\n"
274 				"\t-help\t\tDisplay this message"),
275 				"PCSXR", 0);
276 
277 			return 0;
278 		}
279 	}
280 
281 	// Use Full Application Path for load memory card and load bios.
282 	// It have to execute before SysInit().
283 	if (!UseGui) {
284 		if( is_appath ) {
285 
286 			//char fullpath[MAXPATHLEN] = { '\0' };
287 			//int len = GetModuleFileName(NULL, fullpath, MAXPATHLEN);
288 			//if( len > 0 && len < MAXPATHLEN ) {
289 			//	char tmp_drive[ MAXPATHLEN ];
290 			//	char tmp_dir[ MAXPATHLEN ];
291 			//	char tmp_file[ MAXPATHLEN ];
292 			//	char tmp_ext[ MAXPATHLEN ];
293 			//	char* pp = NULL;
294 			//	_splitpath(fullpath, tmp_drive, tmp_dir, tmp_file, tmp_ext );
295 			//	Setappath( strcat( tmp_drive, tmp_dir ) );
296 			//}
297 
298 			int apppath_len = strlen(appath);
299 			if( apppath_len > 0 ) {
300 				char app_last = appath[ apppath_len - 1 ];
301 				if( app_last != '\\' )
302 					strcat(appath, "\\");
303 			}
304 			SetAppPath( appath );
305 		}
306 	}
307 
308 	if (SysInit() == -1) return 1;
309 
310 	CreateMainWindow(nCmdShow);
311 
312 	if (!UseGui) {
313 
314 		if( is_ldfile )
315 			SetLdrFile(ldfile);
316 
317 		if( is_exfile ) {
318 			SetExeFile(exfile);
319 			PostMessage(gApp.hWnd, WM_COMMAND, ID_FILE_RUN_EXE_NOGUI, 0);
320 		} else {
321 			SetIsoFile(cdfile);
322 			PostMessage(gApp.hWnd, WM_COMMAND, ID_FILE_RUN_NOGUI, 0);
323 		}
324 	}
325 
326 	RunGui();
327 
328 	return 0;
329 }
330 
RunGui()331 void RunGui() {
332 	MSG msg;
333 
334 	for (;;) {
335 		if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) {
336 			TranslateMessage(&msg);
337 			DispatchMessage(&msg);
338 		}
339 		else
340 		{
341 			// Avoid 100% cpu usage.
342 			Sleep(10);
343 		}
344 	}
345 }
346 
RestoreWindow()347 void RestoreWindow() {
348 	AccBreak = 1;
349 	DestroyWindow(gApp.hWnd);
350 	CreateMainWindow(SW_SHOWNORMAL);
351 
352 	if(Config.HideCursor)
353 		ShowCursor(TRUE);
354 
355 	//SetCursor(LoadCursor(gApp.hInstance, IDC_ARROW));
356 	//ShowCursor(TRUE);
357 
358 	if (!UseGui) PostMessage(gApp.hWnd, WM_COMMAND, ID_FILE_EXIT, 0);
359 }
360 
ResetMenuSlots()361 void ResetMenuSlots() {
362 	char str[256];
363 	int i;
364 
365 	for (i = 0; i < 9; i++) {
366 		GetStateFilename(str, i);
367 		if (CheckState(str) == -1)
368 			EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT1+i, MF_GRAYED);
369 		else
370 			EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT1+i, MF_ENABLED);
371 	}
372 }
373 
OpenConsole()374 void OpenConsole() {
375 	if (hConsole) return;
376 	AllocConsole();
377 	SetConsoleTitle("Psx Output");
378 	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
379 }
380 
CloseConsole()381 void CloseConsole() {
382 	FreeConsole();
383 	hConsole = NULL;
384 }
385 
States_Load(int num)386 void States_Load(int num) {
387 	char Text[256];
388 	int ret;
389 
390 	SetMenu(gApp.hWnd, NULL);
391 	OpenPlugins(gApp.hWnd);
392 
393 	GetStateFilename(Text, num);
394 
395 	ret = LoadState(Text);
396 	if (ret == 0)
397 		 sprintf(Text, _("*PCSXR*: Loaded State %d"), num+1);
398 	else sprintf(Text, _("*PCSXR*: Error Loading State %d"), num+1);
399 	GPU_displayText(Text);
400 
401 	Running = 1;
402 	CheatSearchBackupMemory();
403 	psxCpu->Execute();
404 }
405 
States_Save(int num)406 void States_Save(int num) {
407 	char Text[256];
408 	int ret;
409 
410 	SetMenu(gApp.hWnd, NULL);
411 	OpenPlugins(gApp.hWnd);
412 
413 	GPU_updateLace();
414 
415 	GetStateFilename(Text, num);
416 	GPU_freeze(2, (GPUFreeze_t *)&num);
417 	ret = SaveState(Text);
418 	if (ret == 0)
419 		 sprintf(Text, _("*PCSXR*: Saved State %d"), num+1);
420 	else sprintf(Text, _("*PCSXR*: Error Saving State %d"), num+1);
421 	GPU_displayText(Text);
422 
423 	Running = 1;
424 	CheatSearchBackupMemory();
425 	psxCpu->Execute();
426 }
427 
OnStates_LoadOther()428 void OnStates_LoadOther() {
429 	OPENFILENAME ofn;
430 	char szFileName[MAXPATHLEN];
431 	char szFileTitle[MAXPATHLEN];
432 	char szFilter[256];
433 
434 	memset(&szFileName,  0, sizeof(szFileName));
435 	memset(&szFileTitle, 0, sizeof(szFileTitle));
436 	memset(&szFilter,    0, sizeof(szFilter));
437 
438 	strcpy(szFilter, _("PCSXR State Format"));
439 	strcatz(szFilter, "*.*");
440 
441 	ofn.lStructSize			= sizeof(OPENFILENAME);
442 	ofn.hwndOwner			= gApp.hWnd;
443 	ofn.lpstrFilter			= szFilter;
444 	ofn.lpstrCustomFilter		= NULL;
445 	ofn.nMaxCustFilter		= 0;
446 	ofn.nFilterIndex		= 1;
447 	ofn.lpstrFile			= szFileName;
448 	ofn.nMaxFile			= MAXPATHLEN;
449 	ofn.lpstrInitialDir		= NULL;
450 	ofn.lpstrFileTitle		= szFileTitle;
451 	ofn.nMaxFileTitle		= MAXPATHLEN;
452 	ofn.lpstrTitle			= NULL;
453 	ofn.lpstrDefExt			= NULL;
454 	ofn.Flags			= OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
455 
456 	if (GetOpenFileName ((LPOPENFILENAME)&ofn)) {
457 		char Text[256];
458 		int ret;
459 
460 		SetMenu(gApp.hWnd, NULL);
461 		OpenPlugins(gApp.hWnd);
462 
463 		ret = LoadState(szFileName);
464 		if (ret == 0)
465 			 sprintf(Text, _("*PCSXR*: Loaded State %s"), szFileName);
466 		else sprintf(Text, _("*PCSXR*: Error Loading State %s"), szFileName);
467 		GPU_displayText(Text);
468 
469 		Running = 1;
470 		psxCpu->Execute();
471 	}
472 }
473 
OnStates_SaveOther()474 void OnStates_SaveOther() {
475 	OPENFILENAME ofn;
476 	char szFileName[MAXPATHLEN];
477 	char szFileTitle[MAXPATHLEN];
478 	char szFilter[256];
479 
480 	memset(&szFileName,  0, sizeof(szFileName));
481 	memset(&szFileTitle, 0, sizeof(szFileTitle));
482 	memset(&szFilter,    0, sizeof(szFilter));
483 
484 	strcpy(szFilter, _("PCSXR State Format"));
485 	strcatz(szFilter, "*.*");
486 
487 	ofn.lStructSize			= sizeof(OPENFILENAME);
488 	ofn.hwndOwner			= gApp.hWnd;
489 	ofn.lpstrFilter			= szFilter;
490 	ofn.lpstrCustomFilter	= NULL;
491 	ofn.nMaxCustFilter		= 0;
492 	ofn.nFilterIndex		= 1;
493 	ofn.lpstrFile			= szFileName;
494 	ofn.nMaxFile			= MAXPATHLEN;
495 	ofn.lpstrInitialDir		= NULL;
496 	ofn.lpstrFileTitle		= szFileTitle;
497 	ofn.nMaxFileTitle		= MAXPATHLEN;
498 	ofn.lpstrTitle			= NULL;
499 	ofn.lpstrDefExt			= NULL;
500 	ofn.Flags				= OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
501 
502 	if (GetOpenFileName ((LPOPENFILENAME)&ofn)) {
503 		char Text[256];
504 		int ret;
505 
506 		SetMenu(gApp.hWnd, NULL);
507 		OpenPlugins(gApp.hWnd);
508 
509 		ret = SaveState(szFileName);
510 		if (ret == 0)
511 			 sprintf(Text, _("*PCSXR*: Saved State %s"), szFileName);
512 		else sprintf(Text, _("*PCSXR*: Error Saving State %s"), szFileName);
513 		GPU_displayText(Text);
514 
515 		Running = 1;
516 		psxCpu->Execute();
517 	}
518 }
519 
MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)520 LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
521 	char File[256];
522 	PAINTSTRUCT ps;
523 	RECT rect;
524 
525 	switch (msg) {
526 		case WM_CREATE:
527 			hBm = LoadBitmap(gApp.hInstance, MAKEINTRESOURCE(MAIN_LOGO));
528 			GetObject(hBm, sizeof(BITMAP), (LPVOID)&bm);
529 			hDC = GetDC(hWnd);
530 			hdcmem = CreateCompatibleDC(hDC);
531 			ReleaseDC(hWnd, hDC);
532 			break;
533 
534 		case WM_PAINT:
535 			hDC = BeginPaint(hWnd, &ps);
536 			SelectObject(hdcmem, hBm);
537 			if (!Running) BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hdcmem, 0, 0, SRCCOPY);
538 			EndPaint(hWnd, &ps);
539 			break;
540 
541 		case WM_COMMAND:
542 			switch (LOWORD(wParam)) {
543 				case ID_FILE_EXIT:
544 					SysClose();
545 					SaveConfig();
546 					PostQuitMessage(0);
547 					exit(0);
548 					return TRUE;
549 
550 				case ID_FILE_RUN_CD:
551 					SetIsoFile(NULL);
552 					SetMenu(hWnd, NULL);
553 					LoadPlugins();
554 					if (OpenPlugins(hWnd) == -1) {
555 						ClosePlugins();
556 						RestoreWindow();
557 						return TRUE;
558 					}
559 					if (CheckCdrom() == -1) {
560 						ClosePlugins();
561 						RestoreWindow();
562 						SysMessage(_("The CD does not appear to be a valid Playstation CD"));
563 						return TRUE;
564 					}
565 
566 					// Auto-detect: region first, then rcnt reset
567 					SysReset();
568 
569 					if (LoadCdrom() == -1) {
570 						ClosePlugins();
571 						RestoreWindow();
572 						SysMessage(_("Could not load CD-ROM!"));
573 						return TRUE;
574 					}
575 					if(Config.HideCursor)
576 						ShowCursor(FALSE);
577 					Running = 1;
578 					psxCpu->Execute();
579 					return TRUE;
580 
581 				case ID_FILE_RUNBIOS:
582 					if (strcmp(Config.Bios, "HLE") == 0) {
583 						SysMessage(_("Running BIOS is not supported with Internal HLE Bios."));
584 						return TRUE;
585 					}
586 					SetIsoFile(NULL);
587 					SetMenu(hWnd, NULL);
588 					LoadPlugins();
589 					if (OpenPlugins(hWnd) == -1) {
590 						ClosePlugins();
591 						RestoreWindow();
592 						return TRUE;
593 					}
594 					if(Config.HideCursor)
595 						ShowCursor(FALSE);
596 					SysReset();
597 					CdromId[0] = '\0';
598 					CdromLabel[0] = '\0';
599 					Running = 1;
600 					psxCpu->Execute();
601 					return TRUE;
602 
603 				case ID_FILE_RUN_ISO:
604 					if (!Open_Iso_Proc(File)) return TRUE;
605 					SetIsoFile(File);
606 					SetMenu(hWnd, NULL);
607 					LoadPlugins();
608 					if (OpenPlugins(hWnd) == -1) {
609 						ClosePlugins();
610 						RestoreWindow();
611 						return TRUE;
612 					}
613 					if (CheckCdrom() == -1) {
614 						ClosePlugins();
615 						RestoreWindow();
616 						SysMessage(_("The CD does not appear to be a valid Playstation CD"));
617 						return TRUE;
618 					}
619 
620 					// Auto-detect: region first, then rcnt reset
621 					SysReset();
622 
623 					if (LoadCdrom() == -1) {
624 						ClosePlugins();
625 						RestoreWindow();
626 						SysMessage(_("Could not load CD-ROM!"));
627 						return TRUE;
628 					}
629 					if(Config.HideCursor)
630 						ShowCursor(FALSE);
631 					Running = 1;
632 					psxCpu->Execute();
633 					return TRUE;
634 
635 				case ID_FILE_RUN_EXE:
636 					if (!Open_File_Proc(File)) return TRUE;
637 					SetIsoFile(NULL);
638 					SetMenu(hWnd, NULL);
639 					LoadPlugins();
640 					if (OpenPlugins(hWnd) == -1) {
641 						ClosePlugins();
642 						RestoreWindow();
643 						return TRUE;
644 					}
645 					CheckCdrom();
646 
647 					// Auto-detect: region first, then rcnt reset
648 					SysReset();
649 
650 					Load(File);
651 					Running = 1;
652 					psxCpu->Execute();
653 					return TRUE;
654 
655 				case ID_FILE_STATES_LOAD_SLOT1: States_Load(0); return TRUE;
656 				case ID_FILE_STATES_LOAD_SLOT2: States_Load(1); return TRUE;
657 				case ID_FILE_STATES_LOAD_SLOT3: States_Load(2); return TRUE;
658 				case ID_FILE_STATES_LOAD_SLOT4: States_Load(3); return TRUE;
659 				case ID_FILE_STATES_LOAD_SLOT5: States_Load(4); return TRUE;
660 				case ID_FILE_STATES_LOAD_SLOT6: States_Load(5); return TRUE;
661 				case ID_FILE_STATES_LOAD_SLOT7: States_Load(6); return TRUE;
662 				case ID_FILE_STATES_LOAD_SLOT8: States_Load(7); return TRUE;
663 				case ID_FILE_STATES_LOAD_SLOT9: States_Load(8); return TRUE;
664 				case ID_FILE_STATES_LOAD_OTHER: OnStates_LoadOther(); return TRUE;
665 
666 				case ID_FILE_STATES_SAVE_SLOT1: States_Save(0); return TRUE;
667 				case ID_FILE_STATES_SAVE_SLOT2: States_Save(1); return TRUE;
668 				case ID_FILE_STATES_SAVE_SLOT3: States_Save(2); return TRUE;
669 				case ID_FILE_STATES_SAVE_SLOT4: States_Save(3); return TRUE;
670 				case ID_FILE_STATES_SAVE_SLOT5: States_Save(4); return TRUE;
671 				case ID_FILE_STATES_SAVE_SLOT6: States_Save(5); return TRUE;
672 				case ID_FILE_STATES_SAVE_SLOT7: States_Save(6); return TRUE;
673 				case ID_FILE_STATES_SAVE_SLOT8: States_Save(7); return TRUE;
674 				case ID_FILE_STATES_SAVE_SLOT9: States_Save(8); return TRUE;
675 				case ID_FILE_STATES_SAVE_OTHER: OnStates_SaveOther(); return TRUE;
676 
677 				case ID_FILE_RUN_NOGUI:
678 					SetMenu(hWnd, NULL);
679 					LoadPlugins();
680 					if (OpenPlugins(hWnd) == -1) {
681 						ClosePlugins();
682 						RestoreWindow();
683 						return TRUE;
684 					}
685 					if (CheckCdrom() == -1) {
686 						fprintf(stderr, _("The CD does not appear to be a valid Playstation CD"));
687 						ClosePlugins();
688 						RestoreWindow();
689 						return TRUE;
690 					}
691 
692 					// Auto-detect: region first, then rcnt reset
693 					SysReset();
694 
695 					if (LoadCdrom() == -1) {
696 						fprintf(stderr, _("Could not load CD-ROM!"));
697 						ClosePlugins();
698 						RestoreWindow();
699 						return TRUE;
700 					}
701 					if(Config.HideCursor)
702 						ShowCursor(FALSE);
703 					Running = 1;
704 					psxCpu->Execute();
705 					return TRUE;
706 
707 				case ID_FILE_RUN_EXE_NOGUI:
708 
709 					SetIsoFile(NULL);
710 					SetMenu(hWnd, NULL);
711 					LoadPlugins();
712 					if (OpenPlugins(hWnd) == -1) {
713 						ClosePlugins();
714 						RestoreWindow();
715 						return TRUE;
716 					}
717 					CheckCdrom();
718 
719 					// Auto-detect: region first, then rcnt reset
720 					SysReset();
721 
722 					if(Config.HideCursor)
723 						ShowCursor(FALSE);
724 
725 					LoadLdrFile( GetLdrFile() );
726 
727 					Load( GetExeFile() );
728 					Running = 1;
729 					psxCpu->Execute();
730 					return TRUE;
731 
732 				case ID_EMULATOR_RUN:
733 					SetMenu(hWnd, NULL);
734 					OpenPlugins(hWnd);
735 					if(Config.HideCursor)
736 						ShowCursor(FALSE);
737 					Running = 1;
738 					CheatSearchBackupMemory();
739 					psxCpu->Execute();
740 					return TRUE;
741 
742 				case ID_EMULATOR_RESET:
743 					SetMenu(hWnd, NULL);
744 					OpenPlugins(hWnd);
745 					CheckCdrom();
746 
747 					// Auto-detect: region first, then rcnt reset
748 					SysReset();
749 
750 					LoadCdrom();
751 					if(Config.HideCursor)
752 						ShowCursor(FALSE);
753 					Running = 1;
754 					psxCpu->Execute();
755 					return TRUE;
756 
757 				case ID_EMULATOR_SHUTDOWN:
758 					ReleasePlugins();
759 					SetIsoFile(NULL);
760 					CdromId[0] = '\0';
761 					CdromLabel[0] = '\0';
762 					UpdateMenuItems();
763 					ShowCursor(TRUE); // we want GUI to have cursor always
764 					return TRUE;
765 
766 				case ID_EMULATOR_SWITCH_ISO:
767 					if (!Open_Iso_Proc(File)) return TRUE;
768 					SetIsoFile(File);
769 					SetMenu(hWnd, NULL);
770 					if (OpenPlugins(hWnd) == -1) {
771 						ClosePlugins();
772 						RestoreWindow();
773 						return TRUE;
774 					}
775 					if(Config.HideCursor)
776 						ShowCursor(FALSE);
777 					Running = 1;
778 					SetCdOpenCaseTime(time(NULL) + 2);
779 					CheatSearchBackupMemory();
780 					psxCpu->Execute();
781 					return TRUE;
782 
783 				case ID_CONFIGURATION_GRAPHICS:
784 					if (GPU_configure) GPU_configure();
785 					return TRUE;
786 
787 				case ID_CONFIGURATION_SOUND:
788 					if (SPU_configure) SPU_configure();
789 					return TRUE;
790 
791 				case ID_CONFIGURATION_CONTROLLERS:
792 					if (PAD1_configure) PAD1_configure();
793 					if (strcmp(Config.Pad1, Config.Pad2)) if (PAD2_configure) PAD2_configure();
794 					return TRUE;
795 
796 				case ID_CONFIGURATION_CDROM:
797 				    if (CDR_configure) CDR_configure();
798 					return TRUE;
799 
800 				case ID_CONFIGURATION_LINKCABLE:
801 #ifdef ENABLE_SIO1API
802 					if (SIO1_configure) SIO1_configure();
803 #endif
804 					return TRUE;
805 
806 				case ID_CONFIGURATION_NETPLAY:
807 					DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_NETPLAY), hWnd, (DLGPROC)ConfigureNetPlayDlgProc);
808 					return TRUE;
809 
810 				case ID_CONFIGURATION_MEMORYCARDMANAGER:
811 					DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_MCDCONF), hWnd, (DLGPROC)ConfigureMcdsDlgProc);
812 					return TRUE;
813 
814 				case ID_CONFIGURATION_CPU:
815 					DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_CPUCONF), hWnd, (DLGPROC)ConfigureCpuDlgProc);
816 					return TRUE;
817 
818 				case ID_CONFIGURATION:
819 					ConfigurePlugins(hWnd);
820 					return TRUE;
821 
822 				case ID_CONFIGURATION_CHEATLIST:
823 					DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_CHEATLIST), hWnd, (DLGPROC)CheatDlgProc);
824 					break;
825 
826 				case ID_CONFIGURATION_CHEATSEARCH:
827 					DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_CHEATSEARCH), hWnd, (DLGPROC)CheatSearchDlgProc);
828 					break;
829 
830 				case ID_HELP_ABOUT:
831 					DialogBox(gApp.hInstance, MAKEINTRESOURCE(ABOUT_DIALOG), hWnd, (DLGPROC)AboutDlgProc);
832 					return TRUE;
833 
834 				default:
835 #ifdef ENABLE_NLS
836 					if (LOWORD(wParam) >= ID_LANGS && LOWORD(wParam) <= (ID_LANGS + langsMax)) {
837 						AccBreak = 1;
838 						DestroyWindow(gApp.hWnd);
839 						ChangeLanguage(langs[LOWORD(wParam) - ID_LANGS].lang);
840 						CreateMainWindow(SW_NORMAL);
841 						return TRUE;
842 					}
843 #endif
844 					break;
845 			}
846 			break;
847 
848 		case WM_SYSKEYDOWN:
849 			if (wParam != VK_F10)
850 				return DefWindowProc(hWnd, msg, wParam, lParam);
851 		case WM_KEYDOWN:
852 			PADhandleKey(wParam);
853 			return TRUE;
854 
855 		case WM_DESTROY:
856 			if (!AccBreak) {
857 				if (Running) ClosePlugins();
858 				SysClose();
859 				SaveConfig();
860 				PostQuitMessage(0);
861 				exit(0);
862 			}
863 			else AccBreak = 0;
864 
865 			DeleteObject(hBm);
866 			DeleteDC(hdcmem);
867 			return TRUE;
868 
869 		case WM_EXITSIZEMOVE:
870 			if(Config.SaveWindowPos) {
871 				GetWindowRect(hWnd, &rect);
872 				Config.WindowPos[0] = rect.left;
873 				Config.WindowPos[1] = rect.top;
874 			}
875 			return TRUE;
876 
877 		case WM_QUIT:
878 			SaveConfig();
879 			exit(0);
880 			break;
881 
882 		default:
883 			return DefWindowProc(hWnd, msg, wParam, lParam);
884 	}
885 
886 	return FALSE;
887 }
888 
889 HWND mcdDlg;
890 McdBlock Blocks[2][15];
891 int IconC[2][15];
892 HIMAGELIST Iiml[2];
893 HICON eICON;
894 
CreateListView(int idc)895 void CreateListView(int idc) {
896 	HWND List;
897 	LV_COLUMN col;
898 
899 	List = GetDlgItem(mcdDlg, idc);
900 
901 	col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
902 	col.fmt  = LVCFMT_LEFT;
903 
904 	col.pszText  = _("Title");
905 	col.cx       = 170;
906 	col.iSubItem = 0;
907 
908 	ListView_InsertColumn(List, 0, &col);
909 
910 	col.pszText  = _("Status");
911 	col.cx       = 50;
912 	col.iSubItem = 1;
913 
914 	ListView_InsertColumn(List, 1, &col);
915 
916 	col.pszText  = _("Game ID");
917 	col.cx       = 90;
918 	col.iSubItem = 2;
919 
920 	ListView_InsertColumn(List, 2, &col);
921 
922 	col.pszText  = _("Game");
923 	col.cx       = 80;
924 	col.iSubItem = 3;
925 
926 	ListView_InsertColumn(List, 3, &col);
927 }
928 
GetRGB()929 int GetRGB() {
930     HDC scrDC, memDC;
931     HBITMAP oldBmp = NULL;
932     HBITMAP curBmp = NULL;
933     COLORREF oldColor;
934     COLORREF curColor = RGB(255,255,255);
935     int i, R, G, B;
936 
937     R = G = B = 1;
938 
939     scrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
940     memDC = CreateCompatibleDC(NULL);
941     curBmp = CreateCompatibleBitmap(scrDC, 1, 1);
942     oldBmp = (HBITMAP)SelectObject(memDC, curBmp);
943 
944     for (i = 255; i >= 0; --i) {
945         oldColor = curColor;
946         curColor = SetPixel(memDC, 0, 0, RGB(i, i, i));
947 
948         if (GetRValue(curColor) < GetRValue(oldColor)) ++R;
949         if (GetGValue(curColor) < GetGValue(oldColor)) ++G;
950         if (GetBValue(curColor) < GetBValue(oldColor)) ++B;
951     }
952 
953     DeleteObject(oldBmp);
954     DeleteObject(curBmp);
955     DeleteDC(scrDC);
956     DeleteDC(memDC);
957 
958     return (R * G * B);
959 }
960 
GetIcon(short * icon)961 HICON GetIcon(short *icon) {
962     ICONINFO iInfo;
963     HDC hDC;
964     char mask[16*16];
965     int x, y, c, Depth;
966 
967     hDC = CreateIC("DISPLAY",NULL,NULL,NULL);
968     Depth=GetDeviceCaps(hDC, BITSPIXEL);
969     DeleteDC(hDC);
970 
971     if (Depth == 16) {
972         if (GetRGB() == (32 * 32 * 32))
973             Depth = 15;
974     }
975 
976     for (y=0; y<16; y++) {
977         for (x=0; x<16; x++) {
978             c = icon[y*16+x];
979             if (Depth == 15 || Depth == 32)
980 				c = ((c&0x001f) << 10) |
981 					((c&0x7c00) >> 10) |
982 					((c&0x03e0)      );
983 			else
984                 c = ((c&0x001f) << 11) |
985 					((c&0x7c00) >>  9) |
986 					((c&0x03e0) <<  1);
987 
988             icon[y*16+x] = c;
989         }
990     }
991 
992     iInfo.fIcon = TRUE;
993     memset(mask, 0, 16*16);
994     iInfo.hbmMask  = CreateBitmap(16, 16, 1, 1, mask);
995     iInfo.hbmColor = CreateBitmap(16, 16, 1, 16, icon);
996 
997     return CreateIconIndirect(&iInfo);
998 }
999 
1000 HICON hICON[2][3][15];
1001 int aIover[2];
1002 int ani[2];
1003 
LoadMcdItems(int mcd,int idc)1004 void LoadMcdItems(int mcd, int idc) {
1005     HWND List = GetDlgItem(mcdDlg, idc);
1006     LV_ITEM item;
1007     HIMAGELIST iml = Iiml[mcd-1];
1008     int i, j;
1009     HICON hIcon;
1010     McdBlock *Info;
1011 
1012     aIover[mcd-1]=0;
1013     ani[mcd-1]=0;
1014 
1015     ListView_DeleteAllItems(List);
1016 
1017     for (i=0; i<15; i++) {
1018 
1019         item.mask      = LVIF_TEXT | LVIF_IMAGE;
1020         item.iItem       = i;
1021         item.iImage    = i;
1022         item.pszText  = LPSTR_TEXTCALLBACK;
1023         item.iSubItem = 0;
1024 
1025         IconC[mcd-1][i] = 0;
1026         Info = &Blocks[mcd-1][i];
1027 
1028         if ((Info->Flags & 0xF) == 1 && Info->IconCount != 0) {
1029             hIcon = GetIcon(Info->Icon);
1030 
1031             if (Info->IconCount > 1) {
1032                 for(j = 0; j < 3; j++)
1033                     hICON[mcd-1][j][i]=hIcon;
1034             }
1035         } else {
1036             hIcon = eICON;
1037         }
1038 
1039         ImageList_ReplaceIcon(iml, -1, hIcon);
1040         ListView_InsertItem(List, &item);
1041     }
1042 }
1043 
UpdateMcdItems(int mcd,int idc)1044 void UpdateMcdItems(int mcd, int idc) {
1045     HWND List = GetDlgItem(mcdDlg, idc);
1046     LV_ITEM item;
1047     HIMAGELIST iml = Iiml[mcd-1];
1048     int i, j;
1049     McdBlock *Info;
1050     HICON hIcon;
1051 
1052     aIover[mcd-1]=0;
1053     ani[mcd-1]=0;
1054 
1055     for (i=0; i<15; i++) {
1056 
1057         item.mask     = LVIF_TEXT | LVIF_IMAGE;
1058         item.iItem    = i;
1059         item.iImage   = i;
1060         item.pszText  = LPSTR_TEXTCALLBACK;
1061         item.iSubItem = 0;
1062 
1063         IconC[mcd-1][i] = 0;
1064         Info = &Blocks[mcd-1][i];
1065 
1066         if ((Info->Flags & 0xF) == 1 && Info->IconCount != 0) {
1067             hIcon = GetIcon(Info->Icon);
1068 
1069             if (Info->IconCount > 1) {
1070                 for(j = 0; j < 3; j++)
1071                     hICON[mcd-1][j][i]=hIcon;
1072             }
1073         } else {
1074             hIcon = eICON;
1075         }
1076 
1077         ImageList_ReplaceIcon(iml, i, hIcon);
1078         ListView_SetItem(List, &item);
1079     }
1080     ListView_Update(List, -1);
1081 }
1082 
McdListGetDispInfo(int mcd,int idc,LPNMHDR pnmh)1083 void McdListGetDispInfo(int mcd, int idc, LPNMHDR pnmh) {
1084 	LV_DISPINFO *lpdi = (LV_DISPINFO *)pnmh;
1085 	McdBlock *Info;
1086 	char buf[256];
1087 	static char buftitle[256];
1088 
1089 	Info = &Blocks[mcd - 1][lpdi->item.iItem];
1090 
1091 	switch (lpdi->item.iSubItem) {
1092 		case 0:
1093 			switch (Info->Flags & 0xF) {
1094 				case 1:
1095 					if (MultiByteToWideChar(932, 0, (LPCSTR)Info->sTitle, -1, (LPWSTR)buf, sizeof(buf)) == 0) {
1096 						lpdi->item.pszText = Info->Title;
1097 					} else if (WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)buf, -1, (LPSTR)buftitle, sizeof(buftitle), NULL, NULL) == 0) {
1098 						lpdi->item.pszText = Info->Title;
1099 					} else {
1100 						lpdi->item.pszText = buftitle;
1101 					}
1102 					break;
1103 				case 2:
1104 					lpdi->item.pszText = _("mid link block");
1105 					break;
1106 				case 3:
1107 					lpdi->item.pszText = _("terminiting link block");
1108 					break;
1109 			}
1110 			break;
1111 		case 1:
1112 			if ((Info->Flags & 0xF0) == 0xA0) {
1113 				if ((Info->Flags & 0xF) >= 1 &&
1114 					(Info->Flags & 0xF) <= 3) {
1115 					lpdi->item.pszText = _("Deleted");
1116 				} else lpdi->item.pszText = _("Free");
1117 			} else if ((Info->Flags & 0xF0) == 0x50)
1118 				lpdi->item.pszText = _("Used");
1119 			else { lpdi->item.pszText = _("Free"); }
1120 			break;
1121 		case 2:
1122 			if((Info->Flags & 0xF)==1)
1123 				lpdi->item.pszText = Info->ID;
1124 			break;
1125 		case 3:
1126 			if((Info->Flags & 0xF)==1)
1127 				lpdi->item.pszText = Info->Name;
1128 			break;
1129 	}
1130 }
1131 
McdListNotify(int mcd,int idc,LPNMHDR pnmh)1132 void McdListNotify(int mcd, int idc, LPNMHDR pnmh) {
1133 	switch (pnmh->code) {
1134 		case LVN_GETDISPINFO: McdListGetDispInfo(mcd, idc, pnmh); break;
1135 	}
1136 }
1137 
UpdateMcdDlg()1138 void UpdateMcdDlg() {
1139 	int i;
1140 
1141 	for (i=1; i<16; i++) GetMcdBlockInfo(1, i, &Blocks[0][i-1]);
1142 	for (i=1; i<16; i++) GetMcdBlockInfo(2, i, &Blocks[1][i-1]);
1143 	UpdateMcdItems(1, IDC_LIST1);
1144 	UpdateMcdItems(2, IDC_LIST2);
1145 }
1146 
LoadMcdDlg()1147 void LoadMcdDlg() {
1148 	int i;
1149 
1150 	for (i=1; i<16; i++) GetMcdBlockInfo(1, i, &Blocks[0][i-1]);
1151 	for (i=1; i<16; i++) GetMcdBlockInfo(2, i, &Blocks[1][i-1]);
1152 	LoadMcdItems(1, IDC_LIST1);
1153 	LoadMcdItems(2, IDC_LIST2);
1154 }
1155 
UpdateMcdIcon(int mcd,int idc)1156 void UpdateMcdIcon(int mcd, int idc) {
1157     HWND List = GetDlgItem(mcdDlg, idc);
1158     HIMAGELIST iml = Iiml[mcd-1];
1159     int i;
1160     McdBlock *Info;
1161     int *count;
1162 
1163     if(!aIover[mcd-1]) {
1164         ani[mcd-1]++;
1165 
1166         for (i=0; i<15; i++) {
1167             Info = &Blocks[mcd-1][i];
1168             count = &IconC[mcd-1][i];
1169 
1170             if ((Info->Flags & 0xF) != 1) continue;
1171             if (Info->IconCount <= 1) continue;
1172 
1173             if (*count < Info->IconCount) {
1174                 (*count)++;
1175                 aIover[mcd-1]=0;
1176 
1177                 if(ani[mcd-1] <= (Info->IconCount-1))  // last frame and below...
1178                     hICON[mcd-1][ani[mcd-1]][i] = GetIcon(&Info->Icon[(*count)*16*16]);
1179             } else {
1180                 aIover[mcd-1]=1;
1181             }
1182         }
1183 
1184     } else {
1185 
1186         if (ani[mcd-1] > 1) ani[mcd-1] = 0;  // 1st frame
1187         else ani[mcd-1]++;                       // 2nd, 3rd frame
1188 
1189         for(i=0;i<15;i++) {
1190             Info = &Blocks[mcd-1][i];
1191 
1192             if (((Info->Flags & 0xF) == 1) && (Info->IconCount > 1))
1193                 ImageList_ReplaceIcon(iml, i, hICON[mcd-1][ani[mcd-1]][i]);
1194         }
1195         InvalidateRect(List,  NULL, FALSE);
1196     }
1197 }
1198 
1199 static int copy = 0, copymcd = 0;
1200 //static int listsel = 0;
1201 
ConfigureMcdsDlgProc(HWND hW,UINT uMsg,WPARAM wParam,LPARAM lParam)1202 BOOL CALLBACK ConfigureMcdsDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
1203 	char str[256];
1204 	LPBYTE lpAND, lpXOR;
1205 	LPBYTE lpA, lpX;
1206 	int i, j;
1207 
1208 	switch(uMsg) {
1209 		case WM_INITDIALOG:
1210 			mcdDlg = hW;
1211 
1212 			SetWindowText(hW, _("Memcard Manager"));
1213 
1214 			Button_SetText(GetDlgItem(hW, IDOK),        _("OK"));
1215 			Button_SetText(GetDlgItem(hW, IDCANCEL),    _("Cancel"));
1216 			Button_SetText(GetDlgItem(hW, IDC_MCDSEL1), _("Select Mcd"));
1217 			Button_SetText(GetDlgItem(hW, IDC_FORMAT1), _("Format Mcd"));
1218 			Button_SetText(GetDlgItem(hW, IDC_RELOAD1), _("Reload Mcd"));
1219 			Button_SetText(GetDlgItem(hW, IDC_MCDSEL2), _("Select Mcd"));
1220 			Button_SetText(GetDlgItem(hW, IDC_FORMAT2), _("Format Mcd"));
1221 			Button_SetText(GetDlgItem(hW, IDC_RELOAD2), _("Reload Mcd"));
1222 			Button_SetText(GetDlgItem(hW, IDC_COPYTO2), _("-> Copy ->"));
1223 			Button_SetText(GetDlgItem(hW, IDC_COPYTO1), _("<- Copy <-"));
1224 			Button_SetText(GetDlgItem(hW, IDC_PASTE),   _("Paste"));
1225 			Button_SetText(GetDlgItem(hW, IDC_DELETE1), _("<- Un/Delete"));
1226 			Button_SetText(GetDlgItem(hW, IDC_DELETE2), _("Un/Delete ->"));
1227 
1228 			Static_SetText(GetDlgItem(hW, IDC_FRAMEMCD1), _("Memory Card 1"));
1229 			Static_SetText(GetDlgItem(hW, IDC_FRAMEMCD2), _("Memory Card 2"));
1230 
1231 			lpA=lpAND=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(16*16));
1232 			lpX=lpXOR=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(16*16));
1233 
1234 			for(i=0;i<16;i++)
1235 			{
1236 				for(j=0;j<16;j++)
1237 				{
1238 					*lpA++=0xff;
1239 					*lpX++=0;
1240 				}
1241 			}
1242 			eICON=CreateIcon(gApp.hInstance,16,16,1,1,lpAND,lpXOR);
1243 
1244 			HeapFree(GetProcessHeap(),0,lpAND);
1245 			HeapFree(GetProcessHeap(),0,lpXOR);
1246 
1247 			if (!strlen(Config.Mcd1)) strcpy(Config.Mcd1, "memcards\\Mcd001.mcr");
1248 			if (!strlen(Config.Mcd2)) strcpy(Config.Mcd2, "memcards\\Mcd002.mcr");
1249 			Edit_SetText(GetDlgItem(hW,IDC_MCD1), Config.Mcd1);
1250 			Edit_SetText(GetDlgItem(hW,IDC_MCD2), Config.Mcd2);
1251 
1252 			CreateListView(IDC_LIST1);
1253 			CreateListView(IDC_LIST2);
1254 
1255             Iiml[0] = ImageList_Create(16, 16, ILC_COLOR16, 0, 0);
1256             Iiml[1] = ImageList_Create(16, 16, ILC_COLOR16, 0, 0);
1257 
1258             ListView_SetImageList(GetDlgItem(mcdDlg, IDC_LIST1), Iiml[0], LVSIL_SMALL);
1259             ListView_SetImageList(GetDlgItem(mcdDlg, IDC_LIST2), Iiml[1], LVSIL_SMALL);
1260 
1261 			Button_Enable(GetDlgItem(hW, IDC_PASTE), FALSE);
1262 
1263 			LoadMcdDlg();
1264 
1265 			SetTimer(hW, 1, 250, NULL);
1266 
1267 			return TRUE;
1268 
1269 		case WM_COMMAND:
1270 			switch (LOWORD(wParam)) {
1271 				case IDC_COPYTO1:
1272 					copy = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST2));
1273 					copymcd = 1;
1274 
1275 					Button_Enable(GetDlgItem(hW, IDC_PASTE), TRUE);
1276 					return TRUE;
1277 				case IDC_COPYTO2:
1278 					copy = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST1));
1279 					copymcd = 2;
1280 
1281 					Button_Enable(GetDlgItem(hW, IDC_PASTE), TRUE);
1282 					return TRUE;
1283 				case IDC_PASTE:
1284 					if (MessageBox(hW, _("Are you sure you want to paste this selection?"), _("Confirmation"), MB_YESNO) == IDNO) return TRUE;
1285 
1286 					if (copymcd == 1) {
1287 						Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256);
1288 						i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST1));
1289 
1290 						// save dir data + save data
1291 						memcpy(Mcd1Data + (i+1) * 128, Mcd2Data + (copy+1) * 128, 128);
1292 						SaveMcd(str, Mcd1Data, (i+1) * 128, 128);
1293 						memcpy(Mcd1Data + (i+1) * 1024 * 8, Mcd2Data + (copy+1) * 1024 * 8, 1024 * 8);
1294 						SaveMcd(str, Mcd1Data, (i+1) * 1024 * 8, 1024 * 8);
1295 					} else { // 2
1296 						Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256);
1297 						i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST2));
1298 
1299 						// save dir data + save data
1300 						memcpy(Mcd2Data + (i+1) * 128, Mcd1Data + (copy+1) * 128, 128);
1301 						SaveMcd(str, Mcd2Data, (i+1) * 128, 128);
1302 						memcpy(Mcd2Data + (i+1) * 1024 * 8, Mcd1Data + (copy+1) * 1024 * 8, 1024 * 8);
1303 						SaveMcd(str, Mcd2Data, (i+1) * 1024 * 8, 1024 * 8);
1304 					}
1305 
1306 					UpdateMcdDlg();
1307 
1308 					return TRUE;
1309 				case IDC_DELETE1:
1310 				{
1311 					McdBlock *Info;
1312 					int mcd = 1;
1313 					int i, xor = 0, j;
1314 					unsigned char *data, *ptr;
1315 
1316 					Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256);
1317 					i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST1));
1318 					data = Mcd1Data;
1319 
1320 					i++;
1321 
1322 					ptr = data + i * 128;
1323 
1324 					Info = &Blocks[mcd-1][i-1];
1325 
1326 					if ((Info->Flags & 0xF0) == 0xA0) {
1327 						if ((Info->Flags & 0xF) >= 1 &&
1328 							(Info->Flags & 0xF) <= 3) { // deleted
1329 							*ptr = 0x50 | (Info->Flags & 0xF);
1330 						} else return TRUE;
1331 					} else if ((Info->Flags & 0xF0) == 0x50) { // used
1332 						*ptr = 0xA0 | (Info->Flags & 0xF);
1333 					} else { return TRUE; }
1334 
1335 					for (j=0; j<127; j++) xor^=*ptr++;
1336 					*ptr = xor;
1337 
1338 					SaveMcd(str, data, i * 128, 128);
1339 					UpdateMcdDlg();
1340 				}
1341 
1342 					return TRUE;
1343 				case IDC_DELETE2:
1344 				{
1345 					McdBlock *Info;
1346 					int mcd = 2;
1347 					int i, xor = 0, j;
1348 					unsigned char *data, *ptr;
1349 
1350 					Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256);
1351 					i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST2));
1352 					data = Mcd2Data;
1353 
1354 					i++;
1355 
1356 					ptr = data + i * 128;
1357 
1358 					Info = &Blocks[mcd-1][i-1];
1359 
1360 					if ((Info->Flags & 0xF0) == 0xA0) {
1361 						if ((Info->Flags & 0xF) >= 1 &&
1362 							(Info->Flags & 0xF) <= 3) { // deleted
1363 							*ptr = 0x50 | (Info->Flags & 0xF);
1364 						} else return TRUE;
1365 					} else if ((Info->Flags & 0xF0) == 0x50) { // used
1366 						*ptr = 0xA0 | (Info->Flags & 0xF);
1367 					} else { return TRUE; }
1368 
1369 					for (j=0; j<127; j++) xor^=*ptr++;
1370 					*ptr = xor;
1371 
1372 					SaveMcd(str, data, i * 128, 128);
1373 					UpdateMcdDlg();
1374 				}
1375 
1376 					return TRUE;
1377 
1378 				case IDC_MCDSEL1:
1379 					Open_Mcd_Proc(hW, 1);
1380 					return TRUE;
1381 				case IDC_MCDSEL2:
1382 					Open_Mcd_Proc(hW, 2);
1383 					return TRUE;
1384 				case IDC_RELOAD1:
1385 					Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256);
1386 					LoadMcd(1, str);
1387 					UpdateMcdDlg();
1388 					return TRUE;
1389 				case IDC_RELOAD2:
1390 					Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256);
1391 					LoadMcd(2, str);
1392 					UpdateMcdDlg();
1393 					return TRUE;
1394 				case IDC_FORMAT1:
1395 					if (MessageBox(hW, _("Are you sure you want to format this Memory Card?"), _("Confirmation"), MB_YESNO) == IDNO) return TRUE;
1396 					Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256);
1397 					CreateMcd(str);
1398 					LoadMcd(1, str);
1399 					UpdateMcdDlg();
1400 					return TRUE;
1401 				case IDC_FORMAT2:
1402 					if (MessageBox(hW, _("Are you sure you want to format this Memory Card?"), _("Confirmation"), MB_YESNO) == IDNO) return TRUE;
1403 					Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256);
1404 					CreateMcd(str);
1405 					LoadMcd(2, str);
1406 					UpdateMcdDlg();
1407 					return TRUE;
1408        			case IDCANCEL:
1409 					LoadMcds(Config.Mcd1, Config.Mcd2);
1410 
1411 					EndDialog(hW,FALSE);
1412 
1413 					return TRUE;
1414        			case IDOK:
1415 					Edit_GetText(GetDlgItem(hW,IDC_MCD1), Config.Mcd1, 256);
1416 					Edit_GetText(GetDlgItem(hW,IDC_MCD2), Config.Mcd2, 256);
1417 
1418 					LoadMcds(Config.Mcd1, Config.Mcd2);
1419 					SaveConfig();
1420 
1421 					EndDialog(hW,TRUE);
1422 
1423 					return TRUE;
1424 			}
1425 		case WM_NOTIFY:
1426 			switch (wParam) {
1427 				case IDC_LIST1: McdListNotify(1, IDC_LIST1, (LPNMHDR)lParam); break;
1428 				case IDC_LIST2: McdListNotify(2, IDC_LIST2, (LPNMHDR)lParam); break;
1429 			}
1430 			return TRUE;
1431 		case WM_TIMER:
1432 			UpdateMcdIcon(1, IDC_LIST1);
1433 			UpdateMcdIcon(2, IDC_LIST2);
1434 			return TRUE;
1435 		case WM_DESTROY:
1436 			DestroyIcon(eICON);
1437 			//KillTimer(hW, 1);
1438 			return TRUE;
1439 	}
1440 	return FALSE;
1441 }
1442 
ConfigureCpuDlgProc(HWND hW,UINT uMsg,WPARAM wParam,LPARAM lParam)1443 BOOL CALLBACK ConfigureCpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
1444 	long tmp;
1445 	RECT rect;
1446 
1447 	switch(uMsg) {
1448 		case WM_INITDIALOG:
1449 			SetWindowText(hW, _("Cpu Config"));
1450 
1451 			Button_SetText(GetDlgItem(hW,IDOK),        _("OK"));
1452 			Button_SetText(GetDlgItem(hW,IDCANCEL),    _("Cancel"));
1453 
1454 			Button_SetText(GetDlgItem(hW,IDC_XA),      _("Disable Xa Decoding"));
1455 			Button_SetText(GetDlgItem(hW,IDC_SIO),     _("Sio Irq Always Enabled"));
1456 			Button_SetText(GetDlgItem(hW,IDC_MDEC),    _("Black && White Movies"));
1457 			Button_SetText(GetDlgItem(hW,IDC_CDDA),    _("Disable Cd audio"));
1458 			Button_SetText(GetDlgItem(hW,IDC_SLOWBOOT),_("Slow Boot"));
1459 			Button_SetText(GetDlgItem(hW,IDC_PSXAUTO), _("Autodetect"));
1460 			Button_SetText(GetDlgItem(hW,IDC_CPU),     _("Enable Interpreter Cpu"));
1461 			Button_SetText(GetDlgItem(hW,IDC_PSXOUT),  _("Enable Console Output"));
1462 			Button_SetText(GetDlgItem(hW,IDC_DEBUG),   _("Enable Debugger"));
1463 			Button_SetText(GetDlgItem(hW,IDC_SPUIRQ),  _("Spu Irq Always Enabled"));
1464 			Button_SetText(GetDlgItem(hW,IDC_RCNTFIX), _("Parasite Eve 2, Vandal Hearts 1/2 Fix"));
1465 			Button_SetText(GetDlgItem(hW,IDC_VSYNCWA), _("InuYasha Sengoku Battle Fix"));
1466 			Button_SetText(GetDlgItem(hW,IDC_WIDESCREEN), _("Widescreen (GTE Hack)"));
1467 			Button_SetText(GetDlgItem(hW,IDC_HIDECURSOR), _("Hide cursor"));
1468 			Button_SetText(GetDlgItem(hW,IDC_SAVEWINDOWPOS), _("Save window position"));
1469 			Button_SetText(GetDlgItem(hW,IDC_HACKFIX), _("Compatibility hacks (Raystorm/VH-D/MML/Cart World/...)"));
1470 
1471 			Static_SetText(GetDlgItem(hW,IDC_MISCOPT), _("Options"));
1472 			Static_SetText(GetDlgItem(hW,IDC_SELPSX),  _("Psx System Type"));
1473 
1474 			Button_SetCheck(GetDlgItem(hW,IDC_XA),      Config.Xa);
1475 			Button_SetCheck(GetDlgItem(hW,IDC_SIO),     Config.SioIrq);
1476 			Button_SetCheck(GetDlgItem(hW,IDC_MDEC),    Config.Mdec);
1477 			Button_SetCheck(GetDlgItem(hW,IDC_CDDA),    Config.Cdda);
1478 			Button_SetCheck(GetDlgItem(hW,IDC_SLOWBOOT),Config.SlowBoot);
1479 			Button_SetCheck(GetDlgItem(hW,IDC_PSXAUTO), Config.PsxAuto);
1480 			Button_SetCheck(GetDlgItem(hW,IDC_CPU),     (Config.Cpu == CPU_INTERPRETER));
1481 			Button_SetCheck(GetDlgItem(hW,IDC_PSXOUT),  Config.PsxOut);
1482 			Button_SetCheck(GetDlgItem(hW,IDC_DEBUG),   Config.Debug);
1483 			Button_SetCheck(GetDlgItem(hW,IDC_SPUIRQ),  Config.SpuIrq);
1484 			Button_SetCheck(GetDlgItem(hW,IDC_RCNTFIX), Config.RCntFix);
1485 			Button_SetCheck(GetDlgItem(hW,IDC_VSYNCWA), Config.VSyncWA);
1486 			Button_SetCheck(GetDlgItem(hW,IDC_WIDESCREEN), Config.Widescreen);
1487 			Button_SetCheck(GetDlgItem(hW,IDC_HIDECURSOR), Config.HideCursor);
1488 			Button_SetCheck(GetDlgItem(hW,IDC_SAVEWINDOWPOS), Config.SaveWindowPos);
1489 			Button_SetCheck(GetDlgItem(hW,IDC_HACKFIX), Config.HackFix);
1490 
1491 			ComboBox_AddString(GetDlgItem(hW,IDC_PSXTYPES), "NTSC");
1492 			ComboBox_AddString(GetDlgItem(hW,IDC_PSXTYPES), "PAL");
1493 			ComboBox_SetCurSel(GetDlgItem(hW,IDC_PSXTYPES),Config.PsxType);
1494 
1495 			if (Config.Cpu == CPU_DYNAREC) {
1496 				Config.Debug = 0;
1497 				Button_SetCheck(GetDlgItem(hW, IDC_DEBUG), FALSE);
1498 				EnableWindow(GetDlgItem(hW, IDC_DEBUG), FALSE);
1499 			}
1500 
1501 			EnableWindow(GetDlgItem(hW,IDC_PSXTYPES), !Config.PsxAuto);
1502 			break;
1503 
1504 		case WM_COMMAND: {
1505 			switch (LOWORD(wParam)) {
1506 				case IDCANCEL: EndDialog(hW, FALSE); return TRUE;
1507 				case IDOK:
1508 					tmp = ComboBox_GetCurSel(GetDlgItem(hW,IDC_PSXTYPES));
1509 					if (tmp == 0) Config.PsxType = 0;
1510 					else Config.PsxType = 1;
1511 
1512 					Config.Xa      = Button_GetCheck(GetDlgItem(hW,IDC_XA));
1513 					Config.SioIrq  = Button_GetCheck(GetDlgItem(hW,IDC_SIO));
1514 					Config.Mdec    = Button_GetCheck(GetDlgItem(hW,IDC_MDEC));
1515 					Config.Cdda    = Button_GetCheck(GetDlgItem(hW,IDC_CDDA));
1516 					Config.SlowBoot= Button_GetCheck(GetDlgItem(hW,IDC_SLOWBOOT));
1517 					Config.PsxAuto = Button_GetCheck(GetDlgItem(hW,IDC_PSXAUTO));
1518 					tmp = Config.Cpu;
1519 					Config.Cpu     = (Button_GetCheck(GetDlgItem(hW,IDC_CPU)) ? CPU_INTERPRETER : CPU_DYNAREC);
1520 					if (tmp != Config.Cpu) {
1521 						psxCpu->Shutdown();
1522 						if (Config.Cpu == CPU_INTERPRETER) psxCpu = &psxInt;
1523 						else psxCpu = &psxRec;
1524 						if (psxCpu->Init() == -1) {
1525 							SysClose();
1526 							exit(1);
1527 						}
1528 						psxCpu->Reset();
1529 					}
1530 					Config.PsxOut  = Button_GetCheck(GetDlgItem(hW,IDC_PSXOUT));
1531 					Config.SpuIrq  = Button_GetCheck(GetDlgItem(hW,IDC_SPUIRQ));
1532 					Config.RCntFix = Button_GetCheck(GetDlgItem(hW,IDC_RCNTFIX));
1533 					Config.VSyncWA = Button_GetCheck(GetDlgItem(hW,IDC_VSYNCWA));
1534 					Config.Widescreen = Button_GetCheck(GetDlgItem(hW,IDC_WIDESCREEN));
1535 					Config.HideCursor = Button_GetCheck(GetDlgItem(hW,IDC_HIDECURSOR));
1536 					Config.SaveWindowPos = Button_GetCheck(GetDlgItem(hW,IDC_SAVEWINDOWPOS));
1537 					Config.HackFix = Button_GetCheck(GetDlgItem(hW, IDC_HACKFIX));
1538 
1539 					if(Config.SaveWindowPos) {
1540 						GetWindowRect(gApp.hWnd, &rect);
1541 						Config.WindowPos[0] = rect.left;
1542 						Config.WindowPos[1] = rect.top;
1543 					}
1544 					tmp = Config.Debug;
1545 					Config.Debug   = Button_GetCheck(GetDlgItem(hW,IDC_DEBUG));
1546 					if (tmp != Config.Debug) {
1547 						if (Config.Debug) StartDebugger();
1548 						else StopDebugger();
1549 					}
1550 
1551 					SaveConfig();
1552 
1553 					EndDialog(hW,TRUE);
1554 
1555 					if (Config.PsxOut) OpenConsole();
1556 					else CloseConsole();
1557 
1558 					return TRUE;
1559 
1560 				case IDC_CPU:
1561 					if (Button_GetCheck(GetDlgItem(hW,IDC_CPU))) {
1562 						EnableWindow(GetDlgItem(hW,IDC_DEBUG), TRUE);
1563 					} else {
1564 						Button_SetCheck(GetDlgItem(hW,IDC_DEBUG), FALSE);
1565 						EnableWindow(GetDlgItem(hW,IDC_DEBUG), FALSE);
1566 					}
1567 					break;
1568 
1569 				case IDC_PSXAUTO:
1570 					if (Button_GetCheck(GetDlgItem(hW,IDC_PSXAUTO))) {
1571 						EnableWindow(GetDlgItem(hW,IDC_PSXTYPES), FALSE);
1572 					} else {
1573 						EnableWindow(GetDlgItem(hW,IDC_PSXTYPES), TRUE);
1574 					}
1575 					break;
1576 			}
1577 		}
1578 	}
1579 	return FALSE;
1580 }
1581 
Open_Mcd_Proc(HWND hW,int mcd)1582 void Open_Mcd_Proc(HWND hW, int mcd) {
1583 	OPENFILENAME ofn;
1584 	char szFileName[MAXPATHLEN];
1585 	char szFileTitle[MAXPATHLEN];
1586 	char szFilter[1024];
1587 	char *str;
1588 
1589 	memset(&szFileName,  0, sizeof(szFileName));
1590 	memset(&szFileTitle, 0, sizeof(szFileTitle));
1591 	memset(&szFilter,    0, sizeof(szFilter));
1592 
1593 	strcpy(szFilter, _("Psx Mcd Format (*.mcr;*.mc;*.mem;*.vgs;*.mcd;*.gme;*.ddf)"));
1594 	str = szFilter + strlen(szFilter) + 1;
1595 	strcpy(str, "*.mcr;*.mcd;*.mem;*.gme;*.mc;*.ddf");
1596 
1597 	str+= strlen(str) + 1;
1598 	strcpy(str, _("Psx Memory Card (*.mcr;*.mc)"));
1599 	str+= strlen(str) + 1;
1600 	strcpy(str, "*.mcr;0*.mc");
1601 
1602 	str+= strlen(str) + 1;
1603 	strcpy(str, _("CVGS Memory Card (*.mem;*.vgs)"));
1604 	str+= strlen(str) + 1;
1605 	strcpy(str, "*.mem;*.vgs");
1606 
1607 	str+= strlen(str) + 1;
1608 	strcpy(str, _("Bleem Memory Card (*.mcd)"));
1609 	str+= strlen(str) + 1;
1610 	strcpy(str, "*.mcd");
1611 
1612 	str+= strlen(str) + 1;
1613 	strcpy(str, _("DexDrive Memory Card (*.gme)"));
1614 	str+= strlen(str) + 1;
1615 	strcpy(str, "*.gme");
1616 
1617 	str+= strlen(str) + 1;
1618 	strcpy(str, _("DataDeck Memory Card (*.ddf)"));
1619 	str+= strlen(str) + 1;
1620 	strcpy(str, "*.ddf");
1621 
1622 	str+= strlen(str) + 1;
1623 	strcpy(str, _("All Files"));
1624 	str+= strlen(str) + 1;
1625 	strcpy(str, "*.*");
1626 
1627     ofn.lStructSize			= sizeof(OPENFILENAME);
1628     ofn.hwndOwner			= hW;
1629     ofn.lpstrFilter			= szFilter;
1630 	ofn.lpstrCustomFilter	= NULL;
1631     ofn.nMaxCustFilter		= 0;
1632     ofn.nFilterIndex		= 1;
1633     ofn.lpstrFile			= szFileName;
1634     ofn.nMaxFile			= MAXPATHLEN;
1635     ofn.lpstrInitialDir		= "memcards";
1636     ofn.lpstrFileTitle		= szFileTitle;
1637     ofn.nMaxFileTitle		= MAXPATHLEN;
1638     ofn.lpstrTitle			= NULL;
1639     ofn.lpstrDefExt			= "MCR";
1640     ofn.Flags				= OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
1641 
1642 	if (GetOpenFileName ((LPOPENFILENAME)&ofn)) {
1643 		Edit_SetText(GetDlgItem(hW,mcd == 1 ? IDC_MCD1 : IDC_MCD2), szFileName);
1644 		LoadMcd(mcd, szFileName);
1645 		UpdateMcdDlg();
1646 	}
1647 }
1648 
Open_File_Proc(char * file)1649 int Open_File_Proc(char *file) {
1650 	OPENFILENAME ofn;
1651 	char szFileName[MAXPATHLEN];
1652 	char szFileTitle[MAXPATHLEN];
1653 	char szFilter[256];
1654 
1655 	memset(&szFileName,  0, sizeof(szFileName));
1656 	memset(&szFileTitle, 0, sizeof(szFileTitle));
1657 	memset(&szFilter,    0, sizeof(szFilter));
1658 
1659     ofn.lStructSize			= sizeof(OPENFILENAME);
1660     ofn.hwndOwner			= gApp.hWnd;
1661 
1662 	strcpy(szFilter, _("Psx Exe Format"));
1663 	strcatz(szFilter, "*.*");
1664 
1665     ofn.lpstrFilter			= szFilter;
1666 	ofn.lpstrCustomFilter	= NULL;
1667     ofn.nMaxCustFilter		= 0;
1668     ofn.nFilterIndex		= 1;
1669     ofn.lpstrFile			= szFileName;
1670     ofn.nMaxFile			= MAXPATHLEN;
1671     ofn.lpstrInitialDir		= NULL;
1672     ofn.lpstrFileTitle		= szFileTitle;
1673     ofn.nMaxFileTitle		= MAXPATHLEN;
1674     ofn.lpstrTitle			= NULL;
1675     ofn.lpstrDefExt			= "EXE";
1676     ofn.Flags				= OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
1677 
1678 	if (GetOpenFileName ((LPOPENFILENAME)&ofn)) {
1679 		strcpy(file, szFileName);
1680 		return 1;
1681 	} else
1682 		return 0;
1683 }
1684 
Open_Iso_Proc(char * file)1685 int Open_Iso_Proc(char *file) {
1686 	OPENFILENAME ofn;
1687 	char szFileName[MAXPATHLEN];
1688 	char szFileTitle[MAXPATHLEN];
1689 	char szFilter[256];
1690 	char *str;
1691 
1692 	memset(&szFileName,  0, sizeof(szFileName));
1693 	memset(&szFileTitle, 0, sizeof(szFileTitle));
1694 	memset(&szFilter,    0, sizeof(szFilter));
1695 
1696     ofn.lStructSize			= sizeof(OPENFILENAME);
1697     ofn.hwndOwner			= gApp.hWnd;
1698 
1699 	strcpy(szFilter, _("Psx Isos (*.iso;*.mdf;*.img;*.bin;*.cue;*.pbp;*.cbn)"));
1700 	str = szFilter + strlen(szFilter) + 1;
1701 	strcpy(str, "*.iso;*.mdf;*.img;*.bin;*.cue;*.pbp;*.cbn");
1702 
1703 	str += strlen(str) + 1;
1704 	strcpy(str, _("All Files"));
1705 	str += strlen(str) + 1;
1706 	strcpy(str, "*.*");
1707 
1708     ofn.lpstrFilter			= szFilter;
1709 	ofn.lpstrCustomFilter	= NULL;
1710     ofn.nMaxCustFilter		= 0;
1711     ofn.nFilterIndex		= 1;
1712     ofn.lpstrFile			= szFileName;
1713     ofn.nMaxFile			= MAXPATHLEN;
1714     ofn.lpstrInitialDir		= NULL;
1715     ofn.lpstrFileTitle		= szFileTitle;
1716     ofn.nMaxFileTitle		= MAXPATHLEN;
1717     ofn.lpstrTitle			= NULL;
1718     ofn.lpstrDefExt			= "ISO";
1719     ofn.Flags				= OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
1720 
1721 	if (GetOpenFileName ((LPOPENFILENAME)&ofn)) {
1722 		strcpy(file, szFileName);
1723 		return 1;
1724 	} else
1725 		return 0;
1726 }
1727 
1728 #define _ADDSUBMENU(menu, menun, string) \
1729 	submenu[menun] = CreatePopupMenu(); \
1730 	AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)submenu[menun], string);
1731 
1732 #define ADDSUBMENU(menun, string) \
1733 	_ADDSUBMENU(gApp.hMenu, menun, string);
1734 
1735 #define ADDSUBMENUS(submn, menun, string) \
1736 	submenu[menun] = CreatePopupMenu(); \
1737 	InsertMenu(submenu[submn], 0, MF_BYPOSITION | MF_STRING | MF_POPUP, (UINT)submenu[menun], string);
1738 
1739 #define ADDMENUITEM(menun, string, id) \
1740 	item.fType = MFT_STRING; \
1741 	item.fMask = MIIM_STATE | MIIM_TYPE | MIIM_ID; \
1742 	item.fState = MFS_ENABLED; \
1743 	item.wID = id; \
1744 	sprintf(buf, string); \
1745 	InsertMenuItem(submenu[menun], 0, TRUE, &item);
1746 
1747 #define ADDMENUITEMC(menun, string, id) \
1748 	item.fType = MFT_STRING; \
1749 	item.fMask = MIIM_STATE | MIIM_TYPE | MIIM_ID; \
1750 	item.fState = MFS_ENABLED | MFS_CHECKED; \
1751 	item.wID = id; \
1752 	sprintf(buf, string); \
1753 	InsertMenuItem(submenu[menun], 0, TRUE, &item);
1754 
1755 #define ADDSEPARATOR(menun) \
1756 	item.fMask = MIIM_TYPE; \
1757 	item.fType = MFT_SEPARATOR; \
1758 	InsertMenuItem(submenu[menun], 0, TRUE, &item);
1759 
CreateMainMenu()1760 void CreateMainMenu() {
1761 	MENUITEMINFO item;
1762 	HMENU submenu[256];
1763 	char buf[256];
1764 #ifdef ENABLE_NLS
1765 	char *lang;
1766 	int i;
1767 #endif
1768 
1769 	item.cbSize = sizeof(MENUITEMINFO);
1770 	item.dwTypeData = buf;
1771 	item.cch = 256;
1772 
1773 	gApp.hMenu = CreateMenu();
1774 
1775 	ADDSUBMENU(0, _("&File"));
1776 	ADDMENUITEM(0, _("E&xit"), ID_FILE_EXIT);
1777 	ADDSEPARATOR(0);
1778 	ADDMENUITEM(0, _("Run &EXE..."), ID_FILE_RUN_EXE);
1779 	ADDMENUITEM(0, _("Run &BIOS"), ID_FILE_RUNBIOS);
1780 	ADDMENUITEM(0, _("Run &ISO..."), ID_FILE_RUN_ISO);
1781 	ADDMENUITEM(0, _("Run &CD"), ID_FILE_RUN_CD);
1782 
1783 	ADDSUBMENU(0, _("&Emulator"));
1784 	ADDSUBMENUS(0, 1, _("&States"));
1785 	ADDSEPARATOR(0);
1786 	ADDMENUITEM(0, _("S&witch ISO..."), ID_EMULATOR_SWITCH_ISO);
1787 	ADDSEPARATOR(0);
1788 	ADDMENUITEM(0, _("S&hutdown"), ID_EMULATOR_SHUTDOWN);
1789 	ADDMENUITEM(0, _("Re&set"), ID_EMULATOR_RESET);
1790 	ADDMENUITEM(0, _("&Run"), ID_EMULATOR_RUN);
1791 	ADDSUBMENUS(1, 3, _("&Save"));
1792 	ADDSUBMENUS(1, 2, _("&Load"));
1793 	ADDMENUITEM(2, _("&Other..."), ID_FILE_STATES_LOAD_OTHER);
1794 	ADDMENUITEM(2, _("Slot &9"), ID_FILE_STATES_LOAD_SLOT9);
1795 	ADDMENUITEM(2, _("Slot &8"), ID_FILE_STATES_LOAD_SLOT8);
1796 	ADDMENUITEM(2, _("Slot &7"), ID_FILE_STATES_LOAD_SLOT7);
1797 	ADDMENUITEM(2, _("Slot &6"), ID_FILE_STATES_LOAD_SLOT6);
1798 	ADDMENUITEM(2, _("Slot &5"), ID_FILE_STATES_LOAD_SLOT5);
1799 	ADDMENUITEM(2, _("Slot &4"), ID_FILE_STATES_LOAD_SLOT4);
1800 	ADDMENUITEM(2, _("Slot &3"), ID_FILE_STATES_LOAD_SLOT3);
1801 	ADDMENUITEM(2, _("Slot &2"), ID_FILE_STATES_LOAD_SLOT2);
1802 	ADDMENUITEM(2, _("Slot &1"), ID_FILE_STATES_LOAD_SLOT1);
1803 	ADDMENUITEM(3, _("&Other..."), ID_FILE_STATES_SAVE_OTHER);
1804 	ADDMENUITEM(3, _("Slot &9"), ID_FILE_STATES_SAVE_SLOT9);
1805 	ADDMENUITEM(3, _("Slot &8"), ID_FILE_STATES_SAVE_SLOT8);
1806 	ADDMENUITEM(3, _("Slot &7"), ID_FILE_STATES_SAVE_SLOT7);
1807 	ADDMENUITEM(3, _("Slot &6"), ID_FILE_STATES_SAVE_SLOT6);
1808 	ADDMENUITEM(3, _("Slot &5"), ID_FILE_STATES_SAVE_SLOT5);
1809 	ADDMENUITEM(3, _("Slot &4"), ID_FILE_STATES_SAVE_SLOT4);
1810 	ADDMENUITEM(3, _("Slot &3"), ID_FILE_STATES_SAVE_SLOT3);
1811 	ADDMENUITEM(3, _("Slot &2"), ID_FILE_STATES_SAVE_SLOT2);
1812 	ADDMENUITEM(3, _("Slot &1"), ID_FILE_STATES_SAVE_SLOT1);
1813 
1814 	ADDSUBMENU(0, _("&Configuration"));
1815 	ADDMENUITEM(0, _("Cheat &Search..."), ID_CONFIGURATION_CHEATSEARCH);
1816 	ADDMENUITEM(0, _("Ch&eat Code..."), ID_CONFIGURATION_CHEATLIST);
1817 	ADDSEPARATOR(0);
1818 #ifdef ENABLE_NLS
1819 	ADDSUBMENUS(0, 1, _("&Language"));
1820 
1821 	if (langs) free(langs);
1822 	langs = (_langs*)malloc(sizeof(_langs));
1823 	strcpy(langs[0].lang, "English");
1824 	InitLanguages(); i=1;
1825 	while ((lang = GetLanguageNext()) != NULL) {
1826 		langs = (_langs*)realloc(langs, sizeof(_langs)*(i+1));
1827 		strcpy(langs[i].lang, lang);
1828 		if (!strcmp(Config.Lang, lang)) {
1829 			ADDMENUITEMC(1, ParseLang(langs[i].lang), ID_LANGS + i);
1830 		} else {
1831 			ADDMENUITEM(1, ParseLang(langs[i].lang), ID_LANGS + i);
1832 		}
1833 		i++;
1834 	}
1835 	CloseLanguages();
1836 	langsMax = i;
1837 	if (!strcmp(Config.Lang, "English")) {
1838 		ADDMENUITEMC(1, _("English"), ID_LANGS);
1839 	} else {
1840 		ADDMENUITEM(1, _("English"), ID_LANGS);
1841 	}
1842 	ADDSEPARATOR(0);
1843 #endif
1844 	ADDMENUITEM(0, _("&Memory cards..."), ID_CONFIGURATION_MEMORYCARDMANAGER);
1845 	ADDMENUITEM(0, _("C&PU..."), ID_CONFIGURATION_CPU);
1846 	ADDSEPARATOR(0);
1847 	ADDMENUITEM(0, _("&NetPlay..."), ID_CONFIGURATION_NETPLAY);
1848 	ADDSEPARATOR(0);
1849 	ADDMENUITEM(0, _("&Link cable..."), ID_CONFIGURATION_LINKCABLE);
1850 	ADDMENUITEM(0, _("&Controllers..."), ID_CONFIGURATION_CONTROLLERS);
1851 	ADDMENUITEM(0, _("CD-&ROM..."), ID_CONFIGURATION_CDROM);
1852 	ADDMENUITEM(0, _("&Sound..."), ID_CONFIGURATION_SOUND);
1853 	ADDMENUITEM(0, _("&Graphics..."), ID_CONFIGURATION_GRAPHICS);
1854 	ADDSEPARATOR(0);
1855 	ADDMENUITEM(0, _("&Plugins && Bios..."), ID_CONFIGURATION);
1856 
1857 	ADDSUBMENU(0, _("&Help"));
1858 	ADDMENUITEM(0, _("&About..."), ID_HELP_ABOUT);
1859 
1860 	UpdateMenuItems();
1861 }
1862 
CreateMainWindow(int nCmdShow)1863 void CreateMainWindow(int nCmdShow) {
1864 	WNDCLASS wc;
1865 	HWND hWnd;
1866 
1867 	wc.lpszClassName = "PCSXR Main";
1868 	wc.lpfnWndProc = MainWndProc;
1869 	wc.style = 0;
1870 	wc.hInstance = gApp.hInstance;
1871 	wc.hIcon = LoadIcon(gApp.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
1872 	wc.hCursor = NULL;
1873 	wc.hbrBackground = (HBRUSH)(COLOR_MENUTEXT);
1874 	wc.lpszMenuName = 0;
1875 	wc.cbClsExtra = 0;
1876 	wc.cbWndExtra = 0;
1877 
1878 	RegisterClass(&wc);
1879 
1880 	hWnd = CreateWindow("PCSXR Main",
1881 						"PCSXR",
1882 						WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX,
1883 						CW_USEDEFAULT,
1884 						0,
1885 						360,
1886 						248,
1887 						NULL,
1888 						NULL,
1889 						gApp.hInstance,
1890 						NULL);
1891 
1892 	gApp.hWnd = hWnd;
1893 
1894 	CreateMainMenu();
1895 	SetMenu(gApp.hWnd, gApp.hMenu);
1896 
1897 	if(Config.SaveWindowPos)
1898 		SetWindowPos(hWnd, 0, Config.WindowPos[0], Config.WindowPos[1], 0, 0, SWP_NOSIZE | SWP_NOZORDER);
1899 
1900 	ShowWindow(hWnd, nCmdShow);
1901 }
1902 
1903 #ifdef ENABLE_NLS
1904 
1905 WIN32_FIND_DATA lFindData;
1906 HANDLE lFind;
1907 int lFirst;
1908 
InitLanguages()1909 void InitLanguages() {
1910 	lFind = FindFirstFile("Langs\\*", &lFindData);
1911 	lFirst = 1;
1912 }
1913 
GetLanguageNext()1914 char *GetLanguageNext() {
1915 	if (lFind == INVALID_HANDLE_VALUE)
1916 		return NULL;
1917 
1918 	for (;;) {
1919 		if (lFirst == 0) {
1920 			if (FindNextFile(lFind, &lFindData) == FALSE)
1921 				return NULL;
1922 		}
1923 		else
1924 			lFirst = 0;
1925 
1926 		if (!strcmp(lFindData.cFileName, ".") ||
1927 			!strcmp(lFindData.cFileName, ".."))
1928 			continue;
1929 		break;
1930 	}
1931 
1932 	return lFindData.cFileName;
1933 }
1934 
CloseLanguages()1935 void CloseLanguages() {
1936 	if (lFind != INVALID_HANDLE_VALUE) FindClose(lFind);
1937 }
1938 
ChangeLanguage(char * lang)1939 void ChangeLanguage(char *lang) {
1940 	strcpy(Config.Lang, lang);
1941 	SaveConfig();
1942 	LoadConfig();
1943 }
1944 
1945 #endif
1946 
SysInit()1947 int SysInit() {
1948 	if (Config.PsxOut) OpenConsole();
1949 
1950 	if (EmuInit() == -1) return -1;
1951 
1952 #ifdef EMU_LOG
1953 	emuLog = fopen("emuLog.txt","w");
1954 	setvbuf(emuLog, NULL,  _IONBF, 0);
1955 #endif
1956 
1957 	while (LoadPlugins(0) == -1) {
1958 		CancelQuit = 1;
1959 		ConfigurePlugins(gApp.hWnd);
1960 		CancelQuit = 0;
1961 	}
1962 	LoadMcds(Config.Mcd1, Config.Mcd2);
1963 
1964 	if (Config.Debug) StartDebugger();
1965 
1966 	return 0;
1967 }
1968 
SysReset()1969 void SysReset() {
1970 	EmuReset();
1971 }
1972 
SysClose()1973 void SysClose() {
1974 	EmuShutdown();
1975 	ReleasePlugins();
1976 
1977 	StopDebugger();
1978 
1979 	if (Config.PsxOut) CloseConsole();
1980 
1981 	if (emuLog != NULL) fclose(emuLog);
1982 }
1983 
SysPrintf(const char * fmt,...)1984 void SysPrintf(const char *fmt, ...) {
1985 	va_list list;
1986 	char msg[512];
1987 	DWORD tmp;
1988 
1989 	if (!hConsole) return;
1990 
1991 	va_start(list,fmt);
1992 	vsprintf(msg,fmt,list);
1993 	va_end(list);
1994 
1995 	WriteConsole(hConsole, msg, (DWORD)strlen(msg), &tmp, 0);
1996 #ifdef EMU_LOG
1997 #ifndef LOG_STDOUT
1998 	if (emuLog != NULL) fprintf(emuLog, "%s", msg);
1999 #endif
2000 #endif
2001 }
2002 
SysMessage(const char * fmt,...)2003 void SysMessage(const char *fmt, ...) {
2004 	va_list list;
2005 	char tmp[512];
2006 
2007 	va_start(list,fmt);
2008 	vsprintf(tmp,fmt,list);
2009 	va_end(list);
2010 	MessageBox(0, tmp, _("Pcsxr Msg"), 0);
2011 }
2012 
2013 static char *err = N_("Error Loading Symbol");
2014 static int errval;
2015 
SysLoadLibrary(const char * lib)2016 void *SysLoadLibrary(const char *lib) {
2017 	return LoadLibrary(lib);
2018 }
2019 
SysLoadSym(void * lib,const char * sym)2020 void *SysLoadSym(void *lib, const char *sym) {
2021 	void *tmp = GetProcAddress((HINSTANCE)lib, sym);
2022 	if (tmp == NULL) errval = 1;
2023 	else errval = 0;
2024 	return tmp;
2025 }
2026 
SysLibError()2027 const char *SysLibError() {
2028 	if (errval) { errval = 0; return err; }
2029 	return NULL;
2030 }
2031 
SysCloseLibrary(void * lib)2032 void SysCloseLibrary(void *lib) {
2033 	FreeLibrary((HINSTANCE)lib);
2034 }
2035 
SysUpdate()2036 void SysUpdate() {
2037 	MSG msg;
2038 
2039 	while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) {
2040 		TranslateMessage(&msg);
2041 		DispatchMessage(&msg);
2042 	}
2043 }
2044 
SysRunGui()2045 void SysRunGui() {
2046 	RestoreWindow();
2047 	RunGui();
2048 }
2049 
UpdateMenuItems()2050 void UpdateMenuItems() {
2051 	if (CdromId[0] != '\0') { // Emulating...
2052 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_NETPLAY, MF_BYCOMMAND | MF_GRAYED);
2053 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_LINKCABLE, MF_BYCOMMAND | MF_GRAYED);
2054 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_CONTROLLERS, MF_BYCOMMAND | MF_GRAYED);
2055 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_CDROM, MF_BYCOMMAND | MF_GRAYED);
2056 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_SOUND, MF_BYCOMMAND | MF_GRAYED);
2057 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_GRAPHICS, MF_BYCOMMAND | MF_GRAYED);
2058 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION, MF_BYCOMMAND | MF_GRAYED);
2059 		if (!UsingIso()) {
2060 			EnableMenuItem(gApp.hMenu, ID_EMULATOR_SWITCH_ISO, MF_BYCOMMAND | MF_GRAYED);
2061 		}
2062 
2063 		ResetMenuSlots();
2064 	} else { // GUI...
2065 		EnableMenuItem(gApp.hMenu, ID_EMULATOR_RESET, MF_BYCOMMAND | MF_GRAYED);
2066 		EnableMenuItem(gApp.hMenu, ID_EMULATOR_RUN, MF_BYCOMMAND | MF_GRAYED);
2067 		EnableMenuItem(gApp.hMenu, ID_EMULATOR_SHUTDOWN, MF_BYCOMMAND | MF_GRAYED);
2068 		EnableMenuItem(gApp.hMenu, ID_EMULATOR_SWITCH_ISO, MF_BYCOMMAND | MF_GRAYED);
2069 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT1, MF_BYCOMMAND | MF_GRAYED);
2070 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT2, MF_BYCOMMAND | MF_GRAYED);
2071 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT3, MF_BYCOMMAND | MF_GRAYED);
2072 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT4, MF_BYCOMMAND | MF_GRAYED);
2073 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT5, MF_BYCOMMAND | MF_GRAYED);
2074 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT6, MF_BYCOMMAND | MF_GRAYED);
2075 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT7, MF_BYCOMMAND | MF_GRAYED);
2076 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT8, MF_BYCOMMAND | MF_GRAYED);
2077 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_SLOT9, MF_BYCOMMAND | MF_GRAYED);
2078 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_LOAD_OTHER, MF_BYCOMMAND | MF_GRAYED);
2079 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT1, MF_BYCOMMAND | MF_GRAYED);
2080 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT2, MF_BYCOMMAND | MF_GRAYED);
2081 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT3, MF_BYCOMMAND | MF_GRAYED);
2082 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT4, MF_BYCOMMAND | MF_GRAYED);
2083 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT5, MF_BYCOMMAND | MF_GRAYED);
2084 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT6, MF_BYCOMMAND | MF_GRAYED);
2085 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT7, MF_BYCOMMAND | MF_GRAYED);
2086 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT8, MF_BYCOMMAND | MF_GRAYED);
2087 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_SLOT9, MF_BYCOMMAND | MF_GRAYED);
2088 		EnableMenuItem(gApp.hMenu, ID_FILE_STATES_SAVE_OTHER, MF_BYCOMMAND | MF_GRAYED);
2089 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_CHEATSEARCH, MF_BYCOMMAND | MF_GRAYED);
2090 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_NETPLAY, MF_BYCOMMAND | MF_ENABLED);
2091 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_LINKCABLE, MF_BYCOMMAND | MF_ENABLED);
2092 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_CONTROLLERS, MF_BYCOMMAND | MF_ENABLED);
2093 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_CDROM, MF_BYCOMMAND | ( Config.Cdr[0] != '\0' ? MF_ENABLED : MF_GRAYED ));
2094 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_SOUND, MF_BYCOMMAND | MF_ENABLED);
2095 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_GRAPHICS, MF_BYCOMMAND | MF_ENABLED);
2096 		EnableMenuItem(gApp.hMenu, ID_CONFIGURATION, MF_BYCOMMAND | MF_ENABLED);
2097 	}
2098 
2099 #ifndef ENABLE_SIO1API
2100 	EnableMenuItem(gApp.hMenu, ID_CONFIGURATION_LINKCABLE, MF_BYCOMMAND | MF_GRAYED);
2101 #endif
2102 }
2103