summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-17 04:05:19 +0000
committerennewalker <ennewalker@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-17 04:05:19 +0000
commitd13cbe6df4ddec4d27b8e2077cf7c3672e3cdab8 (patch)
tree9cfab188a751369eb48c7870ce5ac1b747625cd8
parent61ebfeda71005384365b4598594e03bbdaec1e05 (diff)
downloadcrawl-ref-d13cbe6df4ddec4d27b8e2077cf7c3672e3cdab8.tar.gz
crawl-ref-d13cbe6df4ddec4d27b8e2077cf7c3672e3cdab8.zip
[2021551] Fixing Windows 98 crash.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.4@7853 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/libwt.cc1161
1 files changed, 582 insertions, 579 deletions
diff --git a/crawl-ref/source/libwt.cc b/crawl-ref/source/libwt.cc
index 72f23ac872..eb48c63a12 100644
--- a/crawl-ref/source/libwt.cc
+++ b/crawl-ref/source/libwt.cc
@@ -1,579 +1,582 @@
-/*
- * File: guic-win.cc
- * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC
- *
- * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $
- */
-
-#define _WIN32_WINNT 0x0501
-
-#include <windows.h>
-#include <windowsx.h>
-#include <commdlg.h>
-#include <commctrl.h>
-
-// GDT_NONE in commctrl.h conflicts with enum.h
-#ifdef GDT_NONE
-#undef GDT_NONE
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
-#include <tchar.h>
-#include <fcntl.h>
-
-#include "AppHdr.h"
-#include "cio.h"
-#include "debug.h"
-#include "externs.h"
-#include "files.h"
-#include "guic.h"
-#include "itemprop.h"
-#include "state.h"
-#include "tiles.h"
-
-extern int old_main(int argc, char *argv[]);
-
-extern WinClass *win_main;
-extern TileRegionClass *region_tile;
-extern img_type TileImg;
-extern BYTE pix_transparent;
-
-typedef struct ev_data
-{
- int type;
- int key;
- int x1, y1;
- bool sh, ct;
-}ev_data;
-
-#define EV_MAX 1024
-struct ev_data ev_cue[EV_MAX];
-
-static int ev_head = 0;
-static int ev_tail = 0;
-void ev_push(struct ev_data *e);
-static bool skip_key = false;
-
-// Tip text
-static TOOLINFO tiTip;
-static HWND hTool;
-static HWND pWin;
-
-#ifdef USE_TILE
-#define PAL_STD 0 //standard palette
-#define PAL_BER 1 //berserk palette
-#define PAL_SHA 2 //shadow palette
-static int palette = PAL_STD;
-LPBYTE lpPalettes[3] ;
-#endif
-
-#define DF_TOOLTIP_WIDTH 300
-
-ATOM MyRegisterClass( HINSTANCE hInstance );
-BOOL InitInstance( HINSTANCE, int );
-LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
-
-bool libgui_init_sys();
-void libgui_shutdown_sys();
-void update_tip_text(const char *tip);
-
-void GetNextEvent(int *etype, int *key, bool *shift, bool *ctrl,
- int *x1, int *y1, int *x2, int *y2);
-void TileInitWin();
-void delay(unsigned long ms);
-int kbhit();
-
-/***************************/
-void TileInitWin()
-{
- int i;
-
- TileImg->pDib->bmiColors[pix_transparent].rgbRed = 0;
- TileImg->pDib->bmiColors[pix_transparent].rgbGreen = 0;
- TileImg->pDib->bmiColors[pix_transparent].rgbBlue = 0;
-
- RegionClass::set_std_palette(&TileImg->pDib->bmiColors[0]);
-
- WORD chcol;
- lpPalettes[0] = (LPBYTE) (&TileImg->pDib->bmiColors[0]);
- lpPalettes[1] = (LPBYTE)GlobalAlloc(GPTR, 256 * sizeof(RGBQUAD) );
- lpPalettes[2] = (LPBYTE)GlobalAlloc(GPTR, 256 * sizeof(RGBQUAD) );
- for (i = 0; i < 256; i++)
- {
- chcol = (TileImg->pDib->bmiColors[i].rgbRed * 30
- + TileImg->pDib->bmiColors[i].rgbGreen * 59
- + TileImg->pDib->bmiColors[i].rgbBlue * 11) / 100;
- LPBYTE ptr = lpPalettes[1] + i * sizeof(RGBQUAD);
- ptr[2] = (BYTE)chcol;
- ptr[0] = (BYTE)( (chcol +1)/6 );
- ptr[1] = (BYTE)( (chcol +1)/6 );
-
- ptr = lpPalettes[2] + i * sizeof(RGBQUAD);
- ptr[2] = ptr[0] = ptr[1] = (BYTE)chcol;
- }
-}
-
-void update_tip_text(const char *tip)
-{
-#define MAXTIP 512
- static char oldtip[MAXTIP+1];
- if (strncmp(oldtip, tip, MAXTIP) == 0)
- return;
-
- strncpy(oldtip, tip, MAXTIP);
- tiTip.lpszText = (char *)tip;
- SendMessage(hTool, TTM_UPDATETIPTEXT, 0, (LPARAM)&tiTip);
-}
-
-bool libgui_init_sys( )
-{
- return (true);
-}
-
-void libgui_shutdown_sys()
-{
- GlobalFree(lpPalettes[1]);
- GlobalFree(lpPalettes[2]);
- DestroyWindow( pWin );
-}
-
-void GetNextEvent(int *etype, int *key, bool *sh, bool *ct,
- int *x1, int *y1, int *x2, int *y2)
-{
- MSG msg;
-
- while ( GetMessage(&msg, NULL, 0, 0) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- if (ev_tail != ev_head)
- break;
- }
- struct ev_data *e = &ev_cue[ev_head];
- ev_head++;
- if (ev_head == EV_MAX)
- ev_head = 0;
-
- *etype = e->type;
- *key = e->key;
- *sh = e->sh;
- *ct = e->ct;
- *x1 = e->x1;
- *y1 = e->y1;
-}
-
-void ev_push(struct ev_data *e)
-{
- ev_cue[ev_tail] = *e;
- ev_tail++;
- if (ev_tail == EV_MAX)
- ev_tail = 0;
-}
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
-{
- MSG msg;
-
- MyRegisterClass( hInstance );
-
- GuicInit(hInstance, nCmdShow);
-
- // AttachConsole is a WindowsXP and above function. If this function
- // doesn't exist, then don't call it. Call this function indirectly
- // via GetProcAddress so that it is not implicitly linked in.
-
- typedef BOOL (WINAPI *ac_func)(DWORD);
- ac_func attach_console = (ac_func)GetProcAddress(
- GetModuleHandle(TEXT("kernel32.dll")), "AttachConsole");
- typedef BOOL (WINAPI *fc_func)(void);
- fc_func free_console = (fc_func)GetProcAddress(
- GetModuleHandle(TEXT("kernel32.dll")), "FreeConsole");
-
- if (attach_console && free_console)
- {
- // Redirect output to the console
- attach_console(ATTACH_PARENT_PROCESS);
- freopen("CONOUT$", "wb", stdout);
- freopen("CONOUT$", "wb", stderr);
- }
-
- // I'll be damned if I have to parse lpCmdLine myself...
- int argc;
- LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
- char **argv = new char*[argc];
- int args_len = wcslen(GetCommandLineW()) + argc;
- char *args = new char[args_len];
-
- char *ptr = args;
- for (int i = 0; i < argc; i++)
- {
- wsprintfA(ptr, "%S", wargv[i]);
- argv[i] = ptr;
- ptr += strlen(argv[i]) + 1;
- }
- ASSERT(ptr <= args + args_len);
-
- old_main(argc, argv);
-
- delete args;
- delete argv;
-
- if (attach_console && free_console)
- {
- free_console();
- }
-
- return msg.wParam;
-}
-
-
-ATOM MyRegisterClass( HINSTANCE hInstance )
-{
- WNDCLASSEX wcex;
-
- wcex.cbSize = sizeof(WNDCLASSEX);
-
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = (WNDPROC)WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, TEXT("CRAWL_ICON"));
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wcex.lpszMenuName = "CRAWL";
- wcex.lpszClassName = "CrawlList";
- wcex.hIconSm = NULL;//LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
-
- return RegisterClassEx( &wcex );
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
-
- struct ev_data ev;
- static int clix = 0;
- static int cliy = 0;
-
- // For keypad
- const unsigned char ck_table[9] =
- {
- CK_END, CK_DOWN, CK_PGDN,
- CK_LEFT, CK_INSERT, CK_RIGHT,
- CK_HOME, CK_UP, CK_PGUP
- };
-
- switch( message )
- {
- case WM_CREATE:
- {
- pWin = hWnd;
-
- // Example taken from
- // http://black.sakura.ne.jp/~third/system/winapi/common10.html
- InitCommonControls();
- hTool = CreateWindowEx( 0 , TOOLTIPS_CLASS ,
- NULL , TTS_ALWAYSTIP ,
- CW_USEDEFAULT , CW_USEDEFAULT ,
- CW_USEDEFAULT , CW_USEDEFAULT ,
- hWnd , NULL , ((LPCREATESTRUCT)(lParam))->hInstance ,
- NULL
- );
- GetClientRect(hWnd , &tiTip.rect);
-
- tiTip.cbSize = sizeof (TOOLINFO);
- tiTip.uFlags = TTF_SUBCLASS;
- tiTip.hwnd = hWnd;
- tiTip.lpszText = (char *)
- "This text will tell you" EOL
- " what you are pointing";
- SendMessage(hTool, TTM_ADDTOOL , 0 , (LPARAM)&tiTip);
- // Allow line wrap
- SendMessage(hTool, TTM_SETMAXTIPWIDTH, 0, DF_TOOLTIP_WIDTH);
- return 0;
- }
-
- case WM_RBUTTONDOWN:
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- {
- ev.type = EV_BUTTON;
- ev.x1 = LOWORD(lParam);
- ev.y1 = HIWORD(lParam);
- ev.key = 1;
- ev.sh = ((GetKeyState(VK_SHIFT) & 0x80) != 0)? true : false;
- ev.ct = ((GetKeyState(VK_CONTROL) & 0x80) != 0)? true : false;
- if (message == WM_RBUTTONDOWN) ev.key = 2;
- if (message == WM_MBUTTONDOWN) ev.key = 3;
- ev_push(&ev);
- return 0;
- }
-
- case WM_RBUTTONUP:
- {
- ev.type = EV_UNBUTTON;
- ev.x1 = LOWORD(lParam);
- ev.y1 = HIWORD(lParam);
- ev.key = 1;
- if (message == WM_RBUTTONUP) ev.key = 2;
- if (message == WM_MBUTTONUP) ev.key = 3;
- ev_push(&ev);
- return 0;
- }
-
- case WM_MOUSEWHEEL:
- {
- int z = (short)HIWORD(wParam);
- ev.x1 = LOWORD(lParam) - clix;
- ev.y1 = HIWORD(lParam) - cliy;
- ev.type = EV_BUTTON;
- ev.sh = ((GetKeyState(VK_SHIFT) & 0x80) != 0) ? true : false;
- ev.ct = ((GetKeyState(VK_CONTROL) & 0x80) != 0) ? true : false;
- ev.key = (z > 0) ? 4 : 5;
- ev_push(&ev);
- return 0;
- }
-
- case WM_MOUSEMOVE:
- {
- ev.type = EV_MOVE;
- ev.x1 = LOWORD(lParam);
- ev.y1 = HIWORD(lParam);
- ev_push(&ev);
- return 0;
- }
-
- case WM_KEYDOWN:
- {
- int ch = (int) wParam;
- int result = 0;
- int dir = 0;
- bool fs = ((GetKeyState(VK_SHIFT) & 0x80) != 0)? true : false;
- bool fc = ((GetKeyState(VK_CONTROL)& 0x80) != 0)? true : false;
- bool fa = ((GetKeyState(VK_MENU) & 0x80) != 0)? true : false;
-
- if (ch >= VK_NUMPAD1 && ch <= VK_NUMPAD9)
- {
- skip_key = true;
- dir = ch - VK_NUMPAD0;
- }
- else if (VK_PRIOR <= ch && ch <= VK_DOWN || ch == VK_CLEAR)
- {
- switch(ch)
- {
- case VK_LEFT: dir = 4; break;
- case VK_RIGHT: dir = 6; break;
- case VK_UP: dir = 8; break;
- case VK_DOWN: dir = 2; break;
- case VK_HOME: dir = 7; break;
- case VK_PRIOR: dir = 9; break;
- case VK_NEXT: dir = 3; break;
- case VK_END: dir = 1; break;
- case VK_CLEAR: dir = 5; break;
- }
- }
-
- if (dir != 0)
- {
- ch = ck_table[dir-1];
- if (fc)
- ch += CK_CTRL_UP - CK_UP;
- if (fs)
- ch += CK_SHIFT_UP - CK_UP;
-
- if (fa)
- ch |= 2048;
- ev.key = ch;
- ev.type = EV_KEYIN;
- ev_push(&ev);
- return 0;
- }
- else if (ch >= VK_PAUSE
- && (ch < VK_CAPITAL || ch > VK_SPACE)
- && ch != VK_PROCESSKEY
- && ch != VK_NUMLOCK
- && (ch < VK_LSHIFT || ch > VK_RMENU)
- && (ch < 0x30 || ch > 0x39)
- && (ch < 0x41 || ch > 0x5a)
- && (ch < 0xa6 || ch > 0xe4))
- {
- result = 300 + ch;
- }
-
- if (result)
- {
- if (fs) result |= 512;
- if (fc) result |= 1024;
- if (fa) result |= 2048;
- ev.key = result;
- ev.type = EV_KEYIN;
- ev_push(&ev);
- }
-
- return 0;
- }
-
- case WM_CHAR:
- {
- if (skip_key)
- {
- skip_key = false;
- return 0;
- }
- ev.key = (int)wParam;
- ev.type = EV_KEYIN;
- ev_push(&ev);
- return 0;
- }
-
- case WM_PAINT:
- {
- hdc = BeginPaint(hWnd, &ps);
- win_main->redraw();
- EndPaint(hWnd, &ps);
- return 0;
- }
-
- case WM_MOVE:
- {
- clix = LOWORD(lParam);
- cliy = HIWORD(lParam);
- return 0;
- }
-
- case WM_COMMAND:
- {
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- switch( wmId )
- {
- // XXX: Isn't that always the case?
- default:
- return DefWindowProc( hWnd, message, wParam, lParam );
- }
- return 0;
- }
- case WM_CLOSE:
- if (mouse_get_mode() == MOUSE_MODE_COMMAND
- || !crawl_state.need_save )
- {
- if (crawl_state.need_save)
- save_game(true);
-
- libgui_shutdown();
- }
- break;
-
- case WM_DESTROY:
- {
- PostQuitMessage( 0 );
- exit(0);
- break;
- }
- default:
- return DefWindowProc( hWnd, message, wParam, lParam );
- }
- return 0;
-}
-
-#ifdef USE_TILE
-void TileDrawDungeonAux()
-{
- dib_pack *pBuf = region_tile->backbuf;
-
- int new_palette = PAL_STD; // standard
- if (you.duration[DUR_BERSERKER])
- new_palette = PAL_BER;
-
- // XXX: is this supposed to override Berserk?
- if (you.special_wield == SPWLD_SHADOW)
- new_palette = PAL_SHA;
-
- if (new_palette != palette)
- {
- palette = new_palette;
- SetDIBColorTable(pBuf->hDC, 0, 256, (RGBQUAD *)lpPalettes[palette]);
- }
-}
-#endif
-
-bool windows_change_font(char *font_name, int *font_size, bool dos)
-{
- CHOOSEFONT cf;
-
- memset(&cf, 0, sizeof(cf));
- cf.lStructSize = sizeof(cf);
- cf.iPointSize = *font_size;
- cf.nSizeMin = 8;
- cf.nSizeMax = 24;
- cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_NOVERTFONTS
- | CF_INITTOLOGFONTSTRUCT | CF_LIMITSIZE | CF_FORCEFONTEXIST;
-
- LOGFONT lf;
- strcpy(lf.lfFaceName, font_name);
- lf.lfHeight = 16;
- lf.lfWidth = 0;
- lf.lfEscapement = 0;
- lf.lfOrientation = lf.lfEscapement;
- lf.lfWeight = FW_NORMAL;
- lf.lfItalic = FALSE;
- lf.lfUnderline = FALSE;
- lf.lfStrikeOut = FALSE;
- lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
- lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- lf.lfQuality = DEFAULT_QUALITY;
- lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH;
- lf.lfCharSet = (dos)? OEM_CHARSET:ANSI_CHARSET;
- cf.lpLogFont = &lf;
-
- if (ChooseFont(&cf))
- {
- *font_size = (cf.iPointSize / 10);
- strcpy(font_name, lf.lfFaceName);
- return (true);
- }
- return (false);
-}
-
-void windows_get_winpos(int *x, int *y)
-{
- WINDOWPLACEMENT wndpl;
-
- // set length
- wndpl.length = sizeof( WINDOWPLACEMENT );
-
- if (GetWindowPlacement( win_main->hWnd, &wndpl ) != 0)
- {
- *x = wndpl.rcNormalPosition.top;
- *y = wndpl.rcNormalPosition.left;
- }
-}
-
-void delay(unsigned long ms)
-{
- Sleep((DWORD)ms);
-}
-
-int kbhit()
-{
- MSG msg;
-
- if (PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, PM_NOREMOVE)
- || PeekMessage(&msg, NULL, WM_KEYDOWN, WM_KEYDOWN, PM_NOREMOVE))
- {
- return 1;
- }
- else
- return 0;
-}
-
-void update_screen()
-{
-}
+/*
+ * File: guic-win.cc
+ * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC
+ *
+ * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2008-03-07 $
+ */
+
+#define _WIN32_WINNT 0x0501
+
+#include <windows.h>
+#include <windowsx.h>
+#include <commdlg.h>
+#include <commctrl.h>
+
+// GDT_NONE in commctrl.h conflicts with enum.h
+#ifdef GDT_NONE
+#undef GDT_NONE
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <memory.h>
+#include <tchar.h>
+#include <fcntl.h>
+
+#include "AppHdr.h"
+#include "cio.h"
+#include "debug.h"
+#include "externs.h"
+#include "files.h"
+#include "guic.h"
+#include "itemprop.h"
+#include "state.h"
+#include "tiles.h"
+
+extern int old_main(int argc, char *argv[]);
+
+extern WinClass *win_main;
+extern TileRegionClass *region_tile;
+extern img_type TileImg;
+extern BYTE pix_transparent;
+
+typedef struct ev_data
+{
+ int type;
+ int key;
+ int x1, y1;
+ bool sh, ct;
+}ev_data;
+
+#define EV_MAX 1024
+struct ev_data ev_cue[EV_MAX];
+
+static int ev_head = 0;
+static int ev_tail = 0;
+void ev_push(struct ev_data *e);
+static bool skip_key = false;
+
+// Tip text
+static TOOLINFO tiTip;
+static HWND hTool;
+static HWND pWin;
+
+#ifdef USE_TILE
+#define PAL_STD 0 //standard palette
+#define PAL_BER 1 //berserk palette
+#define PAL_SHA 2 //shadow palette
+static int palette = PAL_STD;
+LPBYTE lpPalettes[3] ;
+#endif
+
+#define DF_TOOLTIP_WIDTH 300
+
+ATOM MyRegisterClass( HINSTANCE hInstance );
+BOOL InitInstance( HINSTANCE, int );
+LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
+
+bool libgui_init_sys();
+void libgui_shutdown_sys();
+void update_tip_text(const char *tip);
+
+void GetNextEvent(int *etype, int *key, bool *shift, bool *ctrl,
+ int *x1, int *y1, int *x2, int *y2);
+void TileInitWin();
+void delay(unsigned long ms);
+int kbhit();
+
+/***************************/
+void TileInitWin()
+{
+ int i;
+
+ TileImg->pDib->bmiColors[pix_transparent].rgbRed = 0;
+ TileImg->pDib->bmiColors[pix_transparent].rgbGreen = 0;
+ TileImg->pDib->bmiColors[pix_transparent].rgbBlue = 0;
+
+ RegionClass::set_std_palette(&TileImg->pDib->bmiColors[0]);
+
+ WORD chcol;
+ lpPalettes[0] = (LPBYTE) (&TileImg->pDib->bmiColors[0]);
+ lpPalettes[1] = (LPBYTE)GlobalAlloc(GPTR, 256 * sizeof(RGBQUAD) );
+ lpPalettes[2] = (LPBYTE)GlobalAlloc(GPTR, 256 * sizeof(RGBQUAD) );
+ for (i = 0; i < 256; i++)
+ {
+ chcol = (TileImg->pDib->bmiColors[i].rgbRed * 30
+ + TileImg->pDib->bmiColors[i].rgbGreen * 59
+ + TileImg->pDib->bmiColors[i].rgbBlue * 11) / 100;
+ LPBYTE ptr = lpPalettes[1] + i * sizeof(RGBQUAD);
+ ptr[2] = (BYTE)chcol;
+ ptr[0] = (BYTE)( (chcol +1)/6 );
+ ptr[1] = (BYTE)( (chcol +1)/6 );
+
+ ptr = lpPalettes[2] + i * sizeof(RGBQUAD);
+ ptr[2] = ptr[0] = ptr[1] = (BYTE)chcol;
+ }
+}
+
+void update_tip_text(const char *tip)
+{
+#define MAXTIP 512
+ static char oldtip[MAXTIP+1];
+ if (strncmp(oldtip, tip, MAXTIP) == 0)
+ return;
+
+ strncpy(oldtip, tip, MAXTIP);
+ tiTip.lpszText = (char *)tip;
+ SendMessage(hTool, TTM_UPDATETIPTEXT, 0, (LPARAM)&tiTip);
+}
+
+bool libgui_init_sys( )
+{
+ return (true);
+}
+
+void libgui_shutdown_sys()
+{
+ GlobalFree(lpPalettes[1]);
+ GlobalFree(lpPalettes[2]);
+ DestroyWindow( pWin );
+}
+
+void GetNextEvent(int *etype, int *key, bool *sh, bool *ct,
+ int *x1, int *y1, int *x2, int *y2)
+{
+ MSG msg;
+
+ while ( GetMessage(&msg, NULL, 0, 0) )
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ if (ev_tail != ev_head)
+ break;
+ }
+ struct ev_data *e = &ev_cue[ev_head];
+ ev_head++;
+ if (ev_head == EV_MAX)
+ ev_head = 0;
+
+ *etype = e->type;
+ *key = e->key;
+ *sh = e->sh;
+ *ct = e->ct;
+ *x1 = e->x1;
+ *y1 = e->y1;
+}
+
+void ev_push(struct ev_data *e)
+{
+ ev_cue[ev_tail] = *e;
+ ev_tail++;
+ if (ev_tail == EV_MAX)
+ ev_tail = 0;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nCmdShow )
+{
+ MSG msg;
+
+ MyRegisterClass( hInstance );
+
+ GuicInit(hInstance, nCmdShow);
+
+ // AttachConsole is a WindowsXP and above function. If this function
+ // doesn't exist, then don't call it. Call this function indirectly
+ // via GetProcAddress so that it is not implicitly linked in.
+
+ typedef BOOL (WINAPI *ac_func)(DWORD);
+ ac_func attach_console = (ac_func)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "AttachConsole");
+ typedef BOOL (WINAPI *fc_func)(void);
+ fc_func free_console = (fc_func)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "FreeConsole");
+
+ if (attach_console && free_console)
+ {
+ // Redirect output to the console
+ attach_console(ATTACH_PARENT_PROCESS);
+ freopen("CONOUT$", "wb", stdout);
+ freopen("CONOUT$", "wb", stderr);
+ }
+
+ // I'll be damned if I have to parse lpCmdLine myself...
+ int argc;
+ LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
+ // Windows 98 fix.
+ if (!wargv)
+ argc = 0;
+ char **argv = new char*[argc];
+ int args_len = wcslen(GetCommandLineW()) + argc;
+ char *args = new char[args_len];
+
+ char *ptr = args;
+ for (int i = 0; i < argc; i++)
+ {
+ wsprintfA(ptr, "%S", wargv[i]);
+ argv[i] = ptr;
+ ptr += strlen(argv[i]) + 1;
+ }
+ ASSERT(ptr <= args + args_len);
+
+ old_main(argc, argv);
+
+ delete args;
+ delete argv;
+
+ if (attach_console && free_console)
+ {
+ free_console();
+ }
+
+ return msg.wParam;
+}
+
+
+ATOM MyRegisterClass( HINSTANCE hInstance )
+{
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = (WNDPROC)WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon(hInstance, TEXT("CRAWL_ICON"));
+ wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wcex.lpszMenuName = "CRAWL";
+ wcex.lpszClassName = "CrawlList";
+ wcex.hIconSm = NULL;//LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
+
+ return RegisterClassEx( &wcex );
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId, wmEvent;
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ struct ev_data ev;
+ static int clix = 0;
+ static int cliy = 0;
+
+ // For keypad
+ const unsigned char ck_table[9] =
+ {
+ CK_END, CK_DOWN, CK_PGDN,
+ CK_LEFT, CK_INSERT, CK_RIGHT,
+ CK_HOME, CK_UP, CK_PGUP
+ };
+
+ switch( message )
+ {
+ case WM_CREATE:
+ {
+ pWin = hWnd;
+
+ // Example taken from
+ // http://black.sakura.ne.jp/~third/system/winapi/common10.html
+ InitCommonControls();
+ hTool = CreateWindowEx( 0 , TOOLTIPS_CLASS ,
+ NULL , TTS_ALWAYSTIP ,
+ CW_USEDEFAULT , CW_USEDEFAULT ,
+ CW_USEDEFAULT , CW_USEDEFAULT ,
+ hWnd , NULL , ((LPCREATESTRUCT)(lParam))->hInstance ,
+ NULL
+ );
+ GetClientRect(hWnd , &tiTip.rect);
+
+ tiTip.cbSize = sizeof (TOOLINFO);
+ tiTip.uFlags = TTF_SUBCLASS;
+ tiTip.hwnd = hWnd;
+ tiTip.lpszText = (char *)
+ "This text will tell you" EOL
+ " what you are pointing";
+ SendMessage(hTool, TTM_ADDTOOL , 0 , (LPARAM)&tiTip);
+ // Allow line wrap
+ SendMessage(hTool, TTM_SETMAXTIPWIDTH, 0, DF_TOOLTIP_WIDTH);
+ return 0;
+ }
+
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ {
+ ev.type = EV_BUTTON;
+ ev.x1 = LOWORD(lParam);
+ ev.y1 = HIWORD(lParam);
+ ev.key = 1;
+ ev.sh = ((GetKeyState(VK_SHIFT) & 0x80) != 0)? true : false;
+ ev.ct = ((GetKeyState(VK_CONTROL) & 0x80) != 0)? true : false;
+ if (message == WM_RBUTTONDOWN) ev.key = 2;
+ if (message == WM_MBUTTONDOWN) ev.key = 3;
+ ev_push(&ev);
+ return 0;
+ }
+
+ case WM_RBUTTONUP:
+ {
+ ev.type = EV_UNBUTTON;
+ ev.x1 = LOWORD(lParam);
+ ev.y1 = HIWORD(lParam);
+ ev.key = 1;
+ if (message == WM_RBUTTONUP) ev.key = 2;
+ if (message == WM_MBUTTONUP) ev.key = 3;
+ ev_push(&ev);
+ return 0;
+ }
+
+ case WM_MOUSEWHEEL:
+ {
+ int z = (short)HIWORD(wParam);
+ ev.x1 = LOWORD(lParam) - clix;
+ ev.y1 = HIWORD(lParam) - cliy;
+ ev.type = EV_BUTTON;
+ ev.sh = ((GetKeyState(VK_SHIFT) & 0x80) != 0) ? true : false;
+ ev.ct = ((GetKeyState(VK_CONTROL) & 0x80) != 0) ? true : false;
+ ev.key = (z > 0) ? 4 : 5;
+ ev_push(&ev);
+ return 0;
+ }
+
+ case WM_MOUSEMOVE:
+ {
+ ev.type = EV_MOVE;
+ ev.x1 = LOWORD(lParam);
+ ev.y1 = HIWORD(lParam);
+ ev_push(&ev);
+ return 0;
+ }
+
+ case WM_KEYDOWN:
+ {
+ int ch = (int) wParam;
+ int result = 0;
+ int dir = 0;
+ bool fs = ((GetKeyState(VK_SHIFT) & 0x80) != 0)? true : false;
+ bool fc = ((GetKeyState(VK_CONTROL)& 0x80) != 0)? true : false;
+ bool fa = ((GetKeyState(VK_MENU) & 0x80) != 0)? true : false;
+
+ if (ch >= VK_NUMPAD1 && ch <= VK_NUMPAD9)
+ {
+ skip_key = true;
+ dir = ch - VK_NUMPAD0;
+ }
+ else if (VK_PRIOR <= ch && ch <= VK_DOWN || ch == VK_CLEAR)
+ {
+ switch(ch)
+ {
+ case VK_LEFT: dir = 4; break;
+ case VK_RIGHT: dir = 6; break;
+ case VK_UP: dir = 8; break;
+ case VK_DOWN: dir = 2; break;
+ case VK_HOME: dir = 7; break;
+ case VK_PRIOR: dir = 9; break;
+ case VK_NEXT: dir = 3; break;
+ case VK_END: dir = 1; break;
+ case VK_CLEAR: dir = 5; break;
+ }
+ }
+
+ if (dir != 0)
+ {
+ ch = ck_table[dir-1];
+ if (fc)
+ ch += CK_CTRL_UP - CK_UP;
+ if (fs)
+ ch += CK_SHIFT_UP - CK_UP;
+
+ if (fa)
+ ch |= 2048;
+ ev.key = ch;
+ ev.type = EV_KEYIN;
+ ev_push(&ev);
+ return 0;
+ }
+ else if (ch >= VK_PAUSE
+ && (ch < VK_CAPITAL || ch > VK_SPACE)
+ && ch != VK_PROCESSKEY
+ && ch != VK_NUMLOCK
+ && (ch < VK_LSHIFT || ch > VK_RMENU)
+ && (ch < 0x30 || ch > 0x39)
+ && (ch < 0x41 || ch > 0x5a)
+ && (ch < 0xa6 || ch > 0xe4))
+ {
+ result = 300 + ch;
+ }
+
+ if (result)
+ {
+ if (fs) result |= 512;
+ if (fc) result |= 1024;
+ if (fa) result |= 2048;
+ ev.key = result;
+ ev.type = EV_KEYIN;
+ ev_push(&ev);
+ }
+
+ return 0;
+ }
+
+ case WM_CHAR:
+ {
+ if (skip_key)
+ {
+ skip_key = false;
+ return 0;
+ }
+ ev.key = (int)wParam;
+ ev.type = EV_KEYIN;
+ ev_push(&ev);
+ return 0;
+ }
+
+ case WM_PAINT:
+ {
+ hdc = BeginPaint(hWnd, &ps);
+ win_main->redraw();
+ EndPaint(hWnd, &ps);
+ return 0;
+ }
+
+ case WM_MOVE:
+ {
+ clix = LOWORD(lParam);
+ cliy = HIWORD(lParam);
+ return 0;
+ }
+
+ case WM_COMMAND:
+ {
+ wmId = LOWORD(wParam);
+ wmEvent = HIWORD(wParam);
+ switch( wmId )
+ {
+ // XXX: Isn't that always the case?
+ default:
+ return DefWindowProc( hWnd, message, wParam, lParam );
+ }
+ return 0;
+ }
+ case WM_CLOSE:
+ if (mouse_get_mode() == MOUSE_MODE_COMMAND
+ || !crawl_state.need_save )
+ {
+ if (crawl_state.need_save)
+ save_game(true);
+
+ libgui_shutdown();
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ PostQuitMessage( 0 );
+ exit(0);
+ break;
+ }
+ default:
+ return DefWindowProc( hWnd, message, wParam, lParam );
+ }
+ return 0;
+}
+
+#ifdef USE_TILE
+void TileDrawDungeonAux()
+{
+ dib_pack *pBuf = region_tile->backbuf;
+
+ int new_palette = PAL_STD; // standard
+ if (you.duration[DUR_BERSERKER])
+ new_palette = PAL_BER;
+
+ // XXX: is this supposed to override Berserk?
+ if (you.special_wield == SPWLD_SHADOW)
+ new_palette = PAL_SHA;
+
+ if (new_palette != palette)
+ {
+ palette = new_palette;
+ SetDIBColorTable(pBuf->hDC, 0, 256, (RGBQUAD *)lpPalettes[palette]);
+ }
+}
+#endif
+
+bool windows_change_font(char *font_name, int *font_size, bool dos)
+{
+ CHOOSEFONT cf;
+
+ memset(&cf, 0, sizeof(cf));
+ cf.lStructSize = sizeof(cf);
+ cf.iPointSize = *font_size;
+ cf.nSizeMin = 8;
+ cf.nSizeMax = 24;
+ cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY | CF_NOVERTFONTS
+ | CF_INITTOLOGFONTSTRUCT | CF_LIMITSIZE | CF_FORCEFONTEXIST;
+
+ LOGFONT lf;
+ strcpy(lf.lfFaceName, font_name);
+ lf.lfHeight = 16;
+ lf.lfWidth = 0;
+ lf.lfEscapement = 0;
+ lf.lfOrientation = lf.lfEscapement;
+ lf.lfWeight = FW_NORMAL;
+ lf.lfItalic = FALSE;
+ lf.lfUnderline = FALSE;
+ lf.lfStrikeOut = FALSE;
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfQuality = DEFAULT_QUALITY;
+ lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH;
+ lf.lfCharSet = (dos)? OEM_CHARSET:ANSI_CHARSET;
+ cf.lpLogFont = &lf;
+
+ if (ChooseFont(&cf))
+ {
+ *font_size = (cf.iPointSize / 10);
+ strcpy(font_name, lf.lfFaceName);
+ return (true);
+ }
+ return (false);
+}
+
+void windows_get_winpos(int *x, int *y)
+{
+ WINDOWPLACEMENT wndpl;
+
+ // set length
+ wndpl.length = sizeof( WINDOWPLACEMENT );
+
+ if (GetWindowPlacement( win_main->hWnd, &wndpl ) != 0)
+ {
+ *x = wndpl.rcNormalPosition.top;
+ *y = wndpl.rcNormalPosition.left;
+ }
+}
+
+void delay(unsigned long ms)
+{
+ Sleep((DWORD)ms);
+}
+
+int kbhit()
+{
+ MSG msg;
+
+ if (PeekMessage(&msg, NULL, WM_CHAR, WM_CHAR, PM_NOREMOVE)
+ || PeekMessage(&msg, NULL, WM_KEYDOWN, WM_KEYDOWN, PM_NOREMOVE))
+ {
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void update_screen()
+{
+}