home · contact · privacy
Merged world.wmeta and world.winconf_db into world.wins.
[plomrogue] / src / client / misc.c
1 /* src/client/misc.c */
2
3 #include "misc.h"
4 #include <ncurses.h> /* delwin(), endwin(), refresh() */
5 #include <stdint.h> /* uint8_t, uint16_t */
6 #include <stdio.h> /* sprintf() */
7 #include <stdlib.h> /* exit(), free() */
8 #include <string.h> /* memset(), strlen() */
9 #include <unistd.h> /* global optarg, getopt() */
10 #include "../common/readwrite.h" /* try_fopen(), try_fclose(),
11                                   * try_fclose_unlink_rename(),
12                                   */
13 #include "cleanup.h" /* for set_cleanup_flag() */
14 #include "keybindings.h" /* free_keybindings(), read_keybindings_from_file(),
15                           * write_keybindings_to_file()
16                           */
17 #include "map_window.h" /* for map_center() */
18 #include "wincontrol.h" /* struct WinConf, init_wins(), get_winconf_by_win(),
19                          * sorted_win_toggle_and_activate(), get_win_by_id(),
20                          * toggle_window(), write_winconf_of_id_to_file(),
21                          * read_winconf_from_file(), get_next_winconf_id(),
22                          * read_order_wins_visible_active(),
23                          * write_order_wins_visible_active()
24                          */
25 #include "windows.h" /* struct Win, make_pad(), suspend_win(), free_win() */
26 #include "world.h" /* global world */
27
28
29
30 extern void obey_argv(int argc, char * argv[])
31 {
32     int opt;
33     while (-1 != (opt = getopt(argc, argv, "i:")))
34     {
35         if      ('i' == opt)
36         {
37             world.path_interface_conf = optarg;
38         }
39         else
40         {
41             exit(EXIT_FAILURE);
42         }
43     }
44 }
45
46
47
48 extern void save_interface_conf()
49 {
50     char * f_name = "save_interface_conf()";
51     char * path = world.path_interface_conf;
52     char path_tmp[strlen(path) + 4 + 1];
53     sprintf(path_tmp, "%s_tmp", path);
54     FILE * file = try_fopen(path_tmp, "w", f_name);
55     char * delim = "%\n";
56     write_keybindings_to_file(file, &world.kb_global, delim);
57     write_keybindings_to_file(file, &world.kb_wingeom, delim);
58     write_keybindings_to_file(file, &world.kb_winkeys, delim);
59     write_order_wins_visible_active(file, delim);
60     uint8_t i;
61     for (i = 0; i < strlen(world.wins.ids); i++)
62     {
63         write_winconf_of_id_to_file(file, world.wins.ids[i], delim);
64     }
65     try_fclose_unlink_rename(file, path_tmp, path, f_name);
66 }
67
68
69
70 extern void load_interface_conf()
71 {
72     char * f_name = "load_interface_conf()";
73
74     /* Read keybindings and WincConf DB from interface config file. */
75     FILE * file = try_fopen(world.path_interface_conf, "r", f_name);
76     uint32_t linemax = textfile_sizes(file, NULL);
77     char line[linemax + 1];
78     read_keybindings_from_file(line, linemax, file, &world.kb_global);
79     read_keybindings_from_file(line, linemax, file, &world.kb_wingeom);
80     read_keybindings_from_file(line, linemax, file, &world.kb_winkeys);
81     read_order_wins_visible_active(line, linemax, file);
82     while (read_winconf_from_file(line, linemax, file));
83     try_fclose(file, f_name);
84
85     /* Build windows as defined by read interface data and toggle them on. */
86     make_pad();
87     init_wins();
88     sorted_win_toggle_and_activate();
89
90     /* So that the interface config data and the window structs get freed. */
91     set_cleanup_flag(CLEANUP_INTERFACE);
92 }
93
94
95
96 extern void unload_interface_conf()
97 {
98     free_keybindings(world.kb_global.kbs);
99     world.kb_global.kbs = NULL;
100     free_keybindings(world.kb_wingeom.kbs);
101     world.kb_wingeom.kbs = NULL;
102     free_keybindings(world.kb_winkeys.kbs);
103     world.kb_winkeys.kbs = NULL;
104     while (0 != world.wins.win_active)
105     {
106         suspend_win(world.wins.win_active);
107     }
108     free_winconfs();
109     delwin(world.wins.pad);
110 }
111
112
113
114 extern void winch_called(int signal)
115 {
116     world.winch = 1;
117 }
118
119
120
121 extern void reset_windows()
122 {
123     endwin();  /* "[S]tandard way" to recalibrate ncurses post SIGWINCH, says */
124     refresh(); /* <http://invisible-island.net/ncurses/ncurses-intro.html>.   */
125     struct Win * w_p = world.wins.chain_start;
126     char win_ids[strlen(world.wins.ids) + 1];
127     memset(win_ids, '\0', strlen(world.wins.ids) + 1);
128     uint8_t i = 0;
129     char active = '\0';
130     for (; NULL != w_p; w_p = w_p->next, i++)
131     {
132         struct WinConf * wc_p = get_winconf_by_win(w_p);
133         win_ids[i] = wc_p->id;
134         if (w_p == world.wins.win_active)
135         {
136             active = wc_p->id;
137         }
138     }
139     while (0 != world.wins.win_active)
140     {
141         w_p = world.wins.win_active;
142         suspend_win(w_p);
143     }
144     char id;
145     while (0 != (id = get_next_winconf_id()))
146     {
147         free_win(get_win_by_id(id));
148     }
149     delwin(world.wins.pad);
150     make_pad();
151     init_wins();
152     if (strlen(win_ids) < 1)
153     {
154         return;
155     }
156     for (i = 0; i < strlen(win_ids); i++)
157     {
158         toggle_window(win_ids[i]);
159         if (active == win_ids[i])
160         {
161             world.wins.win_active = get_win_by_id(win_ids[i]);
162         }
163     }
164 }
165
166
167
168 extern void reload_interface_conf()
169 {
170     unload_interface_conf();
171     load_interface_conf();
172     map_center();
173 }
174
175
176
177 extern uint16_t center_offset(uint16_t position, uint16_t mapsize,
178                               uint16_t framesize)
179 {
180     uint16_t offset = 0;
181     if (mapsize > framesize)
182     {
183         if (position > framesize / 2)
184         {
185             if (position < mapsize - (framesize / 2))
186             {
187                 offset = position - (framesize / 2);
188             }
189             else
190             {
191                 offset = mapsize - framesize;
192             }
193         }
194     }
195     return offset;
196 }
197
198
199
200 extern void nav_inventory(char dir)
201 {
202     if ('u' == dir)
203     {
204         world.player_inventory_select = world.player_inventory_select
205                                         - (world.player_inventory_select > 0);
206         return;
207     }
208     uint8_t n_elems = 0;
209     uint8_t i;
210     for (i = 0; '\0' != world.player_inventory[i]; i++)
211     {
212         n_elems = n_elems + ('\n' == world.player_inventory[i]);
213     }
214     world.player_inventory_select = world.player_inventory_select
215                                     + (world.player_inventory_select < n_elems);
216 }
217