platform ps2, handle audio similar to psp
[picodrive.git] / platform / win32 / main.c
CommitLineData
823b9004 1#include <windows.h>\r
2#include <commdlg.h>\r
3#include <stdio.h>\r
4\r
f821bb70 5#include <pico/pico.h>\r
823b9004 6#include "../common/readpng.h"\r
7#include "../common/config.h"\r
823b9004 8#include "../common/emu.h"\r
9#include "../common/menu.h"\r
10#include "../common/input.h"\r
11#include "../common/plat.h"\r
f821bb70 12#include "../common/version.h"\r
823b9004 13#include "direct.h"\r
14#include "in_vk.h"\r
15\r
16char *romname=NULL;\r
17HWND FrameWnd=NULL;\r
18RECT FrameRectMy;\r
19RECT EmuScreenRect = { 0, 0, 320, 224 };\r
20int lock_to_1_1 = 1;\r
21static HWND PicoSwWnd=NULL, PicoPadWnd=NULL;\r
22\r
23static HMENU mmain = 0, mdisplay = 0, mpicohw = 0;\r
24static HBITMAP ppad_bmp = 0;\r
25static HBITMAP ppage_bmps[7] = { 0, };\r
26static char rom_name[0x20*3+1];\r
27static int main_wnd_as_pad = 0;\r
28\r
29static HANDLE loop_enter_event, loop_end_event;\r
30\r
31void error(char *text)\r
32{\r
33 MessageBox(FrameWnd, text, "Error", 0);\r
34}\r
35\r
36static void UpdateRect(void)\r
37{\r
38 WINDOWINFO wi;\r
39 memset(&wi, 0, sizeof(wi));\r
40 wi.cbSize = sizeof(wi);\r
41 GetWindowInfo(FrameWnd, &wi);\r
42 FrameRectMy = wi.rcClient;\r
43}\r
44\r
45static int extract_rom_name(char *dest, const unsigned char *src, int len)\r
46{\r
47 char *p = dest, s_old = 0x20;\r
48 int i;\r
49\r
50 for (i = len - 1; i >= 0; i--)\r
51 {\r
52 if (src[i^1] != ' ') break;\r
53 }\r
54 len = i + 1;\r
55\r
56 for (i = 0; i < len; i++)\r
57 {\r
58 unsigned char s = src[i^1];\r
59 if (s == 0x20 && s_old == 0x20) continue;\r
60 else if (s >= 0x20 && s < 0x7f && s != '%')\r
61 {\r
62 *p++ = s;\r
63 }\r
64 else\r
65 {\r
66 sprintf(p, "%%%02x", s);\r
67 p += 3;\r
68 }\r
69 s_old = s;\r
70 }\r
71 *p = 0;\r
72\r
73 return p - dest;\r
74}\r
75\r
76static void check_name_alias(const char *afname)\r
77{\r
78 char buff[256], *var, *val;\r
79 FILE *f;\r
80 int ret;\r
81\r
82 f = fopen(afname, "r");\r
83 if (f == NULL) return;\r
84\r
85 while (1)\r
86 {\r
87 ret = config_get_var_val(f, buff, sizeof(buff), &var, &val);\r
88 if (ret == 0) break;\r
89 if (ret == -1) continue;\r
90\r
91 if (strcmp(rom_name, var) == 0) {\r
92 lprintf("rom aliased: \"%s\" -> \"%s\"\n", rom_name, val);\r
93 strncpy(rom_name, val, sizeof(rom_name));\r
94 break;\r
95 }\r
96 }\r
97 fclose(f);\r
98}\r
99\r
100static HBITMAP png2hb(const char *fname, int is_480)\r
101{\r
102 BITMAPINFOHEADER bih;\r
103 HBITMAP bmp;\r
104 void *bmem;\r
105 int ret;\r
106\r
107 bmem = calloc(1, is_480 ? 480*240*3 : 320*240*3);\r
108 if (bmem == NULL) return NULL;\r
be672de7 109 ret = readpng(bmem, fname, READPNG_24, is_480 ? 480 : 320, 240);\r
823b9004 110 if (ret != 0) {\r
111 free(bmem);\r
112 return NULL;\r
113 }\r
114\r
115 memset(&bih, 0, sizeof(bih));\r
116 bih.biSize = sizeof(bih);\r
117 bih.biWidth = is_480 ? 480 : 320;\r
118 bih.biHeight = -240;\r
119 bih.biPlanes = 1;\r
120 bih.biBitCount = 24;\r
121 bih.biCompression = BI_RGB;\r
122 bmp = CreateDIBitmap(GetDC(FrameWnd), &bih, CBM_INIT, bmem, (BITMAPINFO *)&bih, 0);\r
123 if (bmp == NULL)\r
124 lprintf("CreateDIBitmap failed with %i", GetLastError());\r
125\r
126 free(bmem);\r
127 return bmp;\r
128}\r
129\r
130static void PrepareForROM(void)\r
131{\r
132 unsigned char *rom_data = NULL;\r
93f9619e 133 int i, ret, show = PicoIn.AHW & PAHW_PICO;\r
823b9004 134 \r
135 PicoGetInternal(PI_ROM, (pint_ret_t *) &rom_data);\r
136 EnableMenuItem(mmain, 2, MF_BYPOSITION|(show ? MF_ENABLED : MF_GRAYED));\r
137 ShowWindow(PicoPadWnd, show ? SW_SHOWNA : SW_HIDE);\r
138 ShowWindow(PicoSwWnd, show ? SW_SHOWNA : SW_HIDE);\r
139 CheckMenuItem(mpicohw, 1210, show ? MF_CHECKED : MF_UNCHECKED);\r
140 CheckMenuItem(mpicohw, 1211, show ? MF_CHECKED : MF_UNCHECKED);\r
141 PostMessage(FrameWnd, WM_COMMAND, 1220 + PicoPicohw.page, 0);\r
142 DrawMenuBar(FrameWnd);\r
143 InvalidateRect(PicoSwWnd, NULL, 1);\r
144\r
145 PicoPicohw.pen_pos[0] =\r
146 PicoPicohw.pen_pos[1] = 0x8000;\r
147 in_vk_add_pl12 = 0;\r
148\r
149 ret = extract_rom_name(rom_name, rom_data + 0x150, 0x20);\r
150 if (ret == 0)\r
151 extract_rom_name(rom_name, rom_data + 0x130, 0x20);\r
152\r
153 if (show)\r
154 {\r
155 char path[MAX_PATH], *p;\r
156 GetModuleFileName(NULL, path, sizeof(path) - 32);\r
157 p = strrchr(path, '\\');\r
158 if (p == NULL) p = path;\r
159 else p++;\r
160 if (ppad_bmp == NULL) {\r
161 strcpy(p, "pico\\pad.png");\r
162 ppad_bmp = png2hb(path, 0);\r
163 }\r
164\r
165 strcpy(p, "pico\\alias.txt");\r
166 check_name_alias(path);\r
167\r
168 for (i = 0; i < 7; i++) {\r
169 if (ppage_bmps[i] != NULL) DeleteObject(ppage_bmps[i]);\r
170 sprintf(p, "pico\\%s_%i.png", rom_name, i);\r
171 ppage_bmps[i] = png2hb(path, 1);\r
172 }\r
173 // games usually don't have page 6, so just duplicate page 5.\r
174 if (ppage_bmps[6] == NULL && ppage_bmps[5] != NULL) {\r
175 sprintf(p, "pico\\%s_5.png", rom_name);\r
176 ppage_bmps[6] = png2hb(path, 1);\r
177 }\r
178 }\r
179}\r
180\r
181static void LoadROM(const char *cmdpath)\r
182{\r
183 char rompath[MAX_PATH];\r
184 int ret;\r
185\r
186 if (cmdpath != NULL && strlen(cmdpath)) {\r
187 strcpy(rompath, cmdpath + (cmdpath[0] == '\"' ? 1 : 0));\r
188 if (rompath[strlen(rompath)-1] == '\"')\r
189 rompath[strlen(rompath)-1] = 0;\r
190 }\r
191 else {\r
192 OPENFILENAME of; ZeroMemory(&of, sizeof(of));\r
193 rompath[sizeof(rompath) - 1] = 0;\r
194 strncpy(rompath, rom_fname_loaded, sizeof(rompath) - 1);\r
195 of.lStructSize = sizeof(of);\r
196 of.lpstrFilter = "ROMs, CD images\0*.smd;*.bin;*.gen;*.zip;*.32x;*.sms;*.iso;*.cso;*.cue\0"\r
197 "whatever\0*.*\0";\r
198 of.lpstrFile = rompath;\r
199 of.nMaxFile = MAX_PATH;\r
200 of.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;\r
201 of.hwndOwner = FrameWnd;\r
202 if (!GetOpenFileName(&of))\r
203 return;\r
204 }\r
205\r
206 if (engineState == PGS_Running) {\r
207 engineState = PGS_Paused;\r
208 WaitForSingleObject(loop_end_event, 5000);\r
209 }\r
210\r
211 ret = emu_reload_rom(rompath);\r
212 if (ret == 0) {\r
213 extern char menu_error_msg[]; // HACK..\r
214 error(menu_error_msg);\r
215 return;\r
216 }\r
217\r
218 PrepareForROM();\r
219 engineState = PGS_Running;\r
220 SetEvent(loop_enter_event);\r
221}\r
222\r
223static const int rect_widths[4] = { 320, 256, 640, 512 };\r
224static const int rect_heights[4] = { 224, 224, 448, 448 };\r
225\r
226// Window proc for the frame window:\r
227static LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
228{\r
229 POINT pt;\r
230 RECT rc;\r
231 int i;\r
232 switch (msg)\r
233 {\r
234 case WM_CLOSE:\r
235 PostQuitMessage(0);\r
236 return 0;\r
237 case WM_DESTROY:\r
238 FrameWnd = NULL; // Blank the handle\r
239 break;\r
240 case WM_SIZE:\r
241 case WM_MOVE:\r
242 case WM_SIZING:\r
243 UpdateRect();\r
244 if (lock_to_1_1 && FrameRectMy.right - FrameRectMy.left != 0 &&\r
245 (FrameRectMy.right - FrameRectMy.left != EmuScreenRect.right - EmuScreenRect.left ||\r
246 FrameRectMy.bottom - FrameRectMy.top != EmuScreenRect.bottom - EmuScreenRect.top)) {\r
247 lock_to_1_1 = 0;\r
248 CheckMenuItem(mdisplay, 1104, MF_UNCHECKED);\r
249 }\r
250 break;\r
251 case WM_COMMAND:\r
252 switch (LOWORD(wparam))\r
253 {\r
254 case 1000:\r
255 LoadROM(NULL);\r
256 break;\r
257 case 1001:\r
258 emu_reset_game();\r
259 return 0;\r
260 case 1002:\r
261 PostQuitMessage(0);\r
262 return 0;\r
263 case 1100:\r
264 case 1101:\r
265 case 1102:\r
266 case 1103:\r
267// LoopWait=1; // another sync hack\r
268// for (i = 0; !LoopWaiting && i < 10; i++) Sleep(10);\r
269 FrameRectMy.right = FrameRectMy.left + rect_widths[wparam&3];\r
270 FrameRectMy.bottom = FrameRectMy.top + rect_heights[wparam&3];\r
271 AdjustWindowRect(&FrameRectMy, WS_OVERLAPPEDWINDOW, 1);\r
272 MoveWindow(hwnd, FrameRectMy.left, FrameRectMy.top,\r
273 FrameRectMy.right-FrameRectMy.left, FrameRectMy.bottom-FrameRectMy.top, 1);\r
274 UpdateRect();\r
275 lock_to_1_1 = 0;\r
276 CheckMenuItem(mdisplay, 1104, MF_UNCHECKED);\r
277// if (rom_loaded) LoopWait=0;\r
278 return 0;\r
279 case 1104:\r
280 lock_to_1_1 = !lock_to_1_1;\r
281 CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);\r
282 /* FALLTHROUGH */\r
283 case 2000: // EmuScreenRect/FrameRectMy sync request\r
284 if (!lock_to_1_1)\r
285 return 0;\r
286 FrameRectMy.right = FrameRectMy.left + (EmuScreenRect.right - EmuScreenRect.left);\r
287 FrameRectMy.bottom = FrameRectMy.top + (EmuScreenRect.bottom - EmuScreenRect.top);\r
288 AdjustWindowRect(&FrameRectMy, WS_OVERLAPPEDWINDOW, 1);\r
289 MoveWindow(hwnd, FrameRectMy.left, FrameRectMy.top,\r
290 FrameRectMy.right-FrameRectMy.left, FrameRectMy.bottom-FrameRectMy.top, 1);\r
291 UpdateRect();\r
292 return 0;\r
293 case 1210:\r
294 case 1211:\r
295 i = IsWindowVisible((LOWORD(wparam)&1) ? PicoPadWnd : PicoSwWnd);\r
296 i = !i;\r
297 ShowWindow((LOWORD(wparam)&1) ? PicoPadWnd : PicoSwWnd, i ? SW_SHOWNA : SW_HIDE);\r
298 CheckMenuItem(mpicohw, LOWORD(wparam), i ? MF_CHECKED : MF_UNCHECKED);\r
299 return 0;\r
300 case 1212:\r
301 main_wnd_as_pad = !main_wnd_as_pad;\r
302 CheckMenuItem(mpicohw, 1212, main_wnd_as_pad ? MF_CHECKED : MF_UNCHECKED);\r
303 return 0;\r
304 case 1220:\r
305 case 1221:\r
306 case 1222:\r
307 case 1223:\r
308 case 1224:\r
309 case 1225:\r
310 case 1226:\r
311 PicoPicohw.page = LOWORD(wparam) % 10;\r
312 for (i = 0; i < 7; i++)\r
313 CheckMenuItem(mpicohw, 1220 + i, MF_UNCHECKED);\r
314 CheckMenuItem(mpicohw, 1220 + PicoPicohw.page, MF_CHECKED);\r
315 InvalidateRect(PicoSwWnd, NULL, 1);\r
316 return 0;\r
317 case 1300:\r
318 MessageBox(FrameWnd, plat_get_credits(), "About", 0);\r
319 return 0;\r
320 }\r
321 break;\r
322 case WM_TIMER:\r
323 GetCursorPos(&pt);\r
324 GetWindowRect(PicoSwWnd, &rc);\r
325 if (PtInRect(&rc, pt)) break;\r
326 GetWindowRect(PicoPadWnd, &rc);\r
327 if (PtInRect(&rc, pt)) break;\r
328 PicoPicohw.pen_pos[0] |= 0x8000;\r
329 PicoPicohw.pen_pos[1] |= 0x8000;\r
330 in_vk_add_pl12 = 0;\r
331 break;\r
332 case WM_LBUTTONDOWN: in_vk_add_pl12 |= 0x20; return 0;\r
333 case WM_LBUTTONUP: in_vk_add_pl12 &= ~0x20; return 0;\r
334 case WM_MOUSEMOVE:\r
335 if (!main_wnd_as_pad) break;\r
336 PicoPicohw.pen_pos[0] = 0x03c + (320 * LOWORD(lparam) / (FrameRectMy.right - FrameRectMy.left));\r
337 PicoPicohw.pen_pos[1] = 0x1fc + (232 * HIWORD(lparam) / (FrameRectMy.bottom - FrameRectMy.top));\r
338 SetTimer(FrameWnd, 100, 1000, NULL);\r
339 break;\r
340 case WM_KEYDOWN:\r
341 if (wparam == VK_TAB) {\r
342 emu_reset_game();\r
343 break;\r
344 }\r
345 if (wparam == VK_ESCAPE) {\r
346 LoadROM(NULL);\r
347 break;\r
348 }\r
349 in_vk_keydown(wparam);\r
350 break;\r
351 case WM_KEYUP:\r
352 in_vk_keyup(wparam);\r
353 break;\r
354 }\r
355\r
356 return DefWindowProc(hwnd,msg,wparam,lparam);\r
357}\r
358\r
359static LRESULT CALLBACK PicoSwWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
360{\r
361 PAINTSTRUCT ps;\r
362 HDC hdc, hdc2;\r
363\r
364 switch (msg)\r
365 {\r
366 case WM_DESTROY: PicoSwWnd=NULL; break;\r
367 case WM_LBUTTONDOWN: in_vk_add_pl12 |= 0x20; return 0;\r
368 case WM_LBUTTONUP: in_vk_add_pl12 &= ~0x20; return 0;\r
369 case WM_MOUSEMOVE:\r
370 if (HIWORD(lparam) < 0x20) break;\r
371 PicoPicohw.pen_pos[0] = 0x03c + LOWORD(lparam) * 2/3;\r
372 PicoPicohw.pen_pos[1] = 0x2f8 + HIWORD(lparam) - 0x20;\r
373 SetTimer(FrameWnd, 100, 1000, NULL);\r
374 break;\r
375 case WM_KEYDOWN: in_vk_keydown(wparam); break;\r
376 case WM_KEYUP: in_vk_keyup(wparam); break;\r
377 case WM_PAINT:\r
378 hdc = BeginPaint(hwnd, &ps);\r
379 if (ppage_bmps[PicoPicohw.page] == NULL)\r
380 {\r
381 SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));\r
382 SetTextColor(hdc, RGB(255, 255, 255));\r
383 SetBkColor(hdc, RGB(0, 0, 0));\r
384 TextOut(hdc, 2, 2, "missing PNGs for", 16);\r
385 TextOut(hdc, 2, 18, rom_name, strlen(rom_name));\r
386 }\r
387 else\r
388 {\r
389 hdc2 = CreateCompatibleDC(GetDC(FrameWnd));\r
390 SelectObject(hdc2, ppage_bmps[PicoPicohw.page]);\r
391 BitBlt(hdc, 0, 0, 480, 240, hdc2, 0, 0, SRCCOPY);\r
392 DeleteDC(hdc2);\r
393 }\r
394 EndPaint(hwnd, &ps);\r
395 return 0;\r
396 case WM_CLOSE:\r
397 ShowWindow(hwnd, SW_HIDE);\r
398 CheckMenuItem(mpicohw, 1210, MF_UNCHECKED);\r
399 return 0;\r
400 }\r
401\r
402 return DefWindowProc(hwnd,msg,wparam,lparam);\r
403}\r
404\r
405static LRESULT CALLBACK PicoPadWndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)\r
406{\r
407 PAINTSTRUCT ps;\r
408 HDC hdc, hdc2;\r
409\r
410 switch (msg)\r
411 {\r
412 case WM_DESTROY: PicoPadWnd=NULL; break;\r
413 case WM_LBUTTONDOWN: in_vk_add_pl12 |= 0x20; return 0;\r
414 case WM_LBUTTONUP: in_vk_add_pl12 &= ~0x20; return 0;\r
415 case WM_MOUSEMOVE:\r
416 PicoPicohw.pen_pos[0] = 0x03c + LOWORD(lparam);\r
417 PicoPicohw.pen_pos[1] = 0x1fc + HIWORD(lparam);\r
418 SetTimer(FrameWnd, 100, 1000, NULL);\r
419 break;\r
420 case WM_KEYDOWN: in_vk_keydown(wparam); break;\r
421 case WM_KEYUP: in_vk_keyup(wparam); break;\r
422 case WM_PAINT:\r
423 if (ppad_bmp == NULL) break;\r
424 hdc = BeginPaint(hwnd, &ps);\r
425 hdc2 = CreateCompatibleDC(GetDC(FrameWnd));\r
426 SelectObject(hdc2, ppad_bmp);\r
427 BitBlt(hdc, 0, 0, 320, 240, hdc2, 0, 0, SRCCOPY);\r
428 EndPaint(hwnd, &ps);\r
429 DeleteDC(hdc2);\r
430 return 0;\r
431 case WM_CLOSE:\r
432 ShowWindow(hwnd, SW_HIDE);\r
433 CheckMenuItem(mpicohw, 1211, MF_UNCHECKED);\r
434 return 0;\r
435 }\r
436\r
437 return DefWindowProc(hwnd,msg,wparam,lparam);\r
438}\r
439\r
440\r
441static int FrameInit()\r
442{\r
443 WNDCLASS wc;\r
444 RECT rect={0,0,0,0};\r
445 HMENU mfile;\r
446 int style=0;\r
447 int left=0,top=0,width=0,height=0;\r
448\r
449 memset(&wc,0,sizeof(wc));\r
450\r
451 // Register the window class:\r
452 wc.lpfnWndProc=WndProc;\r
453 wc.hInstance=GetModuleHandle(NULL);\r
454 wc.hCursor=LoadCursor(NULL,IDC_ARROW);\r
455 wc.hbrBackground=CreateSolidBrush(0);\r
456 wc.lpszClassName="PicoMainFrame";\r
457 RegisterClass(&wc);\r
458\r
459 wc.lpszClassName="PicoSwWnd";\r
460 wc.lpfnWndProc=PicoSwWndProc;\r
461 RegisterClass(&wc);\r
462\r
463 wc.lpszClassName="PicoPadWnd";\r
464 wc.lpfnWndProc=PicoPadWndProc;\r
465 RegisterClass(&wc);\r
466\r
467 rect.right =320;\r
468 rect.bottom=224;\r
469\r
470 // Adjust size of windows based on borders:\r
471 style=WS_OVERLAPPEDWINDOW;\r
472 AdjustWindowRect(&rect,style,1);\r
473 width =rect.right-rect.left;\r
474 height=rect.bottom-rect.top;\r
475\r
476 // Place window in the centre of the screen:\r
477 SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);\r
478 left=rect.left+rect.right;\r
479 top=rect.top+rect.bottom;\r
480\r
481 left-=width; left>>=1;\r
482 top-=height; top>>=1;\r
483\r
484 // Create menu:\r
485 mfile = CreateMenu();\r
486 InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1000, "&Load ROM");\r
487 InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1001, "&Reset");\r
488 InsertMenu(mfile, -1, MF_BYPOSITION|MF_STRING, 1002, "E&xit");\r
489 mdisplay = CreateMenu();\r
490 InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1100, "320x224");\r
491 InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1101, "256x224");\r
492 InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1102, "640x448");\r
493 InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1103, "512x448");\r
494 InsertMenu(mdisplay, -1, MF_BYPOSITION|MF_STRING, 1104, "Lock to 1:1");\r
495 mpicohw = CreateMenu();\r
496 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1210, "Show &Storyware");\r
497 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1211, "Show &Drawing pad");\r
498 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1212, "&Main window as pad");\r
499 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);\r
500 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1220, "Title page (&0)");\r
501 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1221, "Page &1");\r
502 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1222, "Page &2");\r
503 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1223, "Page &3");\r
504 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1224, "Page &4");\r
505 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1225, "Page &5");\r
506 InsertMenu(mpicohw, -1, MF_BYPOSITION|MF_STRING, 1226, "Page &6");\r
507 mmain = CreateMenu();\r
508 InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mfile, "&File");\r
509 InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mdisplay, "&Display");\r
510 InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, (UINT_PTR) mpicohw, "&Pico");\r
511 EnableMenuItem(mmain, 2, MF_BYPOSITION|MF_GRAYED);\r
512// InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING|MF_POPUP, 1200, "&Config");\r
513 InsertMenu(mmain, -1, MF_BYPOSITION|MF_STRING, 1300, "&About");\r
514\r
515 // Create the window:\r
516 FrameWnd=CreateWindow("PicoMainFrame","PicoDrive " VERSION,style|WS_VISIBLE,\r
517 left,top,width,height,NULL,mmain,NULL,NULL);\r
518\r
519 CheckMenuItem(mdisplay, 1104, lock_to_1_1 ? MF_CHECKED : MF_UNCHECKED);\r
520 ShowWindow(FrameWnd, SW_NORMAL);\r
521 UpdateWindow(FrameWnd);\r
522 UpdateRect();\r
523\r
524 // create Pico windows\r
525 style = WS_OVERLAPPED|WS_CAPTION|WS_BORDER|WS_SYSMENU;\r
526 rect.left=rect.top=0;\r
527 rect.right =320;\r
528 rect.bottom=224;\r
529\r
530 AdjustWindowRect(&rect,style,1);\r
531 width =rect.right-rect.left;\r
532 height=rect.bottom-rect.top;\r
533\r
534 left += 326;\r
535 PicoSwWnd=CreateWindow("PicoSwWnd","Storyware",style,\r
536 left,top,width+160,height,FrameWnd,NULL,NULL,NULL);\r
537\r
538 top += 266;\r
539 PicoPadWnd=CreateWindow("PicoPadWnd","Drawing Pad",style,\r
540 left,top,width,height,FrameWnd,NULL,NULL,NULL);\r
541\r
542 return 0;\r
543}\r
544\r
545// --------------------\r
546\r
547static DWORD WINAPI work_thread(void *x)\r
548{\r
549 while (engineState != PGS_Quit) {\r
550 WaitForSingleObject(loop_enter_event, INFINITE);\r
551 if (engineState != PGS_Running)\r
552 continue;\r
553\r
554 printf("loop..\n");\r
555 emu_loop();\r
556 SetEvent(loop_end_event);\r
557 }\r
558\r
559 return 0;\r
560}\r
561\r
562// XXX: use main.c\r
563void xxinit(void)\r
564{\r
565 /* in_init() must go before config, config accesses in_ fwk */\r
566 in_init();\r
697746df 567 emu_prep_defconfig();\r
fcdefcf6 568 emu_read_config(NULL, 0);\r
823b9004 569 config_readlrom(PicoConfigFile);\r
570\r
571 plat_init();\r
572 in_probe();\r
573\r
574 emu_init();\r
575 menu_init();\r
576}\r
577\r
578\r
579int WINAPI WinMain(HINSTANCE p1, HINSTANCE p2, LPSTR cmdline, int p4)\r
580{\r
581 MSG msg;\r
582 DWORD tid = 0;\r
583 HANDLE thread;\r
584 int ret;\r
585\r
586 xxinit();\r
587 FrameInit();\r
588 ret = DirectInit();\r
589 if (ret)\r
590 goto end0;\r
591\r
592 loop_enter_event = CreateEvent(NULL, 0, 0, NULL);\r
593 if (loop_enter_event == NULL)\r
594 goto end0;\r
595\r
596 loop_end_event = CreateEvent(NULL, 0, 0, NULL);\r
597 if (loop_end_event == NULL)\r
598 goto end0;\r
599\r
600 thread = CreateThread(NULL, 0, work_thread, NULL, 0, &tid);\r
601 if (thread == NULL)\r
602 goto end0;\r
603\r
604 LoadROM(cmdline);\r
605\r
606 // Main window loop:\r
607 for (;;)\r
608 {\r
609 GetMessage(&msg,NULL,0,0);\r
610 if (msg.message==WM_QUIT) break;\r
611\r
612 TranslateMessage(&msg);\r
613 DispatchMessage(&msg);\r
614 }\r
615\r
616 // Signal thread to quit and wait for it to exit:\r
617 if (engineState == PGS_Running) {\r
618 engineState = PGS_Quit;\r
619 WaitForSingleObject(loop_end_event, 5000);\r
620 }\r
621 CloseHandle(thread); thread=NULL;\r
622\r
623 emu_write_config(0);\r
624 emu_finish();\r
625 //plat_finish();\r
626\r
627end0:\r
628 DirectExit();\r
629 DestroyWindow(FrameWnd);\r
630\r
631// _CrtDumpMemoryLeaks();\r
632 return 0;\r
633}\r
634\r