1 /* NetHack 3.6 winhack.c $NHDT-Date: 1449488876 2015/12/07 11:47:56 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.44 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* NetHack may be freely redistributed. See license for details. */
5 // winhack.cpp : Defines the entry point for the application.
18 #if !defined(SAFEPROCS)
19 #error You must #define SAFEPROCS to build winhack.c
22 /* Borland and MinGW redefine "boolean" in shlwapi.h,
23 so just use the little bit we need */
24 typedef struct _DLLVERSIONINFO {
26 DWORD dwMajorVersion; // Major version
27 DWORD dwMinorVersion; // Minor version
28 DWORD dwBuildNumber; // Build number
29 DWORD dwPlatformID; // DLLVER_PLATFORM_*
33 // The caller should always GetProcAddress("DllGetVersion"), not
34 // implicitly link to it.
37 typedef HRESULT(CALLBACK *DLLGETVERSIONPROC)(DLLVERSIONINFO *);
39 /* end of shlwapi.h */
41 /* Minimal common control library version
42 Version _WIN_32IE Platform/IE
43 ======= ========= ===========
44 4.00 0x0200 Microsoft(r) Windows 95/Windows NT 4.0
45 4.70 0x0300 Microsoft(r) Internet Explorer 3.x
46 4.71 0x0400 Microsoft(r) Internet Explorer 4.0
47 4.72 0x0401 Microsoft(r) Internet Explorer 4.01
48 ...and probably going on infinitely...
50 #define MIN_COMCTLMAJOR 4
51 #define MIN_COMCTLMINOR 71
52 #define INSTALL_NOTES "http://www.nethack.org/v340/ports/download-win.html#cc"
54 * "http://www.microsoft.com/msdownload/ieplatform/ie/comctrlx86.asp"*/
56 extern void FDECL(nethack_exit, (int));
57 static TCHAR *_get_cmd_arg(TCHAR *pCmdLine);
58 static HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor);
60 _nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
61 HDC sourceDC, int s_x, int s_y, int s_width,
62 int s_height, UINT cTransparent);
65 NHWinApp _nethack_app;
66 extern int GUILaunched; /* We tell shared startup code in windmain.c
67 that the GUI was launched via this */
70 #define _stricmp(s1, s2) stricmp(s1, s2)
71 #define _strdup(s1) strdup(s1)
74 // Foward declarations of functions included in this code module:
75 extern boolean FDECL(main, (int, char **));
76 static void __cdecl mswin_moveloop(void *);
78 #define MAX_CMDLINE_PARAM 255
81 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
84 INITCOMMONCONTROLSEX InitCtrls;
86 char *argv[MAX_CMDLINE_PARAM];
93 /* OSVERSIONINFO osvi; */
95 UNREFERENCED_PARAMETER(hPrevInstance);
96 UNREFERENCED_PARAMETER(lpCmdLine);
97 UNREFERENCED_PARAMETER(nCmdShow);
100 * Get a set of valid safe windowport function
101 * pointers during early startup initialization.
103 * When get_safe_procs is called with 0 as the param,
104 * non-functional, but safe function pointers are set
105 * for all windowport routines.
107 * When get_safe_procs is called with 1 as the param,
108 * raw_print, raw_print_bold, and wait_synch, and nhgetch
109 * are set to use C stdio routines via stdio_raw_print,
110 * stdio_raw_print_bold, stdio_wait_synch, and
113 windowprocs = *get_safe_procs(0);
116 * Now we are going to override a couple
117 * of the windowprocs functions so that
118 * error messages are handled in a suitable
119 * way for the graphical version.
121 windowprocs.win_raw_print = mswin_raw_print;
122 windowprocs.win_raw_print_bold = mswin_raw_print_bold;
123 windowprocs.win_wait_synch = mswin_wait_synch;
128 /* init application structure */
129 _nethack_app.hApp = hInstance;
130 _nethack_app.hAccelTable =
131 LoadAccelerators(hInstance, (LPCTSTR) IDC_NETHACKW);
132 _nethack_app.hMainWnd = NULL;
133 _nethack_app.hPopupWnd = NULL;
134 _nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
135 if (_nethack_app.bmpTiles == NULL)
136 panic("cannot load tiles bitmap");
137 _nethack_app.bmpPetMark =
138 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
139 if (_nethack_app.bmpPetMark == NULL)
140 panic("cannot load pet mark bitmap");
142 _nethack_app.bmpPileMark =
143 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PILEMARK));
144 if (_nethack_app.bmpPileMark == NULL)
145 panic("cannot load pile mark bitmap");
147 _nethack_app.bmpRip = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_RIP));
148 if (_nethack_app.bmpRip == NULL)
149 panic("cannot load rip bitmap");
150 _nethack_app.bmpSplash =
151 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SPLASH));
152 if (_nethack_app.bmpSplash == NULL)
153 panic("cannot load splash bitmap");
154 _nethack_app.bmpMapTiles = _nethack_app.bmpTiles;
155 _nethack_app.mapTile_X = TILE_X;
156 _nethack_app.mapTile_Y = TILE_Y;
157 _nethack_app.mapTilesPerLine = TILES_PER_LINE;
159 _nethack_app.bNoHScroll = FALSE;
160 _nethack_app.bNoVScroll = FALSE;
161 _nethack_app.saved_text = strdup("");
163 _nethack_app.bAutoLayout = TRUE;
164 _nethack_app.bWindowsLocked = TRUE;
166 _nethack_app.bNoSounds = FALSE;
168 #if 0 /* GdiTransparentBlt does not render spash bitmap for whatever reason */
169 /* use system-provided TransparentBlt for Win2k+ */
170 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
171 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
173 if (osvi.dwMajorVersion >= 5)
174 _nethack_app.lpfnTransparentBlt = GdiTransparentBlt;
177 _nethack_app.lpfnTransparentBlt = _nhapply_image_transparent;
180 if (FAILED(GetComCtlVersion(&major, &minor))) {
182 Sprintf(buf, "Cannot load common control library.\n%s\n%s",
183 "For further information, refer to the installation notes at",
187 if (major < MIN_COMCTLMAJOR
188 || (major == MIN_COMCTLMAJOR && minor < MIN_COMCTLMINOR)) {
190 Sprintf(buf, "Common control library is outdated.\n%s %d.%d\n%s\n%s",
191 "NetHack requires at least version ", MIN_COMCTLMAJOR,
193 "For further information, refer to the installation notes at",
197 ZeroMemory(&InitCtrls, sizeof(InitCtrls));
198 InitCtrls.dwSize = sizeof(InitCtrls);
199 InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
200 InitCommonControlsEx(&InitCtrls);
202 /* get command line parameters */
203 p = _get_cmd_arg(GetCommandLine());
204 p = _get_cmd_arg(NULL); /* skip first paramter - command name */
205 for (argc = 1; p && argc < MAX_CMDLINE_PARAM; argc++) {
208 argv[argc] = _strdup(NH_W2A(p, buf, BUFSZ));
212 p = _get_cmd_arg(NULL);
214 GetModuleFileName(NULL, wbuf, BUFSZ);
215 argv[0] = _strdup(NH_W2A(wbuf, buf, BUFSZ));
218 TCHAR *savefile = strdup(argv[1]);
220 for (p = savefile; *p && *p != '-'; p++)
225 for (p = plname; *p && *p != '.'; p++)
228 if (strcmp(p + 1, "NetHack-saved-game") == 0) {
231 argv[2] = _strdup(plname);
239 /* let main do the argument processing */
240 (void) main(argc, argv);
247 return &_nethack_app;
251 _get_cmd_arg(TCHAR *pCmdLine)
253 static TCHAR *pArgs = NULL;
257 if (!pCmdLine && !pArgs)
262 /* skip whitespace */
263 for (pRetArg = pArgs; *pRetArg && _istspace(*pRetArg);
264 pRetArg = CharNext(pRetArg))
271 /* check for quote */
272 if (*pRetArg == TEXT('"')) {
274 pRetArg = CharNext(pRetArg);
275 pArgs = _tcschr(pRetArg, TEXT('"'));
277 /* skip to whitespace */
278 for (pArgs = pRetArg; *pArgs && !_istspace(*pArgs);
279 pArgs = CharNext(pArgs))
283 if (pArgs && *pArgs) {
286 pArgs = CharNext(pArgs);
295 /* Get the version of the Common Control library on this machine.
296 Copied from the Microsoft SDK
299 GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
303 DLLGETVERSIONPROC pDllGetVersion;
305 if (IsBadWritePtr(pdwMajor, sizeof(DWORD))
306 || IsBadWritePtr(pdwMinor, sizeof(DWORD)))
309 hComCtl = LoadLibrary(TEXT("comctl32.dll"));
314 You must get this function explicitly because earlier versions of the DLL
315 don't implement this function. That makes the lack of implementation of
317 function a version marker in itself.
320 (DLLGETVERSIONPROC) GetProcAddress(hComCtl, TEXT("DllGetVersion"));
321 if (pDllGetVersion) {
323 ZeroMemory(&dvi, sizeof(dvi));
324 dvi.cbSize = sizeof(dvi);
325 hr = (*pDllGetVersion)(&dvi);
327 *pdwMajor = dvi.dwMajorVersion;
328 *pdwMinor = dvi.dwMinorVersion;
334 If GetProcAddress failed, then the DLL is a version previous to the
341 FreeLibrary(hComCtl);
345 /* apply bitmap pointed by sourceDc transparently over
346 bitmap pointed by hDC */
348 _nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
349 HDC sourceDC, int s_x, int s_y, int s_width,
350 int s_height, UINT cTransparent)
352 /* Don't use TransparentBlt; According to Microsoft, it contains a memory
353 * leak in Window 95/98. */
354 HDC hdcMem, hdcBack, hdcObject, hdcSave;
356 HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
357 HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
359 /* Create some DCs to hold temporary data. */
360 hdcBack = CreateCompatibleDC(hDC);
361 hdcObject = CreateCompatibleDC(hDC);
362 hdcMem = CreateCompatibleDC(hDC);
363 hdcSave = CreateCompatibleDC(hDC);
365 /* this is bitmap for our pet image */
366 bmSave = CreateCompatibleBitmap(hDC, width, height);
369 bmAndBack = CreateBitmap(width, height, 1, 1, NULL);
370 bmAndObject = CreateBitmap(width, height, 1, 1, NULL);
372 /* resulting bitmap */
373 bmAndMem = CreateCompatibleBitmap(hDC, width, height);
375 /* Each DC must select a bitmap object to store pixel data. */
376 bmBackOld = SelectObject(hdcBack, bmAndBack);
377 bmObjectOld = SelectObject(hdcObject, bmAndObject);
378 bmMemOld = SelectObject(hdcMem, bmAndMem);
379 bmSaveOld = SelectObject(hdcSave, bmSave);
381 /* copy source image because it is going to be overwritten */
382 StretchBlt(hdcSave, 0, 0, width, height, sourceDC, s_x, s_y, s_width,
385 /* Set the background color of the source DC to the color.
386 contained in the parts of the bitmap that should be transparent */
387 cColor = SetBkColor(hdcSave, cTransparent);
389 /* Create the object mask for the bitmap by performing a BitBlt
390 from the source bitmap to a monochrome bitmap. */
391 BitBlt(hdcObject, 0, 0, width, height, hdcSave, 0, 0, SRCCOPY);
393 /* Set the background color of the source DC back to the original
395 SetBkColor(hdcSave, cColor);
397 /* Create the inverse of the object mask. */
398 BitBlt(hdcBack, 0, 0, width, height, hdcObject, 0, 0, NOTSRCCOPY);
400 /* Copy background to the resulting image */
401 BitBlt(hdcMem, 0, 0, width, height, hDC, x, y, SRCCOPY);
403 /* Mask out the places where the source image will be placed. */
404 BitBlt(hdcMem, 0, 0, width, height, hdcObject, 0, 0, SRCAND);
406 /* Mask out the transparent colored pixels on the source image. */
407 BitBlt(hdcSave, 0, 0, width, height, hdcBack, 0, 0, SRCAND);
409 /* XOR the source image with the beckground. */
410 BitBlt(hdcMem, 0, 0, width, height, hdcSave, 0, 0, SRCPAINT);
412 /* blt resulting image to the screen */
413 BitBlt(hDC, x, y, width, height, hdcMem, 0, 0, SRCCOPY);
416 DeleteObject(SelectObject(hdcBack, bmBackOld));
417 DeleteObject(SelectObject(hdcObject, bmObjectOld));
418 DeleteObject(SelectObject(hdcMem, bmMemOld));
419 DeleteObject(SelectObject(hdcSave, bmSaveOld));