*/
#include "map_object_actions.h" /* for player_wait(), move_player() */
#include "map.h" /* for struct Map, init_map() */
-#include "misc.h" /* for update_log(), toggle_window(), exit_game(),
- * find_passable_pos(), meta_keys(), save_game()
+#include "misc.h" /* for update_log(), toggle_window(), find_passable_pos(),
+ * meta_keys(), save_game()
*/
#include "yx_uint16.h" /* for dir enum */
#include "rrand.h" /* for rrand(), rrand_seed() */
+#include "rexit.h" /* for exit_game() */
int main(int argc, char *argv[])
{
/* Initialize log, player, monster/item definitions and monsters/items. */
world.log = calloc(1, sizeof(char));
+ set_cleanup_flag(CLEANUP_LOG);
update_log (&world, " ");
struct Player player;
player.hitpoints = 5;
rrand_seed(world.seed);
struct Map map = init_map();
world.map = ↦
+ set_cleanup_flag(CLEANUP_MAP);
if (1 == world.turn)
{
player.pos = find_passable_pos(&map);
/* Initialize window system and windows. */
WINDOW * screen = initscr();
+ set_cleanup_flag(CLEANUP_NCURSES);
noecho();
curs_set(0);
keypad(screen, TRUE);
raw();
init_keybindings(&world);
+ set_cleanup_flag(CLEANUP_KEYBINDINGS);
struct WinMeta win_meta = init_win_meta(screen);
struct Win win_keys = init_win(&win_meta, "Keys",
0, 29, &world, draw_keys_win);
&win_map, &win_info, &win_log);
if (1 == quit_called)
{
- exit_game(&world, &map);
+ exit_game(&world);
}
}
}
&win_map, &win_info, &win_log);
if (1 == quit_called)
{
- exit_game(&world, &map);
+ exit_game(&world);
}
}
}
/* misc.c */
#include "misc.h"
-#include <stdlib.h> /* for exit(), EXIT_SUCCESS define, calloc(), free() */
+#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for strlen(), strcmp(), memcpy() */
-#include <ncurses.h> /* for endwin() */
#include "windows.h" /* for suspend_win(), append_win(), reset_pad_offset(),
* resize_active_win(), cycle_active_win(),
* shift_active_win(), struct Win, struct WinMeta
-extern void exit_game(struct World * world, struct Map * map)
-{
- endwin();
- free(map->cells);
- uint16_t key;
- for (key = 0; key <= world->keyswindata->max; key++)
- {
- free(world->keybindings[key].name);
- }
- free(world->keybindings);
- free(world->keyswindata);
- free(world->log);
- exit (EXIT_SUCCESS);
-}
-
-
-
extern void textfile_sizes(FILE * file, uint16_t * linemax_p,
uint16_t * n_lines_p)
{
-/* Reset terminal (end ncurses), clean up memory and exit. */
-extern void exit_game(struct World * world, struct Map * map);
-
-
-
/* Learn from "file" the largest line length (pointed to by "linemax_p") and
* (pointed to by "n_lines_p" if it is not set to NULL) the number of lines.
*/
--- /dev/null
+/* rexit.c */
+
+#include "rexit.h"
+#include <stdlib.h> /* for exit(), free(), defines EXIT_SUCESS, EXIT_FAILURE */
+#include <stdio.h> /* for printf() */
+#include <ncurses.h> /* for endwin() */
+#include "main.h" /* for World struct */
+#include "map.h" /* for Map struct */
+#include "keybindings.h" /* for KeysWinData, KeyBinding structs */
+
+
+
+/* The clean-up routine and the flag resource by which it decides what to do. */
+static unsigned char cleanup_flags = 0x00;
+static void cleanup(struct World * world);
+
+
+
+static void cleanup(struct World * world)
+{
+ if (cleanup_flags & CLEANUP_NCURSES)
+ {
+ endwin();
+ }
+ if (cleanup_flags & CLEANUP_MAP)
+ {
+ free(world->map->cells);
+ }
+ if (cleanup_flags & CLEANUP_KEYBINDINGS)
+ {
+ uint16_t key;
+ for (key = 0; key <= world->keyswindata->max; key++)
+ {
+ free(world->keybindings[key].name);
+ }
+ free(world->keybindings);
+ free(world->keyswindata);
+ }
+ if (cleanup_flags & CLEANUP_LOG)
+ {
+ free(world->log);
+ }
+}
+
+
+
+extern void set_cleanup_flag(enum cleanup_flag flag)
+{
+ cleanup_flags = cleanup_flags | flag;
+}
+
+
+
+extern void exit_game(struct World * world)
+{
+ cleanup(world);
+ exit(EXIT_SUCCESS);
+}
+
+
+
+extern void exit_err(struct World * world, char * msg)
+{
+ cleanup(world);
+ printf(msg);
+ exit(EXIT_FAILURE);
+}
--- /dev/null
+/* rexit.h
+ *
+ * Routines to exit the game orderly or on error, with as much cleaning up as is
+ * possible in both cases.
+ */
+
+#ifndef REXIT_H
+#define REXIT_H
+
+
+
+struct World;
+struct Map;
+
+
+
+/* set_cleanup_flag() sets any of the flags defined in cleanup_flag to announce
+ * the resources that need cleaning up upon program exit. It is to be called at
+ * the earliest moment possible after resource creation / initialization.
+ */
+enum cleanup_flag
+{
+ CLEANUP_NCURSES = 0x01,
+ CLEANUP_MAP = 0x02,
+ CLEANUP_KEYBINDINGS = 0x04,
+ CLEANUP_LOG = 0x08
+};
+extern void set_cleanup_flag(enum cleanup_flag flag);
+
+
+
+/* Exit orderly without message or on error with an error message ("msg").
+ */
+extern void exit_game(struct World * world);
+extern void exit_err(struct World * world, char * msg);
+
+
+
+#endif