4 #include <stdio.h> /* for rename() */
5 #include <unistd.h> /* for unlink(), acess() */
6 #include <stdlib.h> /* for calloc(), free() */
7 #include <string.h> /* for strlen(), strcmp(), memcpy() */
8 #include <stdint.h> /* for uint8_t */
9 #include "windows.h" /* for suspend_win(), append_win(), reset_pad_offset(),
10 * resize_active_win(), struct Win, struct WinMeta
12 #include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */
13 #include "map_objects.h" /* for struct Monster, write_map_objects(), */
14 #include "map_object_actions.h" /* for is_passable(), move_monster() */
15 #include "map.h" /* for Map struct */
16 #include "main.h" /* for World struct */
17 #include "yx_uint16.h" /* for yx_uint16 */
18 #include "rrand.h" /* for rrand(), rrand_seed() */
19 #include "rexit.h" /* for exit_err() */
22 extern void textfile_sizes(FILE * file, uint16_t * linemax_p,
35 if (c_count > linemax)
37 linemax = c_count + 1;
46 fseek(file, 0, SEEK_SET);
47 * linemax_p = linemax;
50 * n_lines_p = n_lines;
56 extern void update_log(struct World * world, char * text)
58 static char * last_msg;
61 last_msg = calloc(1, sizeof(char));
64 uint16_t len_old = strlen(world->log);
65 if (0 == strcmp(last_msg, text))
67 uint16_t len_whole = len_old + 1;
68 new_text = calloc(len_whole + 1, sizeof(char));
69 memcpy(new_text, world->log, len_old);
70 memcpy(new_text + len_old, ".", 1);
74 uint16_t len_new = strlen(text);
75 uint16_t len_whole = len_old + len_new + 1;
76 new_text = calloc(len_whole, sizeof(char));
77 memcpy(new_text, world->log, len_old);
78 memcpy(new_text + len_old, text, len_new);
79 last_msg = calloc(len_new + 1, sizeof(char));
80 memcpy(last_msg, text, len_new);
83 world->log = new_text;
88 extern uint16_t center_offset(uint16_t pos, uint16_t mapsize,
92 if (mapsize > framesize)
94 if (pos > framesize / 2)
96 if (pos < mapsize - (framesize / 2))
98 offset = pos - (framesize / 2);
102 offset = mapsize - framesize;
111 extern void turn_over(struct World * world, char action)
113 char * err_open = "Trouble in turn_over() with fopen() "
114 "opening file 'record_tmp' for appending.";
115 char * err_write = "Trouble in turn_over() with write_uint8() "
116 "writing to opened file 'record_tmp'.";
117 char * err_close = "Trouble in turn_over() with fclose() "
118 "closing opened file 'record'.";
119 char * err_unl = "Trouble in turn_over() with unlink() "
120 "unlinking old file 'record'.";
121 char * err_move = "Trouble in turn_over() with rename() "
122 "renaming file 'record_tmp' to 'record'.";
123 char * recordfile_tmp = "record_tmp";
124 char * recordfile = "record";
125 if (1 == world->interactive)
127 FILE * file_old = fopen(recordfile, "r");
128 FILE * file_new = fopen(recordfile_tmp, "w");
129 exit_err(0 == file_old, world, err_open);
130 char c = fgetc(file_old);
133 exit_err(write_uint8(c, file_new), world, err_write);
136 exit_err(fclose(file_old), world, err_close);
137 exit_err(write_uint8(action, file_new), world, err_write);
138 err_close = "Trouble in turn_over() with fclose() "
139 "closing opened file 'record_tmp'.";
140 exit_err(fclose(file_new), world, err_close);
141 exit_err(unlink(recordfile), world, err_unl);
142 exit_err(rename(recordfile_tmp, recordfile), world, err_move);
145 rrand_seed(world->seed * world->turn);
146 struct Monster * monster;
147 for (monster = world->monster;
149 monster = monster->map_obj.next)
151 move_monster(world, monster);
157 extern void save_game(struct World * world)
159 char * err_open = "Trouble in save_game() with fopen() "
160 "opening file 'savefile_tmp' for writing.";
161 char * err_write = "Trouble in save_game() "
162 "writing to opened file 'savefile_tmp'.";
163 char * err_close = "Trouble in save_game() with fclose() "
164 "closing opened file 'savefile_tmp'.";
165 char * err_unl = "Trouble in save_game() with unlink() "
166 "unlinking old 'savefile' file.";
167 char * err_move = "Trouble in save_game() with rename() "
168 "renaming 'file savefile_tmp' to 'savefile'.";
169 char * savefile_tmp = "savefile_tmp";
170 char * savefile = "savefile";
171 FILE * file = fopen(savefile_tmp, "w");
172 exit_err(0 == file, world, err_open);
173 if ( write_uint32_bigendian(world->seed, file)
174 || write_uint32_bigendian(world->turn, file)
175 || write_uint16_bigendian(world->score, file)
176 || write_uint16_bigendian(world->player->pos.y + 1, file)
177 || write_uint16_bigendian(world->player->pos.x + 1, file)
178 || write_uint8(world->player->hitpoints, file)
179 || write_map_objects(world, world->monster, file)
180 || write_map_objects(world, world->item, file))
182 exit_err(1, world, err_write);
184 exit_err(fclose(file), world, err_close);
185 if (!access(savefile, F_OK))
187 exit_err(unlink(savefile), world, err_unl);
189 exit_err(rename(savefile_tmp, savefile), world, err_move);
194 extern uint8_t toggle_window(struct WinMeta * win_meta, struct Win * win)
196 if (0 != win->frame.curses_win)
198 return suspend_win(win_meta, win);
202 return append_win(win_meta, win);
208 extern void scroll_pad(struct WinMeta * win_meta, char dir)
212 reset_pad_offset(win_meta, win_meta->pad_offset + 1);
216 reset_pad_offset(win_meta, win_meta->pad_offset - 1);
222 extern uint8_t growshrink_active_window(struct WinMeta * win_meta, char change)
224 if (0 != win_meta->active)
226 struct yx_uint16 size = win_meta->active->frame.size;
231 else if (change == '+')
235 else if (change == '_')
239 else if (change == '*')
243 return resize_active_win (win_meta, size);
250 extern struct yx_uint16 find_passable_pos(struct Map * map)
252 struct yx_uint16 pos;
253 for (pos.y = pos.x = 0; 0 == is_passable(map, pos);)
255 pos.y = rrand() % map->size.y;
256 pos.x = rrand() % map->size.x;