1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed.  See license for details. */
3 
4 #include "winMS.h"
5 #include "resource.h"
6 #include "mhrip.h"
7 #include "mhmsg.h"
8 #include "mhfont.h"
9 
10 #define RIP_WIDTH	400
11 #define RIP_HEIGHT	200
12 
13 #define RIP_GRAVE_HEIGHT 	120
14 #define RIP_GRAVE_WIDTH		115
15 #define RIP_GRAVE_X		90
16 #define RIP_GRAVE_Y		60
17 
18 #define RIP_OFFSET_X		10
19 #define RIP_OFFSET_Y		10
20 
21 PNHWinApp GetNHApp(void);
22 
23 typedef struct mswin_nethack_text_window {
24 	HANDLE	rip_bmp;
25 	TCHAR*  window_text;
26 	TCHAR*  rip_text;
27 } NHRIPWindow, *PNHRIPWindow;
28 
29 BOOL CALLBACK NHRIPWndProc(HWND, UINT, WPARAM, LPARAM);
30 static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
31 
mswin_init_RIP_window()32 HWND mswin_init_RIP_window () {
33 	HWND ret;
34 	PNHRIPWindow data;
35 
36 	ret = CreateDialog(
37 			GetNHApp()->hApp,
38 			MAKEINTRESOURCE(IDD_NHRIP),
39 			GetNHApp()->hMainWnd,
40 			NHRIPWndProc
41 	);
42 	if( !ret ) panic("Cannot create rip window");
43 
44 	data = (PNHRIPWindow)malloc(sizeof(NHRIPWindow));
45 	if( !data ) panic("out of memory");
46 
47 	ZeroMemory(data, sizeof(NHRIPWindow));
48 	SetWindowLong(ret, GWL_USERDATA, (LONG)data);
49 	return ret;
50 }
51 
mswin_display_RIP_window(HWND hWnd)52 void mswin_display_RIP_window (HWND hWnd)
53 {
54 	MSG msg;
55 	RECT rt;
56 	PNHRIPWindow data;
57 	HWND mapWnd;
58 	RECT riprt;
59 	RECT clientrect;
60 	RECT textrect;
61 	HDC hdc;
62 	HFONT OldFont;
63 
64 	data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);
65 
66 	GetNHApp()->hPopupWnd = hWnd;
67 	mapWnd = mswin_hwnd_from_winid(WIN_MAP);
68 	if( !IsWindow(mapWnd) ) mapWnd = GetNHApp()->hMainWnd;
69 	GetWindowRect(mapWnd, &rt);
70 	GetWindowRect(hWnd, &riprt);
71 	GetClientRect (hWnd, &clientrect);
72 	textrect = clientrect;
73 	textrect.top += RIP_OFFSET_Y;
74 	textrect.left += RIP_OFFSET_X;
75 	textrect.right -= RIP_OFFSET_X;
76 	if (data->window_text)
77 	{
78 	    hdc = GetDC (hWnd);
79 	    OldFont = SelectObject (hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE));
80 	    DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
81 		DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
82 	    SelectObject (hdc, OldFont);
83 	    ReleaseDC(hWnd, hdc);
84 	}
85 	if (textrect.right - textrect.left > RIP_WIDTH)
86 	    clientrect.right = textrect.right + RIP_OFFSET_X - clientrect.right;
87 	else
88 	    clientrect.right = textrect.left + 2 * RIP_OFFSET_X + RIP_WIDTH - clientrect.right;
89 	clientrect.bottom = textrect.bottom + RIP_HEIGHT + RIP_OFFSET_Y - clientrect.bottom;
90 	GetWindowRect (GetDlgItem(hWnd, IDOK), &textrect);
91 	textrect.right -= textrect.left;
92 	textrect.bottom -= textrect.top;
93 	clientrect.bottom += textrect.bottom + RIP_OFFSET_Y;
94 	riprt.right -= riprt.left;
95 	riprt.bottom -= riprt.top;
96 	riprt.right += clientrect.right;
97 	riprt.bottom += clientrect.bottom;
98 	rt.left += (rt.right - rt.left - riprt.right) / 2;
99 	rt.top += (rt.bottom - rt.top - riprt.bottom) / 2;
100 
101 	MoveWindow(hWnd, rt.left, rt.top, riprt.right, riprt.bottom, TRUE);
102 	GetClientRect (hWnd, &clientrect);
103 	MoveWindow (GetDlgItem(hWnd, IDOK),
104 	    (clientrect.right - clientrect.left - textrect.right) / 2,
105 	    clientrect.bottom - textrect.bottom - RIP_OFFSET_Y, textrect.right, textrect.bottom, TRUE);
106 	ShowWindow(hWnd, SW_SHOW);
107 
108 	while( IsWindow(hWnd) &&
109 		   GetMessage(&msg, NULL, 0, 0)!=0 ) {
110 		if( !IsDialogMessage(hWnd, &msg) ) {
111 			TranslateMessage(&msg);
112 			DispatchMessage(&msg);
113 		}
114 	}
115 
116 	GetNHApp()->hPopupWnd = NULL;
117 }
118 
NHRIPWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)119 BOOL CALLBACK NHRIPWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
120 {
121 	HDC hdc;
122 	PNHRIPWindow data;
123 
124 	data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);
125 	switch (message)
126 	{
127 	case WM_INITDIALOG:
128 	    /* set text control font */
129 		hdc = GetDC(hWnd);
130 		SendMessage(hWnd, WM_SETFONT,
131 			(WPARAM)mswin_get_font(NHW_TEXT, ATR_NONE, hdc, FALSE), 0);
132 		ReleaseDC(hWnd, hdc);
133 
134 		SetFocus(GetDlgItem(hWnd, IDOK));
135 	return FALSE;
136 
137 	case WM_MSNH_COMMAND:
138 		onMSNHCommand(hWnd, wParam, lParam);
139 	break;
140 
141 	case WM_PAINT:
142 	{
143 		int bitmap_offset;
144 		RECT clientrect;
145 		RECT textrect;
146 		HDC hdcBitmap;
147 		HANDLE OldBitmap;
148 		PAINTSTRUCT ps;
149 		HFONT OldFont;
150 
151 		hdc = BeginPaint (hWnd, &ps);
152 		OldFont = SelectObject (hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE));
153 		hdcBitmap = CreateCompatibleDC(hdc);
154 		SetBkMode (hdc, TRANSPARENT);
155 		GetClientRect (hWnd, &clientrect);
156 		textrect = clientrect;
157 		textrect.top += RIP_OFFSET_Y;
158 		textrect.left += RIP_OFFSET_X;
159 		textrect.right -= RIP_OFFSET_X;
160 		if (data->window_text)
161 		{
162 			DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
163 				DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
164 			DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
165 				DT_LEFT | DT_NOPREFIX);
166 		}
167 		OldBitmap = SelectObject(hdcBitmap, GetNHApp()->bmpRip);
168 		SetBkMode (hdc, OPAQUE);
169 		bitmap_offset = (textrect.right - textrect.left - RIP_WIDTH) / 2;
170 		BitBlt (hdc, textrect.left + bitmap_offset, textrect.bottom, RIP_WIDTH,
171 			RIP_HEIGHT, hdcBitmap, 0, 0, SRCCOPY);
172 		SetBkMode (hdc, TRANSPARENT);
173 		if (data->rip_text)
174 		{
175 			textrect.left += RIP_GRAVE_X + bitmap_offset;
176 			textrect.top = textrect.bottom + RIP_GRAVE_Y;
177 			textrect.right = textrect.left + RIP_GRAVE_WIDTH;
178 			textrect.bottom = textrect.top + RIP_GRAVE_HEIGHT;
179 			DrawText (hdc, data->rip_text, strlen(data->rip_text), &textrect,
180 				DT_CENTER | DT_VCENTER | DT_NOPREFIX | DT_WORDBREAK);
181 		}
182 		SelectObject (hdcBitmap, OldBitmap);
183 		SelectObject (hdc, OldFont);
184 		DeleteDC (hdcBitmap);
185 		EndPaint (hWnd, &ps);
186 	}
187 	break;
188 
189 	case WM_COMMAND:
190 		switch (LOWORD(wParam))
191         {
192           case IDOK:
193 			mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
194 			if( GetNHApp()->hMainWnd==hWnd )
195 				GetNHApp()->hMainWnd=NULL;
196 			DestroyWindow(hWnd);
197 			SetFocus(GetNHApp()->hMainWnd);
198 			return TRUE;
199 		}
200 	break;
201 
202 	case WM_CLOSE:
203 	    /* if we get this here, we saved the bones so we can just force a quit */
204 
205 	    mswin_window_mark_dead(mswin_winid_from_handle(hWnd));
206 	    if( GetNHApp()->hMainWnd==hWnd )
207 		GetNHApp()->hMainWnd=NULL;
208 	    DestroyWindow(hWnd);
209 	    SetFocus(GetNHApp()->hMainWnd);
210 	    program_state.stopprint++;
211 	    return TRUE;
212 
213 	case WM_DESTROY:
214 		if( data ) {
215 			if( data->window_text ) free(data->window_text);
216 			if( data->rip_text ) free(data->rip_text);
217 			if (data->rip_bmp != NULL) DeleteObject(data->rip_bmp);
218 			free(data);
219 			SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
220 		}
221 	break;
222 
223 	}
224 	return FALSE;
225 }
226 
onMSNHCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)227 void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
228 {
229 	PNHRIPWindow data;
230 	static int InRipText = 1;
231 	data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);
232 	switch( wParam ) {
233 		case MSNH_MSG_PUTSTR: {
234 			PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
235 			TCHAR	wbuf[BUFSZ];
236 			size_t text_size;
237 
238 			if( !data->window_text ) {
239 				text_size = strlen(msg_data->text) + 4;
240 				data->window_text = (TCHAR*)malloc(text_size*sizeof(data->window_text[0]));
241 				ZeroMemory(data->window_text, text_size*sizeof(data->window_text[0]));
242 			} else {
243 				text_size = _tcslen(data->window_text) + strlen(msg_data->text) + 4;
244 				data->window_text = (TCHAR*)realloc(data->window_text, text_size*sizeof(data->window_text[0]));
245 			}
246 			if( !data->window_text ) break;
247 
248 			_tcscat(data->window_text, NH_A2W(msg_data->text, wbuf, BUFSZ));
249 			_tcscat(data->window_text, TEXT("\r\n"));
250 			break;
251 		}
252 		case MSNH_MSG_DIED:
253 		{
254 			data->rip_text = data->window_text;
255 			data->window_text = NULL;
256 			break;
257 		}
258 
259 	}
260 }
261 
mswin_finish_rip_text(winid wid)262 void mswin_finish_rip_text(winid wid)
263 {
264 	SendMessage (mswin_hwnd_from_winid(wid), WM_MSNH_COMMAND,  MSNH_MSG_DIED, 0);
265 }
266