OSDN Git Service

Initial Import
[nethackexpress/trunk.git] / sys / wince / winhack.c
1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 // winhack.cpp : Defines the entry point for the application.
3 //
4
5 #include "winMS.h"
6 #include "hack.h"
7 #include "dlb.h"
8 #include "mhmain.h"
9 #include "mhmap.h"
10
11 #ifdef OVL0
12 #define SHARED_DCL
13 #else
14 #define SHARED_DCL extern
15 #endif
16
17 SHARED_DCL char orgdir[PATHLEN];        /* also used in pcsys.c, amidos.c */
18
19 extern void FDECL(nethack_exit,(int));
20 static TCHAR* _get_cmd_arg(TCHAR* pCmdLine);
21
22 // Global Variables:
23 NHWinApp _nethack_app;
24
25 // Foward declarations of functions included in this code module:
26 BOOL                            InitInstance(HINSTANCE, int);
27
28 static void win_hack_init(int, char **);
29 static void __cdecl mswin_moveloop(void *);
30 static BOOL setMapTiles(const char* fname);
31
32 extern void FDECL(pcmain, (int,char **));
33
34 #define MAX_CMDLINE_PARAM 255
35
36 int APIENTRY WinMain(HINSTANCE hInstance,
37                      HINSTANCE hPrevInstance,
38                      LPWSTR     lpCmdLine,
39                      int       nCmdShow)
40 {
41         INITCOMMONCONTROLSEX InitCtrls;
42         HWND nethackWnd;
43         int argc;
44         char* argv[MAX_CMDLINE_PARAM];
45         size_t len;
46         TCHAR* p;
47         TCHAR wbuf[NHSTR_BUFSIZE];
48         char buf[NHSTR_BUFSIZE];
49
50         /* ensure that we don't access violate on a panic() */
51         windowprocs.win_raw_print = mswin_raw_print;
52         windowprocs.win_raw_print_bold = mswin_raw_print_bold;
53
54         /* init applicatio structure */
55         _nethack_app.hApp = hInstance;
56         _nethack_app.nCmdShow = nCmdShow;
57         _nethack_app.hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WINHACK);
58         _nethack_app.hMainWnd = NULL;
59         _nethack_app.hPopupWnd = NULL;
60         _nethack_app.hMenuBar = NULL;
61         _nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
62         if( _nethack_app.bmpTiles==NULL ) panic("cannot load tiles bitmap");
63         _nethack_app.bmpPetMark = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
64         if( _nethack_app.bmpPetMark==NULL ) panic("cannot load pet mark bitmap");
65         _nethack_app.bmpMapTiles = _nethack_app.bmpTiles;
66         _nethack_app.mapTile_X = TILE_X;
67         _nethack_app.mapTile_Y = TILE_Y;
68         _nethack_app.mapTilesPerLine = TILES_PER_LINE;
69         _nethack_app.bNoHScroll = FALSE;
70         _nethack_app.bNoVScroll = FALSE;
71
72 #if  defined(WIN_CE_PS2xx) || defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
73         _nethack_app.bCmdPad = TRUE;
74 #else
75         _nethack_app.bCmdPad = FALSE;
76 #endif
77
78         _nethack_app.bWrapText = TRUE;
79         _nethack_app.bFullScreen = TRUE;
80
81 #if defined(WIN_CE_SMARTPHONE)
82         _nethack_app.bHideScrollBars = TRUE;
83 #else
84         _nethack_app.bHideScrollBars = FALSE;
85 #endif
86
87         _nethack_app.bUseSIP = TRUE;
88
89         // check for running nethack programs
90         nethackWnd = FindWindow(szMainWindowClass, NULL);
91         if( nethackWnd ) {
92                 // bring on top
93                 SetForegroundWindow(nethackWnd);
94                 return FALSE;
95         }
96
97         // init controls
98         ZeroMemory(&InitCtrls, sizeof(InitCtrls));
99         InitCtrls.dwSize = sizeof(InitCtrls);
100         InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
101         if( !InitCommonControlsEx(&InitCtrls) ) {
102                 MessageBox(NULL, TEXT("Cannot init common controls"), TEXT("ERROR"), MB_OK | MB_ICONSTOP);
103                 return FALSE;
104         }
105
106         // Perform application initialization:
107         if (!InitInstance (hInstance, nCmdShow)) 
108         {
109                 return FALSE;
110         }
111
112         /* get command line parameters */       
113         p = _get_cmd_arg(
114 #if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
115                 lpCmdLine
116 #else
117                 GetCommandLine()
118 #endif
119                 );
120         for( argc = 1; p && argc<MAX_CMDLINE_PARAM; argc++ ) {
121                 len = _tcslen(p);
122                 if( len>0 ) {
123                         argv[argc] = _strdup( NH_W2A(p, buf, BUFSZ) );
124                 } else {
125                         argv[argc] = "";
126                 }
127                 p = _get_cmd_arg(NULL);
128         }
129         GetModuleFileName(NULL, wbuf, BUFSZ);
130         argv[0] = _strdup(NH_W2A(wbuf, buf, BUFSZ));
131
132         pcmain(argc,argv);
133
134         moveloop();
135
136         return 0;
137 }
138
139 //
140 //   FUNCTION: InitInstance(HANDLE, int)
141 //
142 //   PURPOSE: Saves instance handle and creates main window
143 //
144 //   COMMENTS:
145 //
146 //        In this function, we save the instance handle in a global variable and
147 //        create and display the main program window.
148 //
149 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
150 {
151    return TRUE;
152 }
153
154 PNHWinApp GetNHApp()
155 {
156         return &_nethack_app;
157 }
158
159 static int
160 eraseoldlocks()
161 {
162         register int i;
163
164         /* cannot use maxledgerno() here, because we need to find a lock name
165          * before starting everything (including the dungeon initialization
166          * that sets astral_level, needed for maxledgerno()) up
167          */
168         for(i = 1; i <= MAXDUNGEON*MAXLEVEL + 1; i++) {
169                 /* try to remove all */
170                 set_levelfile_name(lock, i);
171                 (void) unlink(fqname(lock, LEVELPREFIX, 0));
172         }
173         set_levelfile_name(lock, 0);
174         if(unlink(fqname(lock, LEVELPREFIX, 0)))
175                 return 0;                               /* cannot remove it */
176         return(1);                                      /* success! */
177 }
178
179 void
180 getlock()
181 {
182         const char *fq_lock;
183         char tbuf[BUFSZ];
184         TCHAR wbuf[BUFSZ];
185         HANDLE f;
186         int fd;
187         int choice;
188
189         /* regularize(lock); */ /* already done in pcmain */
190         Sprintf(tbuf, "%s", fqname(lock, LEVELPREFIX, 0));
191         set_levelfile_name(lock, 0);
192         fq_lock = fqname(lock, LEVELPREFIX, 1);
193
194         f = CreateFile(
195                         NH_A2W(fq_lock, wbuf, BUFSZ),
196                         GENERIC_READ,
197                         0,
198                         NULL,
199                         OPEN_EXISTING,
200                         FILE_ATTRIBUTE_NORMAL,
201                         NULL);
202         if( f==INVALID_HANDLE_VALUE ) {
203                 if(GetLastError()==ERROR_FILE_NOT_FOUND) goto gotlock;    /* no such file */
204                 error("Cannot open %s", fq_lock);
205         }
206
207         CloseHandle(f);
208
209         /* prompt user that the game alredy exist */
210         choice = MessageBox(
211                 GetNHApp()->hMainWnd,
212                 TEXT("There are files from a game in progress under your name. Recover?"),
213                 TEXT("Nethack"),
214                 MB_YESNO | MB_DEFBUTTON1 
215                 );
216         switch(choice) {
217         case IDYES:
218                 if(recover_savefile()) {
219                         goto gotlock;
220                 } else {
221                         error("Couldn't recover old game.");
222                 }
223                 break;
224
225         case IDNO: 
226                 unlock_file(HLOCK);
227                 error("%s", "Cannot start a new game.");
228                 break;
229         };
230
231 gotlock:
232         fd = creat(fq_lock, FCMASK);
233         if(fd == -1) {
234                 error("cannot creat lock file (%s.)", fq_lock);
235         } else {
236                 if(write(fd, (char *) &hackpid, sizeof(hackpid))
237                     != sizeof(hackpid)){
238                         error("cannot write lock (%s)", fq_lock);
239                 }
240                 if(close(fd) == -1) {
241                         error("cannot close lock (%s)", fq_lock);
242                 }
243         }
244 }
245
246 /* misc functions */
247 void
248 error VA_DECL(const char *,s)
249         TCHAR  wbuf[1024];
250         char   buf[1024];
251         DWORD last_error = GetLastError();
252
253         VA_START(s);
254         VA_INIT(s, const char *);
255         /* error() may get called before tty is initialized */
256         if (iflags.window_inited) end_screen();
257         
258         vsprintf(buf, s, VA_ARGS);
259         NH_A2W(buf, wbuf, sizeof(wbuf)/sizeof(wbuf[0]));
260         if( last_error>0 ) {
261                 LPVOID lpMsgBuf;
262                 if( FormatMessage( 
263                                 FORMAT_MESSAGE_ALLOCATE_BUFFER | 
264                                 FORMAT_MESSAGE_FROM_SYSTEM | 
265                                 FORMAT_MESSAGE_IGNORE_INSERTS,
266                                 NULL,
267                                 last_error,
268                                 0, // Default language
269                                 (LPTSTR) &lpMsgBuf,
270                                 0,
271                                 NULL 
272                         )
273                         )
274                 {
275                         
276                         _tcsncat(wbuf, TEXT("\nSystem Error: "), sizeof(wbuf)/sizeof(wbuf[0]) - _tcslen(wbuf) );
277                         _tcsncat(wbuf, lpMsgBuf, sizeof(wbuf)/sizeof(wbuf[0]) - _tcslen(wbuf) );
278
279                         // Free the buffer.
280                         LocalFree( lpMsgBuf );
281                 }
282         }
283         VA_END();
284
285         MessageBox( NULL, wbuf, TEXT("Error"), MB_OK | MB_ICONERROR );
286         
287         exit(EXIT_FAILURE);
288 }
289
290 TCHAR* _get_cmd_arg(TCHAR* pCmdLine)
291 {
292     static TCHAR* pArgs = NULL;
293     TCHAR  *pRetArg;
294     BOOL   bQuoted;
295
296     if( !pCmdLine && !pArgs ) return NULL;
297     if( !pArgs ) pArgs = pCmdLine;
298
299     /* skip whitespace */
300     for(pRetArg = pArgs; *pRetArg && _istspace(*pRetArg); pRetArg = CharNext(pRetArg));
301         if( !*pRetArg ) {
302                 pArgs = NULL;
303                 return NULL;
304         }
305
306     /* check for quote */
307     if( *pRetArg==TEXT('"') ) {
308             bQuoted = TRUE;
309             pRetArg = CharNext(pRetArg);
310                         pArgs = _tcschr(pRetArg, TEXT('"'));
311         } else {
312                 /* skip to whitespace */
313                 for(pArgs = pRetArg; *pArgs && !_istspace(*pArgs); pArgs = CharNext(pArgs));
314         }
315         
316         if( pArgs && *pArgs ) {
317                 TCHAR* p;
318                 p = pArgs;
319                 pArgs = CharNext(pArgs);
320                 *p = (TCHAR)0;
321         } else {
322                 pArgs = NULL;
323         }
324
325         return pRetArg;
326 }
327
328 /* 
329  * Strip out troublesome file system characters.
330  */
331
332 void
333 nt_regularize(s)        /* normalize file name */
334 register char *s;
335 {
336         register unsigned char *lp;
337
338         for (lp = s; *lp; lp++)
339             if ( *lp == '?' || *lp == '"' || *lp == '\\' ||
340                  *lp == '/' || *lp == '>' || *lp == '<'  ||
341                  *lp == '*' || *lp == '|' || *lp == ':'  || (*lp > 127))
342                         *lp = '_';
343 }
344
345 void win32_abort()
346 {
347
348 #ifdef WIZARD
349         if (wizard)
350                 DebugBreak();
351 #endif
352         abort();
353 }
354
355 void
356 append_port_id(buf)
357 char *buf;
358 {
359         char *portstr = PORT_CE_PLATFORM " " PORT_CE_CPU;
360         Sprintf(eos(buf), " %s", portstr);
361 }
362