1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed. See license for details. */
3
4 // winhack.cpp : Defines the entry point for the application.
5 //
6
7 #include <process.h>
8 #include "winMS.h"
9 #include "hack.h"
10 #include "dlb.h"
11 #include "resource.h"
12 #include "mhmain.h"
13 #include "mhmap.h"
14
15 #if !defined(__BORLANDC__) && !defined(__MINGW32__)
16 #include <shlwapi.h>
17 #else /* Borland redefines "boolean" in shlwapi.h so just use the little bit we need */
18 typedef struct _DLLVERSIONINFO
19 {
20 DWORD cbSize;
21 DWORD dwMajorVersion; // Major version
22 DWORD dwMinorVersion; // Minor version
23 DWORD dwBuildNumber; // Build number
24 DWORD dwPlatformID; // DLLVER_PLATFORM_*
25 } DLLVERSIONINFO;
26
27 //
28 // The caller should always GetProcAddress("DllGetVersion"), not
29 // implicitly link to it.
30 //
31
32 typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
33
34 #endif
35
36 #ifdef OVL0
37 #define SHARED_DCL
38 #else
39 #define SHARED_DCL extern
40 #endif
41
42 /* Minimal common control library version
43 Version _WIN_32IE Platform/IE
44 ======= ========= ===========
45 4.00 0x0200 Microsoft(r) Windows 95/Windows NT 4.0
46 4.70 0x0300 Microsoft(r) Internet Explorer 3.x
47 4.71 0x0400 Microsoft(r) Internet Explorer 4.0
48 4.72 0x0401 Microsoft(r) Internet Explorer 4.01
49 ...and probably going on infinitely...
50 */
51 #define MIN_COMCTLMAJOR 4
52 #define MIN_COMCTLMINOR 71
53 #define INSTALL_NOTES "http://www.nethack.org/v340/ports/download-win.html#cc"
54 /*#define COMCTL_URL "http://www.microsoft.com/msdownload/ieplatform/ie/comctrlx86.asp"*/
55
56 extern void FDECL(nethack_exit,(int));
57 static TCHAR* _get_cmd_arg(TCHAR* pCmdLine);
58 static HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor);
59
60
61 // Global Variables:
62 NHWinApp _nethack_app;
63
64 #ifdef __BORLANDC__
65 #define _stricmp(s1,s2) stricmp(s1,s2)
66 #define _strdup(s1) strdup(s1)
67 #endif
68
69 // Foward declarations of functions included in this code module:
70 extern void FDECL(pcmain, (int,char **));
71 static void __cdecl mswin_moveloop(void *);
72
73 #define MAX_CMDLINE_PARAM 255
74
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)75 int APIENTRY WinMain(HINSTANCE hInstance,
76 HINSTANCE hPrevInstance,
77 LPSTR lpCmdLine,
78 int nCmdShow)
79 {
80 INITCOMMONCONTROLSEX InitCtrls;
81 int argc;
82 char* argv[MAX_CMDLINE_PARAM];
83 size_t len;
84 TCHAR *p;
85 TCHAR wbuf[BUFSZ];
86 char buf[BUFSZ];
87 DWORD major, minor;
88
89
90 /* ensure that we don't access violate on a panic() */
91 windowprocs.win_raw_print = mswin_raw_print;
92 windowprocs.win_raw_print_bold = mswin_raw_print_bold;
93
94 /* init applicatio structure */
95 _nethack_app.hApp = hInstance;
96 _nethack_app.hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_NETHACKW);
97 _nethack_app.hMainWnd = NULL;
98 _nethack_app.hPopupWnd = NULL;
99 _nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
100 if( _nethack_app.bmpTiles==NULL ) panic("cannot load tiles bitmap");
101 _nethack_app.bmpPetMark = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
102 if( _nethack_app.bmpPetMark==NULL ) panic("cannot load pet mark bitmap");
103 _nethack_app.bmpRip = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_RIP));
104 if ( _nethack_app.bmpRip == NULL ) panic("cannot load rip bitmap");
105 _nethack_app.bmpSplash = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SPLASH));
106 if ( _nethack_app.bmpSplash == NULL ) panic("cannot load splash bitmap");
107 _nethack_app.bmpMapTiles = _nethack_app.bmpTiles;
108 _nethack_app.mapTile_X = TILE_X;
109 _nethack_app.mapTile_Y = TILE_Y;
110 _nethack_app.mapTilesPerLine = TILES_PER_LINE;
111
112 _nethack_app.bNoHScroll = FALSE;
113 _nethack_app.bNoVScroll = FALSE;
114 _nethack_app.saved_text = strdup("");
115
116 // init controls
117 if (FAILED(GetComCtlVersion(&major, &minor)))
118 {
119 char buf[TBUFSZ];
120 Sprintf(buf, "Cannot load common control library.\n%s\n%s",
121 "For further information, refer to the installation notes at",
122 INSTALL_NOTES);
123 panic(buf);
124 }
125 if (major < MIN_COMCTLMAJOR
126 || (major == MIN_COMCTLMAJOR && minor < MIN_COMCTLMINOR))
127 {
128 char buf[TBUFSZ];
129 Sprintf(buf, "Common control library is outdated.\n%s %d.%d\n%s\n%s",
130 "NetHack requires at least version ",
131 MIN_COMCTLMAJOR, MIN_COMCTLMINOR,
132 "For further information, refer to the installation notes at",
133 INSTALL_NOTES);
134 panic(buf);
135 }
136 ZeroMemory(&InitCtrls, sizeof(InitCtrls));
137 InitCtrls.dwSize = sizeof(InitCtrls);
138 InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
139 InitCommonControlsEx(&InitCtrls);
140
141 /* get command line parameters */
142 p = _get_cmd_arg(GetCommandLine());
143 p = _get_cmd_arg(NULL); /* skip first paramter - command name */
144 for( argc = 1; p && argc<MAX_CMDLINE_PARAM; argc++ ) {
145 len = _tcslen(p);
146 if( len>0 ) {
147 argv[argc] = _strdup( NH_W2A(p, buf, BUFSZ) );
148 } else {
149 argv[argc] = "";
150 }
151 p = _get_cmd_arg(NULL);
152 }
153 GetModuleFileName(NULL, wbuf, BUFSZ);
154 argv[0] = _strdup(NH_W2A(wbuf, buf, BUFSZ));
155
156 if (argc == 2) {
157 TCHAR *savefile = strdup(argv[1]);
158 TCHAR *plname;
159 for (p = savefile; *p && *p != '-'; p++)
160 ;
161 if (*p) {
162 /* we found a '-' */
163 plname = p + 1;
164 for (p = plname; *p && *p != '.'; p++)
165 ;
166 if (*p) {
167 if (strcmp(p + 1, "NetHack-saved-game") == 0) {
168 *p = '\0';
169 argv[1] = "-u";
170 argv[2] = _strdup(plname);
171 argc = 3;
172 }
173 }
174 }
175 free(savefile);
176 }
177 pcmain(argc,argv);
178
179 moveloop();
180
181 return 0;
182 }
183
184
GetNHApp()185 PNHWinApp GetNHApp()
186 {
187 return &_nethack_app;
188 }
189
_get_cmd_arg(TCHAR * pCmdLine)190 TCHAR* _get_cmd_arg(TCHAR* pCmdLine)
191 {
192 static TCHAR* pArgs = NULL;
193 TCHAR *pRetArg;
194 BOOL bQuoted;
195
196 if( !pCmdLine && !pArgs ) return NULL;
197 if( !pArgs ) pArgs = pCmdLine;
198
199 /* skip whitespace */
200 for(pRetArg = pArgs; *pRetArg && _istspace(*pRetArg); pRetArg = CharNext(pRetArg));
201 if( !*pRetArg ) {
202 pArgs = NULL;
203 return NULL;
204 }
205
206 /* check for quote */
207 if( *pRetArg==TEXT('"') ) {
208 bQuoted = TRUE;
209 pRetArg = CharNext(pRetArg);
210 pArgs = _tcschr(pRetArg, TEXT('"'));
211 } else {
212 /* skip to whitespace */
213 for(pArgs = pRetArg; *pArgs && !_istspace(*pArgs); pArgs = CharNext(pArgs));
214 }
215
216 if( pArgs && *pArgs ) {
217 TCHAR* p;
218 p = pArgs;
219 pArgs = CharNext(pArgs);
220 *p = (TCHAR)0;
221 } else {
222 pArgs = NULL;
223 }
224
225 return pRetArg;
226 }
227
228 /* Get the version of the Common Control library on this machine.
229 Copied from the Microsoft SDK
230 */
GetComCtlVersion(LPDWORD pdwMajor,LPDWORD pdwMinor)231 HRESULT GetComCtlVersion(LPDWORD pdwMajor, LPDWORD pdwMinor)
232 {
233 HINSTANCE hComCtl;
234 HRESULT hr = S_OK;
235 DLLGETVERSIONPROC pDllGetVersion;
236
237 if(IsBadWritePtr(pdwMajor, sizeof(DWORD)) ||
238 IsBadWritePtr(pdwMinor, sizeof(DWORD)))
239 return E_INVALIDARG;
240 //load the DLL
241 hComCtl = LoadLibrary(TEXT("comctl32.dll"));
242 if (!hComCtl) return E_FAIL;
243
244 /*
245 You must get this function explicitly because earlier versions of the DLL
246 don't implement this function. That makes the lack of implementation of the
247 function a version marker in itself.
248 */
249 pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hComCtl, TEXT("DllGetVersion"));
250 if(pDllGetVersion) {
251 DLLVERSIONINFO dvi;
252 ZeroMemory(&dvi, sizeof(dvi));
253 dvi.cbSize = sizeof(dvi);
254 hr = (*pDllGetVersion)(&dvi);
255 if(SUCCEEDED(hr)) {
256 *pdwMajor = dvi.dwMajorVersion;
257 *pdwMinor = dvi.dwMinorVersion;
258 } else {
259 hr = E_FAIL;
260 }
261 } else {
262 /*
263 If GetProcAddress failed, then the DLL is a version previous to the one
264 shipped with IE 3.x.
265 */
266 *pdwMajor = 4;
267 *pdwMinor = 0;
268 }
269 FreeLibrary(hComCtl);
270 return hr;
271 }
272
273
274