added 12-in-1 mapper to carthw
[picodrive.git] / platform / win32 / GenaDrive / Main.cpp
1 #include "app.h"\r
2 #include "version.h"\r
3 #include <crtdbg.h>\r
4 #include <commdlg.h>\r
5 \r
6 char *romname=NULL;\r
7 HWND FrameWnd=NULL;\r
8 RECT FrameRectMy;\r
9 int lock_to_1_1 = 1;\r
10 \r
11 int MainWidth=720,MainHeight=480;\r
12 \r
13 static HMENU mdisplay = 0;\r
14 static unsigned char *rom_data = NULL;\r
15 \r
16 static void UpdateRect()\r
17 {\r
18   WINDOWINFO wi;\r
19   memset(&wi, 0, sizeof(wi));\r
20   wi.cbSize = sizeof(wi);\r
21   GetWindowInfo(FrameWnd, &wi);\r
22   FrameRectMy = wi.rcClient;\r
23 }\r
24 \r
25 static void LoadROM(const char *cmdpath)\r
26 {\r
27   static char rompath[MAX_PATH] = { 0, };\r
28   unsigned char *rom_data_new = NULL;\r
29   unsigned int rom_size = 0;\r
30   pm_file *rom = NULL;\r
31   int oldwait=LoopWait;\r
32   int i, ret;\r
33 \r
34   if (cmdpath) {\r
35     strcpy(rompath, cmdpath + (cmdpath[0] == '\"' ? 1 : 0));\r
36     if (rompath[strlen(rompath)-1] == '\"') rompath[strlen(rompath)-1] = 0;\r
37     if (strlen(rompath) > 4) rom = pm_open(rompath);\r
38   }\r
39 \r
40   if (!rom) {\r
41     OPENFILENAME of; ZeroMemory(&of, sizeof(OPENFILENAME));\r
42     of.lStructSize = sizeof(OPENFILENAME);\r
43     of.lpstrFilter = "ROMs\0*.smd;*.bin;*.gen;*.zip\0";\r
44     of.lpstrFile = rompath; rompath[0] = 0;\r
45     of.nMaxFile = MAX_PATH;\r
46     of.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;\r
47     of.hwndOwner = FrameWnd;\r
48     if (!GetOpenFileName(&of)) return;\r
49     rom = pm_open(rompath);\r
50     if (!rom) { error("failed to open ROM"); return; }\r
51   }\r
52 \r
53   ret=PicoCartLoad(rom, &rom_data_new, &rom_size);\r
54   pm_close(rom);\r
55   if (ret) {\r
56     error("failed to load ROM");\r
57     return;\r
58   }\r
59 \r
60   // halt the work thread..\r
61   // just a hack, should've used proper sync. primitives here, but who will use this emu anyway..\r
62   LoopWaiting=0;\r
63   LoopWait=1;\r
64   for (i = 0; LoopWaiting == 0 && i < 10; i++) Sleep(100);\r
65 \r
66   PicoCartInsert(rom_data_new, rom_size);\r
67 \r
68   if (rom_data) free(rom_data);\r
69   rom_data = rom_data_new;\r
70   romname = rompath;\r
71   LoopWait=0;\r
72 }\r
73 \r
74 static int rect_widths[4]  = { 320, 256, 640, 512 };\r
75 static int rect_heights[4] = { 224, 224, 448, 448 };\r
76 \r
77 // Window proc for the frame window:\r
78 static LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
79 {\r
80   int i;\r
81   switch (msg)\r
82   {\r
83     case WM_CLOSE:   PostQuitMessage(0); return 0;\r
84     case WM_DESTROY: FrameWnd=NULL; break; // Blank handle\r
85     case WM_SIZE:\r
86     case WM_MOVE:\r
87     case WM_SIZING:  UpdateRect(); break;\r
88     case WM_COMMAND:\r
89       switch (LOWORD(wparam))\r
90       {\r
91         case 1000: LoadROM(NULL); break;\r
92         case 1001: PostQuitMessage(0); return 0;\r
93         case 1100:\r
94         case 1101:\r
95         case 1102:\r
96         case 1103:\r
97           LoopWait=1; // another sync hack\r
98           for (i = 0; !LoopWaiting && i < 10; i++) Sleep(10);\r
99           FrameRectMy.right  = FrameRectMy.left + rect_widths[wparam&3];\r
100           FrameRectMy.bottom = FrameRectMy.top  + rect_heights[wparam&3];\r
101           AdjustWindowRect(&FrameRectMy, WS_OVERLAPPEDWINDOW, 1);\r
102           MoveWindow(hwnd, FrameRectMy.left, FrameRectMy.top,\r
103             FrameRectMy.right-FrameRectMy.left, FrameRectMy.bottom-FrameRectMy.top, 1);\r
104           UpdateRect();\r
105           if (HIWORD(wparam) == 0) { // locally sent\r
106             lock_to_1_1=0;\r
107             CheckMenuItem(mdisplay, 1104, MF_UNCHECKED);\r
108           }\r
109           if (rom_data != NULL) LoopWait=0;\r
110           return 0;\r
111         case 1104:\r
112           lock_to_1_1=!lock_to_1_1;\r
113           CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);\r
114           return 0;\r
115         case 1200: break;\r
116         case 1300:\r
117           MessageBox(FrameWnd, "PicoDrive v" VERSION " (c) notaz, 2006-2008\n"\r
118               "SVP demo edition\n\n"\r
119               "Credits:\n"\r
120               "fDave: base code of PicoDrive, GenaDrive (the frontend)\n"\r
121               "Chui: Fame/C\n"\r
122               "NJ: CZ80\n"\r
123               "MAME devs: YM2612 and SN76496 cores\n"\r
124               "Stéphane Dallongeville: Gens code, base of Fame/C (C68K), CZ80\n"\r
125               "Tasco Deluxe: SVP RE work\n"\r
126               "Pierpaolo Prazzoli: info about SSP16 chips\n",\r
127               "About", 0);\r
128           return 0;\r
129       }\r
130       break;\r
131   }\r
132 \r
133   return DefWindowProc(hwnd,msg,wparam,lparam);\r
134 }\r
135 \r
136 static int FrameInit()\r
137 {\r
138   WNDCLASS wc;\r
139   RECT rect={0,0,0,0};\r
140   HMENU mmain, mfile;\r
141   int style=0;\r
142   int left=0,top=0,width=0,height=0;\r
143 \r
144   memset(&wc,0,sizeof(wc));\r
145 \r
146   // Register the window class:\r
147   wc.lpfnWndProc=WndProc;\r
148   wc.hInstance=GetModuleHandle(NULL);\r
149   wc.hCursor=LoadCursor(NULL,IDC_ARROW);\r
150   wc.hbrBackground=CreateSolidBrush(0);\r
151   wc.lpszClassName="MainFrame";\r
152   RegisterClass(&wc);\r
153 \r
154   rect.right =320;//MainWidth;\r
155   rect.bottom=224;//MainHeight;\r
156 \r
157   // Adjust size of windows based on borders:\r
158   style=WS_OVERLAPPEDWINDOW;\r
159   AdjustWindowRect(&rect,style,1);\r
160   width =rect.right-rect.left;\r
161   height=rect.bottom-rect.top;\r
162 \r
163   // Place window in the centre of the screen:\r
164   SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);\r
165   left=rect.left+rect.right;\r
166   top=rect.top+rect.bottom;\r
167 \r
168   left-=width; left>>=1;\r
169   top-=height; top>>=1;\r
170 \r
171   // Create menu:\r
172   mfile = CreateMenu();\r
173   InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1000, "&Load ROM");\r
174   InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1001, "E&xit");\r
175   mdisplay = CreateMenu();\r
176   InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1100, "320x224");\r
177   InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1101, "256x224");\r
178   InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1102, "640x448");\r
179   InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1103, "512x448");\r
180   InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1104, "Lock to 1:1");\r
181   mmain = CreateMenu();\r
182   InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mfile, "&File");\r
183   InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mdisplay, "&Display");\r
184 //  InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, 1200, "&Config");\r
185   InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING, 1300, "&About");\r
186 \r
187   // Create the window:\r
188   FrameWnd=CreateWindow(wc.lpszClassName,"PicoDrive " VERSION,style|WS_VISIBLE,\r
189     left,top,width,height,NULL,mmain,NULL,NULL);\r
190 \r
191   CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);\r
192   ShowWindow(FrameWnd, SW_NORMAL);\r
193   UpdateWindow(FrameWnd);\r
194   UpdateRect();\r
195 \r
196   return 0;\r
197 }\r
198 \r
199 // --------------------\r
200 \r
201 static DWORD WINAPI ThreadCode(void *)\r
202 {\r
203   LoopCode();\r
204   return 0;\r
205 }\r
206 \r
207 int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR cmdline,int)\r
208 {\r
209   MSG msg;\r
210   int ret=0;\r
211   DWORD tid=0;\r
212   HANDLE thread=NULL;\r
213 \r
214   FrameInit();\r
215   ret=LoopInit(); if (ret) goto end0;\r
216 \r
217   // Make another thread to run LoopCode():\r
218   LoopQuit=0;\r
219   LoopWait=1; // wait for ROM to be loaded\r
220   thread=CreateThread(NULL,0,ThreadCode,NULL,0,&tid);\r
221 \r
222   LoadROM(cmdline);\r
223 \r
224   // Main window loop:\r
225   for (;;)\r
226   {\r
227     GetMessage(&msg,NULL,0,0);\r
228     if (msg.message==WM_QUIT) break;\r
229 \r
230     TranslateMessage(&msg);\r
231     DispatchMessage(&msg);\r
232   }\r
233 \r
234   // Signal thread to quit and wait for it to exit:\r
235   LoopQuit=1; WaitForSingleObject(thread,5000);\r
236   CloseHandle(thread); thread=NULL;\r
237 \r
238 end0:\r
239   LoopExit();\r
240   DestroyWindow(FrameWnd);\r
241 \r
242   _CrtDumpMemoryLeaks();\r
243   return 0;\r
244 }\r
245 \r
246 extern void error(char *text)\r
247 {\r
248   MessageBox(FrameWnd, text, "Error", 0);\r
249 }\r
250 \r