353 lines
9.0 KiB
C
353 lines
9.0 KiB
C
/* NetHack 3.6 winhack.c $NHDT-Date: 1432512799 2015/05/25 00:13:19 $ $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
|
|
/* Copyright (C) 2001 by Alex Kompel */
|
|
// winhack.cpp : Defines the entry point for the application.
|
|
//
|
|
|
|
#include "winMS.h"
|
|
#include "hack.h"
|
|
#include "dlb.h"
|
|
#include "mhmain.h"
|
|
#include "mhmap.h"
|
|
|
|
extern char orgdir[PATHLEN]; /* also used in pcsys.c, amidos.c */
|
|
|
|
extern void nethack_exit(int);
|
|
static TCHAR *_get_cmd_arg(TCHAR *pCmdLine);
|
|
|
|
// Global Variables:
|
|
NHWinApp _nethack_app;
|
|
|
|
// Foward declarations of functions included in this code module:
|
|
BOOL InitInstance(HINSTANCE, int);
|
|
|
|
static void win_hack_init(int, char **);
|
|
static void __cdecl mswin_moveloop(void *);
|
|
static BOOL setMapTiles(const char *fname);
|
|
|
|
extern boolean pcmain(int, char **);
|
|
|
|
#define MAX_CMDLINE_PARAM 255
|
|
|
|
int APIENTRY
|
|
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
INITCOMMONCONTROLSEX InitCtrls;
|
|
HWND nethackWnd;
|
|
int argc;
|
|
char *argv[MAX_CMDLINE_PARAM];
|
|
size_t len;
|
|
TCHAR *p;
|
|
TCHAR wbuf[NHSTR_BUFSIZE];
|
|
char buf[NHSTR_BUFSIZE];
|
|
boolean resuming;
|
|
|
|
early_init();
|
|
|
|
/* ensure that we don't access violate on a panic() */
|
|
windowprocs.win_raw_print = mswin_raw_print;
|
|
windowprocs.win_raw_print_bold = mswin_raw_print_bold;
|
|
|
|
/* init applicatio structure */
|
|
_nethack_app.hApp = hInstance;
|
|
_nethack_app.nCmdShow = nCmdShow;
|
|
_nethack_app.hAccelTable =
|
|
LoadAccelerators(hInstance, (LPCTSTR) IDC_WINHACK);
|
|
_nethack_app.hMainWnd = NULL;
|
|
_nethack_app.hPopupWnd = NULL;
|
|
_nethack_app.hMenuBar = NULL;
|
|
_nethack_app.bmpTiles = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_TILES));
|
|
if (_nethack_app.bmpTiles == NULL)
|
|
panic("cannot load tiles bitmap");
|
|
_nethack_app.bmpPetMark =
|
|
LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_PETMARK));
|
|
if (_nethack_app.bmpPetMark == NULL)
|
|
panic("cannot load pet mark bitmap");
|
|
_nethack_app.bmpMapTiles = _nethack_app.bmpTiles;
|
|
_nethack_app.mapTile_X = TILE_X;
|
|
_nethack_app.mapTile_Y = TILE_Y;
|
|
_nethack_app.mapTilesPerLine = TILES_PER_LINE;
|
|
_nethack_app.bNoHScroll = FALSE;
|
|
_nethack_app.bNoVScroll = FALSE;
|
|
|
|
_nethack_app.bCmdPad = !mswin_has_keyboard();
|
|
|
|
_nethack_app.bWrapText = TRUE;
|
|
_nethack_app.bFullScreen = TRUE;
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
_nethack_app.bHideScrollBars = TRUE;
|
|
#else
|
|
_nethack_app.bHideScrollBars = FALSE;
|
|
#endif
|
|
|
|
_nethack_app.bUseSIP = TRUE;
|
|
|
|
// check for running nethack programs
|
|
nethackWnd = FindWindow(szMainWindowClass, NULL);
|
|
if (nethackWnd) {
|
|
// bring on top
|
|
SetForegroundWindow(nethackWnd);
|
|
return FALSE;
|
|
}
|
|
|
|
// init controls
|
|
ZeroMemory(&InitCtrls, sizeof(InitCtrls));
|
|
InitCtrls.dwSize = sizeof(InitCtrls);
|
|
InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
|
|
if (!InitCommonControlsEx(&InitCtrls)) {
|
|
MessageBox(NULL, TEXT("Cannot init common controls"), TEXT("ERROR"),
|
|
MB_OK | MB_ICONSTOP);
|
|
return FALSE;
|
|
}
|
|
|
|
// Perform application initialization:
|
|
if (!InitInstance(hInstance, nCmdShow)) {
|
|
return FALSE;
|
|
}
|
|
|
|
/* get command line parameters */
|
|
p = _get_cmd_arg(
|
|
#if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
|
|
lpCmdLine
|
|
#else
|
|
GetCommandLine()
|
|
#endif
|
|
);
|
|
for (argc = 1; p && argc < MAX_CMDLINE_PARAM; argc++) {
|
|
len = _tcslen(p);
|
|
if (len > 0) {
|
|
argv[argc] = _strdup(NH_W2A(p, buf, BUFSZ));
|
|
} else {
|
|
argv[argc] = "";
|
|
}
|
|
p = _get_cmd_arg(NULL);
|
|
}
|
|
GetModuleFileName(NULL, wbuf, BUFSZ);
|
|
argv[0] = _strdup(NH_W2A(wbuf, buf, BUFSZ));
|
|
|
|
resuming = pcmain(argc, argv);
|
|
|
|
moveloop(resuming);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// FUNCTION: InitInstance(HANDLE, int)
|
|
//
|
|
// PURPOSE: Saves instance handle and creates main window
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
// In this function, we save the instance handle in a global variable
|
|
// and
|
|
// create and display the main program window.
|
|
//
|
|
BOOL
|
|
InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
PNHWinApp
|
|
GetNHApp()
|
|
{
|
|
return &_nethack_app;
|
|
}
|
|
|
|
static int
|
|
eraseoldlocks()
|
|
{
|
|
register int i;
|
|
|
|
/* cannot use maxledgerno() here, because we need to find a lock name
|
|
* before starting everything (including the dungeon initialization
|
|
* that sets astral_level, needed for maxledgerno()) up
|
|
*/
|
|
for (i = 1; i <= MAXDUNGEON * MAXLEVEL + 1; i++) {
|
|
/* try to remove all */
|
|
set_levelfile_name(g.lock, i);
|
|
(void) unlink(fqname(g.lock, LEVELPREFIX, 0));
|
|
}
|
|
set_levelfile_name(g.lock, 0);
|
|
if (unlink(fqname(g.lock, LEVELPREFIX, 0)))
|
|
return 0; /* cannot remove it */
|
|
return (1); /* success! */
|
|
}
|
|
|
|
void
|
|
getlock()
|
|
{
|
|
const char *fq_lock;
|
|
char tbuf[BUFSZ];
|
|
TCHAR wbuf[BUFSZ];
|
|
HANDLE f;
|
|
int fd;
|
|
int choice;
|
|
|
|
/* regularize(lock); */ /* already done in pcmain */
|
|
Sprintf(tbuf, "%s", fqname(g.lock, LEVELPREFIX, 0));
|
|
set_levelfile_name(g.lock, 0);
|
|
fq_lock = fqname(g.lock, LEVELPREFIX, 1);
|
|
|
|
f = CreateFile(NH_A2W(fq_lock, wbuf, BUFSZ), GENERIC_READ, 0, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (f == INVALID_HANDLE_VALUE) {
|
|
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
|
goto gotlock; /* no such file */
|
|
error("Cannot open %s", fq_lock);
|
|
}
|
|
|
|
CloseHandle(f);
|
|
|
|
/* prompt user that the game alredy exist */
|
|
choice = MessageBox(GetNHApp()->hMainWnd,
|
|
TEXT("There are files from a game in progress under "
|
|
"your name. Recover?"),
|
|
TEXT("Nethack"), MB_YESNO | MB_DEFBUTTON1);
|
|
switch (choice) {
|
|
case IDYES:
|
|
if (recover_savefile()) {
|
|
goto gotlock;
|
|
} else {
|
|
error("Couldn't recover old game.");
|
|
}
|
|
break;
|
|
|
|
case IDNO:
|
|
unlock_file(HLOCK);
|
|
error("%s", "Cannot start a new game.");
|
|
break;
|
|
};
|
|
|
|
gotlock:
|
|
fd = creat(fq_lock, FCMASK);
|
|
if (fd == -1) {
|
|
error("cannot creat lock file (%s.)", fq_lock);
|
|
} else {
|
|
if (write(fd, (char *) &g.hackpid, sizeof(g.hackpid))
|
|
!= sizeof(g.hackpid)) {
|
|
error("cannot write lock (%s)", fq_lock);
|
|
}
|
|
if (close(fd) == -1) {
|
|
error("cannot close lock (%s)", fq_lock);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* misc functions */
|
|
void error
|
|
VA_DECL(const char *, s)
|
|
{
|
|
TCHAR wbuf[1024];
|
|
char buf[1024];
|
|
DWORD last_error = GetLastError();
|
|
|
|
VA_START(s);
|
|
VA_INIT(s, const char *);
|
|
/* error() may get called before tty is initialized */
|
|
if (iflags.window_inited)
|
|
end_screen();
|
|
|
|
vsprintf(buf, s, VA_ARGS);
|
|
NH_A2W(buf, wbuf, sizeof(wbuf) / sizeof(wbuf[0]));
|
|
if (last_error > 0) {
|
|
LPVOID lpMsgBuf;
|
|
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
| FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL, last_error,
|
|
0, // Default language
|
|
(LPTSTR) &lpMsgBuf, 0, NULL)) {
|
|
_tcsncat(wbuf, TEXT("\nSystem Error: "),
|
|
sizeof(wbuf) / sizeof(wbuf[0]) - _tcslen(wbuf));
|
|
_tcsncat(wbuf, lpMsgBuf,
|
|
sizeof(wbuf) / sizeof(wbuf[0]) - _tcslen(wbuf));
|
|
|
|
// Free the buffer.
|
|
LocalFree(lpMsgBuf);
|
|
}
|
|
}
|
|
MessageBox(NULL, wbuf, TEXT("Error"), MB_OK | MB_ICONERROR);
|
|
VA_END();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
TCHAR *
|
|
_get_cmd_arg(TCHAR *pCmdLine)
|
|
{
|
|
static TCHAR *pArgs = NULL;
|
|
TCHAR *pRetArg;
|
|
BOOL bQuoted;
|
|
|
|
if (!pCmdLine && !pArgs)
|
|
return NULL;
|
|
if (!pArgs)
|
|
pArgs = pCmdLine;
|
|
|
|
/* skip whitespace */
|
|
for (pRetArg = pArgs; *pRetArg && _istspace(*pRetArg);
|
|
pRetArg = CharNext(pRetArg))
|
|
;
|
|
if (!*pRetArg) {
|
|
pArgs = NULL;
|
|
return NULL;
|
|
}
|
|
|
|
/* check for quote */
|
|
if (*pRetArg == TEXT('"')) {
|
|
bQuoted = TRUE;
|
|
pRetArg = CharNext(pRetArg);
|
|
pArgs = _tcschr(pRetArg, TEXT('"'));
|
|
} else {
|
|
/* skip to whitespace */
|
|
for (pArgs = pRetArg; *pArgs && !_istspace(*pArgs);
|
|
pArgs = CharNext(pArgs))
|
|
;
|
|
}
|
|
|
|
if (pArgs && *pArgs) {
|
|
TCHAR *p;
|
|
p = pArgs;
|
|
pArgs = CharNext(pArgs);
|
|
*p = (TCHAR) 0;
|
|
} else {
|
|
pArgs = NULL;
|
|
}
|
|
|
|
return pRetArg;
|
|
}
|
|
|
|
/*
|
|
* Strip out troublesome file system characters.
|
|
*/
|
|
|
|
void nt_regularize(s) /* normalize file name */
|
|
register char *s;
|
|
{
|
|
register unsigned char *lp;
|
|
|
|
for (lp = s; *lp; lp++)
|
|
if (*lp == '?' || *lp == '"' || *lp == '\\' || *lp == '/'
|
|
|| *lp == '>' || *lp == '<' || *lp == '*' || *lp == '|'
|
|
|| *lp == ':' || (*lp > 127))
|
|
*lp = '_';
|
|
}
|
|
|
|
void
|
|
win32_abort()
|
|
{
|
|
if (wizard)
|
|
DebugBreak();
|
|
abort();
|
|
}
|
|
|
|
void
|
|
append_port_id(buf)
|
|
char *buf;
|
|
{
|
|
char *portstr = PORT_CE_PLATFORM " " PORT_CE_CPU;
|
|
Sprintf(eos(buf), " %s", portstr);
|
|
}
|