zodttd / snes4iphone

A Super Nintendo (SNES) emulator for the Apple iPhone and iPod Touch.

This URL has Read+Write access

snes4iphone / PocketSNES.cpp
b098ecda » ME 2008-04-28 First commit of snes4iphone 1 // PocketSNES.cpp : Defines the entry point for the application.
2 //
3
4 #include "stdafx.h"
5 #include "PocketSNES.h"
6
7 #include <commctrl.h>
8 #include <aygshell.h>
9 #include <sipapi.h>
10 #ifdef _WIN32_WCE_EMULATION
11 //#include "gapi.h"
12 #else
13 #include "gx.h"
14 #endif
15
16 #include "snes9x.h"
17 #include "pocketpc.h"
18 #include "VOIMAGE.H"
19 #include "Prof/profiler.h"
20
21 #define MAX_LOADSTRING 100
22
23 extern bool InitializeEmulation(int,int,int);
24 extern bool LoadROM();
25 extern bool StartEmulation(HWND, HWND);
26 extern bool StopEmulation(HWND, HWND);
27 extern bool PauseEmulation(HWND, HWND);
28 extern bool ResumeEmulation(HWND, HWND);
29
30 extern "C" void S9xReset();
31 extern "C" void S9xSetTitle(const char *);
32 extern "C" void S9xMainLoop(void);
33
34 extern bool g_bResumeAfterLoadState;
35 extern bool g_bResumeAfterSaveState;
36
37 extern TCHAR g_szTitle[64];
38 extern GXKeyList g_gxkl;
39
40 class Skin
41 {
42 public:
43 TCHAR *pszBitmap;
44 TCHAR *pszName;
45 TCHAR *pszAuthor;
46 short iVersion;
47 short iNumberOfColors;
48 unsigned short iColor[32];
49 unsigned short iMask[32];
50 bool bResource;
51 bool bLandscape;
52
53 Skin()
54 : pszBitmap(NULL), pszName(NULL), pszAuthor(NULL), iNumberOfColors(0), iVersion(0),
55 bResource(false), bLandscape(false)
56 {
57 }
58
59 ~Skin()
60 {
61 if (pszBitmap)
62 delete [] pszBitmap;
63 if (pszName)
64 delete [] pszName;
65 if (pszAuthor)
66 delete [] pszAuthor;
67 }
68
69 void AddColor(DWORD _dwColor, DWORD _dwMask)
70 {
71 iColor[iNumberOfColors] = ((_dwColor & 0xf80000) >> 8)|((_dwColor & 0xfc00) >> 5)|((_dwColor & 0xf8) >> 3);
72 iMask[iNumberOfColors] = _dwMask;
73
74 iNumberOfColors++;
75 }
76
77 void AddColor(TCHAR *_pszColor, TCHAR *_pszMask)
78 {
79 DWORD dwColor = 0;
80 TCHAR *pszTemp = _pszColor;
81
82 pszTemp += 2;
83
84 dwColor = TextToInt(pszTemp);
85 iColor[iNumberOfColors] = ((dwColor & 0xf80000) >> 8)|((dwColor & 0xfc00) >> 5)|((dwColor & 0xf8) >> 3);
86 iMask[iNumberOfColors] = DecodeMask(_pszMask);
87
88 iNumberOfColors++;
89 }
90
91 void SetBitmap(TCHAR *_pszBitmap)
92 {
93 pszBitmap = new TCHAR [_tcslen(_pszBitmap) + 1];
94
95 _tcscpy(pszBitmap, _pszBitmap);
96 }
97
98 void SetName(TCHAR *_pszName)
99 {
100 pszName = new TCHAR [_tcslen(_pszName) + 1];
101
102 _tcscpy(pszName, _pszName);
103 }
104
105 void SetAuthor(TCHAR *_pszAuthor)
106 {
107 static TCHAR *szAuthor = L"Designed by: ";
108
109 pszAuthor = new TCHAR [_tcslen(_pszAuthor) + 1 + _tcslen(szAuthor)];
110
111 _tcscpy(pszAuthor, szAuthor);
112 _tcscat(pszAuthor, _pszAuthor);
113 }
114
115 void LoadBitmap(HBITMAP &_hbmSkin, HDC &_hSkinDC, HINSTANCE &_hInstance, HWND &_hWnd)
116 {
117 if (_hbmSkin)
118 DeleteObject(_hbmSkin);
119 if (_hSkinDC)
120 DeleteObject(_hSkinDC);
121
122 HDC hDC = GetDC(_hWnd);
123
124 if (bResource)
125 {
126 _hbmSkin = ::LoadBitmap(_hInstance, pszBitmap);
127 }
128 else
129 {
130 _hbmSkin = ::SHLoadDIBitmap(pszBitmap);
131 }
132
133 if (_hbmSkin)
134 {
135 _hSkinDC = CreateCompatibleDC(hDC);
136
137 SelectObject(_hSkinDC, _hbmSkin);
138 }
139
140 ReleaseDC(_hWnd, hDC);
141 }
142
143 private:
144
145 DWORD TextToInt(TCHAR *_pszIn)
146 {
147 DWORD dwReturn = 0;
148
149 for (int i = 0; i < (int) _tcslen(_pszIn); i++)
150 {
151 if ((_pszIn[i] >= _T('0')) && (_pszIn[i] <= _T('9')))
152 {
153 dwReturn = (dwReturn * 16) + (_pszIn[i] - _T('0'));
154 }
155 else if ((_pszIn[i] >= _T('A')) && (_pszIn[i] <= _T('F')))
156 {
157 dwReturn = (dwReturn * 16) + (_pszIn[i] - _T('A') + 10);
158 }
159 else if ((_pszIn[i] >= _T('a')) && (_pszIn[i] <= _T('f')))
160 {
161 dwReturn = (dwReturn * 16) + (_pszIn[i] - _T('a') + 10);
162 }
163 }
164
165 return dwReturn;
166 }
167
168 unsigned short DecodeMask(TCHAR *_pszIn)
169 {
170 unsigned short iReturn = 0;
171
172 TCHAR *pszToken = _tcstok(_pszIn, L"+");
173
174 while (pszToken != NULL)
175 {
176 if (_tcsicmp(pszToken, L"n") == 0)
177 {
178 iReturn |= SNES_UP_MASK;
179 }
180 else if (_tcsicmp(pszToken, L"s") == 0)
181 {
182 iReturn |= SNES_DOWN_MASK;
183 }
184 else if (_tcsicmp(pszToken, L"e") == 0)
185 {
186 iReturn |= SNES_RIGHT_MASK;
187 }
188 else if (_tcsicmp(pszToken, L"w") == 0)
189 {
190 iReturn |= SNES_LEFT_MASK;
191 }
192 else if (_tcsicmp(pszToken, L"ne") == 0)
193 {
194 iReturn |= SNES_UP_MASK|SNES_RIGHT_MASK;
195 }
196 else if (_tcsicmp(pszToken, L"se") == 0)
197 {
198 iReturn |= SNES_DOWN_MASK|SNES_RIGHT_MASK;
199 }
200 else if (_tcsicmp(pszToken, L"sw") == 0)
201 {
202 iReturn |= SNES_DOWN_MASK|SNES_LEFT_MASK;
203 }
204 else if (_tcsicmp(pszToken, L"nw") == 0)
205 {
206 iReturn |= SNES_UP_MASK|SNES_LEFT_MASK;
207 }
208 else if (_tcsicmp(pszToken, L"a") == 0)
209 {
210 iReturn |= SNES_A_MASK;
211 }
212 else if (_tcsicmp(pszToken, L"b") == 0)
213 {
214 iReturn |= SNES_B_MASK;
215 }
216 else if (_tcsicmp(pszToken, L"x") == 0)
217 {
218 iReturn |= SNES_X_MASK;
219 }
220 else if (_tcsicmp(pszToken, L"y") == 0)
221 {
222 iReturn |= SNES_Y_MASK;
223 }
224 else if (_tcsicmp(pszToken, L"l") == 0)
225 {
226 iReturn |= SNES_TL_MASK;
227 }
228 else if (_tcsicmp(pszToken, L"r") == 0)
229 {
230 iReturn |= SNES_TR_MASK;
231 }
232 else if (_tcsicmp(pszToken, L"start") == 0)
233 {
234 iReturn |= SNES_START_MASK;
235 }
236 else if (_tcsicmp(pszToken, L"select") == 0)
237 {
238 iReturn |= SNES_SELECT_MASK;
239 }
240
241 pszToken = _tcstok(NULL, L"+");
242 }
243
244 return iReturn;
245 }
246 };
247
248 class Keymap
249 {
250 public:
251 DWORD dwKeyMask[256];
252
253 Keymap()
254 {
255 memset(dwKeyMask, 0, sizeof(DWORD) * 256);
256 }
257
258 short GetKeyFromMask(DWORD dwMask)
259 {
260 for (short i = 0; i < 256; i++)
261 {
262 if (dwKeyMask[i] == dwMask)
263 return i;
264
265 }
266
267 return 0;
268 }
269
270 LPTSTR GetKeyDisplayFromMask(DWORD dwMask)
271 {
272 static TCHAR szDisplay[10];
273
274 if (dwMask == 0)
275 {
276 _tcscpy(szDisplay, L"...");
277 }
278 else
279 {
280 short iKey = GetKeyFromMask(dwMask);
281
282 if (iKey == 0)
283 {
284 _tcscpy(szDisplay, L"...");
285 }
286 else
287 {
288 wsprintf(szDisplay, L"0x%2x", iKey);
289 }
290 }
291
292 return szDisplay;
293 }
294
295 void SetLandscape(Keymap &_kmPortrait)
296 {
297 for (short i = 0; i < 256; i++)
298 {
299 dwKeyMask[i] = _kmPortrait.dwKeyMask[i];
300
301 short iUp = _kmPortrait.GetKeyFromMask(SNES_UP_MASK);
302 short iDown = _kmPortrait.GetKeyFromMask(SNES_DOWN_MASK);
303 short iLeft = _kmPortrait.GetKeyFromMask(SNES_LEFT_MASK);
304 short iRight = _kmPortrait.GetKeyFromMask(SNES_RIGHT_MASK);
305
306 dwKeyMask[iUp] = SNES_RIGHT_MASK;
307 dwKeyMask[iRight] = SNES_DOWN_MASK;
308 dwKeyMask[iDown] = SNES_LEFT_MASK;
309 dwKeyMask[iLeft] = SNES_UP_MASK;
310 }
311 }
312
313 void SetLandscapeRight(Keymap &_kmPortrait)
314 {
315 for (short i = 0; i < 256; i++)
316 {
317 dwKeyMask[i] = _kmPortrait.dwKeyMask[i];
318
319 short iUp = _kmPortrait.GetKeyFromMask(SNES_UP_MASK);
320 short iDown = _kmPortrait.GetKeyFromMask(SNES_DOWN_MASK);
321 short iLeft = _kmPortrait.GetKeyFromMask(SNES_LEFT_MASK);
322 short iRight = _kmPortrait.GetKeyFromMask(SNES_RIGHT_MASK);
323
324 dwKeyMask[iUp] = SNES_LEFT_MASK;
325 dwKeyMask[iRight] = SNES_UP_MASK;
326 dwKeyMask[iDown] = SNES_RIGHT_MASK;
327 dwKeyMask[iLeft] = SNES_DOWN_MASK;
328 }
329 }
330
331 DWORD GetStaticIDFromMask(DWORD dwMask)
332 {
333 switch (dwMask)
334 {
335 case SNES_UP_MASK:
336 return IDC_STATIC_UP;
337
338 case SNES_DOWN_MASK:
339 return IDC_STATIC_DOWN;
340
341 case SNES_LEFT_MASK:
342 return IDC_STATIC_LEFT;
343
344 case SNES_RIGHT_MASK:
345 return IDC_STATIC_RIGHT;
346
347 case SNES_A_MASK:
348 return IDC_STATIC_A;
349
350 case SNES_B_MASK:
351 return IDC_STATIC_B;
352
353 case SNES_X_MASK:
354 return IDC_STATIC_X;
355
356 case SNES_Y_MASK:
357 return IDC_STATIC_Y;
358
359 case SNES_START_MASK:
360 return IDC_STATIC_START;
361
362 case SNES_SELECT_MASK:
363 return IDC_STATIC_SELECT;
364
365 case SNES_TL_MASK:
366 return IDC_STATIC_L;
367
368 case SNES_TR_MASK:
369 return IDC_STATIC_R;
370 }
371
372 return 0;
373 }
374 };
375
376 //------------------------------------------------------------------------------
377 // Global Variables
378 //------------------------------------------------------------------------------
379 bool g_bLoop = true;
380 HWND g_hWnd;
381 HINSTANCE g_hInstance; // The current instance
382 HWND hwndCB; // The command bar handle
383 HFONT g_hFontBold;
384 HFONT g_hFontNormal;
385 HFONT g_hFontPaused;
386 HFONT g_hFontHyperlink;
387 CVOImage g_pngLogo;
388 HDC g_hLogoDC;
389 static TCHAR g_sRootKey[256];
390 Skin *g_pSkins = NULL;
391 int g_iSkinCount = 0;
392 int g_iSelectedSkin = 0;
393 HBITMAP g_hbmSkin = NULL;
394 HDC g_hSkinDC = NULL;
395 Keymap g_kmDefault;
396 Keymap g_kmCurrent;
397 Keymap g_kmLandscape;
398 Keymap *g_pkmInUse;
399 GXKeyList g_gxKeyList;
400 bool g_bSetButtonMode;
401 int g_iSetButton;
402 RECT g_rtLink;
403 HICON g_hiLeftArrow;
404 HICON g_hiRightArrow;
405 uint32 g_iFrameSkip;
406
407 //------------------------------------------------------------------------------
408 // Function definitions
409 //------------------------------------------------------------------------------
410 bool LoadOptions();
411 void SaveOptions();
412 bool LoadSkins();
413 void SaveSkins();
414 bool CheckKeyPad(int, int, bool);
415 void ShowOptions();
416 LRESULT CALLBACK SystemDlgProc(HWND, UINT, WPARAM, LPARAM);
417 LRESULT CALLBACK DisplayDlgProc(HWND, UINT, WPARAM, LPARAM);
418 LRESULT CALLBACK SoundDlgProc(HWND, UINT, WPARAM, LPARAM);
419 LRESULT CALLBACK SkinsDlgProc(HWND, UINT, WPARAM, LPARAM);
420 LRESULT CALLBACK KeysDlgProc(HWND, UINT, WPARAM, LPARAM);
421 LRESULT CALLBACK CreditsDlgProc(HWND, UINT, WPARAM, LPARAM);
422
423 ATOM MyRegisterClass (HINSTANCE, LPTSTR);
424 BOOL InitInstance (HINSTANCE, int);
425 LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
426 HWND CreateRpCommandBar(HWND);
427
428
429 //------------------------------------------------------------------------------
430 // Joypad definitions
431 // Eight directions
432 // Eight buttons - start, select, A, B, X, Y, L, R
433 //------------------------------------------------------------------------------
434 #define KP_JOYPAD_N 0
435 #define KP_JOYPAD_E 1
436 #define KP_JOYPAD_S 2
437 #define KP_JOYPAD_W 3
438 #define KP_JOYPAD_NE 4
439 #define KP_JOYPAD_SE 5
440 #define KP_JOYPAD_SW 6
441 #define KP_JOYPAD_NW 7
442 #define KP_BUTTON_START 8
443 #define KP_BUTTON_SELECT 9
444 #define KP_BUTTON_A 10
445 #define KP_BUTTON_B 11
446 #define KP_BUTTON_X 12
447 #define KP_BUTTON_Y 13
448 #define KP_BUTTON_L 14
449 #define KP_BUTTON_R 15
450
451
452
453 int WINAPI WinMain( HINSTANCE hInstance,
454 HINSTANCE hPrevInstance,
455 LPTSTR lpCmdLine,
456 int nCmdShow)
457 {
458 MSG msg;
459 HACCEL hAccelTable;
460
461 // Perform application initialization:
462 if (!InitInstance (hInstance, nCmdShow))
463 {
464 return FALSE;
465 }
466
467 if (!InitializeEmulation(Settings.Transparency, Settings.APUEnabled, Settings.SixteenBitSound))
468 {
469 MessageBox(NULL, L"PocketSNES needs more memory", NULL, MB_OK);
470 return FALSE;
471 }
472
473 S9xSetTitle("");
474 SetKeypad();
475
476 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_POCKETSNES);
477
478 // Main message loop:
479 while (g_bLoop)
480 {
481 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
482 {
483 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
484 {
485 TranslateMessage(&msg);
486 DispatchMessage(&msg);
487 }
488 }
489
490 if (g_emMode == emRunning)
491 {
492 #ifdef THREADCPU
493 Sleep(0);
494 #else
495 S9xMainLoop();
496 #endif
497 }
498 }
499
500 SaveOptions();
501 #ifdef __PROFILER
502 __profiler_dump();
503 #endif
504 return msg.wParam;
505 }
506
507 //
508 // FUNCTION: MyRegisterClass()
509 //
510 // PURPOSE: Registers the window class.
511 //
512 // COMMENTS:
513 //
514 // It is important to call this function so that the application
515 // will get 'well formed' small icons associated with it.
516 //
517 ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
518 {
519 WNDCLASS wc;
520
521 wc.style = CS_HREDRAW | CS_VREDRAW;
522 wc.lpfnWndProc = (WNDPROC) WndProc;
523 wc.cbClsExtra = 0;
524 wc.cbWndExtra = 0;
525 wc.hInstance = hInstance;
526 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_POCKETSNES));
527 wc.hCursor = 0;
528 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
529 wc.lpszMenuName = 0;
530 wc.lpszClassName = szWindowClass;
531
532 return RegisterClass(&wc);
533 }
534
535 //
536 // FUNCTION: InitInstance(HANDLE, int)
537 //
538 // PURPOSE: Saves instance handle and creates main window
539 //
540 // COMMENTS:
541 //
542 // In this function, we save the instance handle in a global variable and
543 // create and display the main program window.
544 //
545 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
546 {
547 HWND hWnd = NULL;
548 TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
549 TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
550
551 g_hInstance = hInstance; // Store instance handle in our global variable
552
553 // Initialize global strings
554 LoadString(hInstance, IDC_POCKETSNES, szWindowClass, MAX_LOADSTRING);
555 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
556
557 //If it is already running, then focus on the window
558 hWnd = FindWindow(szWindowClass, szTitle);
559 if (hWnd)
560 {
561 SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01));
562 return FALSE;
563 }
564
565 MyRegisterClass(hInstance, szWindowClass);
566
567 RECT rect;
568 GetClientRect(hWnd, &rect);
569
570 hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
571 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
572 NULL, NULL, hInstance, NULL);
573 if (!hWnd)
574 {
575 MessageBox(NULL, L"PocketSNES failed to initialize", NULL, MB_OK);
576 return FALSE;
577 }
578
579 //When the main window is created using CW_USEDEFAULT the height of the menubar (if one
580 // is created is not taken into account). So we resize the window after creating it
581 // if a menubar is present
582 {
583 RECT rc;
584 GetWindowRect(hWnd, &rc);
585 rc.bottom -= MENU_HEIGHT;
586 if (hwndCB)
587 MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE);
588 }
589
590 LOGFONT lfFont;
591 TCHAR szFontName[32] = L"Tahoma";
592 HDC hDC = GetDC(hWnd);
593
594 memset(&lfFont, 0, sizeof(LOGFONT));
595 wcscpy(lfFont.lfFaceName, szFontName);
596 lfFont.lfWeight = FW_BOLD;
597 lfFont.lfHeight = (-12 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72;
598 g_hFontBold = CreateFontIndirect(&lfFont);
599
600 lfFont.lfWeight = FW_NORMAL;
601 lfFont.lfHeight = (-10 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72;
602 g_hFontNormal = CreateFontIndirect(&lfFont);
603
604 lfFont.lfUnderline = TRUE;
605 lfFont.lfHeight = (-10 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72;
606 g_hFontHyperlink = CreateFontIndirect(&lfFont);
607
608 lfFont.lfUnderline = FALSE;
609 lfFont.lfWeight = FW_BOLD;
610 g_hFontPaused = CreateFontIndirect(&lfFont);
611
612 g_hLogoDC = CreateCompatibleDC(hDC);
613
614 g_pngLogo.SetBitmap(g_hLogoDC, IDB_POCKETSNES, TEXT("IMAGE"), GetModuleHandle(NULL));
615 SelectObject(g_hLogoDC, (HBITMAP)g_pngLogo);
616
617 _tcscpy(g_sRootKey, _T("SOFTWARE\\Apps\\PocketSNES"));
618 LoadOptions();
619
620 g_hiLeftArrow = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LEFT_ARROW));
621 g_hiRightArrow = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RIGHT_ARROW));
622
623 LoadSkins();
624 g_pSkins[g_iSelectedSkin].LoadBitmap(g_hbmSkin, g_hSkinDC, g_hInstance, g_hWnd);
625
626 ReleaseDC(hWnd, hDC);
627
628 ShowWindow(hWnd, nCmdShow);
629 UpdateWindow(hWnd);
630
631 g_hWnd = hWnd;
632
633 return TRUE;
634 }
635
636 //
637 // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
638 //
639 // PURPOSE: Processes messages for the main window.
640 //
641 // WM_COMMAND - process the application menu
642 // WM_PAINT - Paint the main window
643 // WM_DESTROY - post a quit message and return
644 //
645 //
646 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
647 {
648 TCHAR szHello[MAX_LOADSTRING];
649
650 switch (message)
651 {
652 case WM_COMMAND:
653 {
654 int wmId = LOWORD(wParam);
655 int wmEvent = HIWORD(wParam);
656
657 // Parse the menu selections:
658 switch (wmId)
659 {
660 case IDM_TOOLS_LOAD:
661 //CSNES
662 //StopEmulation(hWnd, hwndCB);
663 if (LoadROM()) //hack to keep from crashing if no rom
664 {
665 StopEmulation(hWnd, hwndCB);
666 LoadOptions();
667 StartEmulation(hWnd, hwndCB);
668 }
669 break;
670
671 case IDM_OPTIONS_RESET:
672 if(g_emMode != emStopped)
673 {
674 StopEmulation(hWnd, hwndCB);
675 S9xReset();
676 StartEmulation(hWnd, hwndCB);
677 }
678 break;
679
680 case IDM_OPTIONS_DISPLAY:
681 DialogBox(g_hInstance, (LPCTSTR)IDD_DISPLAY, hWnd, (DLGPROC)DisplayDlgProc);
682 SaveOptions();
683 break;
684
685 case IDM_OPTIONS_SOUND:
686 DialogBox(g_hInstance, (LPCTSTR)IDD_SOUND, hWnd, (DLGPROC)SoundDlgProc);
687 SaveOptions();
688 break;
689
690 case IDM_OPTIONS_SYSTEM:
691 DialogBox(g_hInstance, (LPCTSTR)IDD_SYSTEM, hWnd, (DLGPROC)SystemDlgProc);
692 SaveOptions();
693 break;
694
695 case IDM_OPTIONS_KEYS:
696 DialogBox(g_hInstance, (LPCTSTR)IDD_KEYS, hWnd, (DLGPROC)KeysDlgProc);
697 break;
698
699 case IDM_TOOLS_SKINS:
700 DialogBox(g_hInstance, (LPCTSTR)IDD_SKINS, hWnd, (DLGPROC)SkinsDlgProc);
701 break;
702
703 case IDM_TOOLS_CREDITS:
704 DialogBox(g_hInstance, (LPCTSTR)IDD_CREDITS, hWnd, (DLGPROC)CreditsDlgProc);
705 break;
706
707 case IDM_TOOLS_EXIT:
708 StopEmulation(hWnd, hwndCB);
709 SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
710 SendMessage(hWnd, WM_CLOSE, 0, 0);
711 g_bLoop = false;
712 break;
713
714 case IDM_TOOLS_LOADSTATE:
715 LoadState();
716 //StartEmulation(hWnd, hwndCB);
717 break;
718 case IDM_TOOLS_LOAD1:
719 LoadSlot(0);
720 break;
721 case IDM_TOOLS_LOAD2:
722 LoadSlot(1);
723 break;
724 case IDM_TOOLS_LOAD3:
725 LoadSlot(2);
726 break;
727 case IDM_TOOLS_LOAD4:
728 LoadSlot(3);
729 break;
730 case IDM_TOOLS_LOAD5:
731 LoadSlot(4);
732 break;
733 case IDM_TOOLS_LOAD6:
734 LoadSlot(5);
735 break;
736 case IDM_TOOLS_LOAD7:
737 LoadSlot(6);
738 break;
739 case IDM_TOOLS_LOAD8:
740 LoadSlot(7);
741 break;
742 case IDM_TOOLS_LOAD9:
743 LoadSlot(8);
744 break;
745
746 case IDM_TOOLS_SAVESTATE:
747 SaveState();
748 break;
749 case IDM_TOOLS_SAVE1:
750 SaveSlot(0);
751 break;
752 case IDM_TOOLS_SAVE2:
753 SaveSlot(1);
754 break;
755 case IDM_TOOLS_SAVE3:
756 SaveSlot(2);
757 break;
758 case IDM_TOOLS_SAVE4:
759 SaveSlot(3);
760 break;
761 case IDM_TOOLS_SAVE5:
762 SaveSlot(4);
763 break;
764 case IDM_TOOLS_SAVE6:
765 SaveSlot(5);
766 break;
767 case IDM_TOOLS_SAVE7:
768 SaveSlot(6);
769 break;
770 case IDM_TOOLS_SAVE8:
771 SaveSlot(7);
772 break;
773 case IDM_TOOLS_SAVE9:
774 SaveSlot(8);
775 break;
776
777 case IDOK:
778 SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
779 SendMessage(hWnd, WM_CLOSE, 0, 0);
780 break;
781
782 default:
783 return DefWindowProc(hWnd, message, wParam, lParam);
784 }
785 }
786 break;
787
788 case WM_CREATE:
789 hwndCB = CreateRpCommandBar(hWnd);
790 break;
791
792 case WM_KILLFOCUS:
793 GXSuspend();
794 break;
795
796 case WM_SETFOCUS:
797 GXResume();
798 break;
799
800 case WM_PAINT:
801 if (g_emMode == emStopped)
802 {
803 RECT rtTop, rtBottom;
804 PAINTSTRUCT ps;
805 HDC hDC = BeginPaint(hWnd, &ps);
806
807 GetClientRect(hWnd, &rtTop);
808 rtBottom = rtTop;
809 g_rtLink = rtTop;
810 rtBottom.top = ((rtBottom.bottom - rtBottom.top) / 2) + rtBottom.top + 36;
811 rtBottom.bottom = rtBottom.top + 48;
812 g_rtLink.top = rtBottom.bottom;
813 rtTop.bottom = rtBottom.top;
814 rtTop.top = rtTop.bottom - 36;
815
816 BitBlt(hDC, 0, 8, 240, 113, g_hLogoDC, 0, 0, SRCCOPY);
817
818 LoadString(g_hInstance, IDS_HELLO, szHello, MAX_LOADSTRING);
819 SelectObject(hDC, g_hFontBold);
820 SetTextColor(hDC, COLORREF(0x00ff0000));
821 DrawText(hDC, szHello, _tcslen(szHello), &rtTop, DT_CENTER);
822
823 LoadString(g_hInstance, IDS_HELLO2, szHello, MAX_LOADSTRING);
824 SelectObject(hDC, g_hFontNormal);
825 SetTextColor(hDC, COLORREF(0x00000000));
826 DrawText(hDC, szHello, _tcslen(szHello), &rtBottom, DT_CENTER);
827
828 LoadString(g_hInstance, IDS_LINK, szHello, MAX_LOADSTRING);
829 SelectObject(hDC, g_hFontHyperlink);
830 SetTextColor(hDC, COLORREF(0x00ff0000));
831 DrawText(hDC, szHello, _tcslen(szHello), &g_rtLink, DT_CENTER);
832 EndPaint(hWnd, &ps);
833 }
834 else if (g_emMode == emPaused)
835 {
836 PAINTSTRUCT ps;
837 HDC hDC = BeginPaint(hWnd, &ps);
838 RECT rt = { 0, 224, 240, 320 - 52 };
839
840 BitBlt(hDC, 0, 0, 240, 224, g_hPausedDC, 0, 0, SRCCOPY);
841
842 LoadString(g_hInstance, IDS_PAUSED, szHello, MAX_LOADSTRING);
843 SelectObject(hDC, g_hFontPaused);
844 SetTextColor(hDC, COLORREF(0x000000ff));
845 DrawText(hDC, szHello, _tcslen(szHello), &rt, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
846
847 EndPaint(hWnd, &ps);
848 }
849 break;
850
851
852 case WM_LBUTTONDOWN:
853 {
854 POINT ptClick;
855
856 ptClick.x = LOWORD(lParam);
857 ptClick.y = HIWORD(lParam);
858
859 if (g_emMode == emRunning)
860 {
861 static RECT rtScreen = { 0, 0, 240, 180 };
862
863 if (!CheckKeyPad(ptClick.x, ptClick.y, true))
864 {
865 if (PtInRect(&rtScreen, ptClick))
866 {
867 PauseEmulation(hWnd, hwndCB);
868 }
869 }
870 }
871 else if (g_emMode == emPaused)
872 {
873 static RECT rtScreen = { 0, 26, 240, 320 - 26 };
874
875 if (PtInRect(&rtScreen, ptClick))
876 {
877 ResumeEmulation(hWnd, hwndCB);
878 }
879 }
880 else if (PtInRect(&g_rtLink, ptClick))
881 {
882 SHELLEXECUTEINFO seInfo;
883 TCHAR *szCommand = _T("\\Windows\\iexplore.exe");
884 TCHAR *szURL = _T("http://www.pocketsnes.com");
885
886 memset(&seInfo, 0, sizeof(SHELLEXECUTEINFO));
887 seInfo.cbSize = sizeof(SHELLEXECUTEINFO);
888 seInfo.lpFile = szCommand;
889 seInfo.lpParameters = szURL;
890 seInfo.nShow = SW_SHOW;
891
892 ShellExecuteEx(&seInfo);
893 }
894 }
895 break;
896
897 case WM_LBUTTONUP:
898 if (g_emMode == emRunning)
899 {
900 CheckKeyPad(LOWORD(lParam), HIWORD(lParam), false);
901 }
902 break;
903
904 case WM_KEYDOWN:
905 g_iJoypadState |= g_pkmInUse->dwKeyMask[(short) wParam];
906 break;
907
908 case WM_KEYUP:
909 g_iJoypadState &= ~(g_pkmInUse->dwKeyMask[(short) wParam]);
910 break;
911
912 case WM_DESTROY:
913 StopEmulation(hWnd, hwndCB);
914 CommandBar_Destroy(hwndCB);
915 PostQuitMessage(0);
916 g_bLoop = false;
917 break;
918
919 case WM_SETTINGCHANGE:
920 {
921 SHACTIVATEINFO shaInfo;
922
923 SHHandleWMSettingChange(hWnd, wParam, lParam, &shaInfo);
924 }
925 break;
926
927 default:
928 return DefWindowProc(hWnd, message, wParam, lParam);
929 }
930
931 return 0;
932 }
933
934 HWND CreateRpCommandBar(HWND hwnd)
935 {
936 SHMENUBARINFO mbi;
937
938 memset(&mbi, 0, sizeof(SHMENUBARINFO));
939 mbi.cbSize = sizeof(SHMENUBARINFO);
940 mbi.hwndParent = hwnd;
941 mbi.nToolBarId = IDM_MENU;
942 mbi.hInstRes = g_hInstance;
943 mbi.nBmpId = 0;
944 mbi.cBmpImages = 0;
945
946 if (!SHCreateMenuBar(&mbi))
947 return NULL;
948
949 return mbi.hwndMB;
950 }
951
952 // Message handler for the options dialog
953 LRESULT CALLBACK OptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
954 {
955 switch (message)
956 {
957 case WM_INITDIALOG:
958 {
959 SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_SETCHECK, (WPARAM) (Settings.Transparency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
960 SendMessage(GetDlgItem(hDlg, IDC_LANDSCAPE), BM_SETCHECK, (WPARAM) (g_bLandscape)?BST_CHECKED:BST_UNCHECKED, 0);
961 SendMessage(GetDlgItem(hDlg, IDC_LEFT), BM_SETCHECK, (WPARAM) (g_bLandLeft)?BST_CHECKED:BST_UNCHECKED, 0);
962 SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_SETCHECK, (WPARAM) (g_bCompat)?BST_CHECKED:BST_UNCHECKED, 0);
963 SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_SETCHECK, (WPARAM) (g_bAutoSkip)?BST_CHECKED:BST_UNCHECKED, 0);
964 SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_SETCHECK, (WPARAM) (g_bSmoothStretch)?BST_CHECKED:BST_UNCHECKED, 0);
965 SetDlgItemInt(hDlg, IDC_FRAMESKIP, g_iFrameSkip, false);
966 SetDlgItemInt(hDlg, IDC_CYCLES, g_iCycles, false);
967 SendMessage(GetDlgItem(hDlg, IDC_FRAMESKIP), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20);
968 SendMessage(GetDlgItem(hDlg, IDC_CYCLES), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20);
969 SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_SETCHECK, (WPARAM) (Settings.APUEnabled == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
970 SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
971 SendMessage(GetDlgItem(hDlg, IDC_EIGHTBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == FALSE)?BST_CHECKED:BST_UNCHECKED, 0);
972 SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETRANGE, (WPARAM)(BOOL) TRUE, (LPARAM) MAKELONG(1,3));
973 SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETPOS, (WPARAM)(BOOL) TRUE, (LPARAM) Settings.SoundPlaybackRate);
974
975 SHINITDLGINFO shidi;
976
977 // Create a Done button and size it.
978 shidi.dwMask = SHIDIM_FLAGS;
979 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
980 shidi.hDlg = hDlg;
981
982 //initialzes the dialog based on the dwFlags parameter
983 SHInitDialog(&shidi);
984 }
985 return TRUE;
986
987 case WM_COMMAND:
988 if (LOWORD(wParam) == IDOK)
989 {
990 Settings.Transparency = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_GETCHECK, 0, 0))?TRUE:FALSE;
991 g_bLandscape = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_LANDSCAPE), BM_GETCHECK, 0, 0))?true:false;
992 g_bLandLeft = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_LEFT), BM_GETCHECK, 0, 0))?true:false;
993 g_bCompat = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_GETCHECK, 0, 0))?true:false;
994 g_bAutoSkip = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_GETCHECK, 0, 0))?true:false;
995 g_bSmoothStretch = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_GETCHECK, 0, 0))?true:false;
996 g_iFrameSkip = GetDlgItemInt(hDlg, IDC_FRAMESKIP, NULL, false);
997 g_iCycles = GetDlgItemInt(hDlg, IDC_CYCLES, NULL, false);
998 Settings.CyclesPercentage = g_iCycles;
999 Settings.APUEnabled = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_GETCHECK, 0, 0))?true:false;
1000 Settings.SixteenBitSound = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_GETCHECK, 0, 0))?TRUE:FALSE;
1001 Settings.SoundPlaybackRate = SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_GETPOS, 0, 0);
1002
1003 EndDialog(hDlg, LOWORD(wParam));
1004 return TRUE;
1005 }
1006 break;
1007
1008 case WM_NOTIFY:
1009 if ((int) wParam == IDC_SPIN_FRAMESKIP)
1010 {
1011 LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
1012
1013 if ((lpnmud->iPos + lpnmud->iDelta) > 20)
1014 return TRUE;
1015
1016 return FALSE;
1017 }
1018 break;
1019
1020 case WM_CTLCOLORSTATIC:
1021 {
1022 HDC hDC = (HDC) wParam;
1023 HWND hctl = (HWND) lParam;
1024 LOGFONT lf;
1025
1026 if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE)
1027 return DefWindowProc(hDlg, message, wParam, lParam);
1028
1029 lf.lfWeight = FW_BOLD;
1030 lf.lfEscapement = 0;
1031 lf.lfOrientation = 0;
1032 lf.lfHeight = 13;
1033 lf.lfWidth = 0;
1034 lf.lfCharSet = DEFAULT_CHARSET;
1035 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1036 lf.lfItalic = FALSE;
1037 lf.lfUnderline = FALSE;
1038 lf.lfStrikeOut = FALSE;
1039 lf.lfQuality = DEFAULT_QUALITY;
1040 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1041 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1042
1043 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1044
1045 SelectObject(hDC, CreateFontIndirect(&lf));
1046 SetTextColor(hDC, RGB(0,0,153));
1047
1048 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1049 }
1050
1051 case WM_PAINT:
1052 {
1053 HDC hDC;
1054 PAINTSTRUCT ps;
1055
1056 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1057
1058 SelectObject(hDC, GetStockObject(BLACK_BRUSH));
1059 Rectangle(hDC, 0, 24, 240, 25);
1060
1061 EndPaint(hDlg, &ps);
1062 }
1063 return TRUE;
1064
1065 default:
1066 return DefWindowProc(hDlg, message, wParam, lParam);
1067 }
1068
1069 return 0;
1070 }
1071
1072 // Message handler for the options dialog
1073 LRESULT CALLBACK DisplayDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1074 {
1075 switch (message)
1076 {
1077 case WM_INITDIALOG:
1078 {
1079 if(g_bLandscape)
1080 {
1081 if(g_bSmoothStretch)
1082 {
1083 if(g_bLandLeft)
1084 {
1085 SendMessage(GetDlgItem(hDlg, IDC_LANDLEFTSTRETCH), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0);
1086 }
1087 else
1088 {
1089 SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHTSTRETCH), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0);
1090 }
1091 }
1092 else
1093 {
1094 if(g_bLandLeft)
1095 {
1096 SendMessage(GetDlgItem(hDlg, IDC_LANDLEFT), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0);
1097 }
1098 else
1099 {
1100 SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHT), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0);
1101 }
1102 }
1103 }
1104 else
1105 {
1106 SendMessage(GetDlgItem(hDlg, IDC_PORTRAIT), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0);
1107 }
1108
1109
1110 SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_SETCHECK, (WPARAM) (Settings.DisplayFrameRate == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1111
1112
1113 SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_SETCHECK, (WPARAM) (Settings.Transparency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1114 SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_SETCHECK, (WPARAM) (g_bAutoSkip)?BST_CHECKED:BST_UNCHECKED, 0);
1115 SetDlgItemInt(hDlg, IDC_FRAMESKIP, g_iFrameSkip, false);
1116 SetDlgItemInt(hDlg, IDC_CYCLES, g_iCycles, false);
1117 SendMessage(GetDlgItem(hDlg, IDC_FRAMESKIP_SLIDER), UDM_SETRANGE32, (WPARAM) 0, (LPARAM) 10);
1118 SendMessage(GetDlgItem(hDlg, IDC_CYCLES), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20);
1119 SHINITDLGINFO shidi;
1120
1121 // Create a Done button and size it.
1122 shidi.dwMask = SHIDIM_FLAGS;
1123 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
1124 shidi.hDlg = hDlg;
1125
1126 //initialzes the dialog based on the dwFlags parameter
1127 SHInitDialog(&shidi);
1128 }
1129 return TRUE;
1130
1131 case WM_COMMAND:
1132 if (LOWORD(wParam) == IDOK)
1133 {
1134 Settings.Transparency = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_GETCHECK, 0, 0))?TRUE:FALSE;
1135 g_bCompat = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_GETCHECK, 0, 0))?true:false;
1136 g_bAutoSkip = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_GETCHECK, 0, 0))?true:false;
1137 //g_bSmoothStretch = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_GETCHECK, 0, 0))?true:false;
1138 g_iFrameSkip = GetDlgItemInt(hDlg, IDC_FRAMESKIP, NULL, false);
1139 //g_iCycles = GetDlgItemInt(hDlg, IDC_CYCLES, NULL, false);
1140
1141 Settings.DisplayFrameRate = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_GETCHECK, 0, 0))?TRUE:FALSE;
1142
1143
1144
1145 //Process DisplaySelection
1146 //if((BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_PORTRAIT), BM_GETCHECK, 0, 0))?TRUE:FALSE;))
1147 if(SendMessage(GetDlgItem(hDlg, IDC_PORTRAIT), BM_GETCHECK, 0, 0))
1148 {
1149 g_bLandscape = false;
1150 g_bLandLeft = false;
1151 g_bSmoothStretch = false;
1152 }
1153
1154 if(SendMessage(GetDlgItem(hDlg, IDC_LANDLEFT), BM_GETCHECK, 0, 0))
1155 {
1156 g_bLandscape = true;
1157 g_bLandLeft = true;
1158 g_bSmoothStretch = false;
1159 }
1160
1161 if(SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHT), BM_GETCHECK, 0, 0))
1162 {
1163 g_bLandscape = true;
1164 g_bLandLeft = false;
1165 g_bSmoothStretch = false;
1166 }
1167
1168 if(SendMessage(GetDlgItem(hDlg, IDC_LANDLEFTSTRETCH), BM_GETCHECK, 0, 0))
1169 {
1170 g_bLandscape = true;
1171 g_bLandLeft = true;
1172 g_bSmoothStretch = true;
1173 }
1174
1175 if(SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHTSTRETCH), BM_GETCHECK, 0, 0))
1176 {
1177 g_bLandscape = true;
1178 g_bLandLeft = false;
1179 g_bSmoothStretch = true;
1180 }
1181
1182
1183 EndDialog(hDlg, LOWORD(wParam));
1184 return TRUE;
1185 }
1186 break;
1187
1188 case WM_NOTIFY:
1189 if ((int) wParam == IDC_SPIN_FRAMESKIP)
1190 {
1191 LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
1192
1193 if ((lpnmud->iPos + lpnmud->iDelta) > 20)
1194 return TRUE;
1195
1196 return FALSE;
1197 }
1198 break;
1199
1200 case WM_CTLCOLORSTATIC:
1201 {
1202 HDC hDC = (HDC) wParam;
1203 HWND hctl = (HWND) lParam;
1204 LOGFONT lf;
1205
1206 if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE)
1207 return DefWindowProc(hDlg, message, wParam, lParam);
1208
1209 lf.lfWeight = FW_BOLD;
1210 lf.lfEscapement = 0;
1211 lf.lfOrientation = 0;
1212 lf.lfHeight = 13;
1213 lf.lfWidth = 0;
1214 lf.lfCharSet = DEFAULT_CHARSET;
1215 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1216 lf.lfItalic = FALSE;
1217 lf.lfUnderline = FALSE;
1218 lf.lfStrikeOut = FALSE;
1219 lf.lfQuality = DEFAULT_QUALITY;
1220 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1221 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1222
1223 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1224
1225 SelectObject(hDC, CreateFontIndirect(&lf));
1226 SetTextColor(hDC, RGB(0,0,0));
1227
1228 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1229 }
1230
1231 case WM_PAINT:
1232 {
1233 HDC hDC;
1234 PAINTSTRUCT ps;
1235
1236 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1237
1238 SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
1239 SelectObject(hDC, CreatePen(PS_NULL,2,RGB(50,50,50)));
1240
1241 Rectangle(hDC, 5, 20, 235, 21);
1242
1243 EndPaint(hDlg, &ps);
1244 }
1245 return TRUE;
1246
1247 default:
1248 return DefWindowProc(hDlg, message, wParam, lParam);
1249 }
1250
1251 return 0;
1252 }
1253
1254 // Message handler for the options dialog
1255 LRESULT CALLBACK SoundDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1256 {
1257 switch (message)
1258 {
1259 case WM_INITDIALOG:
1260 {
1261 SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_SETCHECK, (WPARAM) (Settings.APUEnabled == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1262 SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1263 SendMessage(GetDlgItem(hDlg, IDC_EIGHTBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == FALSE)?BST_CHECKED:BST_UNCHECKED, 0);
1264 SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETRANGE, (WPARAM)(BOOL) TRUE, (LPARAM) MAKELONG(1,7));
1265 SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETPOS, (WPARAM)(BOOL) TRUE, (LPARAM) Settings.SoundPlaybackRate);
1266
1267 //CSNES
1268 SendMessage(GetDlgItem(hDlg, IDC_ECHO), BM_SETCHECK, (WPARAM) (Settings.DisableSoundEcho == FALSE)?BST_CHECKED:BST_UNCHECKED, 0);
1269 SendMessage(GetDlgItem(hDlg, IDC_STEREO), BM_SETCHECK, (WPARAM) (Settings.Stereo == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1270 SendMessage(GetDlgItem(hDlg, IDC_REVERSESTEREO), BM_SETCHECK, (WPARAM) (Settings.ReverseStereo == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1271 SendMessage(GetDlgItem(hDlg, IDC_SYNCSOUND), BM_SETCHECK, (WPARAM) (Settings.SoundSync == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1272 SendMessage(GetDlgItem(hDlg, IDC_INTERPOLATESOUND), BM_SETCHECK, (WPARAM) (Settings.InterpolatedSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1273 SendMessage(GetDlgItem(hDlg, IDC_ENVELOPEHEIGHT), BM_SETCHECK, (WPARAM) (Settings.SoundEnvelopeHeightReading == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1274 SendMessage(GetDlgItem(hDlg, IDC_ALTDECODE), BM_SETCHECK, (WPARAM) (Settings.AltSampleDecode == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1275 SendMessage(GetDlgItem(hDlg, IDC_FIXFREQUENCY), BM_SETCHECK, (WPARAM) (Settings.FixFrequency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1276
1277
1278 SHINITDLGINFO shidi;
1279
1280 // Create a Done button and size it.
1281 shidi.dwMask = SHIDIM_FLAGS;
1282 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
1283 shidi.hDlg = hDlg;
1284
1285 //initialzes the dialog based on the dwFlags parameter
1286 SHInitDialog(&shidi);
1287 }
1288 return TRUE;
1289
1290 case WM_COMMAND:
1291 if (LOWORD(wParam) == IDOK)
1292 {
1293 Settings.APUEnabled = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_GETCHECK, 0, 0))?true:false;
1294 Settings.SixteenBitSound = SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_GETCHECK, 0, 0);
1295 Settings.SoundPlaybackRate = SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_GETPOS, 0, 0);
1296 Settings.Stereo = SendMessage(GetDlgItem(hDlg, IDC_STEREO) , BM_GETCHECK, 0, 0);
1297 Settings.ReverseStereo = SendMessage(GetDlgItem(hDlg, IDC_REVERSESTEREO) , BM_GETCHECK, 0, 0);
1298 Settings.DisableSoundEcho = !(SendMessage(GetDlgItem(hDlg, IDC_ECHO) , BM_GETCHECK, 0, 0));
1299 Settings.InterpolatedSound = SendMessage(GetDlgItem(hDlg, IDC_INTERPOLATESOUND), BM_GETCHECK, 0, 0);
1300 Settings.SoundSync = SendMessage(GetDlgItem(hDlg, IDC_SYNCSOUND) , BM_GETCHECK, 0, 0);
1301 Settings.FixFrequency = SendMessage(GetDlgItem(hDlg, IDC_FIXFREQUENCY) , BM_GETCHECK, 0, 0);
1302 Settings.SoundEnvelopeHeightReading = SendMessage(GetDlgItem(hDlg, IDC_ENVELOPEHEIGHT) , BM_GETCHECK, 0, 0);
1303 Settings.AltSampleDecode = SendMessage(GetDlgItem(hDlg, IDC_ALTDECODE) , BM_GETCHECK, 0, 0);
1304
1305 //CSNES - turning on/off sound involves more than APUEnabled
1306 /*
1307 Settings.NextAPUEnabled = Settings.APUEnabled;
1308 Settings.DisableSampleCaching = !(Settings.APUEnabled);
1309 Settings.DisableMasterVolume = !(Settings.APUEnabled);
1310 Settings.ThreadSound = FALSE;
1311 Settings.Mute = !(Settings.APUEnabled);
1312 */
1313 EndDialog(hDlg, LOWORD(wParam));
1314 return TRUE;
1315 }
1316 break;
1317
1318 case WM_NOTIFY:
1319 if ((int) wParam == IDC_SPIN_FRAMESKIP)
1320 {
1321 LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
1322
1323 if ((lpnmud->iPos + lpnmud->iDelta) > 20)
1324 return TRUE;
1325
1326 return FALSE;
1327 }
1328 break;
1329
1330 case WM_CTLCOLORSTATIC:
1331 {
1332 HDC hDC = (HDC) wParam;
1333 HWND hctl = (HWND) lParam;
1334 LOGFONT lf;
1335
1336 if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE)
1337 return DefWindowProc(hDlg, message, wParam, lParam);
1338
1339 lf.lfWeight = FW_BOLD;
1340 lf.lfEscapement = 0;
1341 lf.lfOrientation = 0;
1342 lf.lfHeight = 13;
1343 lf.lfWidth = 0;
1344 lf.lfCharSet = DEFAULT_CHARSET;
1345 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1346 lf.lfItalic = FALSE;
1347 lf.lfUnderline = FALSE;
1348 lf.lfStrikeOut = FALSE;
1349 lf.lfQuality = DEFAULT_QUALITY;
1350 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1351 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1352
1353 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1354
1355 SelectObject(hDC, CreateFontIndirect(&lf));
1356 SetTextColor(hDC, RGB(0,0,0));
1357
1358 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1359 }
1360
1361 case WM_PAINT:
1362 {
1363 HDC hDC;
1364 PAINTSTRUCT ps;
1365
1366 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1367
1368 SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
1369 SelectObject(hDC, CreatePen(PS_NULL,2,RGB(50,50,50)));
1370
1371 Rectangle(hDC, 5, 20, 235, 21);
1372
1373 EndPaint(hDlg, &ps);
1374 }
1375 return TRUE;
1376
1377 default:
1378 return DefWindowProc(hDlg, message, wParam, lParam);
1379 }
1380
1381 return 0;
1382 }
1383
1384 // Message handler for the System dialog
1385 LRESULT CALLBACK SystemDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1386 {
1387 switch (message)
1388 {
1389 case WM_INITDIALOG:
1390 {
1391 //SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_SETCHECK, (WPARAM) (Settings.Transparency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1392 //SendMessage(GetDlgItem(hDlg, IDC_LANDSCAPE), BM_SETCHECK, (WPARAM) (g_bLandscape)?BST_CHECKED:BST_UNCHECKED, 0);
1393 //SendMessage(GetDlgItem(hDlg, IDC_LEFT), BM_SETCHECK, (WPARAM) (g_bLandLeft)?BST_CHECKED:BST_UNCHECKED, 0);
1394 SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_SETCHECK, (WPARAM) (g_bCompat)?BST_CHECKED:BST_UNCHECKED, 0);
1395 SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_SETCHECK, (WPARAM) (g_bAutoSkip)?BST_CHECKED:BST_UNCHECKED, 0);
1396 //SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_SETCHECK, (WPARAM) (g_bSmoothStretch)?BST_CHECKED:BST_UNCHECKED, 0);
1397 SetDlgItemInt(hDlg, IDC_FRAMESKIP, g_iFrameSkip, false);
1398 SetDlgItemInt(hDlg, IDC_CYCLES, g_iCycles, false);
1399 SendMessage(GetDlgItem(hDlg, IDC_FRAMESKIP), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20);
1400 SendMessage(GetDlgItem(hDlg, IDC_CYCLES), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20);
1401 SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_SETCHECK, (WPARAM) (Settings.APUEnabled == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1402 SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0);
1403 SendMessage(GetDlgItem(hDlg, IDC_EIGHTBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == FALSE)?BST_CHECKED:BST_UNCHECKED, 0);
1404 SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETRANGE, (WPARAM)(BOOL) TRUE, (LPARAM) MAKELONG(1,3));
1405 SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETPOS, (WPARAM)(BOOL) TRUE, (LPARAM) Settings.SoundPlaybackRate);
1406
1407 //CSNES
1408 SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERLOADSTATE), BM_SETCHECK, (WPARAM) (g_bResumeAfterLoadState)?BST_CHECKED:BST_UNCHECKED, 0);
1409 SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERSAVESTATE), BM_SETCHECK, (WPARAM) (g_bResumeAfterSaveState)?BST_CHECKED:BST_UNCHECKED, 0);
1410 SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_SETCHECK, (WPARAM) (Settings.DisplayFrameRate)?BST_CHECKED:BST_UNCHECKED, 0);
1411
1412 SHINITDLGINFO shidi;
1413
1414 // Create a Done button and size it.
1415 shidi.dwMask = SHIDIM_FLAGS;
1416 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
1417 shidi.hDlg = hDlg;
1418
1419 //initialzes the dialog based on the dwFlags parameter
1420 SHInitDialog(&shidi);
1421 }
1422 return TRUE;
1423
1424 case WM_COMMAND:
1425 if (LOWORD(wParam) == IDOK)
1426 {
1427 g_iCycles = GetDlgItemInt(hDlg, IDC_CYCLES, NULL, false);
1428 Settings.CyclesPercentage = g_iCycles;
1429
1430 //CSNES
1431 g_bResumeAfterLoadState = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERLOADSTATE), BM_GETCHECK, 0, 0))?true:false;
1432 g_bResumeAfterSaveState = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERSAVESTATE), BM_GETCHECK, 0, 0))?true:false;
1433 Settings.DisplayFrameRate = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_GETCHECK, 0, 0))?true:false;
1434
1435 EndDialog(hDlg, LOWORD(wParam));
1436 return TRUE;
1437 }
1438 break;
1439
1440 case WM_NOTIFY:
1441 if ((int) wParam == IDC_SPIN_FRAMESKIP)
1442 {
1443 LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam;
1444
1445 if ((lpnmud->iPos + lpnmud->iDelta) > 20)
1446 return TRUE;
1447
1448 return FALSE;
1449 }
1450 break;
1451
1452 case WM_CTLCOLORSTATIC:
1453 {
1454 HDC hDC = (HDC) wParam;
1455 HWND hctl = (HWND) lParam;
1456 LOGFONT lf;
1457
1458 if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE)
1459 return DefWindowProc(hDlg, message, wParam, lParam);
1460
1461 lf.lfWeight = FW_BOLD;
1462 lf.lfEscapement = 0;
1463 lf.lfOrientation = 0;
1464 lf.lfHeight = 13;
1465 lf.lfWidth = 0;
1466 lf.lfCharSet = DEFAULT_CHARSET;
1467 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1468 lf.lfItalic = FALSE;
1469 lf.lfUnderline = FALSE;
1470 lf.lfStrikeOut = FALSE;
1471 lf.lfQuality = DEFAULT_QUALITY;
1472 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1473 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1474
1475 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1476
1477 SelectObject(hDC, CreateFontIndirect(&lf));
1478 SetTextColor(hDC, RGB(0,0,0));
1479
1480 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1481 }
1482
1483 case WM_PAINT:
1484 {
1485 HDC hDC;
1486 PAINTSTRUCT ps;
1487
1488 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1489
1490 SelectObject(hDC, GetStockObject(LTGRAY_BRUSH));
1491 SelectObject(hDC, CreatePen(PS_NULL,2,RGB(50,50,50)));
1492
1493 Rectangle(hDC, 5, 20, 235, 21);
1494
1495 EndPaint(hDlg, &ps);
1496 }
1497 return TRUE;
1498
1499 default:
1500 return DefWindowProc(hDlg, message, wParam, lParam);
1501 }
1502
1503 return 0;
1504 }
1505
1506
1507
1508 // Message handler for the options dialog
1509 LRESULT CALLBACK SkinsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1510 {
1511 switch (message)
1512 {
1513 case WM_INITDIALOG:
1514 {
1515 SHINITDLGINFO shidi;
1516
1517 // Create a Done button and size it.
1518 shidi.dwMask = SHIDIM_FLAGS;
1519 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
1520 shidi.hDlg = hDlg;
1521
1522 //initialzes the dialog based on the dwFlags parameter
1523 SHInitDialog(&shidi);
1524 }
1525 return TRUE;
1526
1527 case WM_COMMAND:
1528 {
1529 static RECT rtPaint = { 0, 28, 240, 240 };
1530
1531 switch (LOWORD(wParam))
1532 {
1533 case IDOK:
1534 EndDialog(hDlg, LOWORD(wParam));
1535 return TRUE;
1536
1537 case IDC_BUTTON_PREVIOUS:
1538 g_iSelectedSkin--;
1539 if (g_iSelectedSkin < 0)
1540 g_iSelectedSkin = g_iSkinCount - 1;
1541 g_pSkins[g_iSelectedSkin].LoadBitmap(g_hbmSkin, g_hSkinDC, g_hInstance, g_hWnd);
1542 InvalidateRect(hDlg, &rtPaint, TRUE);
1543 break;
1544
1545 case IDC_BUTTON_NEXT:
1546 g_iSelectedSkin = (g_iSelectedSkin + 1) % g_iSkinCount;
1547 g_pSkins[g_iSelectedSkin].LoadBitmap(g_hbmSkin, g_hSkinDC, g_hInstance, g_hWnd);
1548 InvalidateRect(hDlg, &rtPaint, TRUE);
1549 break;
1550 }
1551 }
1552 break;
1553
1554 case WM_CTLCOLORSTATIC:
1555 {
1556 HDC hDC = (HDC) wParam;
1557 HWND hctl = (HWND) lParam;
1558 LOGFONT lf;
1559
1560 if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE)
1561 return DefWindowProc(hDlg, message, wParam, lParam);
1562
1563 lf.lfWeight = FW_BOLD;
1564 lf.lfEscapement = 0;
1565 lf.lfOrientation = 0;
1566 lf.lfHeight = 13;
1567 lf.lfWidth = 0;
1568 lf.lfCharSet = DEFAULT_CHARSET;
1569 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1570 lf.lfItalic = FALSE;
1571 lf.lfUnderline = FALSE;
1572 lf.lfStrikeOut = FALSE;
1573 lf.lfQuality = DEFAULT_QUALITY;
1574 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1575 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1576
1577 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1578
1579 SelectObject(hDC, CreateFontIndirect(&lf));
1580 SetTextColor(hDC, RGB(0,0,153));
1581
1582 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1583 }
1584
1585 case WM_PAINT:
1586 {
1587 HDC hDC;
1588 PAINTSTRUCT ps;
1589 RECT rtName = { 0, 28, 240, 48 };
1590 RECT rtAuthor = { 0, 160, 240, 180 };
1591
1592 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1593
1594 SelectObject(hDC, GetStockObject(BLACK_BRUSH));
1595 Rectangle(hDC, 0, 24, 240, 25);
1596
1597 Rectangle(hDC, 0, 51, 240, 52);
1598 if (g_pSkins[g_iSelectedSkin].bLandscape)
1599 {
1600 BitBlt(hDC, 0, 52, 240, 64, g_hSkinDC, 0, 0, SRCCOPY);
1601 Rectangle(hDC, 0, 52 + 96, 240, 52 + 64 + 1);
1602 }
1603 else
1604 {
1605 BitBlt(hDC, 0, 52, 240, 96, g_hSkinDC, 0, 0, SRCCOPY);
1606 Rectangle(hDC, 0, 52 + 96, 240, 52 + 96 + 1);
1607 }
1608
1609 SelectObject(hDC, g_hFontPaused);
1610 SetTextColor(hDC, COLORREF(0x00000000));
1611 DrawText(hDC, g_pSkins[g_iSelectedSkin].pszName, _tcslen(g_pSkins[g_iSelectedSkin].pszName), &rtName, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
1612 SelectObject(hDC, g_hFontNormal);
1613 SetTextColor(hDC, COLORREF(0x0000000));
1614 DrawText(hDC, g_pSkins[g_iSelectedSkin].pszAuthor, _tcslen(g_pSkins[g_iSelectedSkin].pszAuthor), &rtAuthor, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
1615
1616 EndPaint(hDlg, &ps);
1617 }
1618 return TRUE;
1619
1620 case WM_DRAWITEM:
1621 {
1622 DRAWITEMSTRUCT *psDrawItem = (LPDRAWITEMSTRUCT) lParam;
1623
1624 if (psDrawItem->CtlID == IDC_BUTTON_PREVIOUS)
1625 DrawIcon(psDrawItem->hDC, 0, 0, g_hiLeftArrow);
1626 else
1627 DrawIcon(psDrawItem->hDC, 0, 0, g_hiRightArrow);
1628 }
1629 return TRUE;
1630
1631 default:
1632 return DefWindowProc(hDlg, message, wParam, lParam);
1633 }
1634
1635 return 0;
1636 }
1637
1638 #define SETBUTTON(a,b) \
1639 { \
1640 DWORD dwCurrentMask = g_kmCurrent.dwKeyMask[vkKey]; \
1641 if (dwCurrentMask != 0) \
1642 SendMessage(GetDlgItem(GetParent(hWnd), g_kmCurrent.GetStaticIDFromMask(dwCurrentMask)), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(0)); \
1643 g_kmCurrent.dwKeyMask[g_kmCurrent.GetKeyFromMask(a)] = 0; \
1644 g_kmCurrent.dwKeyMask[vkKey] = a; \
1645 SendMessage(GetDlgItem(GetParent(hWnd), b), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(a)); \
1646 }
1647
1648 DWORD g_pOriginalWndProc = NULL;
1649
1650 LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1651 {
1652 switch (message)
1653 {
1654 case WM_GETDLGCODE:
1655 return DLGC_WANTARROWS|DLGC_WANTALLKEYS;
1656
1657 case WM_KEYDOWN:
1658 if (g_bSetButtonMode)
1659 {
1660 short vkKey = (short) wParam;
1661
1662 if (vkKey == VK_LWIN)
1663 return TRUE;
1664
1665 switch (g_iSetButton)
1666 {
1667 case IDC_BUTTON_UP:
1668 SETBUTTON(SNES_UP_MASK, IDC_STATIC_UP);
1669 break;
1670
1671 case IDC_BUTTON_DOWN:
1672 SETBUTTON(SNES_DOWN_MASK, IDC_STATIC_DOWN);
1673 break;
1674
1675 case IDC_BUTTON_LEFT:
1676 SETBUTTON(SNES_LEFT_MASK, IDC_STATIC_LEFT);
1677 break;
1678
1679 case IDC_BUTTON_RIGHT:
1680 SETBUTTON(SNES_RIGHT_MASK, IDC_STATIC_RIGHT);
1681 break;
1682
1683 case IDC_BUTTON_A:
1684 SETBUTTON(SNES_A_MASK, IDC_STATIC_A);
1685 break;
1686
1687 case IDC_BUTTON_B:
1688 SETBUTTON(SNES_B_MASK, IDC_STATIC_B);
1689 break;
1690
1691 case IDC_BUTTON_X:
1692 SETBUTTON(SNES_X_MASK, IDC_STATIC_X);
1693 break;
1694
1695 case IDC_BUTTON_Y:
1696 SETBUTTON(SNES_Y_MASK, IDC_STATIC_Y);
1697 break;
1698
1699 case IDC_BUTTON_START:
1700 SETBUTTON(SNES_START_MASK, IDC_STATIC_START);
1701 break;
1702
1703 case IDC_BUTTON_SELECT:
1704 SETBUTTON(SNES_SELECT_MASK, IDC_STATIC_SELECT);
1705 break;
1706
1707 case IDC_BUTTON_L:
1708 SETBUTTON(SNES_TL_MASK, IDC_STATIC_L);
1709 break;
1710
1711 case IDC_BUTTON_R:
1712 SETBUTTON(SNES_TR_MASK, IDC_STATIC_R);
1713 break;
1714 }
1715
1716 g_bSetButtonMode = false;
1717
1718 GXCloseInput();
1719
1720 return TRUE;
1721 }
1722 break;
1723
1724 default:
1725 break;
1726 }
1727
1728 return CallWindowProc((WNDPROC) g_pOriginalWndProc, hWnd, message, wParam, lParam);
1729 }
1730
1731 // Message handler for the keys dialog
1732 LRESULT CALLBACK KeysDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1733 {
1734 switch (message)
1735 {
1736 case WM_INITDIALOG:
1737 {
1738 SendMessage(GetDlgItem(hDlg, IDC_STATIC_UP), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_UP_MASK));
1739 SendMessage(GetDlgItem(hDlg, IDC_STATIC_DOWN), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_DOWN_MASK));
1740 SendMessage(GetDlgItem(hDlg, IDC_STATIC_LEFT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_LEFT_MASK));
1741 SendMessage(GetDlgItem(hDlg, IDC_STATIC_RIGHT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_RIGHT_MASK));
1742 SendMessage(GetDlgItem(hDlg, IDC_STATIC_B), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_B_MASK));
1743 SendMessage(GetDlgItem(hDlg, IDC_STATIC_A), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_A_MASK));
1744 SendMessage(GetDlgItem(hDlg, IDC_STATIC_Y), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_Y_MASK));
1745 SendMessage(GetDlgItem(hDlg, IDC_STATIC_X), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_X_MASK));
1746 SendMessage(GetDlgItem(hDlg, IDC_STATIC_START), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_START_MASK));
1747 SendMessage(GetDlgItem(hDlg, IDC_STATIC_SELECT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_SELECT_MASK));
1748 SendMessage(GetDlgItem(hDlg, IDC_STATIC_L), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_TL_MASK));
1749 SendMessage(GetDlgItem(hDlg, IDC_STATIC_R), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_TR_MASK));
1750
1751 g_bSetButtonMode = false;
1752
1753 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_UP), GWL_WNDPROC, (DWORD) ButtonProc);
1754 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_DOWN), GWL_WNDPROC, (DWORD) ButtonProc);
1755 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_LEFT), GWL_WNDPROC, (DWORD) ButtonProc);
1756 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_RIGHT), GWL_WNDPROC, (DWORD) ButtonProc);
1757 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_A), GWL_WNDPROC, (DWORD) ButtonProc);
1758 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_B), GWL_WNDPROC, (DWORD) ButtonProc);
1759 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_X), GWL_WNDPROC, (DWORD) ButtonProc);
1760 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_Y), GWL_WNDPROC, (DWORD) ButtonProc);
1761 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_START), GWL_WNDPROC, (DWORD) ButtonProc);
1762 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_SELECT), GWL_WNDPROC, (DWORD) ButtonProc);
1763 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_L), GWL_WNDPROC, (DWORD) ButtonProc);
1764 g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_R), GWL_WNDPROC, (DWORD) ButtonProc);
1765
1766 SHINITDLGINFO shidi;
1767
1768 // Create a Done button and size it.
1769 shidi.dwMask = SHIDIM_FLAGS;
1770 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
1771 shidi.hDlg = hDlg;
1772
1773 //initialzes the dialog based on the dwFlags parameter
1774 SHInitDialog(&shidi);
1775 }
1776 return TRUE;
1777
1778 case WM_COMMAND:
1779 {
1780 switch (LOWORD(wParam))
1781 {
1782 case IDOK:
1783 EndDialog(hDlg, LOWORD(wParam));
1784 return TRUE;
1785
1786 case IDC_BUTTON_UP:
1787 case IDC_BUTTON_DOWN:
1788 case IDC_BUTTON_LEFT:
1789 case IDC_BUTTON_RIGHT:
1790 case IDC_BUTTON_A:
1791 case IDC_BUTTON_B:
1792 case IDC_BUTTON_X:
1793 case IDC_BUTTON_Y:
1794 case IDC_BUTTON_START:
1795 case IDC_BUTTON_SELECT:
1796 case IDC_BUTTON_L:
1797 case IDC_BUTTON_R:
1798 if (!g_bSetButtonMode)
1799 {
1800 if (GXOpenInput() != 0)
1801 {
1802 g_bSetButtonMode = true;
1803 g_iSetButton = LOWORD(wParam);
1804 }
1805 }
1806 else
1807 {
1808 // g_bSetButtonMode = false;
1809 }
1810 return TRUE;
1811
1812 default:
1813 break;
1814 }
1815 }
1816 break;
1817
1818 case WM_CTLCOLORSTATIC:
1819 {
1820 HDC hDC = (HDC) wParam;
1821 HWND hctl = (HWND) lParam;
1822 LOGFONT lf;
1823
1824 if ((GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) &&
1825 (GetDlgCtrlID(hctl) != IDC_STATIC_INFO))
1826 return DefWindowProc(hDlg, message, wParam, lParam);
1827
1828 lf.lfWeight = FW_BOLD;
1829 lf.lfEscapement = 0;
1830 lf.lfOrientation = 0;
1831 lf.lfHeight = 13;
1832 lf.lfWidth = 0;
1833 lf.lfCharSet = DEFAULT_CHARSET;
1834 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1835 lf.lfItalic = FALSE;
1836 lf.lfUnderline = FALSE;
1837 lf.lfStrikeOut = FALSE;
1838 lf.lfQuality = DEFAULT_QUALITY;
1839 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1840 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1841
1842 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1843
1844 SelectObject(hDC, CreateFontIndirect(&lf));
1845 if (GetDlgCtrlID(hctl) == IDC_STATIC_TITLE)
1846 SetTextColor(hDC, RGB(0,0,153));
1847 else
1848 SetTextColor(hDC, RGB(0,0,0));
1849
1850 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1851 }
1852
1853 case WM_PAINT:
1854 {
1855 HDC hDC;
1856 PAINTSTRUCT ps;
1857
1858 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1859
1860 SelectObject(hDC, GetStockObject(BLACK_BRUSH));
1861 Rectangle(hDC, 0, 24, 240, 25);
1862
1863 EndPaint(hDlg, &ps);
1864 }
1865 return TRUE;
1866
1867 default:
1868 return DefWindowProc(hDlg, message, wParam, lParam);
1869 }
1870
1871 return 0;
1872 }
1873
1874 #define CREDITS_LENGTH 4000
1875
1876 // Message handler for the credits dialog
1877 LRESULT CALLBACK CreditsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1878 {
1879 switch (message)
1880 {
1881 case WM_INITDIALOG:
1882 {
1883 TCHAR szCredits[CREDITS_LENGTH];
1884 int iLength;
1885
1886 LoadString(g_hInstance, IDS_CREDITS0, szCredits, CREDITS_LENGTH);
1887 iLength = _tcslen(szCredits);
1888 LoadString(g_hInstance, IDS_CREDITS1, &(szCredits[iLength]), CREDITS_LENGTH - iLength);
1889 iLength = _tcslen(szCredits);
1890 LoadString(g_hInstance, IDS_CREDITS2, &(szCredits[iLength]), CREDITS_LENGTH - iLength);
1891
1892 SendMessage(GetDlgItem(hDlg, IDC_CREDITS), WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCTSTR) szCredits);
1893 SendMessage(GetDlgItem(hDlg, IDC_CREDITS), EM_SETSEL, (WPARAM)(INT) -1, (LPARAM) 0);
1894
1895 SHINITDLGINFO shidi;
1896
1897 // Create a Done button and size it.
1898 shidi.dwMask = SHIDIM_FLAGS;
1899 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN;
1900 shidi.hDlg = hDlg;
1901
1902 //initialzes the dialog based on the dwFlags parameter
1903 SHInitDialog(&shidi);
1904
1905 RECT rc;
1906 HWND hDlgItem = GetDlgItem(hDlg, IDC_CREDITS);
1907
1908 rc.top = 25;
1909 rc.left = 0;
1910 rc.right = 240;
1911 rc.bottom = 320 - 26 - 25;
1912 MoveWindow(hDlgItem, rc.left, rc.top, rc.right, rc.bottom - rc.top, TRUE);
1913 }
1914 return TRUE;
1915
1916 case WM_COMMAND:
1917 if (LOWORD(wParam) == IDOK)
1918 {
1919 EndDialog(hDlg, LOWORD(wParam));
1920 return TRUE;
1921 }
1922 break;
1923
1924 case WM_CTLCOLORSTATIC:
1925 {
1926 HDC hDC = (HDC) wParam;
1927 HWND hctl = (HWND) lParam;
1928 LOGFONT lf;
1929
1930 if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE)
1931 return DefWindowProc(hDlg, message, wParam, lParam);
1932
1933 lf.lfWeight = FW_BOLD;
1934 lf.lfEscapement = 0;
1935 lf.lfOrientation = 0;
1936 lf.lfHeight = 13;
1937 lf.lfWidth = 0;
1938 lf.lfCharSet = DEFAULT_CHARSET;
1939 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1940 lf.lfItalic = FALSE;
1941 lf.lfUnderline = FALSE;
1942 lf.lfStrikeOut = FALSE;
1943 lf.lfQuality = DEFAULT_QUALITY;
1944 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1945 lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH;
1946
1947 _tcscpy(lf.lfFaceName, _T("Tahoma"));
1948
1949 SelectObject(hDC, CreateFontIndirect(&lf));
1950 SetTextColor(hDC, RGB(0,0,153));
1951
1952 return (BOOL) GetSysColorBrush(COLOR_STATIC);
1953 }
1954
1955 case WM_PAINT:
1956 {
1957 HDC hDC;
1958 PAINTSTRUCT ps;
1959
1960 hDC = BeginPaint(hDlg, &ps); // begin painting for window
1961
1962 SelectObject(hDC, GetStockObject(BLACK_BRUSH));
1963 Rectangle(hDC, 0, 24, 240, 25);
1964
1965 EndPaint(hDlg, &ps);
1966 }
1967 return TRUE;
1968
1969 default:
1970 return DefWindowProc(hDlg, message, wParam, lParam);
1971 }
1972
1973 return 0;
1974 }
1975
1976 // Eight directions
1977 // Eight buttons - start, select, A, B, X, Y, L, R
1978
1979 bool CheckKeyPad(int _iX, int _iY, bool _bDown)
1980 {
1981 if (g_bLandscape || (g_pKeypad == NULL) || (_iY < 224))
1982 return false;
1983
1984 DWORD dwColor = *(g_pKeypad + _iX + ((96 - (_iY - 224)) * 240));
1985
1986 for (int i = 0; i < g_pSkins[g_iSelectedSkin].iNumberOfColors; i++)
1987 {
1988 if (dwColor == g_pSkins[g_iSelectedSkin].iColor[i])
1989 {
1990 if (_bDown)
1991 g_iJoypadState |= g_pSkins[g_iSelectedSkin].iMask[i];
1992 else
1993 g_iJoypadState &= ~(g_pSkins[g_iSelectedSkin].iMask[i]);
1994
1995 return true;
1996 }
1997 }
1998
1999 return false;
2000 }
2001
2002
2003 //------------------------------------------------------------------------------
2004 // OpenRegistry
2005 // Opens and returns a key to the program's registry.
2006 //------------------------------------------------------------------------------
2007 HKEY OpenRegistry()
2008 {
2009 HKEY hRootKey;
2010 DWORD dwDisposition;
2011
2012 if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, g_sRootKey, 0, NULL, 0, 0, NULL, &hRootKey, &dwDisposition))
2013 {
2014 return hRootKey;
2015 }
2016
2017 return NULL;
2018 }
2019
2020 //------------------------------------------------------------------------------
2021 // CloseRegistry
2022 // Closes the program's registry.
2023 //------------------------------------------------------------------------------
2024 void CloseRegistry(HKEY hRootKey)
2025 {
2026 RegCloseKey(hRootKey);
2027 }
2028
2029 //------------------------------------------------------------------------------
2030 // RegQueryBool
2031 // Reads a boolean flag from the registry.
2032 //------------------------------------------------------------------------------
2033 bool RegQueryBool(HKEY hKey, LPCWSTR lpValueName, bool bDefault = true)
2034 {
2035 DWORD dwValue;
2036 DWORD dwType;
2037 DWORD dwSize = sizeof(dwValue);
2038
2039 if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpValueName, 0, &dwType, (unsigned char *) &dwValue, &dwSize))
2040 {
2041 return ((DWORD) 0 != dwValue);
2042 }
2043
2044 return bDefault;
2045 }
2046
2047 //------------------------------------------------------------------------------
2048 // RegSetBool
2049 // Sets a boolean flag in the registry.
2050 //------------------------------------------------------------------------------
2051 void RegSetBool(HKEY hKey, LPCWSTR lpValueName, bool bValue)
2052 {
2053 DWORD dwValue = (DWORD) bValue;
2054
2055 RegSetValueEx(hKey, lpValueName, 0, REG_DWORD, (unsigned char *) &dwValue, sizeof(dwValue));
2056 }
2057
2058 //------------------------------------------------------------------------------
2059 // RegQueryDword
2060 // Reads a dword value from the registry.
2061 //------------------------------------------------------------------------------
2062 DWORD RegQueryDword(HKEY hKey, LPCWSTR lpValueName, DWORD dwDefault)
2063 {
2064 DWORD dwValue;
2065 DWORD dwType;
2066 DWORD dwSize = sizeof(dwValue);
2067
2068 if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpValueName, 0, &dwType, (unsigned char *) &dwValue, &dwSize))
2069 {
2070 return dwValue;
2071 }
2072
2073 return dwDefault;
2074 }
2075
2076 //------------------------------------------------------------------------------
2077 // RegSetDword
2078 // Sets a dword value in the registry.
2079 //------------------------------------------------------------------------------
2080 void RegSetDword(HKEY hKey, LPCWSTR lpValueName, DWORD dwValue)
2081 {
2082 RegSetValueEx(hKey, lpValueName, 0, REG_DWORD, (unsigned char *) &dwValue, sizeof(dwValue));
2083 }
2084
2085 //------------------------------------------------------------------------------
2086 // LoadDefaultKeys
2087 // Loads default key mappings.
2088 //------------------------------------------------------------------------------
2089 void LoadDefaultKeys()
2090 {
2091 g_gxKeyList = GXGetDefaultKeys(GX_NORMALKEYS);
2092
2093 g_kmDefault.dwKeyMask[g_gxKeyList.vkUp] = SNES_UP_MASK;
2094 g_kmDefault.dwKeyMask[g_gxKeyList.vkDown] = SNES_DOWN_MASK;
2095 g_kmDefault.dwKeyMask[g_gxKeyList.vkLeft] = SNES_LEFT_MASK;
2096 g_kmDefault.dwKeyMask[g_gxKeyList.vkRight] = SNES_RIGHT_MASK;
2097 g_kmDefault.dwKeyMask[g_gxKeyList.vkA] = SNES_B_MASK;
2098 g_kmDefault.dwKeyMask[g_gxKeyList.vkB] = SNES_A_MASK;
2099 g_kmDefault.dwKeyMask[g_gxKeyList.vkC] = SNES_SELECT_MASK;
2100 g_kmDefault.dwKeyMask[g_gxKeyList.vkStart] = SNES_START_MASK;
2101
2102 g_kmDefault.dwKeyMask[0xc1] = SNES_X_MASK;
2103 g_kmDefault.dwKeyMask[0xc2] = SNES_Y_MASK;
2104 }
2105
2106 //------------------------------------------------------------------------------
2107 // LoadOptions
2108 // Loads stored options from the registry.
2109 //------------------------------------------------------------------------------
2110 #define SETKEYMASK(a,b) \
2111 g_kmCurrent.dwKeyMask[RegQueryDword(hRootKey, a, g_kmDefault.GetKeyFromMask(b))] = b
2112
2113 bool LoadOptions()
2114 {
2115 HKEY hRootKey = OpenRegistry();
2116 bool bReturn = false;
2117
2118 Settings.Transparency = RegQueryBool (hRootKey, L"Transparency");
2119 g_bLandscape = RegQueryBool (hRootKey, L"Landscape", false);
2120 g_bLandLeft = RegQueryBool (hRootKey, L"LandscapeLeft", true);
2121 g_bAutoSkip = RegQueryBool (hRootKey, L"AutoSkip", true);
2122 g_bCompat = RegQueryBool (hRootKey, L"Compat", false);
2123 g_bSmoothStretch = RegQueryBool (hRootKey, L"Widescreen", false);
2124 g_iFrameSkip = RegQueryDword(hRootKey, L"FrameSkip", 5);
2125 g_iCycles = RegQueryDword(hRootKey, L"Cycles", 100);
2126 Settings.APUEnabled = RegQueryBool (hRootKey, L"SoundEmulation", false);
2127 Settings.SixteenBitSound = RegQueryBool (hRootKey, L"SixteenBitSound", false);
2128 Settings.SoundPlaybackRate = RegQueryDword(hRootKey, L"SoundQuality", 1);
2129 //CSNES
2130 g_bResumeAfterLoadState = RegQueryBool (hRootKey, L"ResumeAfterLoadState",false);
2131 g_bResumeAfterSaveState = RegQueryBool (hRootKey, L"ResumeAfterSaveState",false);
2132 Settings.DisplayFrameRate = RegQueryBool (hRootKey, L"DisplayFrameRate",false);
2133 Settings.DisableSoundEcho = RegQueryBool (hRootKey, L"DisableSoundEcho",true);
2134 Settings.Stereo = RegQueryBool (hRootKey, L"Stereo",false);
2135 Settings.ReverseStereo = RegQueryBool (hRootKey, L"ReverseStereo",false);
2136 Settings.SoundSync = RegQueryBool (hRootKey, L"SoundSync",true);
2137 Settings.InterpolatedSound = RegQueryBool (hRootKey, L"InterpolatedSound",false);
2138 Settings.FixFrequency = RegQueryBool (hRootKey, L"FixFrequency",false);
2139 Settings.AltSampleDecode = RegQueryBool (hRootKey, L"AltSampleDecode",false);
2140 Settings.SoundEnvelopeHeightReading = RegQueryBool (hRootKey, L"SoundEnvelopeHeightReading",false);
2141 g_bUseGameFolders = RegQueryBool (hRootKey, L"UseGameFolders",false);
2142
2143 LoadDefaultKeys();
2144
2145 SETKEYMASK(L"SNES up", SNES_UP_MASK);
2146 SETKEYMASK(L"SNES down", SNES_DOWN_MASK);
2147 SETKEYMASK(L"SNES left", SNES_LEFT_MASK);
2148 SETKEYMASK(L"SNES right", SNES_RIGHT_MASK);
2149 SETKEYMASK(L"SNES A", SNES_A_MASK);
2150 SETKEYMASK(L"SNES B", SNES_B_MASK);
2151 SETKEYMASK(L"SNES X", SNES_X_MASK);
2152 SETKEYMASK(L"SNES Y", SNES_Y_MASK);
2153 SETKEYMASK(L"SNES start", SNES_START_MASK);
2154 SETKEYMASK(L"SNES select", SNES_SELECT_MASK);
2155 SETKEYMASK(L"SNES L", SNES_TL_MASK);
2156 SETKEYMASK(L"SNES R", SNES_TR_MASK);
2157
2158 CloseRegistry(hRootKey);
2159
2160 return bReturn;
2161 }
2162
2163 //------------------------------------------------------------------------------
2164 // SaveOptions
2165 // Stores options into the registry.
2166 //------------------------------------------------------------------------------
2167 void SaveOptions()
2168 {
2169 HKEY hRootKey = OpenRegistry();
2170
2171 RegSetBool (hRootKey, L"Transparency", (Settings.Transparency == TRUE)?true:false);
2172 RegSetBool (hRootKey, L"Landscape", g_bLandscape);
2173 RegSetBool (hRootKey, L"LandscapeLeft", g_bLandLeft);
2174 RegSetBool (hRootKey, L"AutoSkip", g_bAutoSkip);
2175 RegSetBool (hRootKey, L"Compat", g_bCompat);
2176
2177 RegSetBool (hRootKey, L"Widescreen", g_bSmoothStretch);
2178 RegSetDword(hRootKey, L"FrameSkip", (DWORD) g_iFrameSkip);
2179 RegSetDword(hRootKey, L"Cycles", (DWORD) g_iCycles);
2180 RegSetBool (hRootKey, L"SoundEmulation", (Settings.APUEnabled == TRUE)?true:false);
2181 RegSetBool (hRootKey, L"SixteenBitSound", (Settings.SixteenBitSound == TRUE)?true:false);
2182 RegSetDword(hRootKey, L"SoundQuality", (DWORD)Settings.SoundPlaybackRate);
2183
2184 RegSetDword(hRootKey, L"SNES up", g_kmCurrent.GetKeyFromMask(SNES_UP_MASK));
2185 RegSetDword(hRootKey, L"SNES down", g_kmCurrent.GetKeyFromMask(SNES_DOWN_MASK));
2186 RegSetDword(hRootKey, L"SNES left", g_kmCurrent.GetKeyFromMask(SNES_LEFT_MASK));
2187 RegSetDword(hRootKey, L"SNES right", g_kmCurrent.GetKeyFromMask(SNES_RIGHT_MASK));
2188 RegSetDword(hRootKey, L"SNES A", g_kmCurrent.GetKeyFromMask(SNES_A_MASK));
2189 RegSetDword(hRootKey, L"SNES B", g_kmCurrent.GetKeyFromMask(SNES_B_MASK));
2190 RegSetDword(hRootKey, L"SNES X", g_kmCurrent.GetKeyFromMask(SNES_X_MASK));
2191 RegSetDword(hRootKey, L"SNES Y", g_kmCurrent.GetKeyFromMask(SNES_Y_MASK));
2192 RegSetDword(hRootKey, L"SNES start", g_kmCurrent.GetKeyFromMask(SNES_START_MASK));
2193 RegSetDword(hRootKey, L"SNES select", g_kmCurrent.GetKeyFromMask(SNES_SELECT_MASK));
2194 RegSetDword(hRootKey, L"SNES L", g_kmCurrent.GetKeyFromMask(SNES_TL_MASK));
2195 RegSetDword(hRootKey, L"SNES R", g_kmCurrent.GetKeyFromMask(SNES_TR_MASK));
2196
2197 //CSNES
2198 RegSetBool (hRootKey, L"DisplayFrameRate", (Settings.DisplayFrameRate == TRUE)?true:false);
2199 RegSetBool (hRootKey, L"DisableSoundEcho", (Settings.DisableSoundEcho == TRUE)?true:false);
2200 RegSetBool (hRootKey, L"ResumeAfterLoadState", (g_bResumeAfterLoadState == TRUE)?true:false);
2201 RegSetBool (hRootKey, L"ResumeAfterSaveState", (g_bResumeAfterSaveState == TRUE)?true:false);
2202 RegSetBool (hRootKey, L"Stereo", (Settings.Stereo == TRUE)?true:false);
2203 RegSetBool (hRootKey, L"ReverseStereo", (Settings.ReverseStereo == TRUE)?true:false);
2204 RegSetBool (hRootKey, L"SoundSync", (Settings.SoundSync == TRUE)?true:false);
2205 RegSetBool (hRootKey, L"InterpolatedSound", (Settings.InterpolatedSound == TRUE)?true:false);
2206 RegSetBool (hRootKey, L"DisableSoundEcho", (Settings.DisableSoundEcho == TRUE)?true:false);
2207 RegSetBool (hRootKey, L"SoundEnvelopeHeightReading", (Settings.SoundEnvelopeHeightReading == TRUE)?true:false);
2208 RegSetBool (hRootKey, L"AltSampleDecode", (Settings.AltSampleDecode == TRUE)?true:false);
2209 RegSetBool (hRootKey, L"FixFrequency", (Settings.FixFrequency == TRUE)?true:false);
2210
2211
2212 CloseRegistry(hRootKey);
2213 }
2214 //------------------------------------------------------------------------------
2215 // InitializeDefaultSkins
2216 // Loads default skins.
2217 //------------------------------------------------------------------------------
2218 bool InitializeDefaultSkins()
2219 {
2220 g_pSkins[0].SetAuthor(L"999");
2221 g_pSkins[0].SetName(L"Four Button [default]");
2222 g_pSkins[0].bResource = true;
2223 g_pSkins[0].pszBitmap = MAKEINTRESOURCE(IDB_4BUTTON);
2224 g_pSkins[0].AddColor(0x0000ff, SNES_UP_MASK);
2225 g_pSkins[0].AddColor(0xff0000, SNES_DOWN_MASK);
2226 g_pSkins[0].AddColor(0xffff00, SNES_LEFT_MASK);
2227 g_pSkins[0].AddColor(0x00ff00, SNES_RIGHT_MASK);
2228 g_pSkins[0].AddColor(0xff9900, SNES_B_MASK);
2229 g_pSkins[0].AddColor(0x593400, SNES_A_MASK);
2230 g_pSkins[0].AddColor(0xff00ff, SNES_Y_MASK);
2231 g_pSkins[0].AddColor(0x00ffff, SNES_X_MASK);
2232 g_pSkins[0].AddColor(0x996363, SNES_TR_MASK);
2233 g_pSkins[0].AddColor(0x990000, SNES_TL_MASK);
2234 g_pSkins[0].AddColor(0x475911, SNES_START_MASK);
2235 g_pSkins[0].AddColor(0x99bf26, SNES_SELECT_MASK);
2236
2237 g_pSkins[1].SetAuthor(L"999");
2238 g_pSkins[1].SetName(L"Six Button [default]");
2239 g_pSkins[1].bResource = true;
2240 g_pSkins[1].pszBitmap = MAKEINTRESOURCE(IDB_6BUTTON);
2241 g_pSkins[1].AddColor(0x0000ff, SNES_UP_MASK);
2242 g_pSkins[1].AddColor(0xff0000, SNES_DOWN_MASK);
2243 g_pSkins[1].AddColor(0xffff00, SNES_LEFT_MASK);
2244 g_pSkins[1].AddColor(0x00ff00, SNES_RIGHT_MASK);
2245 g_pSkins[1].AddColor(0x00ffff, SNES_B_MASK);
2246 g_pSkins[1].AddColor(0x00b8bf, SNES_A_MASK);
2247 g_pSkins[1].AddColor(0xfd40ff, SNES_Y_MASK);
2248 g_pSkins[1].AddColor(0xe200e5, SNES_X_MASK);
2249 g_pSkins[1].AddColor(0x005559, SNES_TR_MASK);
2250 g_pSkins[1].AddColor(0x570059, SNES_TL_MASK);
2251
2252 return true;
2253 }
2254
2255 //------------------------------------------------------------------------------
2256 // LoadSkins
2257 // Loads stored skins from the registry.
2258 //------------------------------------------------------------------------------
2259 bool LoadSkins()
2260 {
2261 HKEY hRootKey = OpenRegistry();
2262 bool bReturn = false;
2263 TCHAR szSkinDir[128];
2264 TCHAR szSkinFilename[128];
2265 TCHAR szSkinSearch[128];
2266 DWORD dwType;
2267 DWORD dwSize = 128 * sizeof(TCHAR);
2268
2269 g_iSkinCount = 2;
2270 g_pSkins = new Skin [32 + 2];
2271
2272 InitializeDefaultSkins();
2273
2274 if (ERROR_SUCCESS == RegQueryValueEx(hRootKey, L"Skins Path", 0, &dwType, (unsigned char *) szSkinDir, &dwSize))
2275 {
2276 CreateDirectory(szSkinDir, NULL);
2277
2278 _tcscpy(szSkinSearch, szSkinDir);
2279 _tcscat(szSkinSearch, L"\\*.txt");
2280
2281 WIN32_FIND_DATA w32FindData;
2282 HANDLE hSearch;
2283 FILE *pFile;
2284 bool bFinished = false;
2285 TCHAR szBuffer[256];
2286
2287 hSearch = FindFirstFile(szSkinSearch, &w32FindData);
2288
2289 if (INVALID_HANDLE_VALUE == hSearch)
2290 return true;
2291
2292 do
2293 {
2294 _tcscpy(szSkinFilename, szSkinDir);
2295 _tcscat(szSkinFilename, _T("\\"));
2296 _tcscat(szSkinFilename, w32FindData.cFileName);
2297
2298 if ((pFile = _tfopen(szSkinFilename, _T("r"))) != NULL)
2299 {
2300 if (_fgetts(szBuffer, 256, pFile) != NULL)
2301 {
2302 if (_tcsnicmp(szBuffer, _T("PocketSNES.Skin.1"), 17) == 0)
2303 {
2304 while (_fgetts(szBuffer, 256, pFile) != NULL)
2305 {
2306 if (_tcsncmp(szBuffer, _T("//"), 2) == 0)
2307 {
2308 continue;
2309 }
2310 else if (_tcsnicmp(szBuffer, _T("Bitmap="), 7) == 0)
2311 {
2312 TCHAR szTemp[128];
2313
2314 _tcscpy(szTemp, szSkinDir);
2315 _tcscat(szTemp, _T("\\"));
2316 _tcscat(szTemp, &(szBuffer[7]));
2317 szTemp[_tcslen(szTemp) - 1] = _T('\0');
2318
2319 g_pSkins[g_iSkinCount].SetBitmap(szTemp);
2320 }
2321 else if (_tcsnicmp(szBuffer, _T("Name="), 5) == 0)
2322 {
2323 szBuffer[_tcslen(szBuffer) - 1] = _T('\0');
2324 g_pSkins[g_iSkinCount].SetName(&(szBuffer[5]));
2325 }
2326 else if (_tcsnicmp(szBuffer, _T("Author="), 7) == 0)
2327 {
2328 szBuffer[_tcslen(szBuffer) - 1] = _T('\0');
2329 g_pSkins[g_iSkinCount].SetAuthor(&(szBuffer[7]));
2330 }
2331 else if (_tcsnicmp(szBuffer, _T("Landscape="), 10) == 0)
2332 {
2333 if (szBuffer[10] == _T('1'))
2334 g_pSkins[g_iSkinCount].bLandscape = true;
2335 }
2336 else if (_tcsnicmp(szBuffer, _T("0x"), 2) == 0)
2337 {
2338 szBuffer[_tcslen(szBuffer) - 1] = _T('\0');
2339 szBuffer[8] = _T('\0');
2340 g_pSkins[g_iSkinCount].AddColor(szBuffer, &(szBuffer[9]));
2341 }
2342 }
2343
2344 g_iSkinCount++;
2345 }
2346 }
2347
2348 fclose(pFile);
2349 }
2350
2351 if (!FindNextFile(hSearch, &w32FindData))
2352 {
2353 bFinished = true;
2354 }
2355 } while (!bFinished);
2356
2357 FindClose(hSearch);
2358 }
2359
2360 return true;
2361 }
2362
2363
2364 void SetKeypad()
2365 {
2366 if (g_bLandscape)
2367 {
2368 if(g_bLandLeft)
2369 g_kmLandscape.SetLandscape(g_kmCurrent);
2370 else
2371 g_kmLandscape.SetLandscapeRight(g_kmCurrent);
2372
2373 g_pkmInUse = &g_kmLandscape;
2374 }
2375 else
2376 g_pkmInUse = &g_kmCurrent;
2377 }