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.
16 /* Borland and MinGW redefine "boolean" in shlwapi.h,
17 so just use the little bit we need */
18 typedef struct _DLLVERSIONINFO {
20 DWORD dwMajorVersion; // Major version
21 DWORD dwMinorVersion; // Minor version
22 DWORD dwBuildNumber; // Build number
23 DWORD dwPlatformID; // DLLVER_PLATFORM_*
27 // The caller should always GetProcAddress("DllGetVersion"), not
28 // implicitly link to it.
31 typedef HRESULT(CALLBACK *DLLGETVERSIONPROC)(DLLVERSIONINFO *);
33 /* end of shlwapi.h */
35 /* Minimal common control library version
36 Version _WIN_32IE Platform/IE
37 ======= ========= ===========
38 4.00 0x0200 Microsoft(r) Windows 95/Windows NT 4.0
39 4.70 0x0300 Microsoft(r) Internet Explorer 3.x
40 4.71 0x0400 Microsoft(r) Internet Explorer 4.0
41 4.72 0x0401 Microsoft(r) Internet Explorer 4.01
42 ...and probably going on infinitely...
44 #define MIN_COMCTLMAJOR 4
45 #define MIN_COMCTLMINOR 71
46 #define INSTALL_NOTES "http://www.nethack.org/v340/ports/download-win.html#cc"
48 * "http://www.microsoft.com/msdownload/ieplatform/ie/comctrlx86.asp"*/
50 extern void FDECL(nethack_exit, (int));
51 static TCHAR *_get_cmd_arg(TCHAR *pCmdLine);
52 static HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor);
54 _nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
55 HDC sourceDC, int s_x, int s_y, int s_width,
56 int s_height, UINT cTransparent);
59 NHWinApp _nethack_app;
62 #define _stricmp(s1, s2) stricmp(s1, s2)
63 #define _strdup(s1) strdup(s1)
66 // Foward declarations of functions included in this code module:
67 extern boolean FDECL(pcmain, (int, char **));
68 static void __cdecl mswin_moveloop(void *);
70 #define MAX_CMDLINE_PARAM 255
73 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
76 INITCOMMONCONTROLSEX InitCtrls;
78 char *argv[MAX_CMDLINE_PARAM];
85 /* OSVERSIONINFO osvi; */
87 UNREFERENCED_PARAMETER(hPrevInstance);
88 UNREFERENCED_PARAMETER(lpCmdLine);
89 UNREFERENCED_PARAMETER(nCmdShow);
93 /* ensure that we don't access violate on a panic() */
94 windowprocs.win_raw_print = mswin_raw_print;
95 windowprocs.win_raw_print_bold = mswin_raw_print_bold;
97 /* init applicatio structure */
98 _nethack_app.hApp = hInstance;
99 _nethack_app.hAccelTable =
100 LoadAccelerators(hInstance, (LPCTSTR) IDC_NETHACKW);
101 _nethack_app.hMainWnd = NULL;
102 _nethack_app.hPopupWnd = NULL;
103 _nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
104 if (_nethack_app.bmpTiles == NULL)
105 panic("cannot load tiles bitmap");
106 _nethack_app.bmpPetMark =
107 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
108 if (_nethack_app.bmpPetMark == NULL)
109 panic("cannot load pet mark bitmap");
111 _nethack_app.bmpPileMark =
112 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PILEMARK));
113 if (_nethack_app.bmpPileMark == NULL)
114 panic("cannot load pile mark bitmap");
116 _nethack_app.bmpRip = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_RIP));
117 if (_nethack_app.bmpRip == NULL)
118 panic("cannot load rip bitmap");
119 _nethack_app.bmpSplash =
120 LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SPLASH));
121 if (_nethack_app.bmpSplash == NULL)
122 panic("cannot load splash bitmap");
123 _nethack_app.bmpMapTiles = _nethack_app.bmpTiles;
124 _nethack_app.mapTile_X = TILE_X;
125 _nethack_app.mapTile_Y = TILE_Y;
126 _nethack_app.mapTilesPerLine = TILES_PER_LINE;
128 _nethack_app.bNoHScroll = FALSE;
129 _nethack_app.bNoVScroll = FALSE;
130 _nethack_app.saved_text = strdup("");
132 _nethack_app.bAutoLayout = TRUE;
133 _nethack_app.bWindowsLocked = TRUE;
135 _nethack_app.bNoSounds = FALSE;
137 #if 0 /* GdiTransparentBlt does not render spash bitmap for whatever reason */
138 /* use system-provided TransparentBlt for Win2k+ */
139 ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
140 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
142 if (osvi.dwMajorVersion >= 5)
143 _nethack_app.lpfnTransparentBlt = GdiTransparentBlt;
146 _nethack_app.lpfnTransparentBlt = _nhapply_image_transparent;
149 if (FAILED(GetComCtlVersion(&major, &minor))) {
151 Sprintf(buf, "Cannot load common control library.\n%s\n%s",
152 "For further information, refer to the installation notes at",
156 if (major < MIN_COMCTLMAJOR
157 || (major == MIN_COMCTLMAJOR && minor < MIN_COMCTLMINOR)) {
159 Sprintf(buf, "Common control library is outdated.\n%s %d.%d\n%s\n%s",
160 "NetHack requires at least version ", MIN_COMCTLMAJOR,
162 "For further information, refer to the installation notes at",
166 ZeroMemory(&InitCtrls, sizeof(InitCtrls));
167 InitCtrls.dwSize = sizeof(InitCtrls);
168 InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
169 InitCommonControlsEx(&InitCtrls);
171 /* get command line parameters */
172 p = _get_cmd_arg(GetCommandLine());
173 p = _get_cmd_arg(NULL); /* skip first paramter - command name */
174 for (argc = 1; p && argc < MAX_CMDLINE_PARAM; argc++) {
177 argv[argc] = _strdup(NH_W2A(p, buf, BUFSZ));
181 p = _get_cmd_arg(NULL);
183 GetModuleFileName(NULL, wbuf, BUFSZ);
184 argv[0] = _strdup(NH_W2A(wbuf, buf, BUFSZ));
187 TCHAR *savefile = strdup(argv[1]);
189 for (p = savefile; *p && *p != '-'; p++)
194 for (p = plname; *p && *p != '.'; p++)
197 if (strcmp(p + 1, "NetHack-saved-game") == 0) {
200 argv[2] = _strdup(plname);
207 resuming = pcmain(argc, argv);
217 return &_nethack_app;
221 _get_cmd_arg(TCHAR *pCmdLine)
223 static TCHAR *pArgs = NULL;
227 if (!pCmdLine && !pArgs)
232 /* skip whitespace */
233 for (pRetArg = pArgs; *pRetArg && _istspace(*pRetArg);
234 pRetArg = CharNext(pRetArg))
241 /* check for quote */
242 if (*pRetArg == TEXT('"')) {
244 pRetArg = CharNext(pRetArg);
245 pArgs = _tcschr(pRetArg, TEXT('"'));
247 /* skip to whitespace */
248 for (pArgs = pRetArg; *pArgs && !_istspace(*pArgs);
249 pArgs = CharNext(pArgs))
253 if (pArgs && *pArgs) {
256 pArgs = CharNext(pArgs);
265 /* Get the version of the Common Control library on this machine.
266 Copied from the Microsoft SDK
269 GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
273 DLLGETVERSIONPROC pDllGetVersion;
275 if (IsBadWritePtr(pdwMajor, sizeof(DWORD))
276 || IsBadWritePtr(pdwMinor, sizeof(DWORD)))
279 hComCtl = LoadLibrary(TEXT("comctl32.dll"));
284 You must get this function explicitly because earlier versions of the DLL
285 don't implement this function. That makes the lack of implementation of
287 function a version marker in itself.
290 (DLLGETVERSIONPROC) GetProcAddress(hComCtl, TEXT("DllGetVersion"));
291 if (pDllGetVersion) {
293 ZeroMemory(&dvi, sizeof(dvi));
294 dvi.cbSize = sizeof(dvi);
295 hr = (*pDllGetVersion)(&dvi);
297 *pdwMajor = dvi.dwMajorVersion;
298 *pdwMinor = dvi.dwMinorVersion;
304 If GetProcAddress failed, then the DLL is a version previous to the
311 FreeLibrary(hComCtl);
315 /* apply bitmap pointed by sourceDc transparently over
316 bitmap pointed by hDC */
318 _nhapply_image_transparent(HDC hDC, int x, int y, int width, int height,
319 HDC sourceDC, int s_x, int s_y, int s_width,
320 int s_height, UINT cTransparent)
322 /* Don't use TransparentBlt; According to Microsoft, it contains a memory
323 * leak in Window 95/98. */
324 HDC hdcMem, hdcBack, hdcObject, hdcSave;
326 HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
327 HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
329 /* Create some DCs to hold temporary data. */
330 hdcBack = CreateCompatibleDC(hDC);
331 hdcObject = CreateCompatibleDC(hDC);
332 hdcMem = CreateCompatibleDC(hDC);
333 hdcSave = CreateCompatibleDC(hDC);
335 /* this is bitmap for our pet image */
336 bmSave = CreateCompatibleBitmap(hDC, width, height);
339 bmAndBack = CreateBitmap(width, height, 1, 1, NULL);
340 bmAndObject = CreateBitmap(width, height, 1, 1, NULL);
342 /* resulting bitmap */
343 bmAndMem = CreateCompatibleBitmap(hDC, width, height);
345 /* Each DC must select a bitmap object to store pixel data. */
346 bmBackOld = SelectObject(hdcBack, bmAndBack);
347 bmObjectOld = SelectObject(hdcObject, bmAndObject);
348 bmMemOld = SelectObject(hdcMem, bmAndMem);
349 bmSaveOld = SelectObject(hdcSave, bmSave);
351 /* copy source image because it is going to be overwritten */
352 StretchBlt(hdcSave, 0, 0, width, height, sourceDC, s_x, s_y, s_width,
355 /* Set the background color of the source DC to the color.
356 contained in the parts of the bitmap that should be transparent */
357 cColor = SetBkColor(hdcSave, cTransparent);
359 /* Create the object mask for the bitmap by performing a BitBlt
360 from the source bitmap to a monochrome bitmap. */
361 BitBlt(hdcObject, 0, 0, width, height, hdcSave, 0, 0, SRCCOPY);
363 /* Set the background color of the source DC back to the original
365 SetBkColor(hdcSave, cColor);
367 /* Create the inverse of the object mask. */
368 BitBlt(hdcBack, 0, 0, width, height, hdcObject, 0, 0, NOTSRCCOPY);
370 /* Copy background to the resulting image */
371 BitBlt(hdcMem, 0, 0, width, height, hDC, x, y, SRCCOPY);
373 /* Mask out the places where the source image will be placed. */
374 BitBlt(hdcMem, 0, 0, width, height, hdcObject, 0, 0, SRCAND);
376 /* Mask out the transparent colored pixels on the source image. */
377 BitBlt(hdcSave, 0, 0, width, height, hdcBack, 0, 0, SRCAND);
379 /* XOR the source image with the beckground. */
380 BitBlt(hdcMem, 0, 0, width, height, hdcSave, 0, 0, SRCPAINT);
382 /* blt resulting image to the screen */
383 BitBlt(hDC, x, y, width, height, hdcMem, 0, 0, SRCCOPY);
386 DeleteObject(SelectObject(hdcBack, bmBackOld));
387 DeleteObject(SelectObject(hdcObject, bmObjectOld));
388 DeleteObject(SelectObject(hdcMem, bmMemOld));
389 DeleteObject(SelectObject(hdcSave, bmSaveOld));