1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Win32 interface
5 *
6 * Copyright 1997-1998 Mathias Ortmann
7 * Copyright 1997-1999 Brian King
8 */
9
10 /* Uncomment this line if you want the logs time-stamped */
11 /* #define TIMESTAMP_LOGS */
12
13 #include "sysconfig.h"
14
15 #include <stdlib.h>
16 #include <stdarg.h>
17 #include <signal.h>
18
19 #include <windows.h>
20 #include <commctrl.h>
21 #include <commdlg.h>
22 #include <shellapi.h>
23 #include <zmouse.h>
24 #include <ddraw.h>
25 #include <dbt.h>
26 #include <math.h>
27
28 #include "sysdeps.h"
29 #include "options.h"
30 #include "gensound.h"
31 #include "sounddep/sound.h"
32 #include "uae.h"
33 #include "memory.h"
34 #include "custom.h"
35 #include "events.h"
36 #include "xwin.h"
37 #include "keyboard.h"
38 #include "keybuf.h"
39 #include "drawing.h"
40 #include "picasso96.h"
41 #include "bsdsocket.h"
42 #include "osdep/win32.h"
43 #include "osdep/win32gfx.h"
44 #include "osdep/win32gui.h"
45 #include "osdep/dxwrap.h"
46 #include "autoconf.h"
47 #include "gui.h"
48 #include "newcpu.h"
49 extern void WIN32GFX_WindowMove ( void );
50 extern void WIN32GFX_WindowSize ( void );
51 unsigned long *win32_stackbase;
52 unsigned long *win32_freestack[42]; //EXTRA_STACK_SIZE
53
54 /* Comment out the following line if you don't want ZLIB.DLL support */
55 #undef USE_ZLIB_DLL
56
57 #ifdef USE_ZLIB_DLL
58 #include "zlib.h"
59 #endif
60
61 int useqpc = 0; /* Set to TRUE to use the QueryPerformanceCounter() function instead of rdtsc() */
62
63 static FILE *debugfile = NULL;
64
65 HINSTANCE hInst = NULL;
66 HMODULE hUIDLL = NULL;
67
68 HWND (WINAPI *pHtmlHelp)(HWND, LPCSTR, UINT, LPDWORD ) = NULL;
69
70 HWND hAmigaWnd, hMainWnd;
71 /*DWORD Keys; */
72 RECT amigawin_rect;
73
74 char VersionStr[256];
75
76 int in_sizemove = 0;
77 int manual_painting_needed = 0;
78 int customsize = 0;
79
80 int bActive;
81 int toggle_sound;
82
83 BOOL viewing_child = FALSE;
84
85 HKEY hWinUAEKey = NULL;
86 COLORREF g_dwBackgroundColor = RGB(10, 0, 10);
87
88 /* Keyboard emulation, Win32 helper routines. */
89 static LPARAM keysdown[256];
90 static short numkeysdown;
checkkey(int vkey,LPARAM lParam)91 int checkkey (int vkey, LPARAM lParam)
92 {
93 switch (vkey) {
94 case VK_LWIN:
95 case VK_RWIN:
96 case VK_SHIFT:
97 case VK_LSHIFT:
98 case VK_RSHIFT:
99 case VK_CONTROL:
100 case VK_LCONTROL:
101 case VK_RCONTROL:
102 case VK_MENU:
103 case VK_LMENU:
104 case VK_RMENU:
105 return GetKeyState (vkey) & 0x8000;
106 }
107 return GetAsyncKeyState (vkey) & 0x8000;
108 }
109
110 /* Mouse emulation, Win32 interface */
111 static int mousecx = 160, mousecy = 100, mousedx = 160, mousedy = 100;
112 static int mousecl = MAKELONG (160, 100);
113 int mouseactive;
114
WIN32_MouseDefaults(void)115 void WIN32_MouseDefaults( void )
116 {
117 mousecx = 160, mousecy = 100, mousedx = 160, mousedy = 100, mousecl = MAKELONG (160, 100);
118 }
119
setmouseactive(int active)120 void setmouseactive (int active)
121 {
122 mousedx = (amigawin_rect.right - amigawin_rect.left) / 2;
123 mousedy = (amigawin_rect.bottom - amigawin_rect.top) / 2;
124 mousecl = MAKELONG (mousedx, mousedy);
125 mousecx = amigawin_rect.left + mousedx;
126 mousecy = amigawin_rect.top + mousedy;
127
128 if (active == mouseactive)
129 return;
130 mouseactive = active;
131
132 if (active)
133 {
134 #ifdef HARDWARE_SPRITE_EMULATION
135 if( !WIN32GFX_IsPicassoScreen() )
136 #endif
137 {
138 ShowCursor (FALSE);
139 SetCursorPos (mousecx, mousecy);
140 }
141 SetWindowText (hMainWnd ? hMainWnd : hAmigaWnd, "UAE/Win32 - [Mouse active - press Alt-Tab to cancel]");
142 ClipCursor (&amigawin_rect);
143 }
144 else
145 {
146 ShowCursor (TRUE);
147 SetWindowText (hMainWnd ? hMainWnd : hAmigaWnd, "UAE/Win32" );
148 ClipCursor (NULL);
149 }
150 }
151
152 static int hascapture = 0;
153
setcapture(void)154 static void setcapture (void)
155 {
156 if (hascapture)
157 return;
158 hascapture++;
159 SetCapture (hAmigaWnd);
160 }
161
releasecapture(void)162 void releasecapture (void)
163 {
164 if (!hascapture)
165 return;
166 hascapture--;
167 ReleaseCapture ();
168 }
169
read_processor_time_cyrix(void)170 frame_time_t read_processor_time_cyrix (void)
171 {
172 LARGE_INTEGER counter;
173 QueryPerformanceCounter( &counter );
174 return (frame_time_t)(counter.LowPart);
175 }
176
177 #include <setjmp.h>
178 jmp_buf catch_test;
179
illhandler(int foo)180 static RETSIGTYPE illhandler(int foo)
181 {
182 rpt_available = 0;
183 longjmp(catch_test,1);
184 }
185
have_rdtsc(void)186 int have_rdtsc (void)
187 {
188 rpt_available = 1;
189 write_log ("Testing the RDTSC instruction ... ");
190 signal (SIGILL, illhandler);
191 if (setjmp (catch_test) == 0)
192 read_processor_time ();
193 signal (SIGILL, SIG_DFL);
194 write_log ("done.\n");
195 if (! rpt_available) {
196 write_log ("Your processor does not support the RDTSC instruction.\n");
197 return 0;
198 }
199 return 1;
200 }
201
figure_processor_speed(void)202 static void figure_processor_speed (void)
203 {
204 extern volatile frame_time_t vsynctime;
205 extern unsigned long syncbase;
206 frame_time_t clockrate;
207
208 #if defined __GNUC__
209 if (! have_rdtsc ())
210 useqpc = 1;
211 #else
212 LARGE_INTEGER freq;
213
214 __try
215 {
216 __asm{rdtsc};
217 }
218 __except( GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION )
219 {
220 useqpc = 1;
221 }
222 if( QueryPerformanceFrequency( &freq ) )
223 {
224 if (freq.LowPart > 90000000) /* looks like CPU freq. */
225 write_log ( "CLOCKFREQ: QueryPerformanceFrequency() reports %d-MHz\n", freq.LowPart / 1000000 );
226 else
227 write_log ( "CLOCKFREQ: QueryPerformanceFrequency() reports %.2f-MHz\n", (float)freq.LowPart / 1000000.0f );
228
229 if( freq.LowPart < 1000000 )
230 {
231 write_log ( "CLOCKFREQ: Weird value. Using QueryPerformanceCounter() instead of RDTSC.\n" );
232 useqpc = 1;
233 }
234 rpt_available = 1;
235 }
236 else
237 {
238 write_log ( "CLOCKFREQ: No support for clock-rate stuff!\n" );
239 rpt_available = 0;
240 }
241 #endif
242 SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
243 clockrate = read_processor_time();
244 Sleep( 1000 );
245 clockrate = read_processor_time() - clockrate;
246 SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
247
248 write_log ( "CLOCKFREQ: Measured as %d-MHz\n", clockrate / 1000000 );
249 syncbase = clockrate;
250 vsynctime = syncbase / VBLANK_HZ_PAL; /* default to 50Hz */
251 }
252
253 static BOOL bDiskChanged = FALSE;
254
AmigaWindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)255 static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
256 {
257 PAINTSTRUCT ps;
258 HDC hDC;
259 short wheeldelta;
260 static int store_xy = 0;
261 BOOL minimized;
262 LPMINMAXINFO lpmmi;
263 RECT rect;
264
265 switch( message )
266 {
267 case WM_PALETTECHANGED:
268 if( (HWND)wParam != hWnd )
269 {
270 write_log ( "WM_PALETTECHANGED Request\n" );
271 WIN32GFX_PaletteChange();
272 }
273 break;
274 case WM_ACTIVATEAPP:
275 if (bActive = wParam)
276 {
277 if( WIN32GFX_IsFullScreen() )
278 {
279 SetCursor (NULL);
280 #ifndef HARDWARE_SPRITE_EMULATION
281 SetCursorPos (mousecx, mousecy);
282 #else
283 if( !WIN32GFX_IsPicassoScreen() )
284 SetCursorPos (mousecx, mousecy);
285 #endif
286 }
287 my_kbd_handler (VK_CAPITAL, 0x3a, TRUE);
288 }
289 else
290 {
291 if( !WIN32GFX_IsFullScreen() )
292 setmouseactive (0);
293 else
294 {
295 if( WIN32GFX_IsPicassoScreen() )
296 {
297 WIN32GFX_DisablePicasso();
298 }
299 }
300 }
301 break;
302 case WM_ACTIVATE:
303 minimized = HIWORD( wParam );
304 if (LOWORD (wParam) != WA_INACTIVE)
305 {
306 write_log ( "WinUAE now active via WM_ACTIVATE\n" );
307 if( !minimized )
308 {
309 if( currprefs.win32_iconified_nospeed )
310 {
311 SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
312 }
313 if( currprefs.win32_iconified_nosound )
314 {
315 resume_sound();
316 }
317
318 clear_inhibit_frame( IHF_WINDOWHIDDEN );
319 }
320 ShowWindow (hWnd, SW_RESTORE);
321 if( WIN32GFX_IsPicassoScreen() )
322 {
323 WIN32GFX_EnablePicasso();
324 }
325 }
326 else
327 {
328 write_log ( "WinUAE now inactive via WM_ACTIVATE\n" );
329 if( minimized && !quit_program )
330 {
331 if( currprefs.win32_iconified_nospeed )
332 {
333 SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
334 }
335 if( currprefs.win32_iconified_nosound )
336 {
337 pause_sound ();
338 }
339 set_inhibit_frame( IHF_WINDOWHIDDEN );
340 }
341 }
342 break;
343
344 case WM_SETCURSOR:
345 if( WIN32GFX_IsFullScreen() )
346 {
347 #ifdef HARDWARE_SPRITE_EMULATION
348 if( !WIN32GFX_IsPicassoScreen() )
349 #endif
350 SetCursor (NULL);
351 return TRUE;
352 }
353 break;
354
355 case WM_SYSCOMMAND:
356 switch( wParam & 0xFFF0 )
357 {
358 case SC_MAXIMIZE:
359 WIN32GFX_ToggleFullScreen();
360 return 0;
361 break;
362 case SC_MINIMIZE:
363 WIN32GFX_DisablePicasso();
364 break;
365 }
366 break;
367
368 case WM_KEYUP:
369 case WM_SYSKEYUP:
370 numkeysdown--;
371 keysdown[wParam] = 0;
372 my_kbd_handler (wParam, (lParam >> 16) & 0x1ff, FALSE);
373 return 0;
374 break;
375
376 case WM_KEYDOWN:
377 case WM_SYSKEYDOWN:
378 if (LOWORD (lParam) == 1)
379 {
380 if (numkeysdown)
381 {
382 int key;
383 numkeysdown = 0;
384
385 for (key = 256; key--;)
386 {
387 if (keysdown[key])
388 {
389 if (checkkey (key, lParam))
390 numkeysdown++;
391 else
392 {
393 my_kbd_handler (key, (keysdown[key] >> 16) & 0x1ff, FALSE);
394 keysdown[key] = 0;
395 }
396 }
397 }
398 }
399 if (!keysdown[wParam])
400 {
401 keysdown[wParam] = lParam;
402 numkeysdown++;
403 }
404 numkeysdown++;
405 my_kbd_handler (wParam, (lParam >> 16) & 0x1ff, TRUE);
406 }
407 break;
408
409 case WM_LBUTTONDBLCLK: // According to MSDN, having CS_DBLCLKS in your window-class
410 // means that the sequence is WM_LBUTTONDOWN, WM_LBUTTONUP,
411 // WM_LBUTTONDBLCLK, and WM_LBUTTONUP.
412 // So we need to make WM_LBUTTONDBLCLK act like WM_LBUTTONDOWN.
413 case WM_LBUTTONDOWN:
414 if (ievent_alive) {
415 setcapture ();
416 buttonstate[0] = 1;
417 } else if (!WIN32GFX_IsFullScreen() && !mouseactive)
418 setmouseactive (1);
419 else
420 buttonstate[0] = 1;
421 break;
422
423 case WM_LBUTTONUP:
424 releasecapture ();
425 buttonstate[0] = 0;
426 break;
427
428
429 case WM_MBUTTONDOWN:
430 if (ievent_alive)
431 setcapture ();
432 buttonstate[1] = 1;
433 break;
434
435 case WM_MBUTTONUP:
436 releasecapture ();
437 buttonstate[1] = 0;
438 break;
439
440 case WM_RBUTTONDOWN:
441 if (ievent_alive)
442 setcapture ();
443 buttonstate[2] = 1;
444 break;
445
446 case WM_RBUTTONUP:
447 releasecapture ();
448 buttonstate[2] = 0;
449 break;
450
451 case WM_VSCROLL:
452 write_log ( "WM_VSCROLL\n" );
453 if( LOWORD( wParam ) == SB_LINEDOWN )
454 record_key(0x7A<<1);
455 else if( LOWORD( wParam ) == SB_LINEUP )
456 record_key(0x7B<<1);
457 break;
458
459 case WM_MOUSEWHEEL:
460 wheeldelta = HIWORD(wParam);
461 write_log ( "WM_MOUSEWHEEL with delta %d\n", wheeldelta );
462 if( wheeldelta > 0 )
463 record_key(0x7A<<1);
464 else if( wheeldelta < 0 )
465 record_key(0x7B<<1);
466 break;
467
468 case WM_MOUSEMOVE:
469 #ifndef HARDWARE_SPRITE_EMULATION
470 if( ( mouseactive && !ievent_alive ) ||
471 WIN32GFX_IsFullScreen() )
472 #else
473 if( ( ( mouseactive && !ievent_alive ) || WIN32GFX_IsFullScreen() ) &&
474 !WIN32GFX_IsPicassoScreen() )
475 #endif
476 {
477 /*
478 * In this mode, the mouse pointer is always centered in the window,
479 * this is ensured by the SetCursorPos call below.
480 * We don't want to handle messages that result from such a SetCursorPos
481 * call (recursion!), so exit early if we see one.
482 */
483 if (lParam == mousecl)
484 break;
485 lastmx += (signed short) LOWORD (lParam) - mousedx;
486 lastmy += (signed short) HIWORD (lParam) - mousedy;
487 if (ievent_alive)
488 {
489 if (lastmx < 0)
490 lastmx = 0;
491 if (lastmx > WIN32GFX_GetWidth() )
492 lastmx = WIN32GFX_GetWidth();
493 if (lastmy < 0)
494 lastmy = 0;
495 if (lastmy > WIN32GFX_GetHeight() )
496 lastmy = WIN32GFX_GetHeight();
497 }
498 SetCursorPos (mousecx, mousecy);
499 break;
500 }
501 lastmx = (signed short) LOWORD (lParam);
502 lastmy = (signed short) HIWORD (lParam);
503 break;
504
505 case WM_PAINT:
506 notice_screen_contents_lost ();
507
508 hDC = BeginPaint (hWnd, &ps);
509 /* Check to see if this WM_PAINT is coming while we've got the GUI visible */
510 if( manual_painting_needed )
511 {
512 /* Update the display area */
513 if( !WIN32GFX_IsFullScreen() )
514 {
515 if( DirectDraw_GetLockableType() != overlay_surface )
516 DX_Blit( 0, 0, 0, 0, WIN32GFX_GetWidth(), WIN32GFX_GetHeight(), BLIT_SRC );
517 }
518 else
519 {
520 DirectDraw_Blt( primary_surface, NULL, secondary_surface, NULL, DDBLT_WAIT, NULL );
521 }
522 }
523 EndPaint (hWnd, &ps);
524
525 break;
526
527 case WM_DROPFILES:
528 if (DragQueryFile ((HDROP) wParam, (UINT) - 1, NULL, 0)) {
529 if (DragQueryFile ((HDROP) wParam, 0, NULL, 0) < 255)
530 DragQueryFile ((HDROP) wParam, 0, changed_prefs.df[0], sizeof (changed_prefs.df[0]));
531 }
532 DragFinish ((HDROP) wParam);
533 break;
534
535 case WM_CAPTURECHANGED:
536 if ((HWND)lParam != hAmigaWnd)
537 buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
538 break;
539
540 case WM_TIMER:
541 finishjob ();
542 break;
543
544 case WM_CREATE:
545 DragAcceptFiles (hWnd, TRUE);
546 break;
547
548 case WM_CLOSE:
549 uae_quit ();
550 return 0;
551
552 case WM_WINDOWPOSCHANGED:
553 if( GetWindowRect( hWnd, &amigawin_rect) )
554 {
555 if( hMainWnd )
556 {
557 if( hWinUAEKey && store_xy++)
558 {
559 RegSetValueEx( hWinUAEKey, "xPos", 0, REG_DWORD, (LPBYTE)&amigawin_rect.left, sizeof( LONG ) );
560 RegSetValueEx( hWinUAEKey, "yPos", 0, REG_DWORD, (LPBYTE)&amigawin_rect.top, sizeof( LONG ) );
561 }
562 }
563 }
564 break;
565
566 case WM_MOVING:
567 case WM_MOVE:
568 WIN32GFX_WindowMove();
569 return TRUE;
570
571 case WM_SIZING:
572 WIN32GFX_WindowSize();
573 return TRUE;
574 case WM_SIZE:
575 WIN32GFX_WindowSize();
576 return 0;
577
578 case WM_GETMINMAXINFO:
579 rect.left=0;
580 rect.top=0;
581 lpmmi=(LPMINMAXINFO)lParam;
582 rect.right=320;
583 rect.bottom=256;
584 //AdjustWindowRectEx(&rect,WSTYLE,0,0);
585 lpmmi->ptMinTrackSize.x=rect.right-rect.left;
586 lpmmi->ptMinTrackSize.y=rect.bottom-rect.top;
587 return 0;
588
589 default:
590 #if 0
591 #ifdef BSDSOCKET_SUPPORTED
592 if( message >= 0xB000 && message < 0xB000+MAXPENDINGASYNC*2 )
593 {
594 #if DEBUG_SOCKETS
595 write_log ( "sockmsg(0x%x, 0x%x, 0x%x)\n", message, wParam, lParam );
596 #endif
597 sockmsg( message, wParam, lParam );
598 return 0;
599 }
600 #endif
601 #endif
602 break;
603 }
604
605 return DefWindowProc (hWnd, message, wParam, lParam);
606 }
607
MainWindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)608 static long FAR PASCAL MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
609 {
610 PAINTSTRUCT ps;
611 RECT rc;
612 HDC hDC;
613
614 switch (message) {
615 case WM_LBUTTONDOWN:
616 case WM_MOUSEWHEEL:
617 case WM_MOUSEMOVE:
618 case WM_ACTIVATEAPP:
619 case WM_DROPFILES:
620 case WM_ACTIVATE:
621 case WM_SETCURSOR:
622 case WM_SYSCOMMAND:
623 case WM_KEYUP:
624 case WM_SYSKEYUP:
625 case WM_KEYDOWN:
626 case WM_SYSKEYDOWN:
627 case WM_LBUTTONUP:
628 case WM_MBUTTONDOWN:
629 case WM_MBUTTONUP:
630 case WM_RBUTTONDOWN:
631 case WM_RBUTTONUP:
632 case WM_MOVING:
633 case WM_MOVE:
634 case WM_SIZING:
635 case WM_SIZE:
636 case WM_GETMINMAXINFO:
637 case WM_CREATE:
638 case WM_DESTROY:
639 case WM_USER + 0x200:
640 case WM_CLOSE:
641 case WM_HELP:
642 case WM_DEVICECHANGE:
643 return AmigaWindowProc (hWnd, message, wParam, lParam);
644
645 case WM_DISPLAYCHANGE:
646 if (!WIN32GFX_IsFullScreen && (wParam + 7) / 8 != DirectDraw_GetBytesPerPixel() )
647 WIN32GFX_DisplayChangeRequested();
648 break;
649
650 case WM_ENTERSIZEMOVE:
651 in_sizemove++;
652 break;
653
654 case WM_EXITSIZEMOVE:
655 in_sizemove--;
656 /* fall through */
657
658 case WM_WINDOWPOSCHANGED:
659 WIN32GFX_WindowMove();
660 if( hAmigaWnd && GetWindowRect (hAmigaWnd, &amigawin_rect) )
661 {
662 if (in_sizemove > 0)
663 break;
664
665 if( !WIN32GFX_IsFullScreen() && hAmigaWnd )
666 {
667 if( amigawin_rect.left & 3 )
668 {
669 RECT rc2;
670 if( GetWindowRect( hMainWnd, &rc2 ) )
671 {
672 MoveWindow (hMainWnd, rc2.left + 4 - amigawin_rect.left % 4, rc2.top,
673 rc2.right - rc2.left, rc2.bottom - rc2.top, TRUE);
674 }
675 }
676 //setmouseactive (0);
677 return 0;
678 }
679 }
680 break;
681
682 case WM_PAINT:
683 hDC = BeginPaint (hWnd, &ps);
684 GetClientRect (hWnd, &rc);
685 DrawEdge (hDC, &rc, EDGE_SUNKEN, BF_RECT);
686 EndPaint (hWnd, &ps);
687 break;
688 case WM_NCLBUTTONDBLCLK:
689 if (wParam == HTCAPTION) {
690 WIN32GFX_ToggleFullScreen();
691 return 0;
692 }
693 break;
694 default:
695 break;
696
697 }
698
699 return DefWindowProc (hWnd, message, wParam, lParam);
700 }
701
handle_events(void)702 void handle_events (void)
703 {
704 MSG msg;
705
706 while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
707 TranslateMessage (&msg);
708 DispatchMessage (&msg);
709 }
710 }
711
712 /* Console Win32 helper routines */
713 void activate_debugger ();
714
715 /* We're not a console-app anymore! */
setup_brkhandler(void)716 void setup_brkhandler (void)
717 {
718 }
719
remove_brkhandler(void)720 void remove_brkhandler (void)
721 {
722 }
723
WIN32_RegisterClasses(void)724 int WIN32_RegisterClasses( void )
725 {
726 WNDCLASS wc;
727 HDC hDC = GetDC( NULL );
728
729 if( GetDeviceCaps( hDC, NUMCOLORS ) != -1 )
730 g_dwBackgroundColor = RGB( 255, 0, 255 );
731 ReleaseDC( NULL, hDC );
732
733 wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS;
734 wc.lpfnWndProc = AmigaWindowProc;
735 wc.cbClsExtra = 0;
736 wc.cbWndExtra = 0;
737 wc.hInstance = 0;
738 wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE( IDI_APPICON ) );
739 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
740 wc.lpszMenuName = 0;
741 wc.lpszClassName = "AmigaPowah";
742 wc.hbrBackground = CreateSolidBrush( g_dwBackgroundColor );
743 if (!RegisterClass (&wc))
744 return 0;
745
746 wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
747 wc.lpfnWndProc = MainWindowProc;
748 wc.cbClsExtra = 0;
749 wc.cbWndExtra = 0;
750 wc.hInstance = 0;
751 wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE( IDI_APPICON ) );
752 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
753 wc.hbrBackground = CreateSolidBrush( g_dwBackgroundColor );
754 wc.lpszMenuName = 0;
755 wc.lpszClassName = "PCsuxRox";
756 if (!RegisterClass (&wc))
757 return 0;
758 return 1;
759 }
760
761 #ifdef __GNUC__
762 #undef WINAPI
763 #define WINAPI
764 #endif
765
766 static HINSTANCE hRichEdit = NULL, hHtmlHelp = NULL;
767
768 #ifdef USE_ZLIB_DLL
769 static HINSTANCE hZlib = NULL;
770 FARPROC pgzread = NULL, pgzopen = NULL, pgzclose = NULL, pgzwrite = NULL, pgzerror = NULL;
771 #endif
772
WIN32_CleanupLibraries(void)773 int WIN32_CleanupLibraries( void )
774 {
775 if (hRichEdit)
776 FreeLibrary (hRichEdit);
777
778 if( hHtmlHelp )
779 FreeLibrary( hHtmlHelp );
780
781 if( hUIDLL )
782 FreeLibrary( hUIDLL );
783
784 #ifdef USE_ZLIB_DLL
785 if( hZlib )
786 FreeLibrary( hZlib );
787 #endif
788
789 return 1;
790 }
791
792 /* HtmlHelp Initialization - optional component */
WIN32_InitHtmlHelp(void)793 int WIN32_InitHtmlHelp( void )
794 {
795 int result = 0;
796 if( hHtmlHelp = LoadLibrary( "HHCTRL.OCX" ) )
797 {
798 pHtmlHelp = ( HWND(WINAPI *)(HWND, LPCSTR, UINT, LPDWORD ) )GetProcAddress( hHtmlHelp, "HtmlHelpA" );
799 result = 1;
800 }
801
802
803 return result;
804 }
805
806 #if 0
807 #define TESTING_LANGUAGES
808 #define TEST_LANGID LANG_GERMAN
809 //#define TEST_LANGID LANG_FRENCH
810 //#define TEST_LANGID LANG_TURKISH
811 #endif
812
LoadGUI(void)813 static HMODULE LoadGUI( void )
814 {
815 HMODULE result = NULL;
816 LPCTSTR dllname = NULL;
817 LANGID language = GetUserDefaultLangID() & 0x3FF; // low 9-bits form the primary-language ID
818 #ifdef TESTING_LANGUAGES
819 language = TEST_LANGID;
820 #endif
821
822 switch( language )
823 {
824 case LANG_AFRIKAANS:
825 dllname = "WinUAE_Afrikaans.dll";
826 break;
827 case LANG_ARABIC:
828 dllname = "WinUAE_Arabic.dll";
829 break;
830 case LANG_ARMENIAN:
831 dllname = "WinUAE_Armenian.dll";
832 break;
833 case LANG_ASSAMESE:
834 dllname = "WinUAE_Assamese.dll";
835 break;
836 case LANG_AZERI:
837 dllname = "WinUAE_Azeri.dll";
838 break;
839 case LANG_BASQUE:
840 dllname = "WinUAE_Basque.dll";
841 break;
842 case LANG_BELARUSIAN:
843 dllname = "WinUAE_Belarusian.dll";
844 break;
845 case LANG_BENGALI:
846 dllname = "WinUAE_Bengali.dll";
847 break;
848 case LANG_BULGARIAN:
849 dllname = "WinUAE_Bulgarian.dll";
850 break;
851 case LANG_CATALAN:
852 dllname = "WinUAE_Catalan.dll";
853 break;
854 case LANG_CHINESE:
855 dllname = "WinUAE_Chinese.dll";
856 break;
857 case LANG_CROATIAN:
858 dllname = "WinUAE_CroatianSerbian.dll";
859 break;
860 case LANG_CZECH:
861 dllname = "WinUAE_Czech.dll";
862 break;
863 case LANG_DANISH:
864 dllname = "WinUAE_Danish.dll";
865 break;
866 case LANG_DUTCH:
867 dllname = "WinUAE_Dutch.dll";
868 break;
869 case LANG_ESTONIAN:
870 dllname = "WinUAE_Estonian.dll";
871 break;
872 case LANG_FAEROESE:
873 dllname = "WinUAE_Faeroese.dll";
874 break;
875 case LANG_FARSI:
876 dllname = "WinUAE_Farsi.dll";
877 break;
878 case LANG_FINNISH:
879 dllname = "WinUAE_Finnish.dll";
880 break;
881 case LANG_FRENCH:
882 dllname = "WinUAE_French.dll";
883 break;
884 case LANG_GEORGIAN:
885 dllname = "WinUAE_Georgian.dll";
886 break;
887 case LANG_GERMAN:
888 dllname = "WinUAE_German.dll";
889 break;
890 case LANG_GREEK:
891 dllname = "WinUAE_Greek.dll";
892 break;
893 case LANG_GUJARATI:
894 dllname = "WinUAE_Gujarati.dll";
895 break;
896 case LANG_HEBREW:
897 dllname = "WinUAE_Hebrew.dll";
898 break;
899 case LANG_HINDI:
900 dllname = "WinUAE_Hindi.dll";
901 break;
902 case LANG_HUNGARIAN:
903 dllname = "WinUAE_Hungarian.dll";
904 break;
905 case LANG_ICELANDIC:
906 dllname = "WinUAE_Icelandic.dll";
907 break;
908 case LANG_INDONESIAN:
909 dllname = "WinUAE_Indonesian.dll";
910 break;
911 case LANG_ITALIAN:
912 dllname = "WinUAE_Italian.dll";
913 break;
914 case LANG_JAPANESE:
915 dllname = "WinUAE_Japanese.dll";
916 break;
917 case LANG_KANNADA:
918 dllname = "WinUAE_Kannada.dll";
919 break;
920 case LANG_KASHMIRI:
921 dllname = "WinUAE_Kashmiri.dll";
922 break;
923 case LANG_KAZAK:
924 dllname = "WinUAE_Kazak.dll";
925 break;
926 case LANG_KONKANI:
927 dllname = "WinUAE_Konkani.dll";
928 break;
929 case LANG_KOREAN:
930 dllname = "WinUAE_Korean.dll";
931 break;
932 case LANG_LATVIAN:
933 dllname = "WinUAE_Latvian.dll";
934 break;
935 case LANG_LITHUANIAN:
936 dllname = "WinUAE_Lithuanian.dll";
937 break;
938 case LANG_MACEDONIAN:
939 dllname = "WinUAE_Macedonian.dll";
940 break;
941 case LANG_MALAY:
942 dllname = "WinUAE_Malay.dll";
943 break;
944 case LANG_MALAYALAM:
945 dllname = "WinUAE_Malayalam.dll";
946 break;
947 case LANG_MANIPURI:
948 dllname = "WinUAE_Manipuri.dll";
949 break;
950 case LANG_MARATHI:
951 dllname = "WinUAE_Marathi.dll";
952 break;
953 case LANG_NEPALI:
954 dllname = "WinUAE_Nepali.dll";
955 break;
956 case LANG_NORWEGIAN:
957 dllname = "WinUAE_Norwegian.dll";
958 break;
959 case LANG_ORIYA:
960 dllname = "WinUAE_Oriya.dll";
961 break;
962 case LANG_POLISH:
963 dllname = "WinUAE_Polish.dll";
964 break;
965 case LANG_PORTUGUESE:
966 dllname = "WinUAE_Portuguese.dll";
967 break;
968 case LANG_PUNJABI:
969 dllname = "WinUAE_Punjabi.dll";
970 break;
971 case LANG_ROMANIAN:
972 dllname = "WinUAE_Romanian.dll";
973 break;
974 case LANG_RUSSIAN:
975 dllname = "WinUAE_Russian.dll";
976 break;
977 case LANG_SANSKRIT:
978 dllname = "WinUAE_Sanskrit.dll";
979 break;
980 case LANG_SINDHI:
981 dllname = "WinUAE_Sindhi.dll";
982 break;
983 case LANG_SLOVAK:
984 dllname = "WinUAE_Slovak.dll";
985 break;
986 case LANG_SLOVENIAN:
987 dllname = "WinUAE_Slovenian.dll";
988 break;
989 case LANG_SPANISH:
990 dllname = "WinUAE_Spanish.dll";
991 break;
992 case LANG_SWAHILI:
993 dllname = "WinUAE_Swahili.dll";
994 break;
995 case LANG_SWEDISH:
996 dllname = "WinUAE_Swedish.dll";
997 break;
998 case LANG_TAMIL:
999 dllname = "WinUAE_Tamil.dll";
1000 break;
1001 case LANG_TATAR:
1002 dllname = "WinUAE_Tatar.dll";
1003 break;
1004 case LANG_TELUGU:
1005 dllname = "WinUAE_Telugu.dll";
1006 break;
1007 case LANG_THAI:
1008 dllname = "WinUAE_Thai.dll";
1009 break;
1010 case LANG_TURKISH:
1011 dllname = "WinUAE_Turkish.dll";
1012 break;
1013 case LANG_UKRAINIAN:
1014 dllname = "WinUAE_Ukrainian.dll";
1015 break;
1016 case LANG_URDU:
1017 dllname = "WinUAE_Urdu.dll";
1018 break;
1019 case LANG_UZBEK:
1020 dllname = "WinUAE_Uzbek.dll";
1021 break;
1022 case LANG_VIETNAMESE:
1023 dllname = "WinUAE_Vietnamese.dll";
1024 break;
1025 case 0x400:
1026 dllname = "guidll.dll";
1027 break;
1028 }
1029
1030 if( dllname )
1031 {
1032 TCHAR szFilename[ MAX_PATH ];
1033 DWORD dwVersionHandle, dwFileVersionInfoSize;
1034 LPVOID lpFileVersionData = NULL;
1035 BOOL success = FALSE;
1036 result = LoadLibrary( dllname );
1037 if( result && GetModuleFileName( result, (LPTSTR)&szFilename, MAX_PATH ) )
1038 {
1039 dwFileVersionInfoSize = GetFileVersionInfoSize( szFilename, &dwVersionHandle );
1040 if( dwFileVersionInfoSize )
1041 {
1042 if( lpFileVersionData = calloc( 1, dwFileVersionInfoSize ) )
1043 {
1044 if( GetFileVersionInfo( szFilename, dwVersionHandle, dwFileVersionInfoSize, lpFileVersionData ) )
1045 {
1046 VS_FIXEDFILEINFO *vsFileInfo = NULL;
1047 UINT uLen;
1048 if( VerQueryValue( lpFileVersionData, TEXT("\\"), (void **)&vsFileInfo, &uLen ) )
1049 {
1050 if( vsFileInfo &&
1051 ( HIWORD(vsFileInfo->dwProductVersionMS) == UAEMAJOR )
1052 && ( LOWORD(vsFileInfo->dwProductVersionMS) == UAEMINOR )
1053 && ( HIWORD(vsFileInfo->dwProductVersionLS) == UAESUBREV )
1054 // Change this to an #if 1 when the WinUAE Release version (as opposed to UAE-core version)
1055 // requires a GUI-DLL change...
1056 #if 0
1057 && ( LOWORD(vsFileInfo->dwProductVersionLS) == WINUAERELEASE)
1058 #endif
1059 )
1060 {
1061 success = TRUE;
1062 }
1063 }
1064 }
1065 free( lpFileVersionData );
1066 }
1067 }
1068 }
1069 if( result && !success )
1070 {
1071 FreeLibrary( result );
1072 result = NULL;
1073 }
1074 }
1075
1076 return result;
1077 }
1078
1079 #ifndef _WIN32_WCE
1080 /* try to load COMDLG32 and DDRAW, initialize csDraw */
WIN32_InitLibraries(void)1081 int WIN32_InitLibraries( void )
1082 {
1083 int result = 1;
1084 /* Determine our processor speed and capabilities */
1085 figure_processor_speed();
1086
1087 /* Make sure we do an InitCommonControls() to get some advanced controls */
1088 InitCommonControls();
1089
1090 hRichEdit = LoadLibrary( "RICHED32.DLL" );
1091
1092 hUIDLL = LoadGUI();
1093
1094 #ifdef USE_ZLIB_DLL
1095 hZlib = LoadLibrary( "ZLIB.DLL" );
1096 if( hZlib )
1097 {
1098 pgzread = GetProcAddress( hZlib, "gzread" );
1099 pgzopen = GetProcAddress( hZlib, "gzopen" );
1100 pgzclose = GetProcAddress( hZlib, "gzclose" );
1101 pgzwrite = GetProcAddress( hZlib, "gzwrite" );
1102 pgzerror = GetProcAddress( hZlib, "gzerror" );
1103 if( !pgzread || !pgzopen || !pgzclose || !pgzwrite || !pgzerror)
1104 {
1105 FreeLibrary( hZlib );
1106 hZlib = NULL;
1107 }
1108 }
1109 #endif
1110 return result;
1111 }
1112 #endif
1113
1114 /* Mathias says: "this truly sucks, I'll include a native gunzip() routine soon" */
1115
1116 #ifdef USE_ZLIB_DLL
1117 extern FARPROC pgzread, pgzopen, pgzclose, pgzwrite, pgzerror;
1118 #define GZOPEN( X, Y ) (gzFile)pgzopen( X, Y )
1119 #define GZCLOSE( X ) (int)pgzclose( X )
1120 #define GZREAD( X, Y, Z ) (int)pgzread( X, Y, Z )
1121
1122 #define ZLIB_BUFFER_SIZE 32767
1123
1124 /* gzip decompression via zlib */
zlib_gunzip(const char * src,char * dst)1125 static int zlib_gunzip( const char *src, char *dst )
1126 {
1127 int result = 0, gzResult = 0;
1128 gzFile zSrc = NULL;
1129 FILE *fDst = NULL;
1130 size_t filesize = 0;
1131 uae_u8 *buffer = NULL;
1132
1133 if( hZlib )
1134 {
1135 zSrc = GZOPEN( src, "rb" );
1136 fDst = fopen( dst, "wb" );
1137 buffer = xmalloc( ZLIB_BUFFER_SIZE + 1 );
1138
1139 if( zSrc && fDst && buffer )
1140 {
1141 DWORD dwWritten = 0;
1142 result = 1;
1143 do
1144 {
1145 gzResult = GZREAD( zSrc, buffer, ZLIB_BUFFER_SIZE );
1146 if( gzResult > 0 )
1147 {
1148 if( fwrite( buffer, gzResult, 1, fDst ) != 1 )
1149 {
1150 result = 0;
1151 break;
1152 }
1153 }
1154 } while( gzResult == ZLIB_BUFFER_SIZE );
1155 }
1156
1157 if( zSrc )
1158 {
1159 GZCLOSE( zSrc );
1160 }
1161
1162 if( fDst )
1163 {
1164 fclose( fDst );
1165 }
1166 }
1167 return result;
1168 }
1169 #endif
1170
1171 static char *uncompress_error[2] = { "Error: You need zlib.dll to use .adz/.roz files!\n",
1172 "Error: You need xdms.exe (32 bit) to use .dms files!\n" };
1173
uncompress_hack(int type,const char * src,const char * dst)1174 int uncompress_hack( int type, const char *src, const char *dst)
1175 {
1176 int result = 0;
1177 char fullname[1024];
1178 char buf[1024];
1179 char cmd[256];
1180 char *posn = NULL;
1181 STARTUPINFO si = {sizeof si};
1182 PROCESS_INFORMATION pi;
1183
1184 strcpy( fullname, dst );
1185
1186 if( type == 1 )
1187 {
1188 #ifdef USE_ZLIB_DLL
1189 result = zlib_gunzip( src, fullname );
1190 if( !result )
1191 {
1192 gui_message( uncompress_error[type-1] );
1193 }
1194 return result;
1195 #else
1196 strcpy( cmd, "gzip.exe -f -d" );
1197 strcat( fullname, ".gz" );
1198 #endif
1199 }
1200 else if( type == 2 )
1201 {
1202 strcpy( cmd, "xdms.exe u" );
1203 posn = strrchr( fullname, '.' );
1204 if( posn )
1205 {
1206 *posn = 0;
1207 strcat( fullname, ".dms" );
1208 }
1209 }
1210
1211 if( CopyFile( src, fullname, FALSE ) )
1212 {
1213 sprintf (buf, "%s %s +%s", cmd, fullname, dst );
1214 si.dwFlags = STARTF_USESTDHANDLES;
1215 if( CreateProcess( NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ) )
1216 {
1217 WaitForSingleObject( pi.hProcess, INFINITE );
1218 result = -1;
1219 }
1220 else
1221 {
1222 gui_message( uncompress_error[type-1] );
1223 }
1224 }
1225
1226 /* Special handling for broken xdms.exe */
1227 if( type == 2 )
1228 {
1229 DeleteFile( fullname ); /* Delete the uaeXX.dms file */
1230 }
1231
1232 return result;
1233 }
1234
1235 /* console window for debugging messages */
1236 /* Brian: disable for release version if you want (TW) */
1237
1238 #define WRITE_LOG_BUF_SIZE 4096
1239
1240 static int consoleopen = 0;
1241 HANDLE stdinput,stdoutput;
1242
openconsole(void)1243 static void openconsole(void)
1244 {
1245 if(consoleopen) return;
1246 AllocConsole();
1247 stdinput=GetStdHandle(STD_INPUT_HANDLE);
1248 stdoutput=GetStdHandle(STD_OUTPUT_HANDLE);
1249 SetConsoleMode(stdinput,ENABLE_PROCESSED_INPUT|ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_OUTPUT);
1250 consoleopen = 1;
1251 }
1252
1253 /* console functions for debugger */
1254
console_out(const char * format,...)1255 void console_out (const char *format,...)
1256 {
1257 va_list parms;
1258 char buffer[WRITE_LOG_BUF_SIZE];
1259 DWORD temp;
1260
1261 va_start (parms, format);
1262 _vsnprintf( buffer, WRITE_LOG_BUF_SIZE-1, format, parms );
1263 va_end (parms);
1264 openconsole();
1265 WriteConsole(stdoutput,buffer,strlen(buffer),&temp,0);
1266 }
1267
console_get(char * out,int maxlen)1268 int console_get (char *out, int maxlen)
1269 {
1270 DWORD len,totallen;
1271
1272 totallen=0;
1273 while(maxlen>0)
1274 {
1275 ReadConsole(stdinput,out,1,&len,0);
1276 if(*out == 13) break;
1277 out++;
1278 maxlen--;
1279 totallen++;
1280 }
1281 *out=0;
1282 return totallen;
1283 }
1284
console_flush(void)1285 void console_flush (void)
1286 {
1287 }
1288
1289 /* GCC/EGCS wants this write_log in order to work from socket-land and to do traces */
1290 #ifdef __GNUC__
write_log(const char * format,...)1291 void write_log (const char *format, ...)
1292 {
1293 int result = 0;
1294 DWORD numwritten;
1295 char buffer[12];
1296 va_list parms;
1297 int count = 0;
1298 int *blah = NULL;
1299
1300 if( debugfile )
1301 {
1302 #if defined HAVE_GETTICKCOUNT && defined TIMESTAMP_LOGS
1303 {
1304 sprintf( buffer, "%7d - ", GetTickCount() );
1305 fprintf( debugfile, buffer );
1306 }
1307 #endif
1308 va_start (parms, format);
1309 count = vfprintf( debugfile, format, parms );
1310 fflush( debugfile );
1311 if( count >= WRITE_LOG_BUF_SIZE-1 )
1312 {
1313 fprintf( debugfile, "SHIT in write_log ()\n" );
1314 fflush( debugfile );
1315 *blah = 0; /* Access Violation here! */
1316 abort();
1317 }
1318 else
1319 result = count;
1320 va_end (parms);
1321 }
1322 }
1323 #else /* MSVC likes this one, and so do I */
write_log(const char * format,...)1324 int write_log ( const char *format, ... )
1325 {
1326 int result = 0;
1327 #ifdef _DEBUG
1328 DWORD numwritten;
1329 #endif
1330 char buffer[ WRITE_LOG_BUF_SIZE ];
1331 va_list parms;
1332 int count = 0;
1333 int *blah = (int *)0xdeadbeef;
1334
1335 va_start (parms, format);
1336 count = _vsnprintf( buffer, WRITE_LOG_BUF_SIZE-1, format, parms );
1337 #if defined HAVE_GETTICKCOUNT && defined TIMESTAMP_LOGS
1338 {
1339 char buffme[WRITE_LOG_BUF_SIZE];
1340 sprintf( buffme, "%7d - %s", GetTickCount(), buffer );
1341 OutputDebugString( buffme );
1342 if( debugfile )
1343 fprintf( debugfile, buffme );
1344 result = strlen( buffme );
1345 }
1346 #else
1347 OutputDebugString( buffer );
1348 if( debugfile )
1349 {
1350 fprintf( debugfile, buffer );
1351 fflush( debugfile );
1352 }
1353 result = strlen( buffer );
1354 #endif
1355 #ifdef _DEBUG
1356 openconsole();
1357 WriteConsole(stdoutput,buffer,strlen(buffer),&numwritten,0);
1358 #endif
1359 va_end (parms);
1360 return result;
1361 }
1362 #endif
1363
debuggable(void)1364 int debuggable (void)
1365 {
1366 return 0;
1367 }
1368
needmousehack(void)1369 int needmousehack (void)
1370 {
1371 if( WIN32GFX_IsFullScreen() || WIN32GFX_IsPicassoScreen() )
1372 return 0;
1373 else
1374 return 1;
1375 }
1376
LED(int a)1377 void LED (int a)
1378 {
1379 }
1380
logging_init(void)1381 void logging_init( void )
1382 {
1383 char debugfilename[MAX_PATH];
1384 if (1) {
1385 sprintf( debugfilename, "%s\\winuaelog.txt", start_path );
1386 if( !debugfile )
1387 debugfile = fopen( debugfilename, "wt" );
1388 }
1389 write_log ( "%s\n", VersionStr );
1390 write_log ("\n(c) 1995-2001 Bernd Schmidt - Core UAE concept and implementation."
1391 "\n(c) 1996-1999 Mathias Ortmann - Win32 port and bsdsocket support."
1392 "\n(c) 1996-2001 Brian King - Win32 port, Picasso96 RTG, and GUI."
1393 "\n(c) 1998-2001 Toni Wilen - AGA chipset, NTSC/PAL modes.\n"
1394 "\n(c) 2000-2001 Bernd Meyer - JIT engine.\n"
1395 "\n(c) 2000-2001 Bernd Roesch - MIDI input, many fixes.\n"
1396 "\nPress F12 to show the Settings Dialog (GUI), Alt-F4 to quit."
1397 "\nEnd+F1 changes floppy 0, End+F2 changes floppy 1, etc.\n"
1398 "\nhttp://www.codepoet.com/UAE/\n\n");
1399 }
1400
logging_cleanup(void)1401 void logging_cleanup( void )
1402 {
1403 if( debugfile )
1404 fclose( debugfile );
1405 }
1406
1407 static const char *sound_styles[] = { "waveout_looping", "waveout_dblbuff", "dsound_looping", "dsound_dblbuff", 0 };
1408
target_save_options(FILE * f,struct uae_prefs * p)1409 void target_save_options (FILE *f, struct uae_prefs *p)
1410 {
1411 fprintf (f, "win32.middle_mouse=%s\n", p->win32_middle_mouse ? "true" : "false");
1412 fprintf (f, "win32.logfile=%s\n", p->win32_logfile ? "true" : "false");
1413 fprintf (f, "win32.map_drives=%s\n", p->win32_automount_drives ? "true" : "false" );
1414 fprintf (f, "win32.serial_port=%s\n", p->use_serial ? p->sername : "none" );
1415 fprintf (f, "win32.parallel_port=%s\n", p->prtname[0] ? p->prtname : "none" );
1416 fprintf (f, "win32.iconified_nospeed=%s\n", p->win32_iconified_nospeed ? "true" : "false");
1417 fprintf (f, "win32.iconified_nosound=%s\n", p->win32_iconified_nosound ? "true" : "false");
1418 fprintf (f, "win32.no_overlay=%s\n", p->win32_no_overlay ? "true" : "false" );
1419 }
1420
target_parse_option(struct uae_prefs * p,char * option,char * value)1421 int target_parse_option (struct uae_prefs *p, char *option, char *value)
1422 {
1423 int result = (cfgfile_yesno (option, value, "middle_mouse", &p->win32_middle_mouse)
1424 || cfgfile_yesno (option, value, "logfile", &p->win32_logfile)
1425 || cfgfile_yesno (option, value, "no_overlay", &p->win32_no_overlay)
1426 || cfgfile_yesno (option, value, "map_drives", &p->automount_drives)
1427 || cfgfile_yesno (option, value, "iconified_nospeed", &p->win32_iconified_nospeed)
1428 || cfgfile_yesno (option, value, "iconified_nosound", &p->win32_iconified_nosound)
1429 || cfgfile_string (option, value, "serial_port", &p->sername[0], 256)
1430 || cfgfile_string (option, value, "parallel_port", &p->prtname[0], 256));
1431
1432 if (p->sername[0] == 'n')
1433 p->use_serial = 0;
1434 else
1435 p->use_serial = 1;
1436
1437 return 0;
1438 }
1439
WIN32_HandleRegistryStuff(void)1440 void WIN32_HandleRegistryStuff( void )
1441 {
1442 RGBFTYPE colortype = RGBFB_NONE;
1443 DWORD dwType = REG_DWORD;
1444 DWORD dwDisplayInfoSize = sizeof( colortype );
1445 DWORD disposition;
1446 char path[MAX_PATH] = "";
1447 HKEY hWinUAEKeyLocal = NULL;
1448
1449 /* Create/Open the hWinUAEKey which points to our config-info */
1450 if( RegCreateKeyEx( HKEY_CLASSES_ROOT, ".uae", 0, "", REG_OPTION_NON_VOLATILE,
1451 KEY_ALL_ACCESS, NULL, &hWinUAEKey, &disposition ) == ERROR_SUCCESS )
1452 {
1453 // Regardless of opening the existing key, or creating a new key, we will write the .uae filename-extension
1454 // commands in. This way, we're always up to date.
1455
1456 /* Set our (default) sub-key to point to the "WinUAE" key, which we then create */
1457 RegSetValueEx( hWinUAEKey, "", 0, REG_SZ, (CONST BYTE *)"WinUAE", strlen( "WinUAE" ) + 1 );
1458
1459 if( ( RegCreateKeyEx( HKEY_CLASSES_ROOT, "WinUAE\\shell\\Edit\\command", 0, "", REG_OPTION_NON_VOLATILE,
1460 KEY_ALL_ACCESS, NULL, &hWinUAEKeyLocal, &disposition ) == ERROR_SUCCESS ) )
1461 {
1462 /* Set our (default) sub-key to BE the "WinUAE" command for editing a configuration */
1463 sprintf( path, "%s\\WinUAE.exe -f \"%%1\" -s use_gui=yes", start_path );
1464 RegSetValueEx( hWinUAEKeyLocal, "", 0, REG_SZ, (CONST BYTE *)path, strlen( path ) + 1 );
1465 }
1466 RegCloseKey( hWinUAEKeyLocal );
1467
1468 if( ( RegCreateKeyEx( HKEY_CLASSES_ROOT, "WinUAE\\shell\\Open\\command", 0, "", REG_OPTION_NON_VOLATILE,
1469 KEY_ALL_ACCESS, NULL, &hWinUAEKeyLocal, &disposition ) == ERROR_SUCCESS ) )
1470 {
1471 /* Set our (default) sub-key to BE the "WinUAE" command for launching a configuration */
1472 sprintf( path, "%s\\WinUAE.exe -f \"%%1\"", start_path );
1473 RegSetValueEx( hWinUAEKeyLocal, "", 0, REG_SZ, (CONST BYTE *)path, strlen( path ) + 1 );
1474 }
1475 RegCloseKey( hWinUAEKeyLocal );
1476 }
1477 else
1478 {
1479 char szMessage[ MAX_PATH ];
1480 WIN32GUI_LoadUIString( IDS_REGKEYCREATEFAILED, szMessage, MAX_PATH );
1481 gui_message( szMessage );
1482 hWinUAEKey = NULL;
1483 }
1484 RegCloseKey( hWinUAEKey );
1485
1486 /* Create/Open the hWinUAEKey which points our config-info */
1487 if( RegCreateKeyEx( HKEY_CURRENT_USER, "Software\\CodePoet Computing\\WinUAE", 0, "", REG_OPTION_NON_VOLATILE,
1488 KEY_ALL_ACCESS, NULL, &hWinUAEKey, &disposition ) == ERROR_SUCCESS )
1489 {
1490 if( disposition == REG_CREATED_NEW_KEY )
1491 {
1492 /* Create and initialize all our sub-keys to the default values */
1493 colortype = 0;
1494 RegSetValueEx( hWinUAEKey, "DisplayInfo", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
1495 RegSetValueEx( hWinUAEKey, "xPos", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
1496 RegSetValueEx( hWinUAEKey, "yPos", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
1497 RegSetValueEx( hWinUAEKey, "FloppyPath", 0, REG_SZ, (CONST BYTE *)start_path, strlen( start_path ) + 1 );
1498 RegSetValueEx( hWinUAEKey, "KickstartPath", 0, REG_SZ, (CONST BYTE *)start_path, strlen( start_path ) + 1 );
1499 RegSetValueEx( hWinUAEKey, "hdfPath", 0, REG_SZ, (CONST BYTE *)start_path, strlen( start_path ) + 1 );
1500 }
1501 // Set this even when we're opening an existing key, so that the version info is always up to date.
1502 RegSetValueEx( hWinUAEKey, "Version", 0, REG_SZ, (CONST BYTE *)VersionStr, strlen( VersionStr ) + 1 );
1503
1504 RegQueryValueEx( hWinUAEKey, "DisplayInfo", 0, &dwType, (LPBYTE)&colortype, &dwDisplayInfoSize );
1505 if( colortype == 0 ) /* No color information stored in the registry yet */
1506 {
1507 char szMessage[ 4096 ];
1508 char szTitle[ MAX_PATH ];
1509 WIN32GUI_LoadUIString( IDS_GFXCARDCHECK, szMessage, 4096 );
1510 WIN32GUI_LoadUIString( IDS_GFXCARDTITLE, szTitle, MAX_PATH );
1511
1512 if( MessageBox( NULL, szMessage, szTitle,
1513 MB_YESNO | MB_ICONWARNING | MB_TASKMODAL | MB_SETFOREGROUND ) == IDYES )
1514 {
1515 colortype = WIN32GFX_FigurePixelFormats(0);
1516 RegSetValueEx( hWinUAEKey, "DisplayInfo", 0, REG_DWORD, (CONST BYTE *)&colortype, sizeof( colortype ) );
1517 }
1518 }
1519 if( colortype )
1520 {
1521 /* Set the 16-bit pixel format for the appropriate modes */
1522 WIN32GFX_FigurePixelFormats( colortype );
1523 }
1524 }
1525 else
1526 {
1527 char szMessage[ MAX_PATH ];
1528 WIN32GUI_LoadUIString( IDS_REGKEYCREATEFAILED, szMessage, MAX_PATH );
1529 gui_message( szMessage );
1530 hWinUAEKey = NULL;
1531 }
1532 }
1533
machdep_init(void)1534 void machdep_init (void)
1535 {
1536 }
1537
1538 char *start_path = NULL;
1539 char help_file[ MAX_PATH ];
1540
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)1541 int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
1542 int nCmdShow)
1543 {
1544 char *posn;
1545 HANDLE hMutex;
1546 OSVERSIONINFO osVersion;
1547
1548 #ifdef __GNUC__
1549 __asm__ ("leal -2300*1024(%%esp),%0" : "=r" (win32_stackbase) :);
1550 #else
1551 __asm{
1552 mov eax,esp
1553 sub eax,2300*1024
1554 mov win32_stackbase,eax
1555 }
1556 #endif
1557
1558 hInst = hInstance;
1559 hMutex = CreateMutex( NULL, FALSE, "WinUAE Instantiated" ); // To tell the installer we're running
1560
1561 osVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
1562 if( GetVersionEx( &osVersion ) )
1563 {
1564 if( ( osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT ) &&
1565 ( osVersion.dwMajorVersion <= 4 ) )
1566 {
1567 /* WinUAE not supported on this version of Windows... */
1568 char szWrongOSVersion[ MAX_PATH ];
1569 WIN32GUI_LoadUIString( IDS_WRONGOSVERSION, szWrongOSVersion, MAX_PATH );
1570 gui_message( szWrongOSVersion );
1571 return FALSE;
1572 }
1573 }
1574
1575 /* Get our executable's root-path */
1576 if( ( start_path = xmalloc( MAX_PATH ) ) )
1577 {
1578 GetModuleFileName( NULL, start_path, MAX_PATH );
1579 if( ( posn = strrchr( start_path, '\\' ) ) )
1580 *posn = 0;
1581 sprintf( help_file, "%s\\WinUAE.chm", start_path );
1582
1583 sprintf( VersionStr, "WinUAE %d.%d.%d, Release %d%s", UAEMAJOR, UAEMINOR, UAESUBREV, WINUAERELEASE, WINUAEBETA ? WINUAEBETASTR : "" );
1584
1585 logging_init ();
1586 printf ("Hello, world\n");
1587
1588 if( WIN32_RegisterClasses() && WIN32_InitLibraries() && DirectDraw_Start() )
1589 {
1590 struct foo {
1591 DEVMODE actual_devmode;
1592 char overrun[8];
1593 } devmode;
1594
1595 DWORD i = 0;
1596
1597 DirectDraw_EnumDisplayModes( 0, modesCallback );
1598
1599 memset( &devmode, 0, sizeof(DEVMODE) + 8 );
1600 devmode.actual_devmode.dmSize = sizeof(DEVMODE);
1601 devmode.actual_devmode.dmDriverExtra = 8;
1602 #define ENUM_CURRENT_SETTINGS ((DWORD)-1)
1603 if( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, (LPDEVMODE)&devmode ) )
1604 {
1605 default_freq = devmode.actual_devmode.dmDisplayFrequency;
1606 write_log ( "Your Windows desktop refresh frequency is %d Hz\n", default_freq );
1607 if( default_freq >= 70 )
1608 default_freq = 70;
1609 else
1610 default_freq = 60;
1611 }
1612
1613 WIN32_HandleRegistryStuff();
1614 if( WIN32_InitHtmlHelp() == 0 )
1615 {
1616 char szMessage[ MAX_PATH ];
1617 WIN32GUI_LoadUIString( IDS_NOHELP, szMessage, MAX_PATH );
1618 write_log ( szMessage );
1619 }
1620
1621 DirectDraw_Release();
1622 #ifdef __MINGW32__
1623 real_main (_argc, _argv);
1624 #else
1625 real_main (__argc, __argv);
1626 #endif
1627 }
1628 free( start_path );
1629 }
1630
1631 WIN32_CleanupLibraries();
1632 _fcloseall();
1633 if( hWinUAEKey )
1634 RegCloseKey( hWinUAEKey );
1635 CloseHandle( hMutex );
1636 return FALSE;
1637 }
1638
1639