home · contact · privacy
Built error checking into file reading/writing routines and calls of them.
[plomrogue] / src / misc.c
1 /* misc.c */
2
3 #include "misc.h"
4 #include <stdlib.h> /* for calloc(), free() */
5 #include <string.h> /* for strlen(), strcmp(), memcpy() */
6 #include "windows.h" /* for suspend_win(), append_win(), reset_pad_offset(),
7                       * resize_active_win(), cycle_active_win(),
8                       * shift_active_win(), struct Win, struct WinMeta
9                       */
10 #include "keybindings.h" /* for get_action_key(), save_keybindings(),
11                           * keyswin_move_selection(), keyswin_mod_key()
12                           */
13 #include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */
14 #include "map_objects.h" /* for struct Monster, write_map_objects(), */
15 #include "map_object_actions.h" /* for is_passable(), move_monster() */
16 #include "map.h" /* for map_scroll(),map_center_player(), Map struct,dir enum */
17 #include "main.h" /* for World struct */
18 #include "yx_uint16.h" /* for yx_uint16 */
19 #include "rrand.h" /* for rrand(), rrand_seed() */
20 #include "rexit.h" /* for exit_err() */
21
22
23 extern void textfile_sizes(FILE * file, uint16_t * linemax_p,
24                            uint16_t * n_lines_p)
25 {
26     uint16_t n_lines = 0;
27     int c = 0;
28     uint16_t linemax = 0;
29     uint16_t c_count = 0;
30     while (EOF != c)
31     {
32         c_count++;
33         c = getc(file);
34         if ('\n' == c)
35         {
36             if (c_count > linemax)
37             {
38                 linemax = c_count + 1;
39             }
40             c_count = 0;
41             if (n_lines_p)
42             {
43                 n_lines++;
44             }
45         }
46     }
47     fseek(file, 0, SEEK_SET);
48     * linemax_p = linemax;
49     if (n_lines_p)
50     {
51         * n_lines_p = n_lines;
52     }
53 }
54
55
56
57 extern void update_log(struct World * world, char * text)
58 {
59     static char * last_msg;
60     if (0 == last_msg)
61     {
62         last_msg = calloc(1, sizeof(char));
63     }
64     char * new_text;
65     uint16_t len_old = strlen(world->log);
66     if (0 == strcmp(last_msg, text))
67     {
68         uint16_t len_whole = len_old + 1;
69         new_text = calloc(len_whole + 1, sizeof(char));
70         memcpy(new_text, world->log, len_old);
71         memcpy(new_text + len_old, ".", 1);
72     }
73     else
74     {
75         uint16_t len_new = strlen(text);
76         uint16_t len_whole = len_old + len_new + 1;
77         new_text = calloc(len_whole, sizeof(char));
78         memcpy(new_text, world->log, len_old);
79         memcpy(new_text + len_old, text, len_new);
80         last_msg = calloc(len_new + 1, sizeof(char));
81         memcpy(last_msg, text, len_new);
82     }
83     free(world->log);
84     world->log = new_text;
85 }
86
87
88
89 extern uint16_t center_offset(uint16_t pos, uint16_t mapsize,
90                               uint16_t framesize)
91 {
92     uint16_t offset = 0;
93     if (mapsize > framesize)
94     {
95         if (pos > framesize / 2)
96         {
97             if (pos < mapsize - (framesize / 2))
98             {
99                 offset = pos - (framesize / 2);
100             }
101             else
102             {
103                 offset = mapsize - framesize;
104             }
105         }
106     }
107     return offset;
108 }
109
110
111
112 extern void turn_over(struct World * world, char action)
113 {
114     if (1 == world->interactive)
115     {
116         FILE * file = fopen("record", "a");
117         exit_err(write_uint8(action, file), world, "Record writing failure.");
118         fclose(file);
119     }
120     world->turn++;
121     rrand_seed(world->seed * world->turn);
122     struct Monster * monster;
123     for (monster = world->monster;
124          monster != 0;
125          monster = monster->map_obj.next)
126     {
127         move_monster(world, monster);
128     }
129 }
130
131
132
133 extern void save_game(struct World * world)
134 {
135     uint8_t fail;
136     FILE * file = fopen("savefile", "w");
137     fail = write_uint32_bigendian(world->seed, file);
138     fail = fail | write_uint32_bigendian(world->turn, file);
139     fail = fail | write_uint16_bigendian(world->player->pos.y + 1, file);
140     fail = fail | write_uint16_bigendian(world->player->pos.x + 1, file);
141     fail = fail | write_uint8(world->player->hitpoints, file);
142     fail = fail | write_map_objects(world, world->monster, file);
143     fail = fail | write_map_objects(world, world->item, file);
144     exit_err(fail, world, "Error saving game.");
145     fclose(file);
146 }
147
148
149
150 extern void toggle_window(struct WinMeta * win_meta, struct Win * win)
151 {
152     if (0 != win->frame.curses_win)
153     {
154         suspend_win(win_meta, win);
155     }
156     else
157     {
158         append_win(win_meta, win);
159     }
160 }
161
162
163
164 extern void scroll_pad(struct WinMeta * win_meta, char dir)
165 {
166     if      ('+' == dir)
167     {
168         reset_pad_offset(win_meta, win_meta->pad_offset + 1);
169     }
170     else if ('-' == dir)
171     {
172         reset_pad_offset(win_meta, win_meta->pad_offset - 1);
173     }
174 }
175
176
177
178 extern void growshrink_active_window(struct WinMeta * win_meta, char change)
179 {
180     if (0 != win_meta->active)
181     {
182         struct yx_uint16 size = win_meta->active->frame.size;
183         if      (change == '-')
184         {
185             size.y--;
186         }
187         else if (change == '+')
188         {
189             size.y++;
190         }
191         else if (change == '_')
192         {
193             size.x--;
194         }
195         else if (change == '*')
196         {
197             size.x++;
198         }
199         resize_active_win (win_meta, size);
200     }
201 }
202
203
204
205 extern struct yx_uint16 find_passable_pos(struct Map * map)
206 {
207     struct yx_uint16 pos;
208     for (pos.y = pos.x = 0; 0 == is_passable(map, pos);)
209     {
210         pos.y = rrand() % map->size.y;
211         pos.x = rrand() % map->size.x;
212     }
213     return pos;
214 }
215
216
217
218 extern unsigned char meta_keys(int key, struct World * world,
219                                struct WinMeta * win_meta,
220                                struct Win * win_keys,
221                                struct Win * win_map,
222                                struct Win * win_info,
223                                struct Win * win_log)
224 {
225     if (key == get_action_key(world->keybindings, "quit"))
226     {
227         return 1;
228     }
229     else if (key == get_action_key(world->keybindings, "scroll pad right"))
230     {
231         scroll_pad (win_meta, '+');
232     }
233     else if (key == get_action_key(world->keybindings, "scroll pad left"))
234     {
235         scroll_pad (win_meta, '-');
236     }
237     else if (key == get_action_key(world->keybindings, "toggle keys window"))
238     {
239         toggle_window(win_meta, win_keys);
240     }
241     else if (key == get_action_key(world->keybindings, "toggle map window"))
242     {
243         toggle_window(win_meta, win_map);
244     }
245     else if (key == get_action_key(world->keybindings, "toggle info window"))
246     {
247         toggle_window(win_meta, win_info);
248     }
249     else if (key == get_action_key(world->keybindings, "toggle log window"))
250     {
251         toggle_window(win_meta, win_log);
252     }
253     else if (key == get_action_key(world->keybindings, "cycle forwards"))
254     {
255         cycle_active_win(win_meta, 'n');
256     }
257     else if (key == get_action_key(world->keybindings, "cycle backwards"))
258     {
259         cycle_active_win(win_meta, 'p');
260     }
261     else if (key == get_action_key(world->keybindings, "shift forwards"))
262     {
263         shift_active_win(win_meta, 'f');
264     }
265     else if (key == get_action_key(world->keybindings, "shift backwards"))
266     {
267         shift_active_win(win_meta, 'b');
268     }
269     else if (key == get_action_key(world->keybindings, "grow horizontally"))
270     {
271         growshrink_active_window(win_meta, '*');
272     }
273     else if (key == get_action_key(world->keybindings, "shrink horizontally"))
274     {
275         growshrink_active_window(win_meta, '_');
276     }
277     else if (key == get_action_key(world->keybindings, "grow vertically"))
278     {
279         growshrink_active_window(win_meta, '+');
280     }
281     else if (key == get_action_key(world->keybindings, "shrink vertically"))
282     {
283         growshrink_active_window(win_meta, '-');
284     }
285     else if (key == get_action_key(world->keybindings, "save keys"))
286     {
287         save_keybindings(world);
288     }
289     else if (key == get_action_key(world->keybindings, "keys nav up"))
290     {
291         keyswin_move_selection (world, 'u');
292     }
293     else if (key == get_action_key(world->keybindings, "keys nav down"))
294     {
295         keyswin_move_selection (world, 'd');
296     }
297     else if (key == get_action_key(world->keybindings, "keys mod"))
298     {
299         keyswin_mod_key (world, win_meta);
300     }
301     else if (key == get_action_key(world->keybindings, "map up"))
302     {
303         map_scroll (world->map, NORTH, win_map->frame.size);
304      }
305     else if (key == get_action_key(world->keybindings, "map down"))
306     {
307         map_scroll (world->map, SOUTH, win_map->frame.size);
308     }
309     else if (key == get_action_key(world->keybindings, "map right"))
310     {
311         map_scroll (world->map, EAST, win_map->frame.size);
312     }
313     else if (key == get_action_key(world->keybindings, "map left"))
314     {
315         map_scroll (world->map, WEST, win_map->frame.size);
316     }
317     else if (key == get_action_key(world->keybindings, "map center player"))
318     {
319         map_center_player (world->map, world->player, win_map->frame.size);
320     }
321     return 0;
322 }