|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Win32 interface
5: *
1.1.1.4 root 6: * Copyright 1997-1998 Mathias Ortmann
7: * Copyright 1997-1999 Brian King
1.1 root 8: */
9:
1.1.1.4 root 10: /* Uncomment this line if you want the logs time-stamped */
11: /* #define TIMESTAMP_LOGS */
12:
1.1.1.2 root 13: #include "sysconfig.h"
14:
1.1 root 15: #include <stdlib.h>
16: #include <stdarg.h>
1.1.1.2 root 17: #include <signal.h>
18:
19: #include <windows.h>
1.1 root 20: #include <commctrl.h>
21: #include <commdlg.h>
1.1.1.4 root 22: #include <shellapi.h>
23: #include <zmouse.h>
24: #include <ddraw.h>
25: #include <dbt.h>
26: #include <math.h>
1.1 root 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"
1.1.1.4 root 38: #include "keybuf.h"
39: #include "drawing.h"
1.1 root 40: #include "picasso96.h"
1.1.1.4 root 41: #include "bsdsocket.h"
1.1.1.2 root 42: #include "osdep/win32.h"
1.1.1.4 root 43: #include "osdep/win32gfx.h"
1.1 root 44: #include "osdep/win32gui.h"
1.1.1.4 root 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
1.1 root 53:
1.1.1.4 root 54: /* Comment out the following line if you don't want ZLIB.DLL support */
55: #undef USE_ZLIB_DLL
1.1.1.2 root 56:
1.1.1.4 root 57: #ifdef USE_ZLIB_DLL
58: #include "zlib.h"
59: #endif
1.1.1.2 root 60:
1.1.1.4 root 61: int useqpc = 0; /* Set to TRUE to use the QueryPerformanceCounter() function instead of rdtsc() */
1.1.1.2 root 62:
1.1.1.4 root 63: static FILE *debugfile = NULL;
1.1 root 64:
1.1.1.4 root 65: HINSTANCE hInst = NULL;
66: HMODULE hUIDLL = NULL;
1.1 root 67:
1.1.1.4 root 68: HWND (WINAPI *pHtmlHelp)(HWND, LPCSTR, UINT, LPDWORD ) = NULL;
1.1 root 69:
1.1.1.4 root 70: HWND hAmigaWnd, hMainWnd;
71: /*DWORD Keys; */
72: RECT amigawin_rect;
1.1 root 73:
1.1.1.2 root 74: char VersionStr[256];
1.1 root 75:
1.1.1.4 root 76: int in_sizemove = 0;
77: int manual_painting_needed = 0;
1.1.1.2 root 78: int customsize = 0;
1.1 root 79:
80: int bActive;
81: int toggle_sound;
82:
83: BOOL viewing_child = FALSE;
84:
1.1.1.4 root 85: HKEY hWinUAEKey = NULL;
86: COLORREF g_dwBackgroundColor = RGB(10, 0, 10);
1.1 root 87:
88: /* Keyboard emulation, Win32 helper routines. */
89: static LPARAM keysdown[256];
90: static short numkeysdown;
91: int checkkey (int vkey, LPARAM lParam)
92: {
93: switch (vkey) {
1.1.1.4 root 94: case VK_LWIN:
95: case VK_RWIN:
1.1.1.2 root 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:
1.1 root 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:
1.1.1.4 root 115: void WIN32_MouseDefaults( void )
116: {
117: mousecx = 160, mousecy = 100, mousedx = 160, mousedy = 100, mousecl = MAKELONG (160, 100);
118: }
119:
1.1 root 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:
1.1.1.4 root 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]");
1.1 root 142: ClipCursor (&amigawin_rect);
1.1.1.4 root 143: }
144: else
145: {
1.1 root 146: ShowCursor (TRUE);
1.1.1.4 root 147: SetWindowText (hMainWnd ? hMainWnd : hAmigaWnd, "UAE/Win32" );
1.1 root 148: ClipCursor (NULL);
149: }
150: }
151:
152: static int hascapture = 0;
153:
1.1.1.2 root 154: static void setcapture (void)
1.1 root 155: {
156: if (hascapture)
157: return;
158: hascapture++;
159: SetCapture (hAmigaWnd);
160: }
161:
1.1.1.4 root 162: void releasecapture (void)
1.1 root 163: {
164: if (!hascapture)
165: return;
166: hascapture--;
167: ReleaseCapture ();
168: }
169:
1.1.1.4 root 170: frame_time_t read_processor_time_cyrix (void)
1.1.1.2 root 171: {
1.1.1.4 root 172: LARGE_INTEGER counter;
173: QueryPerformanceCounter( &counter );
174: return (frame_time_t)(counter.LowPart);
1.1.1.2 root 175: }
176:
1.1.1.4 root 177: #include <setjmp.h>
178: jmp_buf catch_test;
179:
180: static RETSIGTYPE illhandler(int foo)
1.1 root 181: {
1.1.1.4 root 182: rpt_available = 0;
183: longjmp(catch_test,1);
184: }
1.1 root 185:
1.1.1.4 root 186: int have_rdtsc (void)
187: {
1.1.1.2 root 188: rpt_available = 1;
1.1.1.4 root 189: write_log ("Testing the RDTSC instruction ... ");
1.1.1.2 root 190: signal (SIGILL, illhandler);
1.1.1.4 root 191: if (setjmp (catch_test) == 0)
192: read_processor_time ();
1.1.1.2 root 193: signal (SIGILL, SIG_DFL);
1.1.1.4 root 194: write_log ("done.\n");
1.1.1.2 root 195: if (! rpt_available) {
1.1.1.4 root 196: write_log ("Your processor does not support the RDTSC instruction.\n");
1.1 root 197: return 0;
198: }
199: return 1;
200: }
201:
1.1.1.4 root 202: static void figure_processor_speed (void)
1.1 root 203: {
1.1.1.4 root 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;
1.1.1.2 root 211: #else
1.1.1.4 root 212: LARGE_INTEGER freq;
1.1.1.2 root 213:
1.1.1.4 root 214: __try
215: {
216: __asm{rdtsc};
1.1.1.2 root 217: }
1.1.1.4 root 218: __except( GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION )
219: {
220: useqpc = 1;
1.1.1.2 root 221: }
1.1.1.4 root 222: if( QueryPerformanceFrequency( &freq ) )
223: {
224: if (freq.LowPart > 90000000) /* looks like CPU freq. */
1.1.1.7 ! root 225: write_log ( "CLOCKFREQ: QueryPerformanceFrequency() reports %d-MHz\n", freq.LowPart / 1000000 );
1.1.1.4 root 226: else
1.1.1.7 ! root 227: write_log ( "CLOCKFREQ: QueryPerformanceFrequency() reports %.2f-MHz\n", (float)freq.LowPart / 1000000.0f );
1.1 root 228:
1.1.1.4 root 229: if( freq.LowPart < 1000000 )
230: {
1.1.1.7 ! root 231: write_log ( "CLOCKFREQ: Weird value. Using QueryPerformanceCounter() instead of RDTSC.\n" );
1.1.1.4 root 232: useqpc = 1;
1.1 root 233: }
1.1.1.4 root 234: rpt_available = 1;
1.1.1.2 root 235: }
1.1.1.4 root 236: else
237: {
1.1.1.7 ! root 238: write_log ( "CLOCKFREQ: No support for clock-rate stuff!\n" );
1.1.1.4 root 239: rpt_available = 0;
1.1 root 240: }
1.1.1.4 root 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:
1.1.1.7 ! root 248: write_log ( "CLOCKFREQ: Measured as %d-MHz\n", clockrate / 1000000 );
1.1.1.4 root 249: syncbase = clockrate;
250: vsynctime = syncbase / VBLANK_HZ_PAL; /* default to 50Hz */
1.1 root 251: }
252:
1.1.1.4 root 253: static BOOL bDiskChanged = FALSE;
1.1 root 254:
1.1.1.2 root 255: static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1 root 256: {
257: PAINTSTRUCT ps;
258: HDC hDC;
1.1.1.4 root 259: short wheeldelta;
260: static int store_xy = 0;
261: BOOL minimized;
262: LPMINMAXINFO lpmmi;
263: RECT rect;
1.1 root 264:
1.1.1.4 root 265: switch( message )
266: {
1.1.1.6 root 267: case WM_PALETTECHANGED:
268: if( (HWND)wParam != hWnd )
269: {
1.1.1.7 ! root 270: write_log ( "WM_PALETTECHANGED Request\n" );
1.1.1.6 root 271: WIN32GFX_PaletteChange();
272: }
273: break;
274: case WM_ACTIVATEAPP:
275: if (bActive = wParam)
276: {
1.1.1.4 root 277: if( WIN32GFX_IsFullScreen() )
1.1.1.6 root 278: {
1.1.1.4 root 279: SetCursor (NULL);
280: #ifndef HARDWARE_SPRITE_EMULATION
281: SetCursorPos (mousecx, mousecy);
282: #else
283: if( !WIN32GFX_IsPicassoScreen() )
284: SetCursorPos (mousecx, mousecy);
285: #endif
1.1.1.6 root 286: }
287: my_kbd_handler (VK_CAPITAL, 0x3a, TRUE);
1.1 root 288: }
1.1.1.6 root 289: else
290: {
291: if( !WIN32GFX_IsFullScreen() )
1.1.1.4 root 292: setmouseactive (0);
1.1.1.6 root 293: else
294: {
295: if( WIN32GFX_IsPicassoScreen() )
296: {
297: WIN32GFX_DisablePicasso();
298: }
299: }
300: }
1.1.1.4 root 301: break;
1.1.1.6 root 302: case WM_ACTIVATE:
303: minimized = HIWORD( wParam );
304: if (LOWORD (wParam) != WA_INACTIVE)
305: {
1.1.1.7 ! root 306: write_log ( "WinUAE now active via WM_ACTIVATE\n" );
1.1.1.6 root 307: if( !minimized )
308: {
309: if( currprefs.win32_iconified_nospeed )
1.1.1.5 root 310: {
311: SetPriorityClass( GetCurrentProcess(), NORMAL_PRIORITY_CLASS );
312: }
1.1.1.6 root 313: if( currprefs.win32_iconified_nosound )
1.1.1.5 root 314: {
315: resume_sound();
316: }
317:
1.1.1.4 root 318: clear_inhibit_frame( IHF_WINDOWHIDDEN );
1.1.1.6 root 319: }
320: ShowWindow (hWnd, SW_RESTORE);
321: if( WIN32GFX_IsPicassoScreen() )
322: {
323: WIN32GFX_EnablePicasso();
324: }
1.1.1.4 root 325: }
1.1.1.6 root 326: else
327: {
1.1.1.7 ! root 328: write_log ( "WinUAE now inactive via WM_ACTIVATE\n" );
1.1.1.6 root 329: if( minimized && !quit_program )
330: {
331: if( currprefs.win32_iconified_nospeed )
1.1.1.5 root 332: {
333: SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
334: }
1.1.1.6 root 335: if( currprefs.win32_iconified_nosound )
1.1.1.5 root 336: {
337: pause_sound ();
338: }
1.1.1.4 root 339: set_inhibit_frame( IHF_WINDOWHIDDEN );
1.1.1.6 root 340: }
341: }
1.1.1.4 root 342: break;
1.1 root 343:
1.1.1.6 root 344: case WM_SETCURSOR:
345: if( WIN32GFX_IsFullScreen() )
346: {
1.1.1.4 root 347: #ifdef HARDWARE_SPRITE_EMULATION
348: if( !WIN32GFX_IsPicassoScreen() )
349: #endif
1.1.1.6 root 350: SetCursor (NULL);
351: return TRUE;
352: }
1.1.1.4 root 353: break;
1.1 root 354:
1.1.1.6 root 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: }
1.1.1.4 root 366: break;
1.1 root 367:
1.1.1.6 root 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;
1.1 root 375:
1.1.1.2 root 376: case WM_KEYDOWN:
377: case WM_SYSKEYDOWN:
1.1.1.4 root 378: if (LOWORD (lParam) == 1)
379: {
380: if (numkeysdown)
1.1.1.6 root 381: {
1.1.1.4 root 382: int key;
383: numkeysdown = 0;
384:
385: for (key = 256; key--;)
1.1.1.6 root 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: }
1.1 root 397: }
398: }
1.1.1.4 root 399: if (!keysdown[wParam])
1.1.1.6 root 400: {
1.1.1.4 root 401: keysdown[wParam] = lParam;
402: numkeysdown++;
1.1 root 403: }
404: numkeysdown++;
405: my_kbd_handler (wParam, (lParam >> 16) & 0x1ff, TRUE);
406: }
407: break;
408:
1.1.1.4 root 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.
1.1.1.2 root 413: case WM_LBUTTONDOWN:
1.1 root 414: if (ievent_alive) {
415: setcapture ();
416: buttonstate[0] = 1;
1.1.1.4 root 417: } else if (!WIN32GFX_IsFullScreen() && !mouseactive)
1.1 root 418: setmouseactive (1);
419: else
420: buttonstate[0] = 1;
421: break;
422:
1.1.1.2 root 423: case WM_LBUTTONUP:
1.1 root 424: releasecapture ();
425: buttonstate[0] = 0;
426: break;
427:
1.1.1.4 root 428:
1.1.1.2 root 429: case WM_MBUTTONDOWN:
1.1 root 430: if (ievent_alive)
431: setcapture ();
432: buttonstate[1] = 1;
433: break;
434:
1.1.1.2 root 435: case WM_MBUTTONUP:
1.1 root 436: releasecapture ();
437: buttonstate[1] = 0;
438: break;
439:
1.1.1.2 root 440: case WM_RBUTTONDOWN:
1.1 root 441: if (ievent_alive)
442: setcapture ();
443: buttonstate[2] = 1;
444: break;
445:
1.1.1.2 root 446: case WM_RBUTTONUP:
1.1 root 447: releasecapture ();
448: buttonstate[2] = 0;
449: break;
450:
1.1.1.4 root 451: case WM_VSCROLL:
1.1.1.7 ! root 452: write_log ( "WM_VSCROLL\n" );
1.1.1.6 root 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;
1.1.1.4 root 458:
459: case WM_MOUSEWHEEL:
1.1.1.6 root 460: wheeldelta = HIWORD(wParam);
1.1.1.7 ! root 461: write_log ( "WM_MOUSEWHEEL with delta %d\n", wheeldelta );
1.1.1.6 root 462: if( wheeldelta > 0 )
463: record_key(0x7A<<1);
464: else if( wheeldelta < 0 )
465: record_key(0x7B<<1);
466: break;
1.1 root 467:
1.1.1.4 root 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;
1.1 root 500: }
501: lastmx = (signed short) LOWORD (lParam);
502: lastmy = (signed short) HIWORD (lParam);
1.1.1.4 root 503: break;
1.1 root 504:
1.1.1.2 root 505: case WM_PAINT:
506: notice_screen_contents_lost ();
1.1.1.4 root 507:
1.1.1.6 root 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: {
1.1.1.4 root 515: if( DirectDraw_GetLockableType() != overlay_surface )
516: DX_Blit( 0, 0, 0, 0, WIN32GFX_GetWidth(), WIN32GFX_GetHeight(), BLIT_SRC );
1.1.1.6 root 517: }
518: else
519: {
520: DirectDraw_Blt( primary_surface, NULL, secondary_surface, NULL, DDBLT_WAIT, NULL );
521: }
522: }
1.1.1.4 root 523: EndPaint (hWnd, &ps);
524:
1.1 root 525: break;
526:
1.1.1.2 root 527: case WM_DROPFILES:
1.1 root 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:
1.1.1.2 root 535: case WM_CAPTURECHANGED:
536: if ((HWND)lParam != hAmigaWnd)
1.1 root 537: buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
538: break;
539:
1.1.1.2 root 540: case WM_TIMER:
541: finishjob ();
1.1 root 542: break;
543:
1.1.1.2 root 544: case WM_CREATE:
1.1 root 545: DragAcceptFiles (hWnd, TRUE);
546: break;
547:
1.1.1.2 root 548: case WM_CLOSE:
549: uae_quit ();
550: return 0;
551:
552: case WM_WINDOWPOSCHANGED:
1.1.1.4 root 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: }
1.1 root 564: break;
1.1.1.4 root 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
1.1.1.7 ! root 595: write_log ( "sockmsg(0x%x, 0x%x, 0x%x)\n", message, wParam, lParam );
1.1.1.4 root 596: #endif
1.1.1.6 root 597: sockmsg( message, wParam, lParam );
598: return 0;
1.1.1.4 root 599: }
600: #endif
601: #endif
602: break;
1.1 root 603: }
604:
605: return DefWindowProc (hWnd, message, wParam, lParam);
606: }
607:
1.1.1.2 root 608: static long FAR PASCAL MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1 root 609: {
610: PAINTSTRUCT ps;
1.1.1.2 root 611: RECT rc;
1.1 root 612: HDC hDC;
613:
614: switch (message) {
615: case WM_LBUTTONDOWN:
1.1.1.4 root 616: case WM_MOUSEWHEEL:
1.1 root 617: case WM_MOUSEMOVE:
618: case WM_ACTIVATEAPP:
1.1.1.4 root 619: case WM_DROPFILES:
1.1 root 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:
1.1.1.4 root 632: case WM_MOVING:
633: case WM_MOVE:
634: case WM_SIZING:
635: case WM_SIZE:
636: case WM_GETMINMAXINFO:
1.1 root 637: case WM_CREATE:
638: case WM_DESTROY:
639: case WM_USER + 0x200:
1.1.1.2 root 640: case WM_CLOSE:
1.1.1.4 root 641: case WM_HELP:
642: case WM_DEVICECHANGE:
1.1 root 643: return AmigaWindowProc (hWnd, message, wParam, lParam);
644:
645: case WM_DISPLAYCHANGE:
1.1.1.4 root 646: if (!WIN32GFX_IsFullScreen && (wParam + 7) / 8 != DirectDraw_GetBytesPerPixel() )
647: WIN32GFX_DisplayChangeRequested();
1.1 root 648: break;
1.1.1.4 root 649:
1.1 root 650: case WM_ENTERSIZEMOVE:
1.1.1.2 root 651: in_sizemove++;
1.1 root 652: break;
653:
654: case WM_EXITSIZEMOVE:
1.1.1.2 root 655: in_sizemove--;
1.1 root 656: /* fall through */
657:
658: case WM_WINDOWPOSCHANGED:
1.1.1.4 root 659: WIN32GFX_WindowMove();
660: if( hAmigaWnd && GetWindowRect (hAmigaWnd, &amigawin_rect) )
661: {
662: if (in_sizemove > 0)
663: break;
1.1.1.2 root 664:
1.1.1.4 root 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: }
1.1 root 675: }
1.1.1.4 root 676: //setmouseactive (0);
677: return 0;
1.1 root 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) {
1.1.1.4 root 690: WIN32GFX_ToggleFullScreen();
1.1 root 691: return 0;
692: }
1.1.1.2 root 693: break;
1.1.1.4 root 694: default:
695: break;
696:
1.1 root 697: }
698:
699: return DefWindowProc (hWnd, message, wParam, lParam);
700: }
701:
1.1.1.4 root 702: void handle_events (void)
1.1 root 703: {
1.1.1.4 root 704: MSG msg;
1.1 root 705:
1.1.1.4 root 706: while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
707: TranslateMessage (&msg);
708: DispatchMessage (&msg);
1.1 root 709: }
710: }
711:
1.1.1.4 root 712: /* Console Win32 helper routines */
713: void activate_debugger ();
714:
715: /* We're not a console-app anymore! */
1.1 root 716: void setup_brkhandler (void)
717: {
718: }
719:
720: void remove_brkhandler (void)
721: {
722: }
723:
1.1.1.4 root 724: int WIN32_RegisterClasses( void )
1.1 root 725: {
726: WNDCLASS wc;
1.1.1.4 root 727: HDC hDC = GetDC( NULL );
728:
729: if( GetDeviceCaps( hDC, NUMCOLORS ) != -1 )
1.1.1.6 root 730: g_dwBackgroundColor = RGB( 255, 0, 255 );
1.1.1.4 root 731: ReleaseDC( NULL, hDC );
1.1 root 732:
1.1.1.4 root 733: wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS;
1.1 root 734: wc.lpfnWndProc = AmigaWindowProc;
735: wc.cbClsExtra = 0;
736: wc.cbWndExtra = 0;
737: wc.hInstance = 0;
1.1.1.4 root 738: wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE( IDI_APPICON ) );
1.1 root 739: wc.hCursor = LoadCursor (NULL, IDC_ARROW);
1.1.1.2 root 740: wc.lpszMenuName = 0;
1.1 root 741: wc.lpszClassName = "AmigaPowah";
1.1.1.4 root 742: wc.hbrBackground = CreateSolidBrush( g_dwBackgroundColor );
1.1 root 743: if (!RegisterClass (&wc))
744: return 0;
745:
1.1.1.4 root 746: wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
1.1 root 747: wc.lpfnWndProc = MainWindowProc;
748: wc.cbClsExtra = 0;
749: wc.cbWndExtra = 0;
750: wc.hInstance = 0;
1.1.1.4 root 751: wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE( IDI_APPICON ) );
1.1 root 752: wc.hCursor = LoadCursor (NULL, IDC_ARROW);
1.1.1.4 root 753: wc.hbrBackground = CreateSolidBrush( g_dwBackgroundColor );
1.1.1.2 root 754: wc.lpszMenuName = 0;
1.1 root 755: wc.lpszClassName = "PCsuxRox";
756: if (!RegisterClass (&wc))
757: return 0;
758: return 1;
759: }
760:
1.1.1.4 root 761: #ifdef __GNUC__
762: #undef WINAPI
763: #define WINAPI
764: #endif
1.1.1.2 root 765:
1.1.1.4 root 766: static HINSTANCE hRichEdit = NULL, hHtmlHelp = NULL;
1.1 root 767:
1.1.1.4 root 768: #ifdef USE_ZLIB_DLL
769: static HINSTANCE hZlib = NULL;
770: FARPROC pgzread = NULL, pgzopen = NULL, pgzclose = NULL, pgzwrite = NULL, pgzerror = NULL;
771: #endif
1.1.1.2 root 772:
1.1.1.4 root 773: int WIN32_CleanupLibraries( void )
1.1.1.2 root 774: {
1.1.1.4 root 775: if (hRichEdit)
776: FreeLibrary (hRichEdit);
777:
778: if( hHtmlHelp )
1.1.1.6 root 779: FreeLibrary( hHtmlHelp );
1.1.1.2 root 780:
1.1.1.4 root 781: if( hUIDLL )
782: FreeLibrary( hUIDLL );
1.1.1.2 root 783:
1.1.1.4 root 784: #ifdef USE_ZLIB_DLL
785: if( hZlib )
786: FreeLibrary( hZlib );
787: #endif
1.1 root 788:
1.1.1.4 root 789: return 1;
790: }
1.1 root 791:
1.1.1.4 root 792: /* HtmlHelp Initialization - optional component */
793: int WIN32_InitHtmlHelp( void )
794: {
795: int result = 0;
796: if( hHtmlHelp = LoadLibrary( "HHCTRL.OCX" ) )
797: {
1.1.1.6 root 798: pHtmlHelp = ( HWND(WINAPI *)(HWND, LPCSTR, UINT, LPDWORD ) )GetProcAddress( hHtmlHelp, "HtmlHelpA" );
799: result = 1;
1.1 root 800: }
801:
802:
1.1.1.4 root 803: return result;
1.1 root 804: }
805:
1.1.1.4 root 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
1.1.1.2 root 812:
1.1.1.4 root 813: static HMODULE LoadGUI( void )
1.1 root 814: {
1.1.1.4 root 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
1.1 root 821:
1.1.1.4 root 822: switch( language )
823: {
824: case LANG_AFRIKAANS:
825: dllname = "WinUAE_Afrikaans.dll";
1.1 root 826: break;
1.1.1.4 root 827: case LANG_ARABIC:
828: dllname = "WinUAE_Arabic.dll";
1.1 root 829: break;
1.1.1.4 root 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";
1.1 root 1012: break;
1.1.1.4 root 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: }
1.1 root 1029:
1.1.1.4 root 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;
1.1 root 1073: }
1074: }
1075:
1.1.1.4 root 1076: return result;
1.1 root 1077: }
1078:
1.1.1.4 root 1079: #ifndef _WIN32_WCE
1080: /* try to load COMDLG32 and DDRAW, initialize csDraw */
1081: int WIN32_InitLibraries( void )
1.1 root 1082: {
1.1.1.4 root 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();
1.1 root 1093:
1.1.1.4 root 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;
1.1 root 1111: }
1.1.1.4 root 1112: #endif
1.1 root 1113:
1.1.1.4 root 1114: /* Mathias says: "this truly sucks, I'll include a native gunzip() routine soon" */
1.1 root 1115:
1.1.1.4 root 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 */
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;
1.1 root 1132:
1.1.1.4 root 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 );
1.1 root 1160: }
1.1.1.4 root 1161:
1162: if( fDst )
1.1 root 1163: {
1.1.1.4 root 1164: fclose( fDst );
1.1 root 1165: }
1166: }
1.1.1.4 root 1167: return result;
1.1 root 1168: }
1.1.1.4 root 1169: #endif
1.1 root 1170:
1.1.1.4 root 1171: static char *uncompress_error[2] = { "Error: You need zlib.dll to use .adz/.roz files!\n",
1.1.1.6 root 1172: "Error: You need xdms.exe (32 bit) to use .dms files!\n" };
1.1 root 1173:
1.1.1.4 root 1174: int uncompress_hack( int type, const char *src, const char *dst)
1.1 root 1175: {
1.1.1.4 root 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;
1.1 root 1183:
1.1.1.4 root 1184: strcpy( fullname, dst );
1.1 root 1185:
1.1.1.4 root 1186: if( type == 1 )
1187: {
1188: #ifdef USE_ZLIB_DLL
1189: result = zlib_gunzip( src, fullname );
1190: if( !result )
1191: {
1.1.1.6 root 1192: gui_message( uncompress_error[type-1] );
1.1.1.4 root 1193: }
1194: return result;
1195: #else
1.1.1.6 root 1196: strcpy( cmd, "gzip.exe -f -d" );
1197: strcat( fullname, ".gz" );
1.1.1.4 root 1198: #endif
1199: }
1200: else if( type == 2 )
1201: {
1.1.1.6 root 1202: strcpy( cmd, "xdms.exe u" );
1203: posn = strrchr( fullname, '.' );
1204: if( posn )
1205: {
1206: *posn = 0;
1207: strcat( fullname, ".dms" );
1208: }
1.1.1.4 root 1209: }
1.1 root 1210:
1.1.1.4 root 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 ) )
1.1.1.6 root 1216: {
1.1.1.4 root 1217: WaitForSingleObject( pi.hProcess, INFINITE );
1.1.1.6 root 1218: result = -1;
1219: }
1220: else
1221: {
1222: gui_message( uncompress_error[type-1] );
1223: }
1.1.1.4 root 1224: }
1.1 root 1225:
1.1.1.4 root 1226: /* Special handling for broken xdms.exe */
1227: if( type == 2 )
1228: {
1.1.1.6 root 1229: DeleteFile( fullname ); /* Delete the uaeXX.dms file */
1.1.1.2 root 1230: }
1.1 root 1231:
1.1.1.4 root 1232: return result;
1.1 root 1233: }
1234:
1.1.1.4 root 1235: /* console window for debugging messages */
1236: /* Brian: disable for release version if you want (TW) */
1.1 root 1237:
1.1.1.4 root 1238: #define WRITE_LOG_BUF_SIZE 4096
1239:
1240: static int consoleopen = 0;
1241: HANDLE stdinput,stdoutput;
1.1 root 1242:
1.1.1.4 root 1243: static void openconsole(void)
1.1 root 1244: {
1.1.1.4 root 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;
1.1 root 1251: }
1252:
1.1.1.4 root 1253: /* console functions for debugger */
1.1 root 1254:
1.1.1.4 root 1255: void console_out (const char *format,...)
1256: {
1257: va_list parms;
1258: char buffer[WRITE_LOG_BUF_SIZE];
1259: DWORD temp;
1.1 root 1260:
1.1.1.4 root 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);
1.1 root 1266: }
1267:
1.1.1.4 root 1268: int console_get (char *out, int maxlen)
1.1.1.2 root 1269: {
1.1.1.4 root 1270: DWORD len,totallen;
1.1 root 1271:
1.1.1.4 root 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++;
1.1 root 1280: }
1.1.1.4 root 1281: *out=0;
1282: return totallen;
1.1 root 1283: }
1.1.1.2 root 1284:
1.1.1.4 root 1285: void console_flush (void)
1.1.1.2 root 1286: {
1287: }
1.1 root 1288:
1.1.1.4 root 1289: /* GCC/EGCS wants this write_log in order to work from socket-land and to do traces */
1.1 root 1290: #ifdef __GNUC__
1.1.1.4 root 1291: void write_log (const char *format, ...)
1.1 root 1292: {
1.1.1.4 root 1293: int result = 0;
1294: DWORD numwritten;
1295: char buffer[12];
1296: va_list parms;
1297: int count = 0;
1298: int *blah = NULL;
1.1 root 1299:
1.1.1.4 root 1300: if( debugfile )
1301: {
1302: #if defined HAVE_GETTICKCOUNT && defined TIMESTAMP_LOGS
1.1.1.6 root 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: {
1.1.1.7 ! root 1313: fprintf( debugfile, "SHIT in write_log ()\n" );
1.1.1.6 root 1314: fflush( debugfile );
1315: *blah = 0; /* Access Violation here! */
1316: abort();
1317: }
1.1.1.2 root 1318: else
1.1.1.4 root 1319: result = count;
1.1.1.6 root 1320: va_end (parms);
1.1.1.2 root 1321: }
1.1 root 1322: }
1.1.1.4 root 1323: #else /* MSVC likes this one, and so do I */
1.1.1.7 ! root 1324: int write_log ( const char *format, ... )
1.1 root 1325: {
1.1.1.4 root 1326: int result = 0;
1327: #ifdef _DEBUG
1.1.1.2 root 1328: DWORD numwritten;
1.1.1.4 root 1329: #endif
1330: char buffer[ WRITE_LOG_BUF_SIZE ];
1.1 root 1331: va_list parms;
1.1.1.4 root 1332: int count = 0;
1333: int *blah = (int *)0xdeadbeef;
1.1 root 1334:
1335: va_start (parms, format);
1.1.1.4 root 1336: count = _vsnprintf( buffer, WRITE_LOG_BUF_SIZE-1, format, parms );
1337: #if defined HAVE_GETTICKCOUNT && defined TIMESTAMP_LOGS
1338: {
1.1.1.6 root 1339: char buffme[WRITE_LOG_BUF_SIZE];
1340: sprintf( buffme, "%7d - %s", GetTickCount(), buffer );
1341: OutputDebugString( buffme );
1342: if( debugfile )
1343: fprintf( debugfile, buffme );
1.1.1.4 root 1344: result = strlen( buffme );
1345: }
1346: #else
1347: OutputDebugString( buffer );
1348: if( debugfile )
1349: {
1.1.1.6 root 1350: fprintf( debugfile, buffer );
1.1.1.4 root 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
1.1 root 1359: va_end (parms);
1.1.1.4 root 1360: return result;
1.1 root 1361: }
1.1.1.4 root 1362: #endif
1.1 root 1363:
1364: int debuggable (void)
1365: {
1.1.1.4 root 1366: return 0;
1.1 root 1367: }
1368:
1369: int needmousehack (void)
1370: {
1.1.1.4 root 1371: if( WIN32GFX_IsFullScreen() || WIN32GFX_IsPicassoScreen() )
1372: return 0;
1373: else
1374: return 1;
1.1 root 1375: }
1376:
1.1.1.2 root 1377: void LED (int a)
1.1 root 1378: {
1379: }
1380:
1.1.1.4 root 1381: void logging_init( void )
1.1 root 1382: {
1.1.1.4 root 1383: char debugfilename[MAX_PATH];
1384: if (1) {
1.1.1.6 root 1385: sprintf( debugfilename, "%s\\winuaelog.txt", start_path );
1386: if( !debugfile )
1387: debugfile = fopen( debugfilename, "wt" );
1.1 root 1388: }
1.1.1.4 root 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");
1.1 root 1399: }
1.1.1.2 root 1400:
1.1.1.4 root 1401: void logging_cleanup( void )
1.1 root 1402: {
1.1.1.4 root 1403: if( debugfile )
1.1.1.6 root 1404: fclose( debugfile );
1.1 root 1405: }
1406:
1.1.1.4 root 1407: static const char *sound_styles[] = { "waveout_looping", "waveout_dblbuff", "dsound_looping", "dsound_dblbuff", 0 };
1.1 root 1408:
1.1.1.4 root 1409: void target_save_options (FILE *f, struct uae_prefs *p)
1.1 root 1410: {
1.1.1.5 root 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" );
1.1 root 1419: }
1420:
1.1.1.4 root 1421: int target_parse_option (struct uae_prefs *p, char *option, char *value)
1.1 root 1422: {
1.1.1.5 root 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:
1.1 root 1437: return 0;
1438: }
1439:
1.1.1.4 root 1440: void WIN32_HandleRegistryStuff( void )
1.1 root 1441: {
1.1.1.4 root 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,
1.1.1.6 root 1451: KEY_ALL_ACCESS, NULL, &hWinUAEKey, &disposition ) == ERROR_SUCCESS )
1.1.1.4 root 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.
1.1 root 1455:
1.1.1.6 root 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 );
1.1 root 1458:
1.1.1.6 root 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: }
1.1.1.4 root 1466: RegCloseKey( hWinUAEKeyLocal );
1467:
1.1.1.6 root 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: }
1.1.1.4 root 1475: RegCloseKey( hWinUAEKeyLocal );
1476: }
1477: else
1478: {
1479: char szMessage[ MAX_PATH ];
1480: WIN32GUI_LoadUIString( IDS_REGKEYCREATEFAILED, szMessage, MAX_PATH );
1.1.1.6 root 1481: gui_message( szMessage );
1482: hWinUAEKey = NULL;
1.1.1.4 root 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,
1.1.1.6 root 1488: KEY_ALL_ACCESS, NULL, &hWinUAEKey, &disposition ) == ERROR_SUCCESS )
1.1.1.4 root 1489: {
1.1.1.6 root 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: }
1.1.1.4 root 1501: // Set this even when we're opening an existing key, so that the version info is always up to date.
1.1.1.6 root 1502: RegSetValueEx( hWinUAEKey, "Version", 0, REG_SZ, (CONST BYTE *)VersionStr, strlen( VersionStr ) + 1 );
1503:
1.1.1.4 root 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 );
1.1.1.6 root 1529: gui_message( szMessage );
1530: hWinUAEKey = NULL;
1.1 root 1531: }
1.1.1.2 root 1532: }
1533:
1534: void machdep_init (void)
1535: {
1536: }
1537:
1.1.1.4 root 1538: char *start_path = NULL;
1539: char help_file[ MAX_PATH ];
1.1.1.2 root 1540:
1541: int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
1542: int nCmdShow)
1543: {
1.1.1.4 root 1544: char *posn;
1545: HANDLE hMutex;
1546: OSVERSIONINFO osVersion;
1.1.1.2 root 1547:
1.1.1.4 root 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
1.1.1.2 root 1557:
1.1.1.4 root 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 ) )
1.1.1.2 root 1563: {
1.1.1.4 root 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;
1.1.1.2 root 1572: }
1.1.1.4 root 1573: }
1.1.1.2 root 1574:
1.1.1.4 root 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 );
1.1.1.2 root 1582:
1.1.1.4 root 1583: sprintf( VersionStr, "WinUAE %d.%d.%d, Release %d%s", UAEMAJOR, UAEMINOR, UAESUBREV, WINUAERELEASE, WINUAEBETA ? WINUAEBETASTR : "" );
1.1.1.2 root 1584:
1.1.1.4 root 1585: logging_init ();
1586: printf ("Hello, world\n");
1.1.1.2 root 1587:
1.1.1.4 root 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;
1.1.1.7 ! root 1606: write_log ( "Your Windows desktop refresh frequency is %d Hz\n", default_freq );
1.1.1.4 root 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 );
1.1.1.7 ! root 1618: write_log ( szMessage );
1.1.1.4 root 1619: }
1620:
1621: DirectDraw_Release();
1622: #ifdef __MINGW32__
1623: real_main (_argc, _argv);
1.1.1.2 root 1624: #else
1.1.1.4 root 1625: real_main (__argc, __argv);
1.1.1.2 root 1626: #endif
1.1.1.4 root 1627: }
1628: free( start_path );
1629: }
1630:
1631: WIN32_CleanupLibraries();
1632: _fcloseall();
1633: if( hWinUAEKey )
1634: RegCloseKey( hWinUAEKey );
1635: CloseHandle( hMutex );
1.1.1.2 root 1636: return FALSE;
1637: }
1.1.1.4 root 1638:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.