author | darkvater |
Tue, 10 Aug 2004 14:50:42 +0000 | |
changeset 5 | 539c9743d999 |
parent 2 | 104b2984cd3e |
child 16 | 5ee72235b403 |
permissions | -rw-r--r-- |
0 | 1 |
#include "stdafx.h" |
2 |
#include "ttd.h" |
|
3 |
#include "town.h" |
|
4 |
#include "window.h" |
|
5 |
#include "gfx.h" |
|
6 |
#include "viewport.h" |
|
7 |
#include "gui.h" |
|
8 |
#include "command.h" |
|
9 |
#include "player.h" |
|
10 |
||
11 |
static const Widget _town_authority_widgets[] = { |
|
12 |
{ WWT_TEXTBTN, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
13 |
{ WWT_CAPTION, 13, 11, 316, 0, 13, STR_2022_LOCAL_AUTHORITY, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
14 |
{ WWT_IMGBTN, 13, 0, 316, 14, 105, 0x0, 0}, |
|
15 |
{ WWT_IMGBTN, 13, 0, 305, 106, 157, 0x0, STR_2043_LIST_OF_THINGS_TO_DO_AT}, |
|
16 |
{ WWT_SCROLLBAR, 13, 306, 316, 106, 157, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, |
|
17 |
{ WWT_IMGBTN, 13, 0, 316, 158, 209, 0x0, 0}, |
|
18 |
{ WWT_PUSHTXTBTN, 13, 0, 316, 210, 221, STR_2042_DO_IT, STR_2044_CARRY_OUT_THE_HIGHLIGHTED}, |
|
19 |
{ WWT_LAST}, |
|
20 |
}; |
|
21 |
||
22 |
extern const byte _town_action_costs[8]; |
|
23 |
extern void DrawPlayerIcon(int p, int x, int y); |
|
24 |
||
25 |
static uint GetMaskOfTownActions(int *nump, Town *t) |
|
26 |
{ |
|
27 |
int32 avail, ref; |
|
28 |
int i, num; |
|
29 |
uint avail_buttons = 0x7F; // by default all buttons except bribe are enabled. |
|
30 |
uint buttons; |
|
31 |
||
1 | 32 |
if (_local_player != OWNER_SPECTATOR) { |
0 | 33 |
// bribe option enabled? |
34 |
if (_patches.bribe) { |
|
35 |
// if unwanted, disable everything. |
|
36 |
if (t->unwanted[_local_player]) { |
|
37 |
avail_buttons = 0; |
|
38 |
} else if (t->ratings[_local_player] < 600) |
|
39 |
avail_buttons |= (1 << 7); // only bribe if less than excellent |
|
40 |
} |
|
41 |
||
42 |
// Things worth more than this are not shown |
|
43 |
avail = DEREF_PLAYER(_local_player)->player_money + _price.station_value * 200; |
|
44 |
ref = _price.build_industry >> 8; |
|
45 |
||
46 |
for(i=0,buttons=0,num=0; i != lengthof(_town_action_costs); i++,avail_buttons>>=1) { |
|
47 |
if (avail_buttons&1 && avail >= _town_action_costs[i] * ref) { |
|
48 |
SETBIT(buttons, i); |
|
49 |
num++; |
|
50 |
} |
|
51 |
} |
|
52 |
||
53 |
// Disable build statue if already built |
|
54 |
if(HASBIT(t->statues, _local_player)) |
|
55 |
{ |
|
56 |
CLRBIT(buttons, 4); |
|
57 |
num--; |
|
58 |
} |
|
59 |
||
60 |
} else { |
|
61 |
// no actions available for spectator |
|
62 |
buttons = 0; |
|
63 |
num = 0; |
|
64 |
} |
|
65 |
||
66 |
if (nump) *nump = num; |
|
67 |
return buttons; |
|
68 |
} |
|
69 |
||
70 |
static int GetNthSetBit(uint32 bits, int n) |
|
71 |
{ |
|
72 |
int i = 0; |
|
73 |
if (n >= 0) { |
|
74 |
do { |
|
75 |
if (bits&1 && --n < 0) return i; |
|
76 |
i++; |
|
77 |
} while (bits>>=1); |
|
78 |
} |
|
79 |
return -1; |
|
80 |
} |
|
81 |
||
82 |
static void TownAuthorityWndProc(Window *w, WindowEvent *e) |
|
83 |
{ |
|
84 |
uint buttons; |
|
85 |
int numact; |
|
86 |
Town *t = DEREF_TOWN(w->window_number); |
|
87 |
||
88 |
switch(e->event) { |
|
89 |
case WE_PAINT: |
|
90 |
buttons = GetMaskOfTownActions(&numact, t); |
|
91 |
SetVScrollCount(w, numact + 1); |
|
92 |
||
93 |
if (WP(w,def_d).data_1 != -1 && !HASBIT(buttons, WP(w,def_d).data_1)) |
|
94 |
WP(w,def_d).data_1 = -1; |
|
95 |
||
96 |
w->disabled_state = (WP(w,def_d).data_1 == -1) ? (1 << 6) : 0; |
|
97 |
||
98 |
{ |
|
99 |
int y; |
|
100 |
Player *p; |
|
101 |
int r; |
|
102 |
StringID str; |
|
103 |
||
104 |
SET_DPARAM16(0, w->window_number); |
|
105 |
DrawWindowWidgets(w); |
|
106 |
||
107 |
DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, 0); |
|
108 |
||
109 |
// Draw list of players |
|
110 |
y = 25; |
|
111 |
FOR_ALL_PLAYERS(p) { |
|
112 |
if (p->is_active && HASBIT(t->have_ratings, p->index)) { |
|
113 |
DrawPlayerIcon(p->index, 2, y); |
|
114 |
||
115 |
SET_DPARAM16(0, p->name_1); |
|
116 |
SET_DPARAM32(1, p->name_2); |
|
2
104b2984cd3e
(svn r3) -[1005611] Player Window patch: When looking in dropdownlist for player stuff, it will say
darkvater
parents:
1
diff
changeset
|
117 |
SET_DPARAM16(2, GetPlayerNameString(p->index, 3)); |
0 | 118 |
|
119 |
r = t->ratings[p->index]; |
|
120 |
(str = STR_3035_APPALLING, r <= -400) || // Apalling |
|
121 |
(str++, r <= -200) || // Very Poor |
|
122 |
(str++, r <= 0) || // Poor |
|
123 |
(str++, r <= 200) || // Mediocore |
|
124 |
(str++, r <= 400) || // Good |
|
125 |
(str++, r <= 600) || // Very Good |
|
126 |
(str++, r <= 800) || // Excellent |
|
127 |
(str++, true); // Outstanding |
|
128 |
||
2
104b2984cd3e
(svn r3) -[1005611] Player Window patch: When looking in dropdownlist for player stuff, it will say
darkvater
parents:
1
diff
changeset
|
129 |
SET_DPARAM16(4, str); |
0 | 130 |
DrawString(19, y, STR_2024, 0); |
131 |
y+=10; |
|
132 |
} |
|
133 |
} |
|
134 |
} |
|
135 |
||
136 |
// Draw actions list |
|
137 |
{ |
|
138 |
int y = 107, i; |
|
139 |
int pos = w->vscroll.pos; |
|
140 |
||
141 |
if (--pos < 0) { |
|
142 |
DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, 0); |
|
143 |
y+=10; |
|
144 |
} |
|
145 |
for(i=0; buttons; i++,buttons>>=1) { |
|
146 |
if (pos <= -5) |
|
147 |
break; |
|
148 |
||
149 |
if (buttons&1 && --pos < 0) { |
|
150 |
DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, 6); |
|
151 |
y += 10; |
|
152 |
} |
|
153 |
} |
|
154 |
} |
|
155 |
||
156 |
{ |
|
157 |
int i; |
|
158 |
if ((i=WP(w,def_d).data_1) != -1) { |
|
159 |
SET_DPARAM32(1, (_price.build_industry >> 8) * _town_action_costs[i]); |
|
160 |
SET_DPARAM16(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i); |
|
161 |
DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313); |
|
162 |
} |
|
163 |
} |
|
164 |
||
165 |
break; |
|
166 |
||
167 |
case WE_CLICK: |
|
168 |
switch(e->click.widget) { |
|
169 |
case 3: { /* listbox */ |
|
170 |
int y = (e->click.pt.y - 0x6B) / 10; |
|
171 |
if (!IS_INT_INSIDE(y, 0, 5)) |
|
172 |
return; |
|
173 |
||
174 |
y = GetNthSetBit(GetMaskOfTownActions(NULL, t), y + w->vscroll.pos - 1); |
|
175 |
if (y >= 0) { |
|
176 |
WP(w,def_d).data_1 = y; |
|
177 |
SetWindowDirty(w); |
|
178 |
} |
|
179 |
break; |
|
180 |
} |
|
181 |
||
182 |
case 6: { /* carry out the action */ |
|
183 |
DoCommandP(t->xy, w->window_number, WP(w,def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_2054_CAN_T_DO_THIS)); |
|
184 |
break; |
|
185 |
} |
|
186 |
} |
|
187 |
break; |
|
188 |
||
189 |
case WE_4: |
|
190 |
SetWindowDirty(w); |
|
191 |
break; |
|
192 |
} |
|
193 |
} |
|
194 |
||
195 |
static const WindowDesc _town_authority_desc = { |
|
196 |
-1, -1, 317, 222, |
|
197 |
WC_TOWN_AUTHORITY,0, |
|
198 |
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
199 |
_town_authority_widgets, |
|
200 |
TownAuthorityWndProc |
|
201 |
}; |
|
202 |
||
203 |
void ShowTownAuthorityWindow(uint town) |
|
204 |
{ |
|
205 |
Window *w; |
|
206 |
||
207 |
w = AllocateWindowDescFront(&_town_authority_desc, town); |
|
208 |
if (w) { |
|
209 |
w->vscroll.cap = 5; |
|
210 |
WP(w,def_d).data_1 = -1; |
|
211 |
} |
|
212 |
} |
|
213 |
||
214 |
static void TownViewWndProc(Window *w, WindowEvent *e) |
|
215 |
{ |
|
216 |
Town *t = DEREF_TOWN(w->window_number); |
|
217 |
||
218 |
switch(e->event) { |
|
219 |
case WE_PAINT: |
|
220 |
SET_DPARAM16(0, t->index); |
|
221 |
DrawWindowWidgets(w); |
|
222 |
||
223 |
SET_DPARAM32(0, t->population); |
|
224 |
SET_DPARAM32(1, t->num_houses); |
|
225 |
DrawString(2,107,STR_2006_POPULATION,0); |
|
226 |
||
227 |
SET_DPARAM16(0, t->act_pass); |
|
228 |
SET_DPARAM16(1, t->max_pass); |
|
229 |
DrawString(2,117,STR_200D_PASSENGERS_LAST_MONTH_MAX,0); |
|
230 |
||
231 |
SET_DPARAM16(0, t->act_mail); |
|
232 |
SET_DPARAM16(1, t->max_mail); |
|
233 |
DrawString(2,127,STR_200E_MAIL_LAST_MONTH_MAX,0); |
|
234 |
||
235 |
DrawWindowViewport(w); |
|
236 |
break; |
|
237 |
||
238 |
case WE_CLICK: |
|
239 |
switch(e->click.widget) { |
|
240 |
case 5: /* scroll to location */ |
|
241 |
ScrollMainWindowToTile(t->xy); |
|
242 |
break; |
|
243 |
case 6: /* town authority */ |
|
244 |
ShowTownAuthorityWindow(w->window_number); |
|
245 |
break; |
|
246 |
case 7: /* rename */ |
|
247 |
SET_DPARAM32(0, t->townnameparts); |
|
248 |
ShowQueryString(t->townnametype, STR_2007_RENAME_TOWN, 31, 130, w->window_class, w->window_number); |
|
249 |
break; |
|
250 |
case 8: /* expand town */ |
|
251 |
ExpandTown(t); |
|
252 |
break; |
|
253 |
case 9: /* delete town */ |
|
254 |
DeleteTown(t); |
|
255 |
break; |
|
256 |
} |
|
257 |
break; |
|
258 |
||
259 |
case WE_ON_EDIT_TEXT: { |
|
260 |
byte *b = e->edittext.str; |
|
261 |
if (*b == 0) |
|
262 |
return; |
|
263 |
memcpy(_decode_parameters, b, 32); |
|
264 |
DoCommandP(0, w->window_number, 0, NULL, CMD_RENAME_TOWN | CMD_MSG(STR_2008_CAN_T_RENAME_TOWN)); |
|
265 |
} break; |
|
266 |
} |
|
267 |
} |
|
268 |
||
269 |
||
270 |
static const Widget _town_view_widgets[] = { |
|
271 |
{ WWT_TEXTBTN, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
272 |
{ WWT_CAPTION, 13, 11, 259, 0, 13, STR_2005, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
273 |
{ WWT_IMGBTN, 13, 0, 259, 14, 105, 0x0, 0}, |
|
274 |
{ WWT_6, 13, 2, 257, 16, 103, 0x0, 0}, |
|
275 |
{ WWT_IMGBTN, 13, 0, 259, 106, 137, 0x0, 0}, |
|
276 |
{ WWT_PUSHTXTBTN, 13, 0, 85, 138, 149, STR_00E4_LOCATION, STR_200B_CENTER_THE_MAIN_VIEW_ON}, |
|
277 |
{ WWT_PUSHTXTBTN, 13, 86, 171, 138, 149, STR_2020_LOCAL_AUTHORITY, STR_2021_SHOW_INFORMATION_ON_LOCAL}, |
|
278 |
{ WWT_PUSHTXTBTN, 13, 172, 259, 138, 149, STR_0130_RENAME, STR_200C_CHANGE_TOWN_NAME}, |
|
279 |
{ WWT_LAST}, |
|
280 |
}; |
|
281 |
||
282 |
static const WindowDesc _town_view_desc = { |
|
283 |
-1, -1, 260, 150, |
|
284 |
WC_TOWN_VIEW,0, |
|
285 |
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
286 |
_town_view_widgets, |
|
287 |
TownViewWndProc |
|
288 |
}; |
|
289 |
||
290 |
static const Widget _town_view_scen_widgets[] = { |
|
291 |
{ WWT_TEXTBTN, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
292 |
{ WWT_CAPTION, 13, 11, 184, 0, 13, STR_2005, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
293 |
{ WWT_IMGBTN, 13, 0, 259, 14, 105, 0x0}, |
|
294 |
{ WWT_6, 13, 2, 257, 16, 103, 0x0}, |
|
295 |
{ WWT_IMGBTN, 13, 0, 259, 106, 137, 0x0}, |
|
296 |
{ WWT_PUSHTXTBTN, 13, 0, 85, 138, 149, STR_00E4_LOCATION, STR_200B_CENTER_THE_MAIN_VIEW_ON}, |
|
297 |
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0x0}, |
|
298 |
{ WWT_PUSHTXTBTN, 13, 185, 259, 0, 13, STR_0130_RENAME, STR_200C_CHANGE_TOWN_NAME}, |
|
299 |
{ WWT_PUSHTXTBTN, 13, 86, 171, 138, 149, STR_023C_EXPAND, STR_023B_INCREASE_SIZE_OF_TOWN}, |
|
300 |
{ WWT_PUSHTXTBTN, 13, 172, 259, 138, 149, STR_0290_DELETE, STR_0291_DELETE_THIS_TOWN_COMPLETELY}, |
|
301 |
{ WWT_LAST}, |
|
302 |
}; |
|
303 |
||
304 |
static const WindowDesc _town_view_scen_desc = { |
|
305 |
-1, -1, 260, 150, |
|
306 |
WC_TOWN_VIEW,0, |
|
307 |
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
308 |
_town_view_scen_widgets, |
|
309 |
TownViewWndProc |
|
310 |
}; |
|
311 |
||
312 |
void ShowTownViewWindow(uint town) |
|
313 |
{ |
|
314 |
Window *w; |
|
315 |
Town *t; |
|
316 |
||
317 |
if (_game_mode != GM_EDITOR) { |
|
318 |
w = AllocateWindowDescFront(&_town_view_desc, town); |
|
319 |
} else { |
|
320 |
w = AllocateWindowDescFront(&_town_view_scen_desc, town); |
|
321 |
} |
|
322 |
||
323 |
if (w) { |
|
324 |
w->flags4 |= WF_DISABLE_VP_SCROLL; |
|
325 |
t = DEREF_TOWN(w->window_number); |
|
326 |
AssignWindowViewport(w, 3, 17, 0xFE, 0x56, t->xy, 1); |
|
327 |
} |
|
328 |
} |
|
329 |
||
330 |
static const Widget _town_directory_widgets[] = { |
|
331 |
{ WWT_TEXTBTN, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, |
|
332 |
{ WWT_CAPTION, 13, 11, 207, 0, 13, STR_2000_TOWNS, STR_018C_WINDOW_TITLE_DRAG_THIS}, |
|
333 |
{ WWT_PUSHTXTBTN, 13, 0, 98, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP}, |
|
334 |
{ WWT_PUSHTXTBTN, 13, 99, 196, 14, 25, STR_SORT_BY_POPULATION,STR_SORT_TIP}, |
|
335 |
{ WWT_IMGBTN, 13, 0, 196, 26, 189, 0x0, STR_200A_TOWN_NAMES_CLICK_ON_NAME}, |
|
336 |
{ WWT_SCROLLBAR, 13, 197, 207, 14, 189, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, |
|
337 |
{ WWT_LAST}, |
|
338 |
}; |
|
339 |
||
340 |
||
341 |
// used to get a sorted list of the towns |
|
342 |
static byte _town_sort[lengthof(_towns)]; |
|
343 |
static uint _num_town_sort; |
|
344 |
||
345 |
static char _bufcache[64]; |
|
346 |
static byte _last_town_idx; |
|
347 |
||
348 |
static int CDECL TownSorterByName(const void *a, const void *b) |
|
349 |
{ |
|
350 |
char buf1[64]; |
|
351 |
Town *t; |
|
352 |
byte val; |
|
353 |
int r; |
|
354 |
||
355 |
t = DEREF_TOWN(*(byte*)a); |
|
356 |
SET_DPARAM32(0, t->townnameparts); |
|
357 |
GetString(buf1, t->townnametype); |
|
358 |
||
359 |
if ( (val=*(byte*)b) != _last_town_idx) { |
|
360 |
_last_town_idx = val; |
|
361 |
t = DEREF_TOWN(val); |
|
362 |
SET_DPARAM32(0, t->townnameparts); |
|
363 |
GetString(_bufcache, t->townnametype); |
|
364 |
} |
|
365 |
||
366 |
r = strcmp(buf1, _bufcache); |
|
367 |
if (_town_sort_order & 1) r = -r; |
|
368 |
return r; |
|
369 |
} |
|
370 |
||
371 |
static int CDECL TownSorterByPop(const void *a, const void *b) |
|
372 |
{ |
|
373 |
Town *ta = DEREF_TOWN(*(byte*)a); |
|
374 |
Town *tb = DEREF_TOWN(*(byte*)b); |
|
375 |
int r = tb->population - ta->population; |
|
376 |
if (_town_sort_order & 1) r = -r; |
|
377 |
return r; |
|
378 |
} |
|
379 |
||
380 |
static void MakeSortedTownList() |
|
381 |
{ |
|
382 |
Town *t; |
|
383 |
int n = 0; |
|
384 |
FOR_ALL_TOWNS(t) if(t->xy) _town_sort[n++] = t->index; |
|
385 |
_num_town_sort = n; |
|
386 |
||
387 |
_last_town_idx = 255; // used for "cache" |
|
388 |
qsort(_town_sort, n, 1, _town_sort_order & 2 ? TownSorterByPop : TownSorterByName); |
|
389 |
} |
|
390 |
||
391 |
||
392 |
static void TownDirectoryWndProc(Window *w, WindowEvent *e) |
|
393 |
{ |
|
394 |
switch(e->event) { |
|
395 |
case WE_PAINT: { |
|
396 |
int n; |
|
397 |
uint p; |
|
398 |
Town *t; |
|
399 |
||
400 |
if (_town_sort_dirty) { |
|
401 |
_town_sort_dirty = false; |
|
402 |
MakeSortedTownList(); |
|
403 |
} |
|
404 |
||
405 |
w->vscroll.count = _num_town_sort; |
|
406 |
||
407 |
DrawWindowWidgets(w); |
|
408 |
DoDrawString(_town_sort_order & 1 ? "\xAA" : "\xA0", _town_sort_order <= 1 ? 88 : 187, 15, 0x10); |
|
409 |
||
410 |
p = w->vscroll.pos; |
|
411 |
n = 0; |
|
412 |
||
413 |
while (p < _num_town_sort) { |
|
414 |
t = DEREF_TOWN(_town_sort[p]); |
|
415 |
SET_DPARAM16(0, t->index); |
|
416 |
SET_DPARAM32(1, t->population); |
|
417 |
DrawString(2, 28+n*10, STR_2057, 0); |
|
418 |
p++; |
|
419 |
if (++n == 16) |
|
420 |
break; |
|
421 |
} |
|
422 |
} break; |
|
423 |
||
424 |
case WE_CLICK: |
|
425 |
switch(e->click.widget) { |
|
426 |
case 2: { |
|
427 |
_town_sort_order = _town_sort_order==0 ? 1 : 0; |
|
428 |
_town_sort_dirty = true; |
|
429 |
SetWindowDirty(w); |
|
430 |
} break; |
|
431 |
||
432 |
case 3: { |
|
433 |
_town_sort_order = _town_sort_order==2 ? 3 : 2; |
|
434 |
_town_sort_dirty = true; |
|
435 |
SetWindowDirty(w); |
|
436 |
} break; |
|
437 |
||
438 |
case 4: { |
|
439 |
int y = (e->click.pt.y - 28) / 10; |
|
440 |
byte p; |
|
441 |
Town *t; |
|
442 |
||
443 |
if (!IS_INT_INSIDE(y, 0, 16)) |
|
444 |
return; |
|
445 |
p = y + w->vscroll.pos; |
|
446 |
if (p < _num_town_sort) { |
|
447 |
t = DEREF_TOWN(_town_sort[p]); |
|
448 |
ScrollMainWindowToTile(t->xy); |
|
449 |
} |
|
450 |
break; |
|
451 |
} |
|
452 |
} |
|
453 |
break; |
|
454 |
||
455 |
||
456 |
case WE_4: |
|
457 |
SetWindowDirty(w); |
|
458 |
break; |
|
459 |
} |
|
460 |
} |
|
461 |
||
462 |
static const WindowDesc _town_directory_desc = { |
|
463 |
-1, -1, 208, 190, |
|
464 |
WC_TOWN_DIRECTORY,0, |
|
465 |
WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, |
|
466 |
_town_directory_widgets, |
|
467 |
TownDirectoryWndProc |
|
468 |
}; |
|
469 |
||
470 |
||
471 |
void ShowTownDirectory() |
|
472 |
{ |
|
473 |
Window *w; |
|
474 |
||
475 |
w = AllocateWindowDescFront(&_town_directory_desc, 0); |
|
476 |
if (w) { |
|
477 |
w->vscroll.cap = 16; |
|
478 |
} |
|
479 |
} |
|
480 |
||
481 |