1 /***************************************************************************
2 gui.c - description
3 -------------------
4 begin : Sun Mar 31 2002
5 copyright : (C) 2001 by Michael Speck
6 email : kulkanie@gmx.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "lgeneral.h"
19 #include "event.h"
20 #include "parser.h"
21 #include "date.h"
22 #include "nation.h"
23 #include "unit.h"
24 #include "file.h"
25 #include "map.h"
26 #include "list.h"
27 #include "nation.h"
28 #include "unit_lib.h"
29 #include "player.h"
30 #include "slot.h"
31 #include "windows.h"
32 #include "purchase_dlg.h"
33 #include "gui.h"
34 #include "scenario.h"
35 #include "campaign.h"
36 #include "localize.h"
37
38 /*
39 ====================================================================
40 Externals
41 ====================================================================
42 */
43 extern Sdl sdl;
44 extern int hex_w, hex_h;
45 extern Player *cur_player;
46 extern Unit_Info_Icons *unit_info_icons;
47 extern int nation_flag_width, nation_flag_height;
48 extern SDL_Surface *nation_flags;
49 extern Unit *cur_unit;
50 extern Unit_Class *unit_classes;
51 extern int trgt_type_count;
52 extern Trgt_Type *trgt_types;
53 extern Mov_Type *mov_types;
54 extern Scen_Info *scen_info;
55 extern char scen_message[128];
56 extern Weather_Type *weather_types;
57 extern int turn;
58 extern int deploy_turn;
59 extern int deploy_unit_id;
60 extern Unit *deploy_unit;
61 extern List *avail_units;
62 extern List *left_deploy_units;
63 extern List *players;
64 extern Setup setup;
65 extern int vcond_check_type;
66 extern VCond *vconds;
67 extern int vcond_count;
68 extern Config config;
69 extern int camp_loaded;
70
71 /*
72 ====================================================================
73 Locals
74 ====================================================================
75 */
76
77 GUI *gui = 0;
78
79 int cursor; /* current cursor id */
80 /* cursor hotspots */
81 typedef struct {
82 int x,y;
83 } HSpot;
84 HSpot hspots[CURSOR_COUNT] = {
85 {0,0},
86 {0,0},
87 {11,11},
88 {0,0},
89 {11,11},
90 {11,11},
91 {11,11},
92 {11,11},
93 {11,11},
94 {11,11},
95 {11,11}
96 };
97
98 Font *log_font = 0; /* this font is used to display the scenarion load
99 info and is initiated by gui_load() */
100
101 int deploy_offset = 0; /* offset in deployment list */
102 int deploy_border = 10;
103 int deploy_show_count = 7; /* number of displayed units in list */
104
105 int unit_list_offset = 0; /* offset in unit_list */
106 int unit_list_max_offset = 0;
107 int unit_list_graphical_offset=150; /* y-offset for rendering in dialog */
108
109 /*
110 ====================================================================
111 Create a frame surface
112 ====================================================================
113 */
gui_create_frame(int w,int h)114 SDL_Surface *gui_create_frame( int w, int h )
115 {
116 int i;
117 SDL_Surface *surf = create_surf( w, h, SDL_SWSURFACE );
118 SDL_FillRect( surf, 0, 0x0 );
119 /* upper, lower horizontal beam */
120 for ( i = 0; i < w; i += gui->fr_hori->w ) {
121 DEST( surf, i, 0, gui->fr_hori->w, gui->fr_hori->h );
122 SOURCE( gui->fr_hori, 0, 0 );
123 blit_surf();
124 DEST( surf, i, h - gui->fr_hori->h, gui->fr_hori->w, gui->fr_hori->h );
125 SOURCE( gui->fr_hori, 0, 0 );
126 blit_surf();
127 }
128 /* left, right vertical beam */
129 for ( i = 0; i < h; i += gui->fr_vert->h ) {
130 DEST( surf, 0, i, gui->fr_vert->w, gui->fr_vert->h );
131 SOURCE( gui->fr_vert, 0, 0 );
132 blit_surf();
133 DEST( surf, w - gui->fr_vert->w, i, gui->fr_vert->w, gui->fr_vert->h );
134 SOURCE( gui->fr_vert, 0, 0 );
135 blit_surf();
136 }
137 /* left upper corner */
138 DEST( surf, 0, 0, gui->fr_luc->w, gui->fr_luc->h );
139 SOURCE( gui->fr_luc, 0, 0 );
140 blit_surf();
141 /* left lower corner */
142 DEST( surf, 0, h - gui->fr_llc->h, gui->fr_llc->w, gui->fr_llc->h );
143 SOURCE( gui->fr_llc, 0, 0 );
144 blit_surf();
145 /* right upper corner */
146 DEST( surf, w - gui->fr_ruc->w, 0, gui->fr_ruc->w, gui->fr_ruc->h );
147 SOURCE( gui->fr_ruc, 0, 0 );
148 blit_surf();
149 /* right lower corner */
150 DEST( surf, w - gui->fr_rlc->w, h - gui->fr_rlc->h, gui->fr_rlc->w, gui->fr_rlc->h );
151 SOURCE( gui->fr_rlc, 0, 0 );
152 blit_surf();
153 return surf;
154 }
155
156 /*
157 ====================================================================
158 Add the units to the deploy window.
159 ====================================================================
160 */
gui_add_deploy_units(SDL_Surface * contents)161 void gui_add_deploy_units( SDL_Surface *contents )
162 {
163 int i;
164 Unit *unit;
165 int deploy_border = 10;
166 int sx = deploy_border, sy = deploy_border;
167 SDL_FillRect( contents, 0, 0x0 );
168 for ( i = 0; i < deploy_show_count; i++ ) {
169 unit = list_get( left_deploy_units, deploy_offset + i );
170 if ( unit ) {
171 if ( unit == deploy_unit ) {
172 DEST( contents, sx, sy, hex_w, hex_h );
173 fill_surf( 0xbbbbbb );
174 }
175 DEST( contents,
176 sx + ( ( hex_w - unit->sel_prop->icon_w ) >> 1 ),
177 sy + ( ( hex_h - unit->sel_prop->icon_h ) >> 1 ),
178 unit->sel_prop->icon_w, unit->sel_prop->icon_h );
179 SOURCE( unit->sel_prop->icon, 0, 0 );
180 blit_surf();
181 sy += hex_h;
182 }
183 }
184 }
185
186 /*
187 ====================================================================
188 Publics
189 ====================================================================
190 */
191
192 /*
193 ====================================================================
194 Create the gui and use the graphics in gfx/themes/...
195 ====================================================================
196 */
gui_load(const char * dir)197 int gui_load( const char *dir )
198 {
199 char str[128];
200 int i;
201 int sx, sy;
202 char path[256], path2[256], path3[256], path4[256];
203
204 gui_delete();
205 gui = calloc( 1, sizeof( GUI ) );
206 /* name */
207 gui->name = strdup( dir );
208 /* frame tiles */
209 sprintf( path, "../themes/%s/fr_luc.bmp", dir );
210 gui->fr_luc = load_surf( path, SDL_SWSURFACE );
211 SDL_SetColorKey( gui->fr_luc, 0, 0 );
212 sprintf( path, "../themes/%s/fr_llc.bmp", dir );
213 gui->fr_llc = load_surf( path, SDL_SWSURFACE );
214 SDL_SetColorKey( gui->fr_llc, 0, 0 );
215 sprintf( path, "../themes/%s/fr_ruc.bmp", dir );
216 gui->fr_ruc = load_surf( path, SDL_SWSURFACE );
217 SDL_SetColorKey( gui->fr_ruc, 0, 0 );
218 sprintf( path, "../themes/%s/fr_rlc.bmp", dir );
219 gui->fr_rlc = load_surf( path, SDL_SWSURFACE );
220 SDL_SetColorKey( gui->fr_rlc, 0, 0 );
221 sprintf( path, "../themes/%s/fr_hori.bmp", dir );
222 gui->fr_hori = load_surf( path, SDL_SWSURFACE );
223 SDL_SetColorKey( gui->fr_hori, 0, 0 );
224 sprintf( path, "../themes/%s/fr_vert.bmp", dir );
225 gui->fr_vert = load_surf( path, SDL_SWSURFACE );
226 SDL_SetColorKey( gui->fr_vert, 0, 0 );
227 /* briefing frame and background */
228 sprintf( path, "../themes/%s/bkgnd.bmp", dir );
229 if ( ( gui->bkgnd = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto sdl_failure;
230 sprintf( path, "../themes/%s/brief_frame.bmp", dir );
231 if ( ( gui->brief_frame = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto sdl_failure;
232 sprintf( path, "../themes/%s/wallpaper.bmp", dir );
233 if ( ( gui->wallpaper = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto sdl_failure;
234 /* folder */
235 sprintf( path, "../themes/%s/folder.bmp", dir );
236 if ( ( gui->folder_icon = load_surf( path, SDL_SWSURFACE ) ) == 0 ) goto sdl_failure;
237 /* basic fonts */
238 sprintf( path, "../themes/%s/font_std.bmp", dir );
239 gui->font_std = load_font( path );
240 sprintf( path, "../themes/%s/font_status.bmp", dir );
241 gui->font_status = load_font( path );
242 sprintf( path, "../themes/%s/font_error.bmp", dir );
243 gui->font_error = load_font( path );
244 sprintf( path, "../themes/%s/font_turn_info.bmp", dir );
245 gui->font_turn_info = load_font( path );
246 sprintf( path, "../themes/%s/font_brief.bmp", dir );
247 gui->font_brief = load_font( path );
248 /* cursors */
249 sprintf( path, "../themes/%s/cursors.bmp", dir );
250 if ( ( gui->cursors = image_create( load_surf( path, SDL_SWSURFACE ), 22, 22, sdl.screen, 0, 0 ) ) == 0 )
251 goto failure;
252 /* info label */
253 if ( ( gui->label = label_create( gui_create_frame( 240, 30 ), 160, gui->font_std, sdl.screen, 0, 0 ) ) == 0 )
254 goto failure;
255 if ( ( gui->label2 = label_create( gui_create_frame( 240, 30 ), 160, gui->font_std, sdl.screen, 0, 0 ) ) == 0 )
256 goto failure;
257 label_hide( gui->label, 1 );
258 label_hide( gui->label2, 1 );
259 /* quick unit infos */
260 if ( ( gui->qinfo1 = frame_create( gui_create_frame( 240, 60 ), 160, sdl.screen, 0, 0 ) ) == 0 )
261 goto failure;
262 frame_hide( gui->qinfo1, 1 );
263 if ( ( gui->qinfo2 = frame_create( gui_create_frame( 240, 60 ), 160, sdl.screen, 0, 0 ) ) == 0 )
264 goto failure;
265 frame_hide( gui->qinfo2, 1 );
266 /* full unit info */
267 if ( ( gui->finfo = frame_create( gui_create_frame( 460, 280 ), 160, sdl.screen, 0, 0 ) ) == 0 )
268 goto failure;
269 frame_hide( gui->finfo, 1 );
270 //unit list
271 if ( ( gui->unit_list = frame_create( gui_create_frame( 600, 460 ), 160, sdl.screen, 0, 0 ) ) == 0 )
272 goto failure;
273 frame_hide( gui->unit_list, 1 );
274 /* scenario info */
275 if ( ( gui->sinfo = frame_create( gui_create_frame( 300, 260 ), 160, sdl.screen, 0, 0 ) ) == 0 )
276 goto failure;
277 frame_hide( gui->sinfo, 1 );
278 /* confirm window */
279 sprintf( path2, "../themes/%s/confirm_buttons.bmp", dir );
280 if ( ( gui->confirm = group_create( gui_create_frame( 200, 80 ), 160, load_surf( path2, SDL_SWSURFACE ),
281 20, 20, 6, ID_OK, gui->label, sdl.screen, 0, 0 ) ) == 0 )
282 goto failure;
283 sx = gui->confirm->frame->img->img->w - 60; sy = gui->confirm->frame->img->img->h - 30;
284 group_add_button( gui->confirm, ID_OK, sx, sy, 0, tr("Accept") ); sx += 30;
285 group_add_button( gui->confirm, ID_CANCEL, sx, sy, 0, tr("Cancel") );
286 group_hide( gui->confirm, 1 );
287 /* unit buttons */
288 sprintf( path2, "../themes/%s/unit_buttons.bmp", dir );
289 if ( ( gui->unit_buttons = group_create( gui_create_frame( 30, 230 ), 160, load_surf( path2, SDL_SWSURFACE ),
290 24, 24, 7, ID_SUPPLY, gui->label, sdl.screen, 0, 0 ) ) == 0 )
291 goto failure;
292 sx = 3; sy = 3;
293 group_add_button( gui->unit_buttons, ID_UNDO, sx, sy, 0, tr("Undo Turn [u]") ); sy += 40;
294 group_add_button( gui->unit_buttons, ID_SUPPLY, sx, sy, 0, tr("Supply Unit [s]") ); sy += 30;
295 group_add_button( gui->unit_buttons, ID_EMBARK_AIR, sx, sy, 0, tr("Air Embark") ); sy += 30;
296 group_add_button( gui->unit_buttons, ID_MERGE, sx, sy, 0, tr("Merge Unit [j]") ); sy += 30;
297 group_add_button( gui->unit_buttons, ID_SPLIT, sx, sy, 0, tr("Split Unit [x+1..9]") ); sy += 30;
298 group_add_button( gui->unit_buttons, ID_RENAME, sx, sy, 0, tr("Rename Unit") ); sy += 40;
299 group_add_button( gui->unit_buttons, ID_DISBAND, sx, sy, 0, tr("Disband Unit") );
300 group_hide( gui->unit_buttons, 1 );
301 /* split menu */
302 sprintf( path2, "../themes/%s/strength_buttons.bmp", dir );
303 if ( ( gui->split_menu = group_create( gui_create_frame( 26, 186 ), 160, load_surf( path2, SDL_SWSURFACE ),
304 20, 20, 10, ID_SPLIT_1, gui->label, sdl.screen, 0, 0 ) ) == 0 )
305 goto failure;
306 sx = 3; sy = 3;
307 for ( i = 0; i < 9; i++ ) {
308 sprintf( str, tr("Split Up %d Strength"), i+1 );
309 group_add_button( gui->split_menu, ID_SPLIT_1 + i, sx, sy, 0, str );
310 sy += 20;
311 }
312 group_hide( gui->split_menu, 1 );
313 /* deploy window */
314 sprintf( path2, "../themes/%s/deploy_buttons.bmp", dir );
315 if ( ( gui->deploy_window = group_create( gui_create_frame( 80, 440 ), 160, load_surf( path2, SDL_SWSURFACE ),
316 20, 20, 6, ID_APPLY_DEPLOY, gui->label, sdl.screen, 0, 0 ) ) == 0 )
317 goto failure;
318 sx = gui->deploy_window->frame->img->img->w - 65;
319 sy = gui->deploy_window->frame->img->img->h - 60;
320 group_add_button( gui->deploy_window, ID_DEPLOY_UP, sx, sy, 0, tr("Scroll Up") );
321 group_add_button( gui->deploy_window, ID_DEPLOY_DOWN, sx + 30, sy, 0, tr("Scroll Down") ); sy += 30;
322 group_add_button( gui->deploy_window, ID_APPLY_DEPLOY, sx, sy, 0, tr("Apply Deployment") );
323 group_add_button( gui->deploy_window, ID_CANCEL_DEPLOY, sx + 30, sy, 0, tr("Cancel Deployment") );
324 group_hide( gui->deploy_window, 1 );
325 /* edit */
326 if ( ( gui->edit = edit_create( gui_create_frame( 240, 30 ), 160, gui->font_std, 20, sdl.screen, 0, 0 ) ) == 0 )
327 goto failure;
328 edit_hide( gui->edit, 1 );
329 /* base menu */
330 sprintf( path2, "../themes/%s/menu0_buttons.bmp", dir );
331 if ( ( gui->base_menu = group_create( gui_create_frame( 30, 280 ), 160, load_surf( path2, SDL_SWSURFACE ),
332 24, 24, 9, ID_MENU, gui->label, sdl.screen, 0, 0 ) ) == 0 )
333 goto failure;
334 sx = 3; sy = 3;
335 group_add_button( gui->base_menu, ID_AIR_MODE, sx, sy, 0, tr("Switch Air/Ground [t]") ); sy += 30;
336 group_add_button( gui->base_menu, ID_STRAT_MAP, sx, sy, 0, tr("Strategic Map [o]") ); sy += 30;
337 group_add_button( gui->base_menu, ID_PURCHASE, sx, sy, 0, tr("Request Reinforcements") ); sy += 30;
338 group_add_button( gui->base_menu, ID_DEPLOY, sx, sy, 0, tr("Deploy Reinforcements [d]") ); sy += 30;
339 group_add_button( gui->base_menu, ID_UNIT_LIST, sx, sy, 0, tr("Unit List") ); sy += 30;
340 group_add_button( gui->base_menu, ID_SCEN_INFO, sx, sy, 0, tr("Scenario Info [i]") ); sy += 30;
341 group_add_button( gui->base_menu, ID_CONDITIONS, sx, sy, 0, tr("Victory Conditions") ); sy += 30;
342 group_add_button( gui->base_menu, ID_END_TURN, sx, sy, 0, tr("End Turn [e]") ); sy += 40;
343 group_add_button( gui->base_menu, ID_MENU, sx, sy, 0, tr("Main Menu") );
344 group_hide( gui->base_menu, 1 );
345 /* main_menu */
346 sprintf( path2, "../themes/%s/menu1_buttons.bmp", dir );
347 if ( ( gui->main_menu = group_create( gui_create_frame( 30, 210 ), 160, load_surf( path2, SDL_SWSURFACE ),
348 24, 24, 7, ID_SAVE, gui->label, sdl.screen, 0, 0 ) ) == 0 )
349 goto failure;
350 sx = 3; sy = 3;
351 group_add_button( gui->main_menu, ID_SAVE, sx, sy, 0, tr("Save Game") ); sy += 30;
352 group_add_button( gui->main_menu, ID_LOAD, sx, sy, 0, tr("Load Game") ); sy += 30;
353 group_add_button( gui->main_menu, ID_RESTART, sx, sy, 0, tr("Restart Scenario") ); sy += 30;
354 group_add_button( gui->main_menu, ID_CAMP, sx, sy, 0, tr("Load Campaign") ); sy += 30;
355 group_add_button( gui->main_menu, ID_SCEN, sx, sy, 0, tr("Load Scenario") ); sy += 30;
356 group_add_button( gui->main_menu, ID_OPTIONS, sx, sy, 0, tr("Options") ); sy += 30;
357 group_add_button( gui->main_menu, ID_QUIT, sx, sy, 0, tr("Quit Game") );
358 group_hide( gui->main_menu, 1 );
359 /* load menu */
360 sprintf( path2, "../themes/%s/menu2_buttons.bmp", dir );
361 if ( ( gui->load_menu = group_create( gui_create_frame( 30, 246+24 ), 160, load_surf( path2, SDL_SWSURFACE ),
362 24, 24, 11, ID_LOAD_0, gui->label, sdl.screen, 0, 0 ) ) == 0 )
363 goto failure;
364 sx = 3; sy = 3;
365 for ( i = 0; i < SLOT_COUNT; i++ ) {
366 sprintf( str, tr("Load: %s"), slot_get_name( i ) );
367 group_add_button( gui->load_menu, ID_LOAD_0 + i, sx, sy, 0, str );
368 sy += 24;
369 }
370 group_hide( gui->load_menu, 1 );
371 /* save menu */
372 sprintf( path2, "../themes/%s/menu2_buttons.bmp", dir );
373 if ( ( gui->save_menu = group_create( gui_create_frame( 30, 246 ), 160, load_surf( path2, SDL_SWSURFACE ),
374 24, 24, 10, ID_SAVE_0, gui->label, sdl.screen, 0, 0 ) ) == 0 )
375 goto failure;
376 sx = 3; sy = 3;
377 for ( i = 0; i < 10; i++ ) {
378 sprintf( str, tr("Save: %s"), slot_get_name( i ) );
379 group_add_button( gui->save_menu, ID_SAVE_0 + i, sx, sy, 0, str );
380 sy += 24;
381 }
382 group_hide( gui->save_menu, 1 );
383 /* options */
384 sprintf( path2, "../themes/%s/menu3_buttons.bmp", dir );
385 if ( ( gui->opt_menu = group_create( gui_create_frame( 30, 300 - 60 ), 160, load_surf( path2, SDL_SWSURFACE ),
386 24, 24, 10, ID_C_SUPPLY, gui->label, sdl.screen, 0, 0 ) ) == 0 )
387 goto failure;
388 sx = 3; sy = 3;
389 //group_add_button( gui->opt_menu, ID_C_SUPPLY, sx, sy, 1, "Unit Supply" ); sy += 30;
390 //group_add_button( gui->opt_menu, ID_C_WEATHER, sx, sy, 1, "Weather Influence" ); sy += 30;
391 group_add_button( gui->opt_menu, ID_C_GRID, sx, sy, 1, tr("Hex Grid [g]") ); sy += 30;
392 group_add_button( gui->opt_menu, ID_C_SHOW_CPU, sx, sy, 1, tr("Show CPU Turn") ); sy += 30;
393 group_add_button( gui->opt_menu, ID_C_SHOW_STRENGTH, sx, sy, 1, tr("Show Unit Strength [.]") ); sy += 30;
394 group_add_button( gui->opt_menu, ID_C_SOUND, sx, sy, 1, tr("Sound") ); sy += 30;
395 group_add_button( gui->opt_menu, ID_C_SOUND_INC, sx, sy, 0, tr("Sound Volume Up") ); sy += 30;
396 group_add_button( gui->opt_menu, ID_C_SOUND_DEC, sx, sy, 0, tr("Sound Volume Down") ); sy += 30;
397 group_add_button( gui->opt_menu, ID_C_MUSIC, sx, sy, 1, tr("Music") ); sy += 30;
398 group_add_button( gui->opt_menu, ID_C_VMODE, sx, sy, 0, tr("Video Mode [v]") );
399 group_hide( gui->opt_menu, 1 );
400 /* video mode dialog */
401 sprintf( path, "../themes/%s/scroll_buttons.bmp", dir );
402 sprintf( path2, "../themes/%s/confirm_buttons.bmp", dir );
403 gui->vmode_dlg = select_dlg_create( gui_create_frame( 210, 120 ),
404 load_surf( path, SDL_SWSURFACE ), 24, 24,
405 8, 190, 12, lbox_render_text,
406 gui_create_frame( 210, 30 ),
407 load_surf( path2, SDL_SWSURFACE ), 20, 20,
408 ID_VMODE_OK, sdl.screen, 0, 0);
409 select_dlg_hide( gui->vmode_dlg, 1 );
410 /* scenario dialogue */
411 sprintf( path, "../themes/%s/scen_dlg_buttons.bmp", dir );
412 sprintf( path2, "../themes/%s/scroll_buttons.bmp", dir );
413 gui->scen_dlg = fdlg_create( gui_create_frame( 120, 240 ), 160, 10,
414 load_surf( path2, SDL_SWSURFACE), 24, 24,
415 20,
416 gui_create_frame( 220, 240),
417 load_surf( path, SDL_SWSURFACE ), 24, 24,
418 ID_SCEN_OK,
419 gui->label,
420 gui_render_file_name, gui_render_scen_info,
421 sdl.screen, 0, 0 );
422 fdlg_add_button( gui->scen_dlg, ID_SCEN_SETUP, 0, tr("Player Setup") );
423 fdlg_hide( gui->scen_dlg, 1 );
424 /* campaign dialogue */
425 sprintf( path, "../themes/%s/confirm_buttons.bmp", dir );
426 sprintf( path2, "../themes/%s/scroll_buttons.bmp", dir );
427 gui->camp_dlg = fdlg_create( gui_create_frame( 120, 240 ), 160, 10,
428 load_surf( path2, SDL_SWSURFACE), 24, 24,
429 20,
430 gui_create_frame( 220, 240),
431 load_surf( path, SDL_SWSURFACE ), 20, 20,
432 ID_CAMP_OK,
433 gui->label,
434 gui_render_file_name, gui_render_camp_info,
435 sdl.screen, 0, 0 );
436 fdlg_hide( gui->camp_dlg, 1 );
437 /* setup window */
438 sprintf( path, "../themes/%s/scroll_buttons.bmp", dir );
439 sprintf( path2, "../themes/%s/ctrl_buttons.bmp", dir );
440 sprintf( path3, "../themes/%s/module_buttons.bmp", dir );
441 sprintf( path4, "../themes/%s/setup_confirm_buttons.bmp", dir );
442 gui->setup = sdlg_create(
443 gui_create_frame( 120, 120 ), load_surf( path, SDL_SWSURFACE ), 24, 24, 20,
444 gui_create_frame( 220, 40 ), load_surf( path2, SDL_SWSURFACE ), 24, 24, ID_SETUP_CTRL,
445 gui_create_frame( 220, 40 ), load_surf( path3, SDL_SWSURFACE ), 24, 24, ID_SETUP_MODULE,
446 gui_create_frame( 220, 40 ), load_surf( path4, SDL_SWSURFACE ), 24, 24, ID_SETUP_OK,
447 gui->label,
448 gui_render_player_name, gui_handle_player_select,
449 sdl.screen, 0, 0 );
450 sdlg_hide( gui->setup, 1 );
451 /* module dialogue */
452 sprintf( path, "../themes/%s/confirm_buttons.bmp", dir );
453 sprintf( path2, "../themes/%s/scroll_buttons.bmp", dir );
454 gui->module_dlg = fdlg_create( gui_create_frame( 120, 240 ), 160, 10,
455 load_surf( path2, SDL_SWSURFACE), 24, 24,
456 20,
457 gui_create_frame( 220, 240),
458 load_surf( path, SDL_SWSURFACE ), 20, 20,
459 ID_MODULE_OK,
460 gui->label,
461 gui_render_file_name, gui_render_module_info,
462 sdl.screen, 0, 0 );
463 fdlg_hide( gui->module_dlg, 1 );
464 /* purchase dialogue */
465 sprintf( path2, "../themes/%s", dir );
466 if ( (gui->purchase_dlg = purchase_dlg_create( path2 )) == NULL)
467 goto failure;
468 purchase_dlg_hide( gui->purchase_dlg, 1 );
469 /* adjust positions */
470 gui_adjust();
471 /* sounds */
472 #ifdef WITH_SOUND
473 sprintf( path, "../themes/%s/click.wav", dir );
474 gui->wav_click = wav_load( path, 1 );
475 sprintf( path, "../themes/%s/edit.wav", dir );
476 gui->wav_edit = wav_load( path, 1 );
477 #endif
478 log_font = gui->font_std;
479 return 1;
480 sdl_failure:
481 fprintf( stderr, "SDL says: %s\n", SDL_GetError() );
482 failure:
483 gui_delete();
484 return 0;
485 }
gui_delete()486 void gui_delete()
487 {
488 if ( gui ) {
489 if ( gui->name ) free( gui->name );
490 free_surf( &gui->bkgnd );
491 free_surf( &gui->brief_frame );
492 free_surf( &gui->wallpaper );
493 free_surf( &gui->fr_luc );
494 free_surf( &gui->fr_llc );
495 free_surf( &gui->fr_ruc );
496 free_surf( &gui->fr_rlc );
497 free_surf( &gui->fr_hori );
498 free_surf( &gui->fr_vert );
499 free_surf( &gui->folder_icon );
500 free_font( &gui->font_std );
501 free_font( &gui->font_status );
502 free_font( &gui->font_error );
503 free_font( &gui->font_turn_info );
504 free_font( &gui->font_brief );
505 image_delete( &gui->cursors );
506 label_delete( &gui->label );
507 label_delete( &gui->label2 );
508 frame_delete( &gui->qinfo1 );
509 frame_delete( &gui->qinfo2 );
510 frame_delete( &gui->finfo );
511 frame_delete( &gui->unit_list );
512 frame_delete( &gui->sinfo );
513 group_delete( &gui->confirm );
514 group_delete( &gui->unit_buttons );
515 group_delete( &gui->split_menu );
516 group_delete( &gui->deploy_window );
517 group_delete( &gui->base_menu );
518 group_delete( &gui->main_menu );
519 group_delete( &gui->load_menu );
520 group_delete( &gui->save_menu );
521 group_delete( &gui->opt_menu );
522 select_dlg_delete( &gui->vmode_dlg );
523 fdlg_delete( &gui->scen_dlg );
524 fdlg_delete( &gui->camp_dlg );
525 sdlg_delete( &gui->setup );
526 fdlg_delete( &gui->module_dlg );
527 edit_delete( &gui->edit );
528 purchase_dlg_delete( &gui->purchase_dlg );
529 #ifdef WITH_SOUND
530 wav_free( gui->wav_click );
531 wav_free( gui->wav_edit );
532 #endif
533 free( gui ); gui = 0;
534 }
535 }
536
537 /*
538 ====================================================================
539 Move all windows to there proper position according to screen's
540 measurements.
541 ====================================================================
542 */
gui_adjust()543 void gui_adjust()
544 {
545 int label_top = 10;
546 int label_x = (sdl.screen->w - gui->label->frame->img->img->w ) >> 1;
547 /* info labels */
548 label_move( gui->label, label_x, label_top );
549 label_top += gui->label->frame->img->img->h + 5;
550 label_move( gui->label2, label_x, label_top );
551 /* unit infos */
552 frame_move( gui->qinfo1, 10, sdl.screen->h - 10 - gui->qinfo1->img->img->h );
553 frame_move( gui->qinfo2, 10, sdl.screen->h - 20 - gui->qinfo1->img->img->h * 2 );
554 /* full info */
555 frame_move( gui->finfo, ( sdl.screen->w - gui->finfo->img->img->w ) >> 1, ( sdl.screen->h - gui->finfo->img->img->h ) >> 1 );
556 frame_move( gui->unit_list, ( sdl.screen->w - gui->unit_list->img->img->w ) >> 1, ( sdl.screen->h - gui->unit_list->img->img->h ) >> 1 );
557 /* basic menu */
558 group_move( gui->base_menu, sdl.screen->w - 10 - gui->base_menu->frame->img->img->w,
559 sdl.screen->h - 10 - gui->base_menu->frame->img->img->h );
560 /* scenario info */
561 frame_move( gui->sinfo, ( sdl.screen->w - gui->sinfo->img->img->w ) >> 1, ( sdl.screen->h - gui->sinfo->img->img->h ) >> 1 );
562 /* confirm window */
563 group_move( gui->confirm, ( sdl.screen->w - gui->confirm->frame->img->img->w ) >> 1, ( sdl.screen->h - gui->confirm->frame->img->img->h ) >> 1 );
564 /* deploy window */
565 group_move( gui->deploy_window, ( sdl.screen->w - gui->deploy_window->frame->img->img->w ) - 10,
566 ( sdl.screen->h - gui->deploy_window->frame->img->img->h ) / 2 );
567 /* edit */
568 edit_move( gui->edit, (sdl.screen->w - gui->edit->label->frame->img->img->w ) >> 1, 50 );
569 /* select dialogs */
570 select_dlg_move( gui->vmode_dlg,
571 (sdl.screen->w - select_dlg_get_width(gui->vmode_dlg)) /2,
572 (sdl.screen->h - select_dlg_get_height(gui->vmode_dlg)) /2);
573 /* scenario dialogue */
574 fdlg_move( gui->scen_dlg, ( sdl.screen->w - ( gui->scen_dlg->group->frame->img->img->w +
575 gui->scen_dlg->lbox->group->frame->img->img->w ) ) / 2,
576 ( sdl.screen->h - gui->scen_dlg->group->frame->img->img->h ) / 2 );
577 /* campaign dialogue */
578 fdlg_move( gui->camp_dlg, ( sdl.screen->w - ( gui->camp_dlg->group->frame->img->img->w +
579 gui->camp_dlg->lbox->group->frame->img->img->w ) ) / 2,
580 ( sdl.screen->h - gui->camp_dlg->group->frame->img->img->h ) / 2 );
581 /* scenario setup */
582 sdlg_move( gui->setup, ( sdl.screen->w - ( gui->setup->list->group->frame->img->img->w + gui->setup->ctrl->frame->img->img->w ) ) / 2,
583 ( sdl.screen->h - ( gui->setup->list->group->frame->img->img->h ) ) / 2 );
584 /* module dialogue */
585 fdlg_move( gui->module_dlg, ( sdl.screen->w - ( gui->module_dlg->group->frame->img->img->w +
586 gui->module_dlg->lbox->group->frame->img->img->w ) ) / 2,
587 ( sdl.screen->h - gui->module_dlg->group->frame->img->img->h ) / 2 );
588
589 /* purchase dialogue */
590 purchase_dlg_move(gui->purchase_dlg,
591 (sdl.screen->w - purchase_dlg_get_width(gui->purchase_dlg)) /2,
592 (sdl.screen->h - purchase_dlg_get_height(gui->purchase_dlg)) /2);
593 }
594
595 /*
596 ====================================================================
597 Change all GUI graphics to the one found in gfx/theme/path.
598 ====================================================================
599 */
600 int gui_change( const char *path );
601
602 /*
603 ====================================================================
604 Hide/draw from/to screen
605 ====================================================================
606 */
gui_get_bkgnds()607 void gui_get_bkgnds()
608 {
609 label_get_bkgnd( gui->label );
610 label_get_bkgnd( gui->label2 );
611 frame_get_bkgnd( gui->qinfo1 );
612 frame_get_bkgnd( gui->qinfo2 );
613 frame_get_bkgnd( gui->finfo );
614 frame_get_bkgnd( gui->unit_list );
615 frame_get_bkgnd( gui->sinfo );
616 group_get_bkgnd( gui->base_menu );
617 group_get_bkgnd( gui->main_menu );
618 group_get_bkgnd( gui->load_menu );
619 group_get_bkgnd( gui->save_menu );
620 group_get_bkgnd( gui->opt_menu );
621 group_get_bkgnd( gui->unit_buttons);
622 group_get_bkgnd( gui->split_menu );
623 edit_get_bkgnd( gui->edit );
624 group_get_bkgnd( gui->confirm );
625 group_get_bkgnd( gui->deploy_window );
626 select_dlg_get_bkgnd( gui->vmode_dlg );
627 fdlg_get_bkgnd( gui->scen_dlg );
628 fdlg_get_bkgnd( gui->camp_dlg );
629 fdlg_get_bkgnd( gui->module_dlg );
630 sdlg_get_bkgnd( gui->setup );
631 purchase_dlg_get_bkgnd( gui->purchase_dlg );
632 image_get_bkgnd( gui->cursors );
633 }
gui_draw_bkgnds()634 void gui_draw_bkgnds()
635 {
636 label_draw_bkgnd( gui->label );
637 label_draw_bkgnd( gui->label2 );
638 frame_draw_bkgnd( gui->qinfo1 );
639 frame_draw_bkgnd( gui->qinfo2 );
640 frame_draw_bkgnd( gui->finfo );
641 frame_draw_bkgnd( gui->unit_list );
642 frame_draw_bkgnd( gui->sinfo );
643 group_draw_bkgnd( gui->base_menu );
644 group_draw_bkgnd( gui->main_menu );
645 group_draw_bkgnd( gui->load_menu );
646 group_draw_bkgnd( gui->save_menu );
647 group_draw_bkgnd( gui->opt_menu );
648 group_draw_bkgnd( gui->unit_buttons);
649 group_draw_bkgnd( gui->split_menu );
650 edit_draw_bkgnd( gui->edit );
651 group_draw_bkgnd( gui->confirm );
652 group_draw_bkgnd( gui->deploy_window );
653 select_dlg_draw_bkgnd( gui->vmode_dlg );
654 fdlg_draw_bkgnd( gui->scen_dlg );
655 fdlg_draw_bkgnd( gui->camp_dlg );
656 fdlg_draw_bkgnd( gui->module_dlg );
657 sdlg_draw_bkgnd( gui->setup );
658 purchase_dlg_draw_bkgnd( gui->purchase_dlg );
659 image_draw_bkgnd( gui->cursors );
660 }
gui_draw()661 void gui_draw()
662 {
663 label_draw( gui->label );
664 label_draw( gui->label2 );
665 frame_draw( gui->qinfo1 );
666 frame_draw( gui->qinfo2 );
667 frame_draw( gui->finfo );
668 frame_draw( gui->unit_list );
669 frame_draw( gui->sinfo );
670 group_draw( gui->base_menu );
671 group_draw( gui->main_menu );
672 group_draw( gui->load_menu );
673 group_draw( gui->save_menu );
674 group_draw( gui->opt_menu );
675 group_draw( gui->unit_buttons);
676 group_draw( gui->split_menu );
677 edit_draw( gui->edit );
678 group_draw( gui->confirm );
679 group_draw( gui->deploy_window );
680 select_dlg_draw( gui->vmode_dlg );
681 fdlg_draw( gui->scen_dlg );
682 fdlg_draw( gui->camp_dlg );
683 fdlg_draw( gui->module_dlg );
684 sdlg_draw( gui->setup );
685 purchase_dlg_draw( gui->purchase_dlg );
686 image_draw( gui->cursors );
687 }
688
689 /*
690 ====================================================================
691 Move cursor.
692 ====================================================================
693 */
gui_move_cursor(int cx,int cy)694 void gui_move_cursor( int cx, int cy )
695 {
696 if ( cx - hspots[cursor].x < 0 ) cx = hspots[cursor].x;
697 if ( cy - hspots[cursor].y < 0 ) cy = hspots[cursor].y;
698 if ( cx + hspots[cursor].x >= sdl.screen->w ) cx = sdl.screen->w - hspots[cursor].x;
699 if ( cy + hspots[cursor].y >= sdl.screen->h ) cy = sdl.screen->h - hspots[cursor].y;
700 /* if ( cx - hspots[cursor].x + gui->cursors->bkgnd->surf_rect.w >= sdl.screen->w )
701 cx = sdl.screen->w - gui->cursors->bkgnd->surf_rect.w + hspots[cursor].x;
702 if ( cy - hspots[cursor].y + gui->cursors->bkgnd->surf_rect.h >= sdl.screen->h )
703 cy = sdl.screen->h - gui->cursors->bkgnd->surf_rect.h + hspots[cursor].y;*/
704 image_move( gui->cursors, cx - hspots[cursor].x, cy - hspots[cursor].y );
705 }
706
707 /*
708 ====================================================================
709 Set cursor.
710 ====================================================================
711 */
gui_set_cursor(int type)712 void gui_set_cursor( int type )
713 {
714 int move = 0;
715 int x = -1, y;
716 if ( type >= CURSOR_COUNT ) type = 0;
717 if ( cursor != type ) {
718 x = gui->cursors->bkgnd->surf_rect.x + hspots[cursor].x;
719 y = gui->cursors->bkgnd->surf_rect.y + hspots[cursor].y;
720 move = 1;
721 }
722 cursor = type;
723 if ( move )
724 gui_move_cursor( x, y );
725 image_set_region( gui->cursors, 22 * type, 0, 22, 22 );
726 }
727
728 /*
729 ====================================================================
730 Handle events.
731 ====================================================================
732 */
gui_handle_motion(int cx,int cy)733 int gui_handle_motion( int cx, int cy )
734 {
735 int ret = 1;
736 if ( !group_handle_motion( gui->base_menu, cx, cy ) )
737 if ( !group_handle_motion( gui->main_menu, cx, cy ) )
738 if ( !group_handle_motion( gui->load_menu, cx, cy ) )
739 if ( !group_handle_motion( gui->save_menu, cx, cy ) )
740 if ( !group_handle_motion( gui->opt_menu, cx, cy ) )
741 if ( !group_handle_motion( gui->unit_buttons, cx, cy ) )
742 if ( !group_handle_motion( gui->split_menu, cx, cy ) )
743 if ( !group_handle_motion( gui->confirm, cx, cy ) )
744 if ( !select_dlg_handle_motion( gui->vmode_dlg, cx, cy ) )
745 if ( !fdlg_handle_motion( gui->scen_dlg, cx, cy ) )
746 if ( !fdlg_handle_motion( gui->camp_dlg, cx, cy ) )
747 if ( !fdlg_handle_motion( gui->module_dlg, cx, cy ) )
748 if ( !sdlg_handle_motion( gui->setup, cx, cy ) )
749 if ( !purchase_dlg_handle_motion( gui->purchase_dlg, cx, cy ) )
750 ret = 0;
751 /* cursor */
752 gui_move_cursor( cx, cy );
753 return ret;
754 }
755 /** If true is returned, @button has to be set for processing upstream. */
gui_handle_button(int button_id,int cx,int cy,Button ** button)756 int gui_handle_button( int button_id, int cx, int cy, Button **button )
757 {
758 int ret = 1;
759 *button = 0;
760 if ( !group_handle_button( gui->base_menu, button_id, cx, cy, button ) )
761 if ( !group_handle_button( gui->main_menu, button_id, cx, cy, button ) )
762 if ( !group_handle_button( gui->load_menu, button_id, cx, cy, button ) )
763 if ( !group_handle_button( gui->save_menu, button_id, cx, cy, button ) )
764 if ( !group_handle_button( gui->opt_menu, button_id, cx, cy, button ) )
765 if ( !group_handle_button( gui->unit_buttons, button_id, cx, cy, button ) )
766 if ( !group_handle_button( gui->split_menu, button_id, cx, cy, button ) )
767 if ( !group_handle_button( gui->confirm, button_id, cx, cy, button ) )
768 if ( !group_handle_button( gui->deploy_window, button_id, cx, cy, button ) )
769 if ( !select_dlg_handle_button( gui->vmode_dlg, button_id, cx, cy, button ) )
770 if ( !fdlg_handle_button( gui->scen_dlg, button_id, cx, cy, button ) )
771 if ( !fdlg_handle_button( gui->camp_dlg, button_id, cx, cy, button ) )
772 if ( !fdlg_handle_button( gui->module_dlg, button_id, cx, cy, button ) )
773 if ( !sdlg_handle_button( gui->setup, button_id, cx, cy, button ) )
774 if ( !purchase_dlg_handle_button( gui->purchase_dlg, button_id, cx, cy, button ) )
775 ret = 0;
776 return ret;
777 }
gui_update(int ms)778 void gui_update( int ms )
779 {
780 }
781
782 /*
783 ====================================================================
784 Set quick info frame with information on this unit and set hide = 0.
785 ====================================================================
786 */
gui_show_quick_info(Frame * qinfo,Unit * unit)787 void gui_show_quick_info( Frame *qinfo, Unit *unit )
788 {
789 int i, len;
790 char str[64];
791 /* clear */
792 SDL_FillRect( qinfo->contents, 0, 0x0 );
793 /* icon */
794 DEST( qinfo->contents,
795 6 + ( ( hex_w - unit->prop.icon_w ) >> 1 ), ( ( qinfo->contents->h - unit->prop.icon_h ) >> 1 ),
796 unit->prop.icon_w, unit->prop.icon_h );
797 SOURCE( unit->prop.icon, 0, 0 );
798 blit_surf();
799 DEST( qinfo->contents,
800 6 + ( ( hex_w - unit_info_icons->str_w ) >> 1 ),
801 ( ( qinfo->contents->h - unit->prop.icon_h ) >> 1 ) + unit->prop.icon_h,
802 unit_info_icons->str_w, unit_info_icons->str_h );
803 SOURCE( unit_info_icons->str, 0, ( unit->str + 14 ) * unit_info_icons->str_h )
804 blit_surf();
805 /* nation flag */
806 DEST( qinfo->contents, 6, 6, nation_flag_width, nation_flag_height );
807 SOURCE( nation_flags, 0, unit->nation->flag_offset );
808 blit_surf();
809 /* core unit flag */
810 if (camp_loaded) {
811 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_BOTTOM;
812 write_text( gui->font_std, qinfo->contents,
813 6, qinfo->contents->h - 6,
814 (unit->core==1)?"C":"A", 255 );
815 }
816 /* name */
817 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
818 write_text( gui->font_std, qinfo->contents, 12 + hex_w, 10, unit->name, 255 );
819 write_text( gui->font_std, qinfo->contents, 12 + hex_w, 22, unit->prop.name, 255 );
820 /* status */
821 gui->font_status->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
822 if ( cur_player && !player_is_ally( unit->player, cur_player ) )
823 len = sprintf( str, GS_AMMO "? " GS_FUEL "? " GS_ENTR "%i " GS_NOEXP GS_NOEXP GS_NOEXP GS_NOEXP GS_NOEXP " ", unit->entr );
824 else
825 if ( unit_check_fuel_usage( unit ) )
826 len = sprintf( str, GS_AMMO "%i " GS_FUEL "%i " GS_ENTR "%i " GS_NOEXP GS_NOEXP GS_NOEXP GS_NOEXP GS_NOEXP " ", unit->cur_ammo, unit->cur_fuel, unit->entr );
827 else
828 len = sprintf( str, GS_AMMO "%i " GS_FUEL "- " GS_ENTR "%i " GS_NOEXP GS_NOEXP GS_NOEXP GS_NOEXP GS_NOEXP " ", unit->cur_ammo, unit->entr );
829 for ( i = 0; i < unit->exp_level; i++ )
830 str[len - 6 + i] = (char)CharExp;
831 str[len - 6 + i] = (char)(CharExpGrowth + (unit->exp % 100 / 20));
832 write_text( gui->font_status, qinfo->contents, 12 + hex_w, 36, str, 255 );
833 /* show */
834 frame_apply( qinfo );
835 frame_hide( qinfo, 0 );
836 }
837
838 /*
839 ====================================================================
840 Draw the expected losses to the label.
841 ====================================================================
842 */
gui_show_expected_losses(Unit * att,Unit * def,int att_dam,int def_dam)843 void gui_show_expected_losses( Unit *att, Unit *def, int att_dam, int def_dam )
844 {
845 char str[128];
846 SDL_Surface *contents = gui->label->frame->contents;
847 SDL_FillRect( contents, 0, 0x0 );
848 /* attacker flag */
849 DEST( contents, 10, ( contents->h - nation_flag_height ) >> 1, nation_flag_width, nation_flag_height );
850 SOURCE( nation_flags, 0, att->nation->flag_offset );
851 blit_surf();
852 /* defender flag */
853 DEST( contents, contents->w - 10 - nation_flag_width, ( contents->h - nation_flag_height ) >> 1,
854 nation_flag_width, nation_flag_height );
855 SOURCE( nation_flags, 0, def->nation->flag_offset );
856 blit_surf();
857 /* kills */
858 sprintf( str, tr("%i CASUALTIES %i"), att_dam, def_dam );
859 gui->font_error->align = ALIGN_X_CENTER | ALIGN_Y_CENTER;
860 write_text( gui->font_error, contents, contents->w >> 1, contents->h >> 1, str, 255 );
861 /* show */
862 frame_apply( gui->label->frame );
863 label_hide( gui->label, 0 );
864 }
865
866 /*
867 ====================================================================
868 Draw the actual losses to the label.
869 ====================================================================
870 */
gui_show_actual_losses(Unit * att,Unit * def,int att_suppr,int att_dam,int def_suppr,int def_dam)871 void gui_show_actual_losses( Unit *att, Unit *def,
872 int att_suppr, int att_dam, int def_suppr, int def_dam )
873 {
874 char str[128];
875 SDL_Surface *contents = gui->label->frame->contents;
876 SDL_FillRect( contents, 0, 0x0 );
877 /* attacker flag */
878 DEST( contents, 10, ( contents->h - nation_flag_height ) >> 1, nation_flag_width, nation_flag_height );
879 SOURCE( nation_flags, 0, att->nation->flag_offset );
880 blit_surf();
881 /* defender flag */
882 DEST( contents, contents->w - 10 - nation_flag_width, ( contents->h - nation_flag_height ) >> 1,
883 nation_flag_width, nation_flag_height );
884 SOURCE( nation_flags, 0, def->nation->flag_offset );
885 blit_surf();
886 /* kills */
887 sprintf( str, tr("%i CASUALTIES %i"), att_dam, def_dam );
888 gui->font_std->align = ALIGN_X_CENTER | ALIGN_Y_CENTER;
889 write_text( gui->font_std, contents, contents->w >> 1, contents->h >> 1, str, 255 );
890 /* show */
891 frame_apply( gui->label->frame );
892 label_hide( gui->label, 0 );
893
894 /* suppression */
895 if (att_suppr>0||def_suppr>0)
896 {
897 contents = gui->label2->frame->contents; SDL_FillRect( contents, 0, 0x0 );
898 /* attacker flag */
899 DEST( contents, 10, ( contents->h - nation_flag_height ) >> 1, nation_flag_width, nation_flag_height );
900 SOURCE( nation_flags, 0, att->nation->flag_offset );
901 blit_surf();
902 /* defender flag */
903 DEST( contents, contents->w - 10 - nation_flag_width, ( contents->h - nation_flag_height ) >> 1,
904 nation_flag_width, nation_flag_height );
905 SOURCE( nation_flags, 0, def->nation->flag_offset );
906 blit_surf();
907 /* kills */
908 sprintf( str, tr("%i SURPRESSED %i"), att_suppr, def_suppr );
909 gui->font_std->align = ALIGN_X_CENTER | ALIGN_Y_CENTER;
910 write_text( gui->font_std, contents, contents->w >> 1, contents->h >> 1, str, 255 );
911 /* show */
912 frame_apply( gui->label2->frame );
913 label_hide( gui->label2, 0 );
914 }
915 }
916
917 /*
918 ====================================================================
919 Show full info window.
920 ====================================================================
921 */
gui_show_full_info(Unit * unit)922 void gui_show_full_info( Unit *unit )
923 {
924 char str[128];
925 int border = 10, offset = 150;
926 int x, y, i;
927 SDL_Surface *contents = gui->finfo->contents;
928 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
929 /* clear */
930 SDL_FillRect( contents, 0, 0x0 );
931 /* icon */
932 x = border + 20; y = border;
933 DEST( contents,
934 x + ( ( hex_w - unit->prop.icon_w ) >> 1 ), y + ( ( ( hex_h - unit->prop.icon_h ) >> 1 ) ),
935 unit->prop.icon_w, unit->prop.icon_h );
936 SOURCE( unit->prop.icon, 0, 0 );
937 blit_surf();
938 /* nation flag */
939 DEST( contents, x, y, nation_flag_width, nation_flag_height );
940 SOURCE( nation_flags, 0, unit->nation->flag_offset );
941 blit_surf();
942 /* tag (if any) */
943 if (unit->tag[0] != 0) {
944 x = border; y = border + hex_h - gui->font_std->height;
945 snprintf(str,8,"[%s]",unit->tag);
946 write_line( contents, gui->font_std, str, x, &y );
947 }
948 /* name and type */
949 x = border; y = border + hex_h;
950 write_line( contents, gui->font_std, unit->name, x, &y );
951 if (camp_loaded) {
952 if (unit->core)
953 write_line( contents, gui->font_std, tr("Core Unit"), x, &y );
954 else
955 write_line( contents, gui->font_std, tr("Auxiliary Unit"), x, &y );
956 }
957 write_line( contents, gui->font_std, unit->prop.name, x, &y );
958 if (!camp_loaded)
959 y += 10;
960 write_line( contents, gui->font_std, unit_classes[unit->prop.class].name, x, &y );
961 //y += 10;
962 sprintf( str, tr("%s Movement"), mov_types[unit->prop.mov_type].name );
963 write_line( contents, gui->font_std, str, x, &y );
964 sprintf( str, tr("%s Target"), trgt_types[unit->prop.trgt_type].name );
965 write_line( contents, gui->font_std, str, x, &y );
966 /* ammo, fuel, spot, mov, ini, range */
967 x = border + hex_w + 90; y = border;
968 if ( unit->prop.ammo == 0 )
969 sprintf( str, tr("Ammo: N.A.") );
970 else
971 if ( cur_player == 0 || player_is_ally( cur_player, unit->player ) )
972 sprintf( str, tr("Ammo: %02i/%02i"), unit->cur_ammo, unit->prop.ammo );
973 else
974 sprintf( str, tr("Ammo: %02i"), unit->prop.ammo );
975 write_line( contents, gui->font_std, str, x, &y );
976 if ( unit->prop.fuel == 0 )
977 sprintf( str, tr("Fuel: N.A.") );
978 else
979 if ( cur_player == 0 || player_is_ally( cur_player, unit->player ) )
980 sprintf( str, tr("Fuel: %2i/%2i"), unit->cur_fuel, unit->prop.fuel );
981 else
982 sprintf( str, tr("Fuel: %2i"), unit->prop.fuel );
983 write_line( contents, gui->font_std, str, x, &y );
984 y += 10;
985 sprintf( str, tr("Spotting: %2i"), unit->prop.spt );
986 write_line( contents, gui->font_std, str, x, &y );
987 sprintf( str, tr("Movement: %2i"), unit->prop.mov );
988 write_line( contents, gui->font_std, str, x, &y );
989 sprintf( str, tr("Initiative: %2i"), unit->prop.ini );
990 write_line( contents, gui->font_std, str, x, &y );
991 sprintf( str, tr("Range: %2i"), unit->prop.rng );
992 write_line( contents, gui->font_std, str, x, &y );
993 y += 10;
994 sprintf( str, tr("Experience: %3i"), unit->exp );
995 write_line( contents, gui->font_std, str, x, &y );
996 sprintf( str, tr("Entrenchment: %i"), unit->entr );
997 write_line( contents, gui->font_std, str, x, &y );
998 /* attack/defense */
999 x = border + hex_w + 90 + 140; y = border;
1000 for ( i = 0; i < trgt_type_count; i++ ) {
1001 if ( unit->prop.atks[i] < 0 )
1002 sprintf( str, tr("%6s Attack:[%2i]"), trgt_types[i].name, -unit->prop.atks[i] );
1003 else
1004 sprintf( str, tr("%6s Attack: %2i"), trgt_types[i].name, unit->prop.atks[i] );
1005 write_line( contents, gui->font_std, str, x, &y );
1006 }
1007 y += 10;
1008 sprintf( str, tr("Ground Defense: %2i"), unit->prop.def_grnd );
1009 write_line( contents, gui->font_std, str, x, &y );
1010 sprintf( str, tr("Air Defense: %2i"), unit->prop.def_air );
1011 write_line( contents, gui->font_std, str, x, &y );
1012 sprintf( str, tr("Close Defense: %2i"), unit->prop.def_cls );
1013 write_line( contents, gui->font_std, str, x, &y );
1014 y += 10;
1015 sprintf( str, tr("Suppression: %2i"), unit->turn_suppr );
1016 write_line( contents, gui->font_std, str, x, &y );
1017 /* transporter */
1018 if ( unit->trsp_prop.id != 0 ) {
1019 /* icon */
1020 x = border + 20; y = border + offset;
1021 DEST( contents,
1022 x + ( ( hex_w - unit->trsp_prop.icon_w ) >> 1 ), y + ( ( ( hex_h - unit->trsp_prop.icon_h ) >> 1 ) ),
1023 unit->trsp_prop.icon_w, unit->trsp_prop.icon_h );
1024 SOURCE( unit->trsp_prop.icon, 0, 0 );
1025 blit_surf();
1026 /* name & type */
1027 x = border; y = border + hex_h + offset;
1028 write_line( contents, gui->font_std, unit->trsp_prop.name, x, &y );
1029 write_line( contents, gui->font_std, unit_classes[unit->trsp_prop.class].name, x, &y );
1030 y += 6;
1031 sprintf( str, tr("%s Movement"), mov_types[unit->trsp_prop.mov_type].name );
1032 write_line( contents, gui->font_std, str, x, &y );
1033 sprintf( str, tr("%s Target"), trgt_types[unit->trsp_prop.trgt_type].name );
1034 write_line( contents, gui->font_std, str, x, &y );
1035 /* spt, mov, ini, rng */
1036 x = border + hex_w + 90; y = border + offset;
1037 sprintf( str, tr("Spotting: %2i"), unit->trsp_prop.spt );
1038 write_line( contents, gui->font_std, str, x, &y );
1039 sprintf( str, tr("Movement: %2i"), unit->trsp_prop.mov );
1040 write_line( contents, gui->font_std, str, x, &y );
1041 sprintf( str, tr("Initiative: %2i"), unit->trsp_prop.ini );
1042 write_line( contents, gui->font_std, str, x, &y );
1043 sprintf( str, tr("Range: %2i"), unit->trsp_prop.rng );
1044 write_line( contents, gui->font_std, str, x, &y );
1045 /* attack & defense */
1046 x = border + hex_w + 90 + 140; y = border + offset;
1047 for ( i = 0; i < trgt_type_count; i++ ) {
1048 sprintf( str, tr("%6s Attack: %2i"), trgt_types[i].name, unit->trsp_prop.atks[i] );
1049 write_line( contents, gui->font_std, str, x, &y );
1050 }
1051 y += 10;
1052 sprintf( str, tr("Ground Defense: %2i"), unit->trsp_prop.def_grnd );
1053 write_line( contents, gui->font_std, str, x, &y );
1054 sprintf( str, tr("Air Defense: %2i"), unit->trsp_prop.def_air );
1055 write_line( contents, gui->font_std, str, x, &y );
1056 sprintf( str, tr("Close Defense: %2i"), unit->trsp_prop.def_cls );
1057 write_line( contents, gui->font_std, str, x, &y );
1058 }
1059 /* show */
1060 frame_apply( gui->finfo );
1061 frame_hide( gui->finfo, 0 );
1062 }
1063
1064 /*
1065 ====================================================================
1066 Show scenario info window.
1067 ====================================================================
1068 */
gui_show_scen_info()1069 void gui_show_scen_info()
1070 {
1071 Text *text;
1072 char str[128];
1073 int border = 10, i;
1074 int x = border, y = border;
1075 SDL_Surface *contents = gui->sinfo->contents;
1076 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1077 SDL_FillRect( contents, 0, 0x0 );
1078 /* title */
1079 write_line( contents, gui->font_std, scen_info->name, x, &y ); y += 10;
1080 /* desc */
1081 text = create_text( gui->font_std, scen_info->desc, contents->w - border*2 );
1082 for ( i = 0; i < text->count; i++ )
1083 write_line( contents, gui->font_std, text->lines[i], x, &y );
1084 delete_text( text );
1085 /* turn and date */
1086 y += 10;
1087 scen_get_date( str );
1088 write_line( contents, gui->font_std, str, x, &y );
1089 if ( turn + 1 < scen_info->turn_limit )
1090 sprintf( str, tr("Turns Left: %i"), scen_info->turn_limit - turn );
1091 else
1092 sprintf( str, tr("Turns Left: Last Turn") );
1093 write_line( contents, gui->font_std, str, x, &y );
1094 /* scenario result at the end */
1095 if ( turn + 1 > scen_info->turn_limit ) {
1096 y += 10;
1097 write_line( contents, gui->font_std, tr("Result: "), x, &y );
1098 text = create_text( gui->font_std, scen_message, contents->w - border*2 );
1099 for ( i = 0; i < text->count; i++ )
1100 write_line( contents, gui->font_std, text->lines[i], x, &y );
1101 delete_text( text );
1102 }
1103 /* players */
1104 if ( cur_player ) {
1105 y += 10;
1106 sprintf( str, tr("Current Player: %s"), cur_player->name );
1107 write_line( contents, gui->font_std, str, x, &y );
1108 if ( players_test_next() ) {
1109 sprintf( str, tr("Next Player: %s"), players_test_next()->name );
1110 write_line( contents, gui->font_std, str, x, &y );
1111 }
1112 }
1113 /* weather */
1114 y += 10;
1115 sprintf( str, tr("Weather: %s"),
1116 (( turn < scen_info->turn_limit ) ?
1117 weather_types[scen_get_weather()].name : tr("n/a")));
1118 write_line( contents, gui->font_std, str, x, &y );
1119 sprintf( str, tr("Forecast: %s"),
1120 ((turn+1 < scen_info->turn_limit ) ?
1121 weather_types[scen_get_forecast()].name : tr("n/a")) );
1122 write_line( contents, gui->font_std, str, x, &y );
1123 /* show */
1124 frame_apply( gui->sinfo );
1125 frame_hide( gui->sinfo, 0 );
1126 }
1127
1128 /*
1129 ====================================================================
1130 Show explicit victory conditions and use scenario info window for
1131 this.
1132 ====================================================================
1133 */
gui_render_subcond(VSubCond * cond,char * str)1134 void gui_render_subcond( VSubCond *cond, char *str )
1135 {
1136 switch( cond->type ) {
1137 case VSUBCOND_TURNS_LEFT:
1138 sprintf( str, tr("%i turns remaining"), cond->count );
1139 break;
1140 case VSUBCOND_CTRL_ALL_HEXES:
1141 sprintf( str, tr("control all victory hexes") );
1142 break;
1143 case VSUBCOND_CTRL_HEX:
1144 sprintf( str, tr("control hex %i,%i"), cond->x, cond->y );
1145 break;
1146 case VSUBCOND_CTRL_HEX_NUM:
1147 sprintf( str, tr("control at least %i vic hexes"), cond->count );
1148 break;
1149 case VSUBCOND_UNITS_KILLED:
1150 sprintf( str, tr("kill units with tag '%s'"), cond->tag );
1151 break;
1152 case VSUBCOND_UNITS_SAVED:
1153 sprintf( str, tr("save units with tag '%s'"), cond->tag );
1154 break;
1155 case VSUBCOND_UNITS_ESCAPED:
1156 sprintf( str, tr("units with tag '%s' escape"), cond->tag );
1157 break;
1158 }
1159 }
gui_show_conds()1160 void gui_show_conds()
1161 {
1162 char str[128];
1163 int border = 10, i, j;
1164 int x = border, y = border;
1165 SDL_Surface *contents = gui->sinfo->contents;
1166 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1167 SDL_FillRect( contents, 0, 0x0 );
1168 /* title */
1169 sprintf( str, tr("Explicit VicConds (%s)"),
1170 (vcond_check_type==VCOND_CHECK_EVERY_TURN)?tr("every turn"):tr("last turn") );
1171 write_line( contents, gui->font_std, str, x, &y ); y += 10;
1172 for ( i = 1; i < vcond_count; i++ ) {
1173 sprintf( str, "'%s':", vconds[i].message );
1174 write_line( contents, gui->font_std, str, x, &y );
1175 for ( j = 0; j < vconds[i].sub_and_count; j++ ) {
1176 if ( vconds[i].subconds_and[j].player )
1177 sprintf( str, tr("AND %.2s "), vconds[i].subconds_and[j].player->name );
1178 else
1179 sprintf( str, tr("AND -- ") );
1180 gui_render_subcond( &vconds[i].subconds_and[j], str + 7 );
1181 write_line( contents, gui->font_std, str, x, &y );
1182 }
1183 for ( j = 0; j < vconds[i].sub_or_count; j++ ) {
1184 if ( vconds[i].subconds_or[j].player )
1185 sprintf( str, tr("OR %.2s "), vconds[i].subconds_or[j].player->name );
1186 else
1187 sprintf( str, tr("OR -- ") );
1188 gui_render_subcond( &vconds[i].subconds_or[j], str + 6 );
1189 write_line( contents, gui->font_std, str, x, &y );
1190 }
1191 }
1192 y += 6;
1193 /* else condition */
1194 sprintf( str, tr("else: '%s'"), vconds[0].message );
1195 write_line( contents, gui->font_std, str, x, &y );
1196 /* show */
1197 frame_apply( gui->sinfo );
1198 frame_hide( gui->sinfo, 0 );
1199 }
1200 /*
1201 ====================================================================
1202 Show confirmation window.
1203 ====================================================================
1204 */
gui_show_confirm(const char * _text)1205 void gui_show_confirm( const char *_text )
1206 {
1207 Text *text;
1208 int border = 10, i;
1209 int x = border, y = border;
1210 SDL_Surface *contents = gui->confirm->frame->contents;
1211 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1212 SDL_FillRect( contents, 0, 0x0 );
1213 text = create_text( gui->font_std, _text, contents->w - border*2 );
1214 for ( i = 0; i < text->count; i++ )
1215 write_line( contents, gui->font_std, text->lines[i], x, &y );
1216 delete_text( text );
1217 /* show */
1218 frame_apply( gui->confirm->frame );
1219 group_hide( gui->confirm, 0 );
1220 }
1221
1222 /*
1223 ====================================================================
1224 Show unit buttons at screen x,y (does not include the button check)
1225 ====================================================================
1226 */
gui_show_unit_buttons(int x,int y)1227 void gui_show_unit_buttons( int x, int y )
1228 {
1229 if ( y + gui->unit_buttons->frame->img->img->h >= sdl.screen->h )
1230 y = sdl.screen->h - gui->unit_buttons->frame->img->img->h;
1231 group_move( gui->unit_buttons, x, y );
1232 group_hide( gui->unit_buttons, 0 );
1233 }
1234
1235 /** Show unit purchase dialogue after preparing it for current player. */
gui_show_purchase_window()1236 void gui_show_purchase_window()
1237 {
1238 purchase_dlg_reset(gui->purchase_dlg);
1239 purchase_dlg_hide(gui->purchase_dlg,0);
1240 }
1241
1242 /*
1243 ====================================================================
1244 Show deploy window and select first unit as 'deploy_unit'.
1245 ====================================================================
1246 */
gui_show_deploy_window()1247 void gui_show_deploy_window()
1248 {
1249 Unit *unit;
1250 SDL_Surface *contents = gui->deploy_window->frame->contents;
1251 SDL_FillRect( contents, 0, 0x0 );
1252 deploy_offset = 0;
1253 deploy_unit = list_get( avail_units, 0 );
1254 list_reset( avail_units );
1255 list_clear( left_deploy_units );
1256 while ( ( unit = list_next( avail_units ) ) ) {
1257 unit->x = -1;
1258 list_add( left_deploy_units, unit );
1259 }
1260 /* add units */
1261 gui_add_deploy_units( contents );
1262 /* activate buttons */
1263 group_set_active( gui->deploy_window, ID_APPLY_DEPLOY, 1 );
1264 group_set_active( gui->deploy_window, ID_CANCEL_DEPLOY, !deploy_turn );
1265 /* show */
1266 frame_apply( gui->deploy_window->frame );
1267 group_hide( gui->deploy_window, 0 );
1268 }
1269
1270 /*
1271 ====================================================================
1272 Handle deploy window.
1273 gui_handle_deploy_motion: 'unit' is the unit the cursor is
1274 currently above
1275 gui_handle_deploy_click: 'new_unit' is set True if a new unit was
1276 selected (which is 'deploy_unit' ) else False
1277 return True if something happended
1278 ====================================================================
1279 */
gui_handle_deploy_click(int button,int cx,int cy)1280 int gui_handle_deploy_click(int button, int cx, int cy)
1281 {
1282 int i;
1283 if ( button == WHEEL_UP ) {
1284 gui_scroll_deploy_up();
1285 }
1286 else
1287 if ( button == WHEEL_DOWN ) {
1288 gui_scroll_deploy_down();
1289 }
1290 else
1291 for ( i = 0; i < deploy_show_count; i++ )
1292 if ( FOCUS( cx, cy,
1293 gui->deploy_window->frame->img->bkgnd->surf_rect.x + deploy_border,
1294 gui->deploy_window->frame->img->bkgnd->surf_rect.y + deploy_border + i * hex_h,
1295 hex_w, hex_h ) ) {
1296 if ( i + deploy_offset < left_deploy_units->count ) {
1297 deploy_unit = list_get( left_deploy_units, i + deploy_offset );
1298 gui_add_deploy_units( gui->deploy_window->frame->contents );
1299 frame_apply( gui->deploy_window->frame );
1300 return 1;
1301 }
1302 }
1303 return 0;
1304 }
gui_handle_deploy_motion(int cx,int cy,Unit ** unit)1305 void gui_handle_deploy_motion( int cx, int cy, Unit **unit )
1306 {
1307 int i;
1308 *unit = 0;
1309 group_handle_motion( gui->deploy_window, cx, cy );
1310 for ( i = 0; i < deploy_show_count; i++ )
1311 if ( FOCUS( cx, cy,
1312 gui->deploy_window->frame->img->bkgnd->surf_rect.x + deploy_border,
1313 gui->deploy_window->frame->img->bkgnd->surf_rect.y + deploy_border + i * hex_h,
1314 hex_w, hex_h ) ) {
1315 *unit = list_get( left_deploy_units, i + deploy_offset );
1316 }
1317 }
1318
1319 /*
1320 ====================================================================
1321 Scroll deploy list up/down.
1322 ====================================================================
1323 */
gui_scroll_deploy_up()1324 void gui_scroll_deploy_up()
1325 {
1326 deploy_offset -= 2;
1327 if ( deploy_offset < 0 ) deploy_offset = 0;
1328 gui_add_deploy_units( gui->deploy_window->frame->contents );
1329 frame_apply( gui->deploy_window->frame );
1330 }
gui_scroll_deploy_down()1331 void gui_scroll_deploy_down()
1332 {
1333 if ( deploy_show_count >= left_deploy_units->count )
1334 deploy_offset = 0;
1335 else {
1336 deploy_offset += 2;
1337 if ( deploy_offset + deploy_show_count >= left_deploy_units->count )
1338 deploy_offset = left_deploy_units->count - deploy_show_count;
1339 }
1340 gui_add_deploy_units( gui->deploy_window->frame->contents );
1341 frame_apply( gui->deploy_window->frame );
1342 }
1343
1344 /*
1345 ====================================================================
1346 Update deploy list. Unit is either removed or added to
1347 left_deploy_units and the deploy window is updated.
1348 ====================================================================
1349 */
gui_remove_deploy_unit(Unit * unit)1350 void gui_remove_deploy_unit( Unit *unit )
1351 {
1352 List_Entry *entry;
1353 Unit *next_unit;
1354 entry = list_entry( left_deploy_units, unit );
1355 if ( entry->next->item )
1356 next_unit = entry->next->item;
1357 else
1358 if ( entry->prev->item )
1359 next_unit = entry->prev->item;
1360 else
1361 next_unit = 0;
1362 list_delete_item( left_deploy_units, unit );
1363 deploy_unit = next_unit;
1364 gui_add_deploy_units( gui->deploy_window->frame->contents );
1365 frame_apply( gui->deploy_window->frame );
1366 }
gui_add_deploy_unit(Unit * unit)1367 void gui_add_deploy_unit( Unit *unit )
1368 {
1369 if ( unit->sel_prop->flags & FLYING )
1370 list_insert( left_deploy_units, unit, 0 );
1371 else
1372 list_add( left_deploy_units, unit );
1373 if ( deploy_unit == 0 ) deploy_unit = unit;
1374 gui_add_deploy_units( gui->deploy_window->frame->contents );
1375 frame_apply( gui->deploy_window->frame );
1376 }
1377
1378 /*
1379 ====================================================================
1380 Show base menu at screen x,y (does not include the button check)
1381 ====================================================================
1382 */
gui_show_menu(int x,int y)1383 void gui_show_menu( int x, int y )
1384 {
1385 if ( y + gui->base_menu->frame->img->img->h >= sdl.screen->h )
1386 y = sdl.screen->h - gui->base_menu->frame->img->img->h;
1387 group_move( gui->base_menu, x, y );
1388 group_hide( gui->base_menu, 0 );
1389 }
1390
1391 /*
1392 ====================================================================
1393 Update save slot names.
1394 ====================================================================
1395 */
gui_update_slot_tooltips()1396 void gui_update_slot_tooltips()
1397 {
1398 int i;
1399 char str[128];
1400 for ( i = 0; i < SLOT_COUNT; i++ ) {
1401 sprintf( str, tr("Load: %s"), slot_get_name( i ) );
1402 strcpy_lt( group_get_button( gui->load_menu, ID_LOAD_0 + i )->tooltip, str, 31 );
1403 }
1404 for ( i = 0; i < 10; i++ ) {
1405 sprintf( str, tr("Save: %s"), slot_get_name( i ) );
1406 strcpy_lt( group_get_button( gui->save_menu, ID_SAVE_0 + i )->tooltip, str, 31 );
1407 }
1408 }
1409
1410 /*
1411 ====================================================================
1412 Render the file name to surface. (directories start with an
1413 asteriks)
1414 ====================================================================
1415 */
gui_render_file_name(void * item,SDL_Surface * buffer)1416 void gui_render_file_name( void *item, SDL_Surface *buffer )
1417 {
1418 const char *fname = (const char*)item;
1419 SDL_FillRect( buffer, 0, 0x0 );
1420 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_CENTER;
1421 if ( fname[0] != '*' )
1422 write_text( gui->font_std, buffer, 4, buffer->h >> 1, fname, 255 );
1423 else {
1424 DEST( buffer, 2, ( buffer->h - gui->folder_icon->h ) >> 1, gui->folder_icon->w, gui->folder_icon->h );
1425 SOURCE( gui->folder_icon, 0, 0 );
1426 blit_surf();
1427 write_text( gui->font_std, buffer, 4 + gui->folder_icon->w, buffer->h >> 1, fname + 1, 255 );
1428 }
1429 }
1430
1431 /*
1432 ====================================================================
1433 Handle the selection of a scenario file (render info and
1434 load scen_info from path)
1435 ====================================================================
1436 */
gui_render_scen_info(const char * path,SDL_Surface * buffer)1437 void gui_render_scen_info( const char *path, SDL_Surface *buffer )
1438 {
1439 Text *text;
1440 int i, x = 0, y = 0;
1441 char *info;
1442 if ( path == 0 ) {
1443 /* no selection met */
1444 group_set_active( gui->scen_dlg->group, ID_SCEN_SETUP, 0 );
1445 group_set_active( gui->scen_dlg->group, ID_SCEN_OK, 0 );
1446 SDL_FillRect( buffer, 0, 0x0 );
1447 }
1448 else
1449 if ( ( info = scen_load_info( path ) ) ) {
1450 group_set_active( gui->scen_dlg->group, ID_SCEN_SETUP, 1 );
1451 group_set_active( gui->scen_dlg->group, ID_SCEN_OK, 1 );
1452 /* render info */
1453 SDL_FillRect( buffer, 0, 0x0 );
1454 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1455 text = create_text( gui->font_std, info, buffer->w );
1456 for ( i = 0; i < text->count; i++ )
1457 write_line( buffer, gui->font_std, text->lines[i], x, &y );
1458 delete_text( text );
1459 free( info );
1460 }
1461 }
1462
1463 /*
1464 ====================================================================
1465 Handle the selection of a campaign file (display info and
1466 load scen_info from full path)
1467 ====================================================================
1468 */
gui_render_camp_info(const char * path,SDL_Surface * buffer)1469 void gui_render_camp_info( const char *path, SDL_Surface *buffer )
1470 {
1471 Text *text;
1472 int i, x = 0, y = 0;
1473 char *info;
1474 if ( path == 0 ) {
1475 /* no selection met */
1476 group_set_active( gui->camp_dlg->group, ID_CAMP_OK, 0 );
1477 }
1478 else
1479 if ( ( info = camp_load_info( path ) ) ) {
1480 group_set_active( gui->camp_dlg->group, ID_CAMP_OK, 1 );
1481 /* render info */
1482 SDL_FillRect( buffer, 0, 0x0 );
1483 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1484 text = create_text( gui->font_std, info, buffer->w );
1485 for ( i = 0; i < text->count; i++ )
1486 write_line( buffer, gui->font_std, text->lines[i], x, &y );
1487 delete_text( text );
1488 free( info );
1489 }
1490 }
1491
1492 /** message pane option for selection */
1493 typedef struct {
1494 /** hit test rectangle for this option (abs. screen coordinates) */
1495 int x1, y1, x2, y2;
1496 /** id to be returned when selected */
1497 char *id;
1498 /** textual description */
1499 char *desc;
1500 } MessagePane_Option;
1501
1502 /**
1503 * Represents data for the message pane.
1504 */
1505 typedef struct MessagePane {
1506 /** general text that will be displayed at the beginning */
1507 char *text;
1508 /** default id */
1509 char *default_id;
1510 /** contains id that was selected or default id if no options exist */
1511 char *selected_id;
1512 /** count of options */
1513 unsigned options_count;
1514 /** array of options */
1515 MessagePane_Option *options;
1516 /** currently focused option */
1517 int focus_idx;
1518 /** focused option on last mouse button press */
1519 int pressed_focus_idx;
1520 /** true if button has been pressed within this pane */
1521 int button_pressed;
1522 /** repaint rectangle */
1523 int refresh_x1, refresh_y1, refresh_x2, refresh_y2;
1524 } MessagePane;
1525
1526 /*
1527 ====================================================================
1528 Creates a new message pane structure.
1529 ====================================================================
1530 */
gui_create_message_pane()1531 MessagePane *gui_create_message_pane()
1532 {
1533 MessagePane *pane = calloc(1, sizeof(MessagePane));
1534 pane->focus_idx = -1;
1535 pane->refresh_x2 = sdl.screen->w;
1536 pane->refresh_y2 = sdl.screen->h;
1537 return pane;
1538 }
1539
1540 /*
1541 ====================================================================
1542 Deletes the given message pane structure.
1543 ====================================================================
1544 */
gui_delete_message_pane(MessagePane * pane)1545 void gui_delete_message_pane(MessagePane *pane)
1546 {
1547 if (pane) {
1548 unsigned i;
1549 for (i = pane->options_count; i; ) {
1550 i--;
1551 free(pane->options[i].id);
1552 free(pane->options[i].desc);
1553 }
1554 free(pane->text);
1555 free(pane->default_id);
1556 }
1557 free(pane);
1558 }
1559
1560 /*
1561 ====================================================================
1562 Sets the text for the message pane.
1563 ====================================================================
1564 */
gui_set_message_pane_text(struct MessagePane * pane,const char * text)1565 void gui_set_message_pane_text( struct MessagePane *pane, const char *text )
1566 {
1567 pane->text = strdup(text);
1568 }
1569
1570 /*
1571 ====================================================================
1572 Sets the default id for the message pane.
1573 ====================================================================
1574 */
gui_set_message_pane_default(struct MessagePane * pane,const char * default_id)1575 void gui_set_message_pane_default( struct MessagePane *pane, const char *default_id )
1576 {
1577 pane->default_id = strdup(default_id);
1578 }
1579
1580 /*
1581 ====================================================================
1582 Returns the currently selected id or 0 if nothing is selected.
1583 ====================================================================
1584 */
gui_get_message_pane_selection(struct MessagePane * pane)1585 const char *gui_get_message_pane_selection( struct MessagePane *pane )
1586 {
1587 return pane->selected_id;
1588 }
1589
1590 /*
1591 ====================================================================
1592 Fills in options for the given message pane.
1593 ids const char * list of ids
1594 descs const char * list of textual description being mapped to ids.
1595 ====================================================================
1596 */
gui_set_message_pane_options(MessagePane * pane,List * ids,List * descs)1597 void gui_set_message_pane_options( MessagePane *pane, List *ids, List *descs ) {
1598 unsigned i;
1599 pane->options_count = (unsigned)ids->count;
1600 pane->options = calloc(pane->options_count, sizeof(MessagePane_Option));
1601 list_reset(ids);
1602 list_reset(descs);
1603 for (i = 0; i < pane->options_count; i++) {
1604 MessagePane_Option *opt = &pane->options[i];
1605 opt->id = strdup(list_next(ids));
1606 opt->desc = strdup(list_next(descs));
1607 }
1608 }
1609
1610 /*
1611 ====================================================================
1612 Draws and fills with text the message pane.
1613 ====================================================================
1614 */
gui_draw_message_pane(MessagePane * pane)1615 void gui_draw_message_pane( MessagePane *pane )
1616 {
1617 static const char checkbox_indent_str[] = GS_CHECK_BOX_EMPTY " ";
1618 int i, j, y, x, checkbox_indent;
1619 Text *text;
1620 if (!(pane->refresh_x2 - pane->refresh_x1 > 0 && pane->refresh_y2 - pane->refresh_y1 > 0)) return;
1621 text = create_text( gui->font_brief, pane->text, gui->brief_frame->w - 40 );
1622 DEST( sdl.screen,
1623 ( sdl.screen->w - gui->brief_frame->w ) / 2,
1624 ( sdl.screen->h - gui->brief_frame->h ) / 2,
1625 gui->brief_frame->w, gui->brief_frame->h );
1626 SOURCE( gui->brief_frame, 0, 0 );
1627 blit_surf();
1628 gui->font_brief->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1629 x = ( sdl.screen->w - gui->brief_frame->w ) / 2 + 20;
1630 y = ( sdl.screen->h - gui->brief_frame->h ) / 2 + 40;
1631 for ( i = 0; i < text->count; i++ )
1632 write_line( sdl.screen, gui->font_brief, text->lines[i], x, &y );
1633 delete_text( text );
1634 checkbox_indent = text_width(gui->font_brief, checkbox_indent_str);
1635 /* draw options and redetermine hit-rectangles */
1636 for (j = 0; j < pane->options_count; j++) {
1637 MessagePane_Option *opt = pane->options + j;
1638 int old_y = y;
1639 const int indent_x = x + checkbox_indent;
1640 char buf[5];
1641 snprintf(buf, sizeof buf, "%c", CharCheckBoxEmpty + (j == pane->focus_idx));
1642 write_line(sdl.screen, gui->font_brief, buf, x, &y );
1643 y = old_y;
1644 text = create_text(gui->font_brief, opt->desc, gui->brief_frame->w - 40 - checkbox_indent);
1645 for (i = 0; i < text->count; i++)
1646 write_line( sdl.screen, gui->font_brief, text->lines[i], indent_x, &y );
1647 delete_text( text );
1648 opt->x1 = x; opt->y1 = old_y;
1649 opt->x2 = x + gui->brief_frame->w - 40;
1650 opt->y2 = y;
1651 }
1652 refresh_screen( pane->refresh_x1, pane->refresh_y1,
1653 pane->refresh_x2 - pane->refresh_x1, pane->refresh_y2 - pane->refresh_y1 );
1654 pane->refresh_x1 = pane->refresh_x2 = pane->refresh_y1 = pane->refresh_y2 = 0;
1655 }
1656
1657 /*
1658 ====================================================================
1659 Returns the index of the focused option under (mx, my) or -1
1660 ====================================================================
1661 */
gui_map_message_pane_focus_index(MessagePane * pane,int mx,int my)1662 static int gui_map_message_pane_focus_index( MessagePane *pane, int mx, int my )
1663 {
1664 int i;
1665 for (i = 0; i < pane->options_count; i++) {
1666 MessagePane_Option *opt = pane->options + i;
1667 if (mx >= opt->x1 && mx < opt->x2 && my >= opt->y1 && my < opt->y2)
1668 return i;
1669 }
1670 return -1;
1671 }
1672
1673 /** unite with existing repaint rectangle */
message_pane_unite_repaint_rect(MessagePane * pane,int x1,int y1,int x2,int y2)1674 inline static void message_pane_unite_repaint_rect(MessagePane *pane, int x1, int y1, int x2, int y2)
1675 {
1676 if ((pane->refresh_x2 - pane->refresh_x1) <= 0
1677 || (pane->refresh_y2 - pane->refresh_y1) <= 0) {
1678 pane->refresh_x1 = x1; pane->refresh_y1 = y1;
1679 pane->refresh_x2 = x2; pane->refresh_y2 = y2;
1680 } else {
1681 pane->refresh_x1 = MINIMUM(x1, pane->refresh_x1);
1682 pane->refresh_y1 = MINIMUM(y1, pane->refresh_y1);
1683 pane->refresh_x2 = MAXIMUM(x2, pane->refresh_x2);
1684 pane->refresh_y2 = MAXIMUM(y2, pane->refresh_y2);
1685 }
1686
1687 }
1688
1689 /*
1690 ====================================================================
1691 Handles an event on the message pane.
1692 ====================================================================
1693 */
gui_handle_message_pane_event(MessagePane * pane,int mx,int my,int button,int pressed)1694 void gui_handle_message_pane_event( MessagePane *pane, int mx, int my, int button, int pressed )
1695 {
1696 int new_focus_idx = gui_map_message_pane_focus_index( pane, mx, my );
1697 pane->selected_id = 0;
1698
1699 /* determine new repaint rectangle if focus changed */
1700 if (new_focus_idx != pane->focus_idx) {
1701 if (pane->focus_idx >= 0 && pane->focus_idx < pane->options_count)
1702 message_pane_unite_repaint_rect(pane,
1703 pane->options[pane->focus_idx].x1,
1704 pane->options[pane->focus_idx].y1,
1705 pane->options[pane->focus_idx].x2,
1706 pane->options[pane->focus_idx].y2);
1707 if (new_focus_idx >= 0 && new_focus_idx < pane->options_count)
1708 message_pane_unite_repaint_rect(pane,
1709 pane->options[new_focus_idx].x1,
1710 pane->options[new_focus_idx].y1,
1711 pane->options[new_focus_idx].x2,
1712 pane->options[new_focus_idx].y2);
1713 }
1714
1715 switch (button) {
1716 case BUTTON_NONE:
1717 break;
1718 case BUTTON_LEFT:
1719 if (pressed) {
1720 pane->pressed_focus_idx = new_focus_idx;
1721 pane->button_pressed = 1;
1722 }
1723 else if (!pressed && pane->button_pressed) {
1724 if (new_focus_idx == pane->pressed_focus_idx
1725 && pane->pressed_focus_idx >= 0 && pane->pressed_focus_idx < pane->options_count) {
1726 pane->selected_id = pane->options[pane->pressed_focus_idx].id;
1727 } else if ((new_focus_idx < 0 || new_focus_idx >= pane->options_count)
1728 && pane->options_count == 0) {
1729 pane->selected_id = pane->default_id;
1730 }
1731 pane->pressed_focus_idx = -1;
1732 pane->button_pressed = 0;
1733 }
1734 break;
1735 default:
1736 break;
1737 }
1738
1739 pane->focus_idx = new_focus_idx;
1740 }
1741
1742 /*
1743 ====================================================================
1744 Open scenario setup and set first player as selected.
1745 ====================================================================
1746 */
gui_open_scen_setup()1747 void gui_open_scen_setup()
1748 {
1749 int i;
1750 List *list;
1751 /* adjust the config settings, might have changed
1752 due to loading */
1753 group_lock_button( gui->setup->confirm, ID_SETUP_FOG, config.fog_of_war );
1754 group_lock_button( gui->setup->confirm, ID_SETUP_SUPPLY, config.supply );
1755 group_lock_button( gui->setup->confirm, ID_SETUP_WEATHER, config.weather );
1756 group_lock_button( gui->setup->confirm, ID_SETUP_DEPLOYTURN, config.deploy_turn );
1757 group_lock_button( gui->setup->confirm, ID_SETUP_PURCHASE, config.purchase);
1758 /* do the list and chose first entry */
1759 list = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );
1760 for ( i = 0; i < setup.player_count; i++ )
1761 list_add( list, strdup( setup.names[i] ) );
1762 lbox_set_items( gui->setup->list, list );
1763 gui->setup->list->cur_item = list_first( list );
1764 lbox_apply( gui->setup->list );
1765 if ( gui->setup->list->cur_item )
1766 gui_handle_player_select( gui->setup->list->cur_item );
1767 sdlg_hide( gui->setup, 0 );
1768 }
1769
1770 /*
1771 ====================================================================
1772 Render the player name in the scenario setup
1773 ====================================================================
1774 */
gui_render_player_name(void * item,SDL_Surface * buffer)1775 void gui_render_player_name( void *item, SDL_Surface *buffer )
1776 {
1777 SDL_FillRect( buffer, 0, 0x0 );
1778 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_CENTER;
1779 write_text( gui->font_std, buffer, 4, buffer->h >> 1, (char*)item, 255 );
1780 }
1781
1782 /*
1783 ====================================================================
1784 Handle the selection of a player in setup.
1785 ====================================================================
1786 */
gui_handle_player_select(void * item)1787 void gui_handle_player_select( void *item )
1788 {
1789 int i;
1790 const char *name;
1791 char str[64];
1792 SDL_Surface *contents;
1793 /* update selection */
1794 name = (const char*)item;
1795 for ( i = 0; i < setup.player_count; i++ )
1796 if ( STRCMP( name, setup.names[i] ) ) {
1797 gui->setup->sel_id = i;
1798 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_CENTER;
1799 contents = gui->setup->ctrl->frame->contents;
1800 SDL_FillRect( contents, 0, 0x0 );
1801 if ( setup.ctrl[i] == PLAYER_CTRL_HUMAN )
1802 sprintf( str, tr("Control: Human") );
1803 else
1804 sprintf( str, tr("Control: CPU") );
1805 write_text( gui->font_std, contents, 10, contents->h >> 1, str, 255 );
1806 frame_apply( gui->setup->ctrl->frame );
1807 contents = gui->setup->module->frame->contents;
1808 SDL_FillRect( contents, 0, 0x0 );
1809 sprintf( str, tr("AI Module: %s"), setup.modules[i] );
1810 write_text( gui->font_std, contents, 10, contents->h >> 1, str, 255 );
1811 frame_apply( gui->setup->module->frame );
1812 break;
1813 }
1814 }
1815
1816
1817 /*
1818 ====================================================================
1819 Load a module's info
1820 ====================================================================
1821 */
gui_render_module_info(const char * path,SDL_Surface * buffer)1822 void gui_render_module_info( const char *path, SDL_Surface *buffer )
1823 {
1824 if ( path )
1825 group_set_active( gui->module_dlg->group, ID_MODULE_OK, 1 );
1826 else
1827 group_set_active( gui->module_dlg->group, ID_MODULE_OK, 0 );
1828 }
1829
1830 /*
1831 ====================================================================
1832 Mirror position of asymmetric windows.
1833 ====================================================================
1834 */
mirror_hori(int plane_x,int x,int w)1835 static int mirror_hori( int plane_x, int x, int w )
1836 {
1837 if (x>=plane_x)
1838 return plane_x-(x-plane_x)-w;
1839 else
1840 return plane_x+(plane_x-(x+w));
1841 }
gui_mirror_asymm_windows()1842 void gui_mirror_asymm_windows()
1843 {
1844 int plane_x=sdl.screen->w/2;
1845 int x,y,w,h;
1846 gui->mirror_asymm = !gui->mirror_asymm;
1847 /* quick info's */
1848 frame_get_geometry(gui->qinfo1,&x,&y,&w,&h);
1849 frame_move(gui->qinfo1,mirror_hori(plane_x,x,w),y);
1850 frame_get_geometry(gui->qinfo2,&x,&y,&w,&h);
1851 frame_move(gui->qinfo2,mirror_hori(plane_x,x,w),y);
1852 /* deploy window */
1853 group_get_geometry(gui->deploy_window,&x,&y,&w,&h);
1854 group_move(gui->deploy_window,mirror_hori(plane_x,x,w),y);
1855 }
1856
1857 /** Show video mode selection */
gui_vmode_dlg_show()1858 void gui_vmode_dlg_show()
1859 {
1860 int i;
1861
1862 /* fill list box on first run */
1863 if (lbox_is_empty(gui->vmode_dlg->select_lbox)) {
1864 List *items = list_create( LIST_AUTO_DELETE, LIST_NO_CALLBACK );
1865 char str[64];
1866
1867 for (i = 0; i < sdl.num_vmodes; i++) {
1868 VideoModeInfo *vmi = &sdl.vmodes[i];
1869 snprintf(str,64,"%dx%dx%d %s",
1870 vmi->width, vmi->height, vmi->depth,
1871 vmi->fullscreen?
1872 tr("Fullscreen"):tr("Window"));
1873 list_add(items, strdup(str));
1874 }
1875 select_dlg_set_items( gui->vmode_dlg, items);
1876 }
1877
1878 /* select current video mode */
1879 for (i = 0; i < sdl.num_vmodes; i++)
1880 if (sdl.screen->w == sdl.vmodes[i].width &&
1881 sdl.screen->h == sdl.vmodes[i].height &&
1882 (!!(sdl.screen->flags & SDL_FULLSCREEN)) ==
1883 sdl.vmodes[i].fullscreen) {
1884 lbox_select_item(gui->vmode_dlg->select_lbox,
1885 list_get(gui->vmode_dlg->select_lbox->items,i));
1886 break;
1887 }
1888
1889 select_dlg_hide( gui->vmode_dlg, 0 );
1890 }
1891
1892 //unit_list
gui_prepare_unit_list()1893 SDL_Surface * gui_prepare_unit_list()
1894 {
1895 SDL_Surface *contents = gui->unit_list->contents;
1896 gui->font_std->align = ALIGN_X_LEFT | ALIGN_Y_TOP;
1897 /* clear */
1898 SDL_FillRect( contents, 0, 0x0 );
1899 return contents;
1900 }
gui_show_unit_list()1901 void gui_show_unit_list( )
1902 {
1903 frame_apply( gui->unit_list );
1904 frame_hide( gui->unit_list, 0 );
1905 }
gui_hide_unit_list()1906 void gui_hide_unit_list( )
1907 {
1908 frame_hide( gui->unit_list, 1 );
1909 }
gui_render_single_unit(SDL_Surface * contents,Unit * unit,int x,int y)1910 static void gui_render_single_unit( SDL_Surface * contents,Unit *unit ,int x,int y)
1911 {
1912 //unit
1913 DEST( contents,
1914 x + ( ( hex_w - unit->prop.icon_w ) >> 1 ), y + ( ( ( hex_h - unit->prop.icon_h ) >> 1 ) ),
1915 unit->prop.icon_w, unit->prop.icon_h );
1916 SOURCE( unit->prop.icon, 0, 0 );
1917 blit_surf();
1918
1919 //move & attack
1920 if ( unit->cur_atk_count > 0 ) {
1921 DEST ( contents, x+hex_w/2-unit_info_icons->str_w/2-unit_info_icons->atk->w,
1922 y + hex_h - unit_info_icons->atk->h,
1923 unit_info_icons->atk->w, unit_info_icons->atk->h );
1924 SOURCE( unit_info_icons->atk, 0, 0 );
1925 blit_surf();
1926 }
1927 if ( unit->cur_mov > 0 ) {
1928 DEST ( contents, x+hex_w/2+unit_info_icons->str_w/2, y + hex_h - unit_info_icons->mov->h,
1929 unit_info_icons->mov->w, unit_info_icons->mov->h );
1930 SOURCE( unit_info_icons->mov, 0, 0 );
1931 blit_surf();
1932 }
1933
1934 //str, highlight core units
1935 if ( unit->core ) {
1936 DEST( contents,
1937 x + ( ( hex_w - unit_info_icons->str_w ) >> 1 ),
1938 y +hex_h - unit_info_icons->atk->h,
1939 unit_info_icons->str_w, unit_info_icons->str_h );
1940 fill_surf( 0xffff00 );
1941 DEST( contents,
1942 x + ( ( hex_w - unit_info_icons->str_w ) >> 1 ) + 1,
1943 y +hex_h - unit_info_icons->atk->h + 1,
1944 unit_info_icons->str_w - 2, unit_info_icons->str_h - 2 );
1945 SOURCE( unit_info_icons->str, 1, ( unit->str + 14 ) * unit_info_icons->str_h )
1946 blit_surf();
1947 }
1948 else {
1949 DEST( contents,
1950 x + ( ( hex_w - unit_info_icons->str_w ) >> 1 ),
1951 y +hex_h - unit_info_icons->atk->h,
1952 unit_info_icons->str_w, unit_info_icons->str_h );
1953 SOURCE( unit_info_icons->str, 0, ( unit->str + 14 ) * unit_info_icons->str_h )
1954 blit_surf();
1955 }
1956 /* nation flag, highlight core units */
1957 if ( unit->core ) {
1958 DEST( contents, x, y, nation_flag_width, nation_flag_height );
1959 fill_surf( 0xffff00 );
1960 DEST( contents, x + 1, y + 1, nation_flag_width - 2, nation_flag_height - 2 );
1961 SOURCE( nation_flags, 1, unit->nation->flag_offset + 1 );
1962 blit_surf();
1963 }
1964 else {
1965 DEST( contents, x, y, nation_flag_width, nation_flag_height );
1966 SOURCE( nation_flags, 0, unit->nation->flag_offset );
1967 blit_surf();
1968 }
1969 /* name and type */
1970 if((2*x/3/hex_w)%2)y+=15;
1971 y+=hex_h;
1972 write_line( contents, gui->font_std, unit->name, x-24, &y );
1973 }
gui_render_unit_list(SDL_Surface * contents,List * units)1974 void gui_render_unit_list( SDL_Surface *contents, List * units)
1975 {
1976 int tagUnits=0;
1977 int x=hex_w/2,y=-unit_list_offset*hex_h*2;
1978 Unit *unit=(Unit *)list_first(units);
1979 char tags[160];
1980 int tag_iterator=0;
1981 int last_tag=0;
1982 int already_added_tag=0;
1983 int class_count=0;
1984 int frame_width = frame_get_width(gui->unit_list);
1985
1986 while (unit)
1987 {
1988 if(unit->player==cur_player&&!unit->killed)
1989 {
1990 for(already_added_tag=0,tag_iterator=0;tag_iterator!=last_tag;tag_iterator+=strlen(tags+tag_iterator)+1)
1991 if((!strcmp(tags+tag_iterator,unit->tag))||!strlen(unit->tag)||!unit->str)
1992 {
1993 already_added_tag=1;
1994 break;
1995 }
1996 if(!already_added_tag&&strlen(unit->tag))
1997 {
1998 sprintf(tags+last_tag,"%s",unit->tag);
1999 last_tag+=strlen(unit->tag)+1;
2000 tagUnits=1;
2001 }
2002 if(unit->prop.class>class_count)
2003 class_count=unit->prop.class;
2004 }
2005 unit=list_next(units);
2006 }
2007 sprintf(tags+last_tag,"[untagged]");
2008 last_tag+=11;
2009 for(tag_iterator=0;tag_iterator!=last_tag;tag_iterator+=strlen(tags+tag_iterator)+1)
2010 {
2011 if(y)y+=20;
2012 if(tagUnits)
2013 write_line( contents,gui->font_std,tags+tag_iterator,x+200,&y);
2014 y+=10;
2015 int j=0;
2016 for(j=0;j<=class_count;j++)
2017 {
2018 unit=(Unit *)list_first(units);
2019 while(unit)
2020 {
2021 if(unit->player==cur_player&&unit->str&&((!strlen(unit->tag)&&!strcmp(tags+tag_iterator,"[untagged]"))||!strcmp(unit->tag,tags+tag_iterator))&&unit->prop.class==j&&!unit->killed)
2022 {
2023 gui_render_single_unit(contents,unit,x,y);
2024 x+=hex_w*3/2;
2025 if(x>frame_width-hex_w)
2026 {
2027 x=hex_w/2;
2028 y+=hex_h*3/2;
2029 }
2030 }
2031 unit=list_next(units);
2032 }
2033 }
2034 if(x>hex_w/2)
2035 {
2036 x=hex_w/2;
2037 y+=hex_h*3/2;
2038 }
2039 }
2040 unit_list_max_offset=y/hex_h/2+unit_list_offset;
2041 }
2042
gui_scroll_unit_list_up(List * units)2043 void gui_scroll_unit_list_up(List * units)
2044 {
2045 unit_list_offset -= 2;
2046 if ( unit_list_offset < 0 )
2047 unit_list_offset = 0;
2048 gui_render_unit_list(gui_prepare_unit_list(),units);
2049 frame_apply( gui->unit_list );
2050 }
gui_scroll_unit_list_down(List * units)2051 void gui_scroll_unit_list_down(List * units)
2052 {
2053 unit_list_offset += 2;
2054 if ( unit_list_offset > unit_list_max_offset )
2055 unit_list_offset = unit_list_max_offset;
2056 gui_render_unit_list(gui_prepare_unit_list(),units);
2057 frame_apply( gui->unit_list );
2058 }
gui_unit_list_unit_clicked(List * units,int cx,int cy)2059 Unit *gui_unit_list_unit_clicked( List * units ,int cx,int cy)
2060 {
2061 int tagUnits=0;
2062 int x=hex_w/2,y=-unit_list_offset*hex_h*2;
2063 Unit *unit=(Unit *)list_first(units);
2064 char tags[160];
2065 int tag_iterator=0;
2066 int last_tag=0;
2067 int already_added_tag=0;
2068 int class_count=0;
2069 int wx, wy;
2070 int frame_width = frame_get_width(gui->unit_list);
2071
2072 /* translate cursor position cx,cy to relative position in window */
2073 wx = cx-(config.width - frame_get_width(gui->unit_list))/2;
2074 wy = cy-(config.height - frame_get_height(gui->unit_list))/2;
2075
2076 while(unit)
2077 {
2078 if(unit->player==cur_player&&!unit->killed)
2079 {
2080 for(already_added_tag=0,tag_iterator=0;tag_iterator!=last_tag;tag_iterator+=strlen(tags+tag_iterator)+1)
2081 if((!strcmp(tags+tag_iterator,unit->tag))||!strlen(unit->tag)||!unit->str)
2082 {
2083 already_added_tag=1;
2084 break;
2085 }
2086 if(!already_added_tag&&strlen(unit->tag))
2087 {
2088 sprintf(tags+last_tag,"%s",unit->tag);
2089 last_tag+=strlen(unit->tag)+1;
2090 tagUnits=1;
2091 }
2092 if(unit->prop.class>class_count)
2093 class_count=unit->prop.class;
2094 }
2095 unit=list_next(units);
2096 }
2097 sprintf(tags+last_tag,"[untagged]");
2098 last_tag+=11;
2099 for(tag_iterator=0;tag_iterator!=last_tag;tag_iterator+=strlen(tags+tag_iterator)+1)
2100 {
2101 if(y)y+=20;
2102 if(tagUnits)
2103 y+=10;
2104 y+=10;
2105 int j=0;
2106 for(j=0;j<=class_count;j++)
2107 {
2108 unit=(Unit *)list_first(units);
2109 while(unit)
2110 {
2111 if(unit->player==cur_player&&unit->str&&((!strlen(unit->tag)&&!strcmp(tags+tag_iterator,"[untagged]"))||!strcmp(unit->tag,tags+tag_iterator))&&unit->prop.class==j&&!unit->killed)
2112 {
2113 if(wx > x && wx < x+hex_w*3/2 &&
2114 wy > y && wy < y+hex_h*3/2)
2115 return unit;
2116
2117 x+=hex_w*3/2;
2118 if(x>frame_width-hex_w)
2119 {
2120 x=hex_w/2;
2121 y+=hex_h*3/2;
2122 }
2123 }
2124 unit=list_next(units);
2125 }
2126 }
2127 if(x>hex_w/2)
2128 {
2129 x=hex_w/2;
2130 y+=hex_h*3/2;
2131 }
2132 }
2133 return NULL;
2134 }
2135