home · contact · privacy
Split roguelike.(c|h) into main.(c|h) and misc.(c|h).
authorChristian Heller <c.heller@plomlompom.de>
Wed, 10 Jul 2013 22:44:02 +0000 (00:44 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 10 Jul 2013 22:44:02 +0000 (00:44 +0200)
src/draw_wins.c
src/keybindings.c
src/main.c [new file with mode: 0644]
src/main.h [new file with mode: 0644]
src/map.c
src/misc.c [new file with mode: 0644]
src/misc.h [new file with mode: 0644]
src/objects_on_map.c
src/roguelike.c [deleted file]
src/roguelike.h [deleted file]

index 5256713e10a82647ab38c81d31ca0432fcc41809..dd96c36e71002212765dd4e2f37ce04e790a3950 100644 (file)
@@ -4,10 +4,11 @@
 #include <string.h>
 #include <ncurses.h>
 #include "windows.h"
-#include "roguelike.h"
+#include "misc.h"
 #include "keybindings.h"
 #include "objects_on_map.h"
 #include "map.h"
+#include "main.h"
 
 static void draw_map_objects (void *, struct Map *, struct Win *);
 
index f9d1b8be60b1a94f179303303afdd334bab25905..dae549741d738c07347dccd243d1d7066db7585e 100644 (file)
@@ -4,7 +4,8 @@
 #include <ncurses.h>
 #include <string.h>
 #include "windows.h"
-#include "roguelike.h"
+#include "misc.h"
+#include "main.h"
 
 void init_keybindings(struct World * world) {
 // Initialize keybindings from file "keybindings".
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..4dd1673
--- /dev/null
@@ -0,0 +1,167 @@
+#include "main.h"
+#include <stdlib.h>
+#include <ncurses.h>
+#include <time.h>
+#include <unistd.h>
+#include "windows.h"
+#include "draw_wins.h"
+#include "keybindings.h"
+#include "readwrite.h"
+#include "objects_on_map.h"
+#include "map.h"
+#include "misc.h"
+
+int main (int argc, char *argv[]) {
+  struct World world;
+
+  // Read in startup options (i.e. replay option and replay start turn).
+  int opt;
+  uint32_t start_turn;
+  world.interactive = 1;
+  while ((opt = getopt(argc, argv, "s::")) != -1) {
+    switch (opt) {
+      case 's':
+        world.interactive = 0;
+        start_turn = 0;
+        if (optarg)
+          start_turn = atoi(optarg);
+        break;
+      default:
+        exit(EXIT_FAILURE); } }
+
+  // Initialize log, player, monsters and items.
+  world.log = calloc(1, sizeof(char));
+  update_log (&world, " ");
+  struct Player player;
+  player.hitpoints = 5;
+  world.player = &player;
+  world.monster = 0;
+  world.item = 0;
+
+  // For interactive mode, try to load world state from savefile.
+  FILE * file;
+  if (1 == world.interactive && 0 == access("savefile", F_OK)) {
+    file = fopen("savefile", "r");
+    world.seed = read_uint32_bigendian(file);
+    world.turn = read_uint32_bigendian(file);
+    player.pos.y = read_uint16_bigendian(file) - 1;
+    player.pos.x = read_uint16_bigendian(file) - 1;
+    player.hitpoints = fgetc(file);
+    read_map_objects (&world.monster, file, sizeof(struct Monster), read_map_objects_monsterdata);
+    read_map_objects (&world.item,    file, sizeof(struct Item),    readwrite_map_objects_dummy);
+    fclose(file); }
+
+  // For non-interactive mode, try to load world state from record file.
+  else {
+    world.turn = 1;
+    if (0 == world.interactive) {
+      file = fopen("record", "r");
+      world.seed = read_uint32_bigendian(file); }
+
+    // For interactive-mode in newly started world, generate a start seed from the current time.
+    else {
+      file = fopen("record", "w");
+      world.seed = time(NULL);
+      write_uint32_bigendian(world.seed, file);
+      fclose(file); } }
+
+  // Generate map from seed and, if newly generated world, start positions of actors.
+  rrand(1, world.seed);
+  struct Map map = init_map();
+  world.map = &map;
+  if (1 == world.turn) {
+    player.pos = find_passable_pos(&map);
+    unsigned char n_monsters = rrand(0, 0) % 16;
+    unsigned char n_items    = rrand(0, 0) % 48;
+    build_map_objects (&world.monster, n_monsters, sizeof(struct Monster), build_map_objects_monsterdata, &map);
+    build_map_objects (&world.item,    n_items,    sizeof(struct Item),    build_map_objects_itemdata,    &map); }
+
+  // Initialize window system and windows.
+  WINDOW * screen = initscr();
+  noecho();
+  curs_set(0);
+  keypad(screen, TRUE);
+  raw();
+  init_keybindings(&world);
+  struct WinMeta win_meta = init_win_meta(screen);
+  struct Win win_keys = init_win(&win_meta, "Keys", &world, draw_keys_win);
+  struct Win win_map = init_win(&win_meta, "Map", &world, draw_map_win);
+  struct Win win_info = init_win(&win_meta, "Info", &world, draw_info_win);
+  struct Win win_log = init_win(&win_meta, "Log", &world, draw_log_win);
+  win_keys.frame.size.x = 29;
+  win_map.frame.size.x = win_meta.pad.size.x - win_keys.frame.size.x - win_log.frame.size.x - 2;
+  win_info.frame.size.y = 2;
+  win_log.frame.size.y = win_meta.pad.size.y - (2 + win_info.frame.size.y);
+  toggle_window(&win_meta, &win_keys);
+  toggle_window(&win_meta, &win_map);
+  toggle_window(&win_meta, &win_info);
+  toggle_window(&win_meta, &win_log);
+
+  // Replay mode.
+  int key;
+  unsigned char quit_called = 0;
+  unsigned char await_actions = 1;
+  if (0 == world.interactive) {
+    int action;
+    while (1) {
+      if (start_turn == world.turn)
+        start_turn = 0;
+      if (0 == start_turn) {
+        draw_all_wins (&win_meta);
+        key = getch(); }
+      if (1 == await_actions &&
+          (world.turn < start_turn || key == get_action_key(world.keybindings, "wait / next turn")) ) {
+        action = getc(file);
+        if (EOF == action) {
+          start_turn = 0;
+          await_actions = 0; }
+        else if (0 == action)
+          player_wait (&world);
+        else if (NORTH == action)
+          move_player(&world, NORTH);
+        else if (EAST  == action)
+          move_player(&world, EAST);
+        else if (SOUTH == action)
+          move_player(&world, SOUTH);
+        else if (WEST == action)
+          move_player(&world, WEST); }
+      else
+        quit_called = meta_keys(key, &world, &win_meta, &win_keys, &win_map, &win_info, &win_log);
+        if (1 == quit_called)
+          break; } }
+
+  // Interactive mode.
+  else {
+    uint32_t last_turn = 0;
+    while (1) {
+      if (last_turn != world.turn) {
+        save_game(&world);
+        last_turn = world.turn; }
+      if (1 == await_actions && 0 == player.hitpoints)
+        await_actions = 0;
+      draw_all_wins (&win_meta);
+      key = getch();
+      if      (1 == await_actions && key == get_action_key(world.keybindings, "player up"))
+        move_player(&world, NORTH);
+      else if (1 == await_actions && key == get_action_key(world.keybindings, "player right"))
+        move_player(&world, EAST);
+      else if (1 == await_actions && key == get_action_key(world.keybindings, "player down"))
+        move_player(&world, SOUTH);
+      else if (1 == await_actions && key == get_action_key(world.keybindings, "player left"))
+        move_player(&world, WEST);
+      else if (1 == await_actions && key == get_action_key(world.keybindings, "wait / next turn"))
+        player_wait (&world);
+      else
+        quit_called = meta_keys(key, &world, &win_meta, &win_keys, &win_map, &win_info, &win_log);
+        if (1 == quit_called)
+          break; } }
+
+  // Clean up and exit.
+  free(map.cells);
+  for (key = 0; key <= world.keyswindata->max; key++)
+    free(world.keybindings[key].name);
+  free(world.keybindings);
+  free(world.keyswindata);
+  free(world.log);
+  endwin();
+  return 0; }
diff --git a/src/main.h b/src/main.h
new file mode 100644 (file)
index 0000000..0427e9a
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef ROGUELIKE_H
+#define ROGUELIKE_H
+
+#include <stdint.h>
+
+struct WinMeta;
+struct Win;
+struct KeyBinding;
+struct KeysWinData;
+struct Map;
+
+struct World {
+  char interactive;
+  struct KeyBinding * keybindings;
+  struct KeysWinData * keyswindata;
+  uint32_t seed;
+  uint32_t turn;
+  char * log;
+  struct Map * map;
+  struct Item * item;
+  struct Monster * monster;
+  struct Player * player; };
+
+#endif
index 6ee67746da9f398d5fb411f49d7e07ad44b3aa04..f72482e2d276d718307ed28fe0b66d97452cf752 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -1,7 +1,7 @@
 #include "map.h"
 #include <stdlib.h>
 #include <stdint.h>
-#include "roguelike.h"
+#include "misc.h"
 #include "objects_on_map.h"
 
 struct Map init_map () {
diff --git a/src/misc.c b/src/misc.c
new file mode 100644 (file)
index 0000000..692198d
--- /dev/null
@@ -0,0 +1,152 @@
+#include "misc.h"
+#include <stdlib.h>
+#include <string.h>
+#include "windows.h"
+#include "keybindings.h"
+#include "readwrite.h"
+#include "objects_on_map.h"
+#include "map.h"
+#include "main.h"
+
+uint16_t rrand(char use_seed, uint32_t new_seed) {
+// Pseudo-random number generator (LGC algorithm). Use instead of rand() to ensure portable predictability.
+  static uint32_t seed;
+  if (0 != use_seed)
+    seed = new_seed;
+  seed = ((seed * 1103515245) + 12345) % 2147483648;   // Values as recommended by POSIX.1-2001 (see rand(3)).
+  return (seed / 65536); }                         // Ignore least significant 16 bits (they are less random).
+
+void update_log (struct World * world, char * text) {
+// Update log by appending text, or by appending a "." if text is the same as the last one.
+  static char * last_msg;
+  if (0 == last_msg)
+    last_msg = calloc(1, sizeof(char));
+  char * new_text;
+  uint16_t len_old = strlen(world->log);
+  if (0 == strcmp(last_msg, text)) {
+    uint16_t len_whole = len_old + 1;
+    new_text = calloc(len_whole + 1, sizeof(char));
+    memcpy(new_text, world->log, len_old);
+    memcpy(new_text + len_old, ".", 1); }
+  else {
+    uint16_t len_new = strlen(text);
+    uint16_t len_whole = len_old + len_new + 1;
+    new_text = calloc(len_whole, sizeof(char));
+    memcpy(new_text, world->log, len_old);
+    memcpy(new_text + len_old, text, len_new);
+    last_msg = calloc(len_new + 1, sizeof(char));
+    memcpy(last_msg, text, len_new); }
+  free(world->log);
+  world->log = new_text; }
+
+uint16_t center_offset (uint16_t pos, uint16_t mapsize, uint16_t framesize) {
+// Return the offset for display of a map inside a frame centered on pos.
+  uint16_t offset = 0;
+  if (mapsize > framesize) {
+    if (pos > framesize / 2) {
+      if (pos < mapsize - (framesize / 2))
+        offset = pos - (framesize / 2);
+      else
+        offset = mapsize - framesize; } }
+  return offset; }
+
+void turn_over (struct World * world, char action) {
+// Record action in game record file, increment turn and move enemy.
+  if (1 == world->interactive) {
+    FILE * file = fopen("record", "a");
+    fputc(action, file);
+    fclose(file); }
+  world->turn++;
+  rrand(1, world->seed * world->turn);
+  struct Monster * monster;
+  for (monster = world->monster; monster != 0; monster = monster->cmo.next)
+    move_monster(world, monster); }
+
+void save_game(struct World * world) {
+// Save game data to game file.
+  FILE * file = fopen("savefile", "w");
+  write_uint32_bigendian(world->seed, file);
+  write_uint32_bigendian(world->turn, file);
+  write_uint16_bigendian(world->player->pos.y + 1, file);
+  write_uint16_bigendian(world->player->pos.x + 1, file);
+  fputc(world->player->hitpoints, file);
+  write_map_objects (world->monster, file, write_map_objects_monsterdata);
+  write_map_objects (world->item, file, readwrite_map_objects_dummy);
+  fclose(file); }
+
+void toggle_window (struct WinMeta * win_meta, struct Win * win) {
+// Toggle display of window win.
+  if (0 != win->frame.curses_win)
+    suspend_win(win_meta, win);
+  else
+    append_win(win_meta, win); }
+
+void scroll_pad (struct WinMeta * win_meta, char dir) {
+// Try to scroll pad left or right.
+  if      ('+' == dir)
+    reset_pad_offset(win_meta, win_meta->pad_offset + 1);
+  else if ('-' == dir)
+    reset_pad_offset(win_meta, win_meta->pad_offset - 1); }
+
+void growshrink_active_window (struct WinMeta * win_meta, char change) {
+// Grow or shrink active window horizontally or vertically by one cell size.
+  if (0 != win_meta->active) {
+    struct yx_uint16 size = win_meta->active->frame.size;
+    if      (change == '-') size.y--;
+    else if (change == '+') size.y++;
+    else if (change == '_') size.x--;
+    else if (change == '*') size.x++;
+    resize_active_win (win_meta, size); } }
+
+unsigned char meta_keys(int key, struct World * world, struct WinMeta * win_meta, struct Win * win_keys,
+                        struct Win * win_map, struct Win * win_info, struct Win * win_log) {
+// Call some meta program / window management actions dependent on key. Return 1 to signal quitting.
+  if (key == get_action_key(world->keybindings, "quit"))
+    return 1;
+  else if (key == get_action_key(world->keybindings, "scroll pad right"))
+    scroll_pad (win_meta, '+');
+  else if (key == get_action_key(world->keybindings, "scroll pad left"))
+    scroll_pad (win_meta, '-');
+  else if (key == get_action_key(world->keybindings, "toggle keys window"))
+    toggle_window(win_meta, win_keys);
+  else if (key == get_action_key(world->keybindings, "toggle map window"))
+    toggle_window(win_meta, win_map);
+  else if (key == get_action_key(world->keybindings, "toggle info window"))
+    toggle_window(win_meta, win_info);
+  else if (key == get_action_key(world->keybindings, "toggle log window"))
+    toggle_window(win_meta, win_log);
+  else if (key == get_action_key(world->keybindings, "cycle forwards"))
+    cycle_active_win(win_meta, 'n');
+  else if (key == get_action_key(world->keybindings, "cycle backwards"))
+    cycle_active_win(win_meta, 'p');
+  else if (key == get_action_key(world->keybindings, "shift forwards"))
+    shift_active_win(win_meta, 'f');
+  else if (key == get_action_key(world->keybindings, "shift backwards"))
+    shift_active_win(win_meta, 'b');
+  else if (key == get_action_key(world->keybindings, "grow horizontally"))
+    growshrink_active_window(win_meta, '*');
+  else if (key == get_action_key(world->keybindings, "shrink horizontally"))
+    growshrink_active_window(win_meta, '_');
+  else if (key == get_action_key(world->keybindings, "grow vertically"))
+    growshrink_active_window(win_meta, '+');
+  else if (key == get_action_key(world->keybindings, "shrink vertically"))
+    growshrink_active_window(win_meta, '-');
+  else if (key == get_action_key(world->keybindings, "save keys"))
+    save_keybindings(world);
+  else if (key == get_action_key(world->keybindings, "keys nav up"))
+    keyswin_move_selection (world, 'u');
+  else if (key == get_action_key(world->keybindings, "keys nav down"))
+    keyswin_move_selection (world, 'd');
+  else if (key == get_action_key(world->keybindings, "keys mod"))
+    keyswin_mod_key (world, win_meta);
+  else if (key == get_action_key(world->keybindings, "map up"))
+    map_scroll (world->map, NORTH, win_map->frame.size);
+  else if (key == get_action_key(world->keybindings, "map down"))
+    map_scroll (world->map, SOUTH, win_map->frame.size);
+  else if (key == get_action_key(world->keybindings, "map right"))
+    map_scroll (world->map, EAST, win_map->frame.size);
+  else if (key == get_action_key(world->keybindings, "map left"))
+    map_scroll (world->map, WEST, win_map->frame.size);
+  else if (key == get_action_key(world->keybindings, "map center player"))
+    map_center_player (world->map, world->player, win_map->frame.size);
+  return 0; }
diff --git a/src/misc.h b/src/misc.h
new file mode 100644 (file)
index 0000000..742374c
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef MISC_H
+#define MISC_H
+
+#include <stdint.h>
+
+struct World;
+struct WinMeta;
+struct Win;
+
+extern uint16_t rrand(char, uint32_t);
+extern void update_log (struct World *, char *);
+uint16_t center_offset (uint16_t, uint16_t, uint16_t);
+extern void turn_over (struct World *, char);
+extern void save_game(struct World *);
+extern void toggle_window (struct WinMeta *, struct Win *);
+extern void scroll_pad (struct WinMeta *, char);
+extern void growshrink_active_window (struct WinMeta *, char);
+extern unsigned char meta_keys(int, struct World *, struct WinMeta *, struct Win *, struct Win *, struct Win *, struct Win *);
+
+#endif
index a7d9c32a75b4e78a9b9e3ff7970aa618bd03c560..d74981b6f652ac95f5e0f6430c60761910bf1233 100644 (file)
@@ -3,8 +3,9 @@
 #include <stdio.h>
 #include "yx_uint16.h"
 #include "readwrite.h"
-#include "roguelike.h"
+#include "misc.h"
 #include "map.h"
+#include "main.h"
 
 static struct ChainMapObject * get_next_cmo (void *, char *, size_t, struct ChainMapObject *);
 
diff --git a/src/roguelike.c b/src/roguelike.c
deleted file mode 100644 (file)
index 0ec8194..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-#include "roguelike.h"
-#include <stdlib.h>
-#include <ncurses.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-#include "windows.h"
-#include "draw_wins.h"
-#include "keybindings.h"
-#include "readwrite.h"
-#include "objects_on_map.h"
-#include "map.h"
-
-uint16_t rrand(char use_seed, uint32_t new_seed) {
-// Pseudo-random number generator (LGC algorithm). Use instead of rand() to ensure portable predictability.
-  static uint32_t seed;
-  if (0 != use_seed)
-    seed = new_seed;
-  seed = ((seed * 1103515245) + 12345) % 2147483648;   // Values as recommended by POSIX.1-2001 (see rand(3)).
-  return (seed / 65536); }                         // Ignore least significant 16 bits (they are less random).
-
-void update_log (struct World * world, char * text) {
-// Update log by appending text, or by appending a "." if text is the same as the last one.
-  static char * last_msg;
-  if (0 == last_msg)
-    last_msg = calloc(1, sizeof(char));
-  char * new_text;
-  uint16_t len_old = strlen(world->log);
-  if (0 == strcmp(last_msg, text)) {
-    uint16_t len_whole = len_old + 1;
-    new_text = calloc(len_whole + 1, sizeof(char));
-    memcpy(new_text, world->log, len_old);
-    memcpy(new_text + len_old, ".", 1); }
-  else {
-    uint16_t len_new = strlen(text);
-    uint16_t len_whole = len_old + len_new + 1;
-    new_text = calloc(len_whole, sizeof(char));
-    memcpy(new_text, world->log, len_old);
-    memcpy(new_text + len_old, text, len_new);
-    last_msg = calloc(len_new + 1, sizeof(char));
-    memcpy(last_msg, text, len_new); }
-  free(world->log);
-  world->log = new_text; }
-
-uint16_t center_offset (uint16_t pos, uint16_t mapsize, uint16_t framesize) {
-// Return the offset for display of a map inside a frame centered on pos.
-  uint16_t offset = 0;
-  if (mapsize > framesize) {
-    if (pos > framesize / 2) {
-      if (pos < mapsize - (framesize / 2))
-        offset = pos - (framesize / 2);
-      else
-        offset = mapsize - framesize; } }
-  return offset; }
-
-void turn_over (struct World * world, char action) {
-// Record action in game record file, increment turn and move enemy.
-  if (1 == world->interactive) {
-    FILE * file = fopen("record", "a");
-    fputc(action, file);
-    fclose(file); }
-  world->turn++;
-  rrand(1, world->seed * world->turn);
-  struct Monster * monster;
-  for (monster = world->monster; monster != 0; monster = monster->cmo.next)
-    move_monster(world, monster); }
-
-void save_game(struct World * world) {
-// Save game data to game file.
-  FILE * file = fopen("savefile", "w");
-  write_uint32_bigendian(world->seed, file);
-  write_uint32_bigendian(world->turn, file);
-  write_uint16_bigendian(world->player->pos.y + 1, file);
-  write_uint16_bigendian(world->player->pos.x + 1, file);
-  fputc(world->player->hitpoints, file);
-  write_map_objects (world->monster, file, write_map_objects_monsterdata);
-  write_map_objects (world->item, file, readwrite_map_objects_dummy);
-  fclose(file); }
-
-void toggle_window (struct WinMeta * win_meta, struct Win * win) {
-// Toggle display of window win.
-  if (0 != win->frame.curses_win)
-    suspend_win(win_meta, win);
-  else
-    append_win(win_meta, win); }
-
-void scroll_pad (struct WinMeta * win_meta, char dir) {
-// Try to scroll pad left or right.
-  if      ('+' == dir)
-    reset_pad_offset(win_meta, win_meta->pad_offset + 1);
-  else if ('-' == dir)
-    reset_pad_offset(win_meta, win_meta->pad_offset - 1); }
-
-void growshrink_active_window (struct WinMeta * win_meta, char change) {
-// Grow or shrink active window horizontally or vertically by one cell size.
-  if (0 != win_meta->active) {
-    struct yx_uint16 size = win_meta->active->frame.size;
-    if      (change == '-') size.y--;
-    else if (change == '+') size.y++;
-    else if (change == '_') size.x--;
-    else if (change == '*') size.x++;
-    resize_active_win (win_meta, size); } }
-
-unsigned char meta_keys(int key, struct World * world, struct WinMeta * win_meta, struct Win * win_keys,
-                        struct Win * win_map, struct Win * win_info, struct Win * win_log) {
-// Call some meta program / window management actions dependent on key. Return 1 to signal quitting.
-  if (key == get_action_key(world->keybindings, "quit"))
-    return 1;
-  else if (key == get_action_key(world->keybindings, "scroll pad right"))
-    scroll_pad (win_meta, '+');
-  else if (key == get_action_key(world->keybindings, "scroll pad left"))
-    scroll_pad (win_meta, '-');
-  else if (key == get_action_key(world->keybindings, "toggle keys window"))
-    toggle_window(win_meta, win_keys);
-  else if (key == get_action_key(world->keybindings, "toggle map window"))
-    toggle_window(win_meta, win_map);
-  else if (key == get_action_key(world->keybindings, "toggle info window"))
-    toggle_window(win_meta, win_info);
-  else if (key == get_action_key(world->keybindings, "toggle log window"))
-    toggle_window(win_meta, win_log);
-  else if (key == get_action_key(world->keybindings, "cycle forwards"))
-    cycle_active_win(win_meta, 'n');
-  else if (key == get_action_key(world->keybindings, "cycle backwards"))
-    cycle_active_win(win_meta, 'p');
-  else if (key == get_action_key(world->keybindings, "shift forwards"))
-    shift_active_win(win_meta, 'f');
-  else if (key == get_action_key(world->keybindings, "shift backwards"))
-    shift_active_win(win_meta, 'b');
-  else if (key == get_action_key(world->keybindings, "grow horizontally"))
-    growshrink_active_window(win_meta, '*');
-  else if (key == get_action_key(world->keybindings, "shrink horizontally"))
-    growshrink_active_window(win_meta, '_');
-  else if (key == get_action_key(world->keybindings, "grow vertically"))
-    growshrink_active_window(win_meta, '+');
-  else if (key == get_action_key(world->keybindings, "shrink vertically"))
-    growshrink_active_window(win_meta, '-');
-  else if (key == get_action_key(world->keybindings, "save keys"))
-    save_keybindings(world);
-  else if (key == get_action_key(world->keybindings, "keys nav up"))
-    keyswin_move_selection (world, 'u');
-  else if (key == get_action_key(world->keybindings, "keys nav down"))
-    keyswin_move_selection (world, 'd');
-  else if (key == get_action_key(world->keybindings, "keys mod"))
-    keyswin_mod_key (world, win_meta);
-  else if (key == get_action_key(world->keybindings, "map up"))
-    map_scroll (world->map, NORTH, win_map->frame.size);
-  else if (key == get_action_key(world->keybindings, "map down"))
-    map_scroll (world->map, SOUTH, win_map->frame.size);
-  else if (key == get_action_key(world->keybindings, "map right"))
-    map_scroll (world->map, EAST, win_map->frame.size);
-  else if (key == get_action_key(world->keybindings, "map left"))
-    map_scroll (world->map, WEST, win_map->frame.size);
-  else if (key == get_action_key(world->keybindings, "map center player"))
-    map_center_player (world->map, world->player, win_map->frame.size);
-  return 0; }
-
-int main (int argc, char *argv[]) {
-  struct World world;
-
-  // Read in startup options (i.e. replay option and replay start turn).
-  int opt;
-  uint32_t start_turn;
-  world.interactive = 1;
-  while ((opt = getopt(argc, argv, "s::")) != -1) {
-    switch (opt) {
-      case 's':
-        world.interactive = 0;
-        start_turn = 0;
-        if (optarg)
-          start_turn = atoi(optarg);
-        break;
-      default:
-        exit(EXIT_FAILURE); } }
-
-  // Initialize log, player, monsters and items.
-  world.log = calloc(1, sizeof(char));
-  update_log (&world, " ");
-  struct Player player;
-  player.hitpoints = 5;
-  world.player = &player;
-  world.monster = 0;
-  world.item = 0;
-
-  // For interactive mode, try to load world state from savefile.
-  FILE * file;
-  if (1 == world.interactive && 0 == access("savefile", F_OK)) {
-    file = fopen("savefile", "r");
-    world.seed = read_uint32_bigendian(file);
-    world.turn = read_uint32_bigendian(file);
-    player.pos.y = read_uint16_bigendian(file) - 1;
-    player.pos.x = read_uint16_bigendian(file) - 1;
-    player.hitpoints = fgetc(file);
-    read_map_objects (&world.monster, file, sizeof(struct Monster), read_map_objects_monsterdata);
-    read_map_objects (&world.item,    file, sizeof(struct Item),    readwrite_map_objects_dummy);
-    fclose(file); }
-
-  // For non-interactive mode, try to load world state from record file.
-  else {
-    world.turn = 1;
-    if (0 == world.interactive) {
-      file = fopen("record", "r");
-      world.seed = read_uint32_bigendian(file); }
-
-    // For interactive-mode in newly started world, generate a start seed from the current time.
-    else {
-      file = fopen("record", "w");
-      world.seed = time(NULL);
-      write_uint32_bigendian(world.seed, file);
-      fclose(file); } }
-
-  // Generate map from seed and, if newly generated world, start positions of actors.
-  rrand(1, world.seed);
-  struct Map map = init_map();
-  world.map = &map;
-  if (1 == world.turn) {
-    player.pos = find_passable_pos(&map);
-    unsigned char n_monsters = rrand(0, 0) % 16;
-    unsigned char n_items    = rrand(0, 0) % 48;
-    build_map_objects (&world.monster, n_monsters, sizeof(struct Monster), build_map_objects_monsterdata, &map);
-    build_map_objects (&world.item,    n_items,    sizeof(struct Item),    build_map_objects_itemdata,    &map); }
-
-  // Initialize window system and windows.
-  WINDOW * screen = initscr();
-  noecho();
-  curs_set(0);
-  keypad(screen, TRUE);
-  raw();
-  init_keybindings(&world);
-  struct WinMeta win_meta = init_win_meta(screen);
-  struct Win win_keys = init_win(&win_meta, "Keys", &world, draw_keys_win);
-  struct Win win_map = init_win(&win_meta, "Map", &world, draw_map_win);
-  struct Win win_info = init_win(&win_meta, "Info", &world, draw_info_win);
-  struct Win win_log = init_win(&win_meta, "Log", &world, draw_log_win);
-  win_keys.frame.size.x = 29;
-  win_map.frame.size.x = win_meta.pad.size.x - win_keys.frame.size.x - win_log.frame.size.x - 2;
-  win_info.frame.size.y = 2;
-  win_log.frame.size.y = win_meta.pad.size.y - (2 + win_info.frame.size.y);
-  toggle_window(&win_meta, &win_keys);
-  toggle_window(&win_meta, &win_map);
-  toggle_window(&win_meta, &win_info);
-  toggle_window(&win_meta, &win_log);
-
-  // Replay mode.
-  int key;
-  unsigned char quit_called = 0;
-  unsigned char await_actions = 1;
-  if (0 == world.interactive) {
-    int action;
-    while (1) {
-      if (start_turn == world.turn)
-        start_turn = 0;
-      if (0 == start_turn) {
-        draw_all_wins (&win_meta);
-        key = getch(); }
-      if (1 == await_actions &&
-          (world.turn < start_turn || key == get_action_key(world.keybindings, "wait / next turn")) ) {
-        action = getc(file);
-        if (EOF == action) {
-          start_turn = 0;
-          await_actions = 0; }
-        else if (0 == action)
-          player_wait (&world);
-        else if (NORTH == action)
-          move_player(&world, NORTH);
-        else if (EAST  == action)
-          move_player(&world, EAST);
-        else if (SOUTH == action)
-          move_player(&world, SOUTH);
-        else if (WEST == action)
-          move_player(&world, WEST); }
-      else
-        quit_called = meta_keys(key, &world, &win_meta, &win_keys, &win_map, &win_info, &win_log);
-        if (1 == quit_called)
-          break; } }
-
-  // Interactive mode.
-  else {
-    uint32_t last_turn = 0;
-    while (1) {
-      if (last_turn != world.turn) {
-        save_game(&world);
-        last_turn = world.turn; }
-      if (1 == await_actions && 0 == player.hitpoints)
-        await_actions = 0;
-      draw_all_wins (&win_meta);
-      key = getch();
-      if      (1 == await_actions && key == get_action_key(world.keybindings, "player up"))
-        move_player(&world, NORTH);
-      else if (1 == await_actions && key == get_action_key(world.keybindings, "player right"))
-        move_player(&world, EAST);
-      else if (1 == await_actions && key == get_action_key(world.keybindings, "player down"))
-        move_player(&world, SOUTH);
-      else if (1 == await_actions && key == get_action_key(world.keybindings, "player left"))
-        move_player(&world, WEST);
-      else if (1 == await_actions && key == get_action_key(world.keybindings, "wait / next turn"))
-        player_wait (&world);
-      else
-        quit_called = meta_keys(key, &world, &win_meta, &win_keys, &win_map, &win_info, &win_log);
-        if (1 == quit_called)
-          break; } }
-
-  // Clean up and exit.
-  free(map.cells);
-  for (key = 0; key <= world.keyswindata->max; key++)
-    free(world.keybindings[key].name);
-  free(world.keybindings);
-  free(world.keyswindata);
-  free(world.log);
-  endwin();
-  return 0; }
diff --git a/src/roguelike.h b/src/roguelike.h
deleted file mode 100644 (file)
index 209f717..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ROGUELIKE_H
-#define ROGUELIKE_H
-
-#include <stdint.h>
-
-struct WinMeta;
-struct Win;
-struct KeyBinding;
-struct KeysWinData;
-struct Map;
-
-struct World {
-  char interactive;
-  struct KeyBinding * keybindings;
-  struct KeysWinData * keyswindata;
-  uint32_t seed;
-  uint32_t turn;
-  char * log;
-  struct Map * map;
-  struct Item * item;
-  struct Monster * monster;
-  struct Player * player; };
-
-extern uint16_t rrand(char, uint32_t);
-extern void update_log (struct World *, char *);
-
-uint16_t center_offset (uint16_t, uint16_t, uint16_t);
-
-extern void turn_over (struct World *, char);
-extern void save_game(struct World *);
-
-extern void toggle_window (struct WinMeta *, struct Win *);
-extern void scroll_pad (struct WinMeta *, char);
-extern void growshrink_active_window (struct WinMeta *, char);
-
-extern unsigned char meta_keys(int, struct World *, struct WinMeta *, struct Win *, struct Win *, struct Win *, struct Win *);
-
-#endif