10 #include "keybindings.h"
11 #include "readwrite.h"
12 #include "map_objects.h"
13 #include "map_object_actions.h"
17 int main (int argc, char *argv[]) {
20 // Read in startup options (i.e. replay option and replay start turn).
23 world.interactive = 1;
24 while ((opt = getopt(argc, argv, "s::")) != -1) {
27 world.interactive = 0;
30 start_turn = atoi(optarg);
33 exit(EXIT_FAILURE); } }
35 // Initialize log, player, monster/item definitions and monsters/items.
36 world.log = calloc(1, sizeof(char));
37 update_log (&world, " ");
40 world.player = &player;
44 world.monster_def = 0;
45 FILE * file = fopen("defs", "r");
47 textfile_sizes (file, &linemax, NULL);
52 struct ItemDef * * p_p_id = &world.item_def;
53 struct MonsterDef * * p_p_md = &world.monster_def;
54 char * defline = malloc(linemax);
56 while (fgets (defline, linemax, file)) {
58 mod.id = atoi(defline);
59 line_p = strchr(defline, ' ') + 1;
61 mod.mapchar = * (line_p + 2);
65 md.hitpoints_start = atoi (line_p + 4);
66 line_p = strchr (line_p + 4, ' ') + 1; }
67 mod.desc = calloc (strlen (line_p), sizeof(char));
68 memcpy (mod.desc, line_p, strlen(line_p) - 1);
71 * p_p_id = malloc (sizeof (struct ItemDef));
73 p_p_id = (struct ItemDef * *) * p_p_id; }
76 * p_p_md = malloc (sizeof (struct MonsterDef));
78 p_p_md = (struct MonsterDef * *) * p_p_md; } }
82 // For interactive mode, try to load world state from savefile.
83 if (1 == world.interactive && 0 == access("savefile", F_OK)) {
84 file = fopen("savefile", "r");
85 world.seed = read_uint32_bigendian(file);
86 world.turn = read_uint32_bigendian(file);
87 player.pos.y = read_uint16_bigendian(file) - 1;
88 player.pos.x = read_uint16_bigendian(file) - 1;
89 player.hitpoints = fgetc(file);
90 read_map_objects (&world.monster, file, sizeof(struct Monster), read_map_objects_monsterdata);
91 read_map_objects (&world.item, file, sizeof(struct Item), readwrite_map_objects_dummy);
94 // For non-interactive mode, try to load world state from record file.
97 if (0 == world.interactive) {
98 file = fopen("record", "r");
99 world.seed = read_uint32_bigendian(file); }
101 // For interactive-mode in newly started world, generate a start seed from the current time.
103 file = fopen("record", "w");
104 world.seed = time(NULL);
105 write_uint32_bigendian(world.seed, file);
108 // Generate map from seed and, if newly generated world, start positions of actors.
109 rrand(1, world.seed);
110 struct Map map = init_map();
112 if (1 == world.turn) {
113 player.pos = find_passable_pos(&map);
114 void * foo = build_map_objects (&world, &world.monster, 0, 1 + rrand(0,0) % 27, sizeof(struct Monster),
115 build_map_objects_monsterdata);
116 foo = build_map_objects (&world, foo, 1, 1 + rrand(0,0) % 9, sizeof(struct Monster),
117 build_map_objects_monsterdata);
118 build_map_objects (&world, foo, 2, 1 + rrand(0,0) % 3, sizeof(struct Monster),
119 build_map_objects_monsterdata);
120 foo = build_map_objects (&world, &world.item, 3, 1 + rrand(0,0) % 3, sizeof(struct Item),
121 build_map_objects_itemdata);
122 build_map_objects (&world, foo, 4, 1 + rrand(0,0) % 3, sizeof(struct Item), build_map_objects_itemdata); }
124 // Initialize window system and windows.
125 WINDOW * screen = initscr();
128 keypad(screen, TRUE);
130 init_keybindings(&world);
131 struct WinMeta win_meta = init_win_meta(screen);
132 struct Win win_keys = init_win(&win_meta, "Keys", &world, draw_keys_win);
133 struct Win win_map = init_win(&win_meta, "Map", &world, draw_map_win);
134 struct Win win_info = init_win(&win_meta, "Info", &world, draw_info_win);
135 struct Win win_log = init_win(&win_meta, "Log", &world, draw_log_win);
136 win_keys.frame.size.x = 29;
137 win_map.frame.size.x = win_meta.pad.size.x - win_keys.frame.size.x - win_log.frame.size.x - 2;
138 win_info.frame.size.y = 2;
139 win_log.frame.size.y = win_meta.pad.size.y - (2 + win_info.frame.size.y);
140 toggle_window(&win_meta, &win_keys);
141 toggle_window(&win_meta, &win_map);
142 toggle_window(&win_meta, &win_info);
143 toggle_window(&win_meta, &win_log);
147 unsigned char quit_called = 0;
148 unsigned char await_actions = 1;
149 if (0 == world.interactive) {
152 if (start_turn == world.turn)
154 if (0 == start_turn) {
155 draw_all_wins (&win_meta);
157 if (1 == await_actions &&
158 (world.turn < start_turn || key == get_action_key(world.keybindings, "wait / next turn")) ) {
163 else if (0 == action)
164 player_wait (&world);
165 else if (NORTH == action)
166 move_player(&world, NORTH);
167 else if (EAST == action)
168 move_player(&world, EAST);
169 else if (SOUTH == action)
170 move_player(&world, SOUTH);
171 else if (WEST == action)
172 move_player(&world, WEST); }
174 quit_called = meta_keys(key, &world, &win_meta, &win_keys, &win_map, &win_info, &win_log);
175 if (1 == quit_called)
180 uint32_t last_turn = 0;
182 if (last_turn != world.turn) {
184 last_turn = world.turn; }
185 if (1 == await_actions && 0 == player.hitpoints)
187 draw_all_wins (&win_meta);
189 if (1 == await_actions && key == get_action_key(world.keybindings, "player up"))
190 move_player(&world, NORTH);
191 else if (1 == await_actions && key == get_action_key(world.keybindings, "player right"))
192 move_player(&world, EAST);
193 else if (1 == await_actions && key == get_action_key(world.keybindings, "player down"))
194 move_player(&world, SOUTH);
195 else if (1 == await_actions && key == get_action_key(world.keybindings, "player left"))
196 move_player(&world, WEST);
197 else if (1 == await_actions && key == get_action_key(world.keybindings, "wait / next turn"))
198 player_wait (&world);
200 quit_called = meta_keys(key, &world, &win_meta, &win_keys, &win_map, &win_info, &win_log);
201 if (1 == quit_called)
204 // Clean up and exit.
206 for (key = 0; key <= world.keyswindata->max; key++)
207 free(world.keybindings[key].name);
208 free(world.keybindings);
209 free(world.keyswindata);