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