home · contact · privacy
Moved textfile_sizes() to readwrite library.
[plomrogue] / src / misc.c
1 /* misc.c */
2
3 #include "misc.h"
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, uint16_t */
9 #include "readwrite.h" /* for [read/write]_uint[8/16/32][_bigendian]() */
10 #include "map_objects.h" /* for struct Monster, write_map_objects(), */
11 #include "map_object_actions.h" /* for is_passable(), move_monster() */
12 #include "map.h" /* for Map struct */
13 #include "main.h" /* for World struct */
14 #include "yx_uint16.h" /* for yx_uint16 struct */
15 #include "rrand.h" /* for rrand(), rrand_seed() */
16 #include "rexit.h" /* for exit_err() */
17
18
19
20 extern void update_log(struct World * world, char * text)
21 {
22     static char * last_msg;                 /* TODO: valgrind is dissatisfied */
23     if (0 == last_msg)                      /* with this calloc'd pointer     */
24     {                                       /* never being freed.             */
25         last_msg = calloc(1, sizeof(char)); /* Rectify this ?                 */
26     }
27     char * new_text;
28     uint16_t len_old = strlen(world->log);
29     if (0 == strcmp(last_msg, text))
30     {
31         uint16_t len_whole = len_old + 1;
32         new_text = calloc(len_whole + 1, sizeof(char));
33         memcpy(new_text, world->log, len_old);
34         memcpy(new_text + len_old, ".", 1);
35     }
36     else
37     {
38         uint16_t len_new = strlen(text);
39         uint16_t len_whole = len_old + len_new + 1;
40         new_text = calloc(len_whole, sizeof(char));
41         memcpy(new_text, world->log, len_old);
42         memcpy(new_text + len_old, text, len_new);
43         last_msg = calloc(len_new + 1, sizeof(char));
44         memcpy(last_msg, text, len_new);
45     }
46     free(world->log);
47     world->log = new_text;
48 }
49
50
51
52 extern uint16_t center_offset(uint16_t pos, uint16_t mapsize,
53                               uint16_t framesize)
54 {
55     uint16_t offset = 0;
56     if (mapsize > framesize)
57     {
58         if (pos > framesize / 2)
59         {
60             if (pos < mapsize - (framesize / 2))
61             {
62                 offset = pos - (framesize / 2);
63             }
64             else
65             {
66                 offset = mapsize - framesize;
67             }
68         }
69     }
70     return offset;
71 }
72
73
74
75 extern void turn_over(struct World * world, char action)
76 {
77     char * err_open  = "Trouble in turn_over() with fopen() "
78                        "opening file 'record_tmp' for appending.";
79     char * err_write = "Trouble in turn_over() with write_uint8() "
80                        "writing to opened file 'record_tmp'.";
81     char * err_close = "Trouble in turn_over() with fclose() "
82                        "closing opened file 'record'.";
83     char * err_unl   = "Trouble in turn_over() with unlink() "
84                        "unlinking old file 'record'.";
85     char * err_move  = "Trouble in turn_over() with rename() "
86                        "renaming file 'record_tmp' to 'record'.";
87     char * recordfile_tmp = "record_tmp";
88     char * recordfile     = "record";
89     if (1 == world->interactive)
90     {
91         FILE * file_old = fopen(recordfile, "r");
92         FILE * file_new = fopen(recordfile_tmp, "w");
93         exit_err(0 == file_old, world, err_open);
94         char c = fgetc(file_old);
95         while (EOF != c)
96         {
97             exit_err(write_uint8(c, file_new), world, err_write);
98             c = fgetc(file_old);
99         }
100         exit_err(fclose(file_old), world, err_close);
101         exit_err(write_uint8(action, file_new), world, err_write);
102         err_close = "Trouble in turn_over() with fclose() "
103                     "closing opened file 'record_tmp'.";
104         exit_err(fclose(file_new), world, err_close);
105         exit_err(unlink(recordfile), world, err_unl);
106         exit_err(rename(recordfile_tmp, recordfile), world, err_move);
107     }
108     world->turn++;
109     rrand_seed(world->seed * world->turn);
110     struct Monster * monster;
111     for (monster = world->monster;
112          monster != 0;
113          monster = monster->map_obj.next)
114     {
115         move_monster(world, monster);
116     }
117 }
118
119
120
121 extern void save_game(struct World * world)
122 {
123     char * err_open  = "Trouble in save_game() with fopen() "
124                        "opening file 'savefile_tmp' for writing.";
125     char * err_write = "Trouble in save_game() "
126                        "writing to opened file 'savefile_tmp'.";
127     char * err_close = "Trouble in save_game() with fclose() "
128                        "closing opened file 'savefile_tmp'.";
129     char * err_unl   = "Trouble in save_game() with unlink() "
130                        "unlinking old 'savefile' file.";
131     char * err_move  = "Trouble in save_game() with rename() "
132                        "renaming 'file savefile_tmp' to 'savefile'.";
133     char * savefile_tmp = "savefile_tmp";
134     char * savefile     = "savefile";
135     FILE * file = fopen(savefile_tmp, "w");
136     exit_err(0 == file, world, err_open);
137     if (   write_uint32_bigendian(world->seed, file)
138         || write_uint32_bigendian(world->turn, file)
139         || write_uint16_bigendian(world->score, file)
140         || write_uint16_bigendian(world->player->pos.y + 1, file)
141         || write_uint16_bigendian(world->player->pos.x + 1, file)
142         || write_uint8(world->player->hitpoints, file)
143         || write_map_objects(world, world->monster, file)
144         || write_map_objects(world, world->item, file))
145     {
146         exit_err(1, world, err_write);
147     }
148     exit_err(fclose(file), world, err_close);
149     if (!access(savefile, F_OK))
150     {
151         exit_err(unlink(savefile), world, err_unl);
152     }
153     exit_err(rename(savefile_tmp, savefile), world, err_move);
154 }
155
156
157
158 extern struct yx_uint16 find_passable_pos(struct Map * map)
159 {
160     struct yx_uint16 pos;
161     for (pos.y = pos.x = 0; 0 == is_passable(map, pos);)
162     {
163         pos.y = rrand() % map->size.y;
164         pos.x = rrand() % map->size.x;
165     }
166     return pos;
167 }