1 /**
2  * \file win-layout.c
3  * \brief Shape an initial or default display on windows systems.
4  *
5  * Copyright (c) 2012 Brett Reid
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 
19 #include <windows.h>
20 #include <windowsx.h>
21 #include "ui-prefs.h"
22 #include "ui-term.h"
23 #include "z-virt.h"
24 
25 typedef unsigned int uint;
26 #include "win-term.h"
27 
28 
29 /**
30  * Default window layout function
31  *
32  * Just a big list of what to do for a specific screen resolution.
33  *
34  * Note: graphics modes are hardcoded, using info from
35  * angband/lib/tiles/graphics.txt at the time of this writing
36  *
37  * Return values:    0 - Success
38  *                  -1 - Invalid argument
39  *                  -3 - Out of memory
40  */
default_layout_win(term_data * data,int maxterms)41 int default_layout_win(term_data *data, int maxterms)
42 {
43 	int sx,sy;
44 	int cap, lcap, bar, borderx, bordery, bottom;
45 	int mult_wid, mult_hgt;
46 	int fx,fy,tx,ty, fx2,fy2;
47 	int i,mode;
48 	RECT r;
49 	char *main_font;
50 	char *sub_font;
51 
52 	/* Make sure the numbers used in this fuction are valid */
53 	if (maxterms < 5) {
54 		return -1;
55 	}
56 
57 	/* Get the various sizes that we need from windows */
58 	sx = GetSystemMetrics(SM_CXSCREEN);
59 	sy = GetSystemMetrics(SM_CYSCREEN);
60 
61 	cap = GetSystemMetrics(SM_CYSMCAPTION);
62 	lcap = GetSystemMetrics(SM_CYCAPTION);
63 	bar = GetSystemMetrics(SM_CYMENU);
64 	borderx = GetSystemMetrics(SM_CXSIZEFRAME);
65 	bordery = GetSystemMetrics(SM_CYSIZEFRAME);
66 
67 	(void) SystemParametersInfo(SPI_GETWORKAREA , 0, &r, 0);
68 
69 	bottom = sy - r.bottom;
70 
71 	if ((sx == 1024) && (sy == 768)) {
72 		arg_graphics = 3;
73 		arg_graphics_nice = 0;
74 		tile_width = 4;
75 		tile_height = 2;
76 
77 		string_free(data[0].font_want);
78 		data[0].font_want = string_make("8x12x.fon");
79 		data[0].font_wid = 8;
80 		data[0].font_hgt = 12;
81 		data[0].tile_wid = 8;
82 		data[0].tile_hgt = 16;
83 		data[0].pos_x = -1;
84 		data[0].pos_y = -1;
85 		data[0].cols = 103;
86 		data[0].rows = 35;
87 		data[0].visible = 1;
88 		data[0].maximized = 0;
89 
90 		/* Messages window */
91 		string_free(data[1].font_want);
92 		data[1].font_want = string_make("6x10x.fon");
93 		data[1].font_wid = 6;
94 		data[1].font_hgt = 10;
95 		data[1].tile_wid = 6;
96 		data[1].tile_hgt = 10;
97 		data[1].pos_x = 0;
98 		data[1].pos_y = 596;
99 		data[1].cols = 80;
100 		data[1].rows = 10;
101 		data[1].visible = 1;
102 		data[1].maximized = 0;
103 
104 		/* Inventory window */
105 		string_free(data[2].font_want);
106 		data[2].font_want = string_make("6x10x.fon");
107 		data[2].font_wid = 6;
108 		data[2].font_hgt = 10;
109 		data[2].tile_wid = 6;
110 		data[2].tile_hgt = 10;
111 		data[2].pos_x = 832;
112 		data[2].pos_y = -1;
113 		data[2].cols = 31;
114 		data[2].rows = 24;
115 		data[2].visible = 1;
116 		data[2].maximized = 0;
117 
118 		/* Monster list window */
119 		string_free(data[3].font_want);
120 		data[3].font_want = string_make("6x10x.fon");
121 		data[3].font_wid = 6;
122 		data[3].font_hgt = 10;
123 		data[3].tile_wid = 6;
124 		data[3].tile_hgt = 10;
125 		data[3].pos_x = 832;
126 		data[3].pos_y = 266;
127 		data[3].cols = 31;
128 		data[3].rows = 30;
129 		data[3].visible = 1;
130 		data[3].maximized = 0;
131 
132 		/* Object list window */
133 		string_free(data[4].font_want);
134 		data[4].font_want = string_make("6x10x.fon");
135 		data[4].font_wid = 6;
136 		data[4].font_hgt = 10;
137 		data[4].tile_wid = 6;
138 		data[4].tile_hgt = 10;
139 		data[4].pos_x = 486;
140 		data[4].pos_y = 596;
141 		data[4].cols = 56;
142 		data[4].rows = 10;
143 		data[4].visible = 1;
144 		data[4].maximized = 0;
145 
146 		/* Recall window */
147 		string_free(data[5].font_want);
148 		data[5].font_want = string_make("6x10x.fon");
149 		data[5].font_wid = 6;
150 		data[5].font_hgt = 10;
151 		data[5].tile_wid = 6;
152 		data[5].tile_hgt = 10;
153 		data[5].pos_x = 832;
154 		data[5].pos_y = 596;
155 		data[5].cols = 31;
156 		data[5].rows = 10;
157 		data[5].visible = 1;
158 		data[5].maximized = 0;
159 
160 		/* The rest of the terms were set by the load pref function */
161 		return 0;
162 	}
163 	if ((sx == 1280) && (sy == 1024)) {
164 		arg_graphics = 5;
165 		arg_graphics_nice = 0;
166 		tile_width = 4;
167 		tile_height = 2;
168 
169 		string_free(data[0].font_want);
170 		data[0].font_want = string_make("8x12x.fon");
171 		data[0].font_wid = 8;
172 		data[0].font_hgt = 12;
173 		data[0].tile_wid = 8;
174 		data[0].tile_hgt = 16;
175 		data[0].pos_x = -1;
176 		data[0].pos_y = -1;
177 		data[0].cols = 134;
178 		data[0].rows = 49;
179 		data[0].visible = 1;
180 		data[0].maximized = 0;
181 
182 		/* Messages window */
183 		string_free(data[1].font_want);
184 		data[1].font_want = string_make("6x10x.fon");
185 		data[1].font_wid = 6;
186 		data[1].font_hgt = 10;
187 		data[1].tile_wid = 6;
188 		data[1].tile_hgt = 10;
189 		data[1].pos_x = 0;
190 		data[1].pos_y = 824;
191 		data[1].cols = 80;
192 		data[1].rows = 11;
193 		data[1].visible = 1;
194 		data[1].maximized = 0;
195 
196 		/* Inventory window */
197 		string_free(data[2].font_want);
198 		data[2].font_want = string_make("6x10x.fon");
199 		data[2].font_wid = 6;
200 		data[2].font_hgt = 10;
201 		data[2].tile_wid = 6;
202 		data[2].tile_hgt = 10;
203 		data[2].pos_x = 1087;
204 		data[2].pos_y = 0;
205 		data[2].cols = 31;
206 		data[2].rows = 24;
207 		data[2].visible = 1;
208 		data[2].maximized = 0;
209 
210 		/* Monster list window */
211 		string_free(data[3].font_want);
212 		data[3].font_want = string_make("6x10x.fon");
213 		data[3].font_wid = 6;
214 		data[3].font_hgt = 10;
215 		data[3].tile_wid = 6;
216 		data[3].tile_hgt = 10;
217 		data[3].pos_x = 1087;
218 		data[3].pos_y = 274;
219 		data[3].cols = 31;
220 		data[3].rows = 52;
221 		data[3].visible = 1;
222 		data[3].maximized = 0;
223 
224 		/* Object list window */
225 		string_free(data[4].font_want);
226 		data[4].font_want = string_make("6x10x.fon");
227 		data[4].font_wid = 6;
228 		data[4].font_hgt = 10;
229 		data[4].tile_wid = 6;
230 		data[4].tile_hgt = 10;
231 		data[4].pos_x = 493;
232 		data[4].pos_y = 824;
233 		data[4].cols = 70;
234 		data[4].rows = 11;
235 		data[4].visible = 1;
236 		data[4].maximized = 0;
237 
238 		/* Recall window */
239 		string_free(data[5].font_want);
240 		data[5].font_want = string_make("6x10x.fon");
241 		data[5].font_wid = 6;
242 		data[5].font_hgt = 10;
243 		data[5].tile_wid = 6;
244 		data[5].tile_hgt = 10;
245 		data[5].pos_x = 923;
246 		data[5].pos_y = 824;
247 		data[5].cols = 57;
248 		data[5].rows = 11;
249 		data[5].visible = 1;
250 		data[5].maximized = 0;
251 
252 		/* The rest of the terms were set by the load pref function */
253 		return 0;
254 	}
255 
256 	/* Size the main and subwindows procedurally */
257 
258 	/* Only consider the working area */
259 	sy = sy - bottom;
260 
261 	/* Get the basic info from the height of the screen */
262 	if (sy <= 250) {
263 		main_font = "5x8x.fon";
264 		fx = 5;
265 		fy = 8;
266 		tx = 4;
267 		ty = 8;
268 		sub_font = NULL;/* "5x8x.fon"; */
269 		fx2 = 4;
270 		fy2 = 8;
271 		mode = 0;
272 		mult_wid = 1;
273 		mult_hgt = 1;
274 	} else if (sy <= 600) {
275 		main_font = "8x12x.fon";
276 		fx = 8;
277 		fy = 12;
278 		tx = 8;
279 		ty = 16;
280 		sub_font = NULL;/* "6x10x.fon"; */
281 		fx2 = 6;
282 		fy2 = 10;
283 		mode = 4;
284 		mult_wid = 1;
285 		mult_hgt = 1;
286 	} else if (sy <= 800) {
287 		main_font = "8x12x.fon";
288 		fx = 8;
289 		fy = 12;
290 		tx = 8;
291 		ty = 16;
292 		sub_font = "6x10x.fon";
293 		fx2 = 6;
294 		fy2 = 10;
295 		mode = 3;
296 		mult_wid = 4;
297 		mult_hgt = 2;
298 	} else if (sy <= 1024) {
299 		main_font = "8x12x.fon";
300 		fx = 8;
301 		fy = 12;
302 		tx = 8;
303 		ty = 16;
304 		sub_font = "6x10x.fon";
305 		fx2 = 6;
306 		fy2 = 10;
307 		mode = 5;
308 		mult_wid = 6;
309 		mult_hgt = 3;
310 	} else if (sy <= 1600) {
311 		main_font = "16x24x.fon";
312 		fx = 16;
313 		fy = 24;
314 		tx = 16;
315 		ty = 24;
316 		sub_font = "8x12x.fon";
317 		fx2 = 8;
318 		fy2 = 12;
319 		mode = 5;
320 		mult_wid = 3;
321 		mult_hgt = 2;
322 	} else {
323 		main_font = "16x24x.fon";
324 		fx = 16;
325 		fy = 24;
326 		tx = 16;
327 		ty = 32;
328 		sub_font = "12x18x.fon";
329 		fx2 = 12;
330 		fy2 = 18;
331 		mode = 5;
332 		mult_wid = 4;
333 		mult_hgt = 2;
334 	}
335 
336 	/* Setup main window */
337 	arg_graphics = mode;
338 	arg_graphics_nice = 0;
339 	tile_width = mult_wid;
340 	tile_height = mult_hgt;
341 
342 	string_free(data[0].font_want);
343 	data[0].font_want = string_make(main_font);
344 	data[0].font_wid = fx;
345 	data[0].font_hgt = fy;
346 	data[0].tile_wid = tx;
347 	data[0].tile_hgt = ty;
348 	data[0].pos_x = 0;
349 	data[0].pos_y = 0;
350 	data[0].cols = (sx - 2*borderx)/tx;
351 	data[0].rows = (sy - 2*bordery - cap - bar)/ty;
352 	data[0].visible = 1;
353 	data[0].maximized = 0;
354 
355 	/* Make sure there is a border around the map area */
356 	if (data[0].cols % mult_wid == 0)
357 		data[0].cols -= 1;
358 	if (data[0].rows % mult_hgt == 0)
359 		data[0].rows -= 1;
360 
361 	if (sub_font) {
362 		data[0].cols = 1 + data[0].cols * 8 / 10;
363 		data[0].rows = 1 + data[0].rows * 8 / 10;
364 
365 		/* Make sure there is a border around the map area */
366 		if (data[0].cols % mult_wid == 0)
367 			data[0].cols += 1;
368 		if (data[0].rows % mult_hgt == 0)
369 			data[0].rows += 1;
370 
371 	} else {
372 		return 0;
373 	}
374 
375 	/* Set up subwindows */
376 	for (i = 1; i < maxterms; i++) {
377 		string_free(data[i].font_want);
378 		data[i].font_want = string_make(sub_font);
379 		data[i].font_wid = fx2;
380 		data[i].font_hgt = fy2;
381 		data[i].tile_wid = fx2;
382 		data[i].tile_hgt = fy2;
383 		data[i].pos_x = i * tx;
384 		data[i].pos_y = i * ty;
385 		data[i].cols = (2 * ((sx - 2 * borderx)/tx) / 10) * tx/fx2;
386 		data[i].rows = (2 * ((sy - 2 * bordery - cap - bar)/ty)/10) * ty/fy2;
387 		data[i].visible = 0;
388 		data[i].maximized = 0;
389 	}
390 	/* Position the specific sub windows */
391 	data[1].pos_x = 0;
392 	data[1].pos_y = (lcap + bar + (data[0].rows * ty) + 2 * bordery) - cap;
393 	data[1].rows = (sy - data[1].pos_y - 2 * cap) / fy2;
394 
395 	data[2].pos_x = (2 * borderx + data[0].cols * tx);
396 	data[2].pos_y = 0;
397 	data[2].cols = (sx - data[2].pos_x)/fx2;
398 
399 	if (data[0].cols * tx > 160 * fx2) {
400 		data[1].cols = 80;
401 
402 		data[4].cols = 60;
403 
404 		data[5].visible = 1;
405 	} else if (data[0].cols * tx > 120 * fx2) {
406 		data[1].cols = 70;
407 
408 		data[4].cols = ((data[0].cols * tx) - (data[1].cols * fx2))/fx2;
409 
410 		data[5].visible = 1;
411 	} else {
412 		data[1].cols = (data[0].cols * tx) * 6 / 10 / fx2;
413 
414 		data[4].cols = (sx - (data[1].cols * fx2)) / fx2;
415 	}
416 	data[4].pos_x = -1 + borderx + (data[1].cols * fx2);
417 	data[4].pos_y = data[1].pos_y;
418 	data[4].rows = data[1].rows;
419 	if (data[5].visible) {
420 		data[5].pos_x = -1 + 2 * borderx + (data[1].cols + data[4].cols) * fx2;
421 		data[5].pos_y = data[1].pos_y;
422 		data[5].rows = data[1].rows;
423 		data[5].cols = (sx - data[5].pos_x + 1) / fx2;
424 	}
425 
426 	data[1].visible = 1;
427 	data[4].visible = 1;
428 
429 	if (data[5].visible) {
430 		i = lcap+(data[0].rows * ty);
431 		if ((data[0].rows * ty) > (40 * fy2)) {
432 			data[2].rows = 24;
433 			data[3].rows = (i - data[2].rows * fy2 - 2 * cap - 2 * bordery)/fy2;
434 		} else if ((data[0].rows * ty) > (24 * fy2)) {
435 			data[2].rows = 10;
436 			data[3].rows = (i - data[2].rows * fy2 - 2 * cap - 2 * bordery)/fy2;
437 		} else {
438 			data[5].visible = 0;
439 			data[2].rows = (sy / 2) / fy2;
440 			if (data[2].rows > 24)
441 				data[2].rows = 24;
442 			/* See if the inventory display will be useless */
443 			if (data[2].rows < 13)
444 				data[2].rows = 3;
445 			data[3].rows = (sy - data[2].rows * fy2 + cap - 2 * bordery) /fy2;
446 
447 			/* Expand object list to the main window, take over the corner */
448 		}
449 	} else {
450 		/* The object list window goes all the way across */
451 		i = lcap + (data[0].rows * ty);
452 		if ((data[0].rows * ty) > (40 * fy2)) {
453 			data[2].rows = 24;
454 			data[3].rows = (i - data[2].rows * fy2 - 2 * cap - 2 * bordery)/fy2;
455 		} else if ((data[0].rows * ty) > (24 * fy2)) {
456 			data[2].rows = 10;
457 			data[3].rows = (i - data[2].rows * fy2 - 2 * cap - 2 * bordery)/fy2;
458 		} else {
459 			/* Shrink object list to the main window, take over the corner */
460 			data[2].rows = 10;
461 			data[3].rows = (i - data[2].rows * fy2 - 2 * cap - 2 * bordery)/fy2;
462 		}
463 	}
464 	data[3].pos_x = data[2].pos_x;
465 	data[3].pos_y = -1 + 2 * bordery + (data[2].rows * fy2) + cap;
466 	data[3].cols = data[2].cols;
467 
468 	data[2].visible = 1;
469 	data[3].visible = 1;
470 
471 	return 0;
472 }
473