From a470e49ace2874380e6018a6166dd2a61e3c689c Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Thu, 23 May 2013 11:34:53 +0200
Subject: [PATCH] Moved draw_*_win() into its own library. Removed some
 unneeded libray includes.

---
 Makefile    |   3 +-
 draw_wins.c | 132 +++++++++++++++++++++++++++++++++++++
 draw_wins.h |   6 ++
 draw_wins.o | Bin 0 -> 13352 bytes
 roguelike.c | 185 +---------------------------------------------------
 5 files changed, 142 insertions(+), 184 deletions(-)
 create mode 100644 draw_wins.c
 create mode 100644 draw_wins.h
 create mode 100644 draw_wins.o

diff --git a/Makefile b/Makefile
index 0bcd8e8..5b7f7d9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,8 @@
 roguelike:
 	cc -Wall -g -o windows.o -c windows.c
+	cc -Wall -g -o draw_wins.o -c draw_wins.c
 	cc -Wall -g -o roguelike.o -c roguelike.c
-	cc -Wall -g -o roguelike windows.o roguelike.o -lncurses
+	cc -Wall -g -o roguelike windows.o draw_wins.o roguelike.o -lncurses
 
 clean:
 	rm *.o; rm roguelike
diff --git a/draw_wins.c b/draw_wins.c
new file mode 100644
index 0000000..3eaf491
--- /dev/null
+++ b/draw_wins.c
@@ -0,0 +1,132 @@
+#include <ncurses.h>
+#include <string.h>
+#include <stdlib.h>
+#include "windows.h"
+#include "roguelike.h"
+
+void draw_with_linebreaks (struct Win * win, char * text, int start_y) {
+// Write text into window content space. Start on row start_y. Fill unused rows with whitespace.
+  int x, y;
+  char toggle;
+  char fin = 0;
+  int z = -1;
+  for (y = start_y; y < win->height; y++) {
+    if (0 == fin)
+      toggle = 0;
+    for (x = 0; x < win->width; x++) {
+       if (0 == toggle) {
+         z++;
+         if ('\n' == text[z]) {
+           toggle = 1;
+           continue; }
+         else
+           mvwaddch(win->curses, y, x, text[z]);
+         if ('\n' == text[z+1]) {
+           z++;
+           toggle = 1; }
+         else if (0 == text[z+1]) {
+            toggle = 1;
+            fin = 1; } } } } }
+
+void draw_text_from_bottom (struct Win * win, char * text) {
+// Draw text from end/bottom to the top.
+  char toggle = 0;
+  int x, y, offset;
+  int z = -1;
+  for (y = 0; 0 == toggle; y++)                           // Determine number of lines text would have in
+    for (x = 0; x < win->width; x++) {                    // a window of available width, but infinite height.
+      z++;
+      if ('\n' == text[z])            // Treat \n and \0 as control characters for incrementing y and stopping
+        break;                        // the loop. Make sure they don't count as cell space themselves.
+      if ('\n' == text[z+1]) {
+        z++;
+        break; }
+      else if (0 == text[z+1]) {
+        toggle = 1;
+        break; } }
+  z = -1;
+  int start_y = 0;
+  if (y < win->height)             // Depending on what is bigger, determine start point in window or in text.
+    start_y = win->height - y;
+  else if (y > win->height) {
+    offset = y - win->height;
+    for (y = 0; y < offset; y++)
+      for (x = 0; x < win->width; x++) {
+        z++;
+        if ('\n' == text[z])
+          break;
+        if ('\n' == text[z+1]) {
+          z++;
+          break; } }
+    text = text + (sizeof(char) * (z + 1)); }
+  draw_with_linebreaks(win, text, start_y); }
+
+void draw_log_win (struct Win * win) {
+// Draw log text from world struct in win->data from bottom to top.
+  struct World * world = (struct World *) win->data;
+  draw_text_from_bottom(win, world->log); }
+
+void draw_map_win (struct Win * win) {
+// Draw map determined by win->data Map struct into window. Respect offset.
+  struct World * world = (struct World *) win->data;
+  struct Map * map = world->map;
+  struct Player * player = world->player;
+  struct Monster * monster = world->monster;
+  char * cells = map->cells;
+  int width_map_av = map->width - map->offset_x;
+  int height_map_av = map->height - map->offset_y;
+  int x, y, z;
+  for (y = 0; y < win->height; y++) {
+    z = map->offset_x + (map->offset_y + y) * (map->width);
+    for (x = 0; x < win->width; x++) {
+      if (y < height_map_av && x < width_map_av) {
+        if (z == (map->width * player->y) + player->x)
+          mvwaddch(win->curses, y, x, '@');
+        else if (z == (map->width * monster->y) + monster->x)
+          mvwaddch(win->curses, y, x, 'M');
+        else
+          mvwaddch(win->curses, y, x, cells[z]);
+        z++; } } } }
+
+void draw_info_win (struct Win * win) {
+// Draw info window by appending win->data integer value to "Turn: " display.
+  struct World * world = (struct World *) win->data;
+  int count = world->turn;
+  char text[100];
+  snprintf(text, 100, "Turn: %d", count);
+  draw_with_linebreaks(win, text, 0); }
+
+void draw_keys_win (struct Win * win) {
+// Draw keybinding window.
+  struct World * world = (struct World *) win->data;
+  struct KeysWinData * keyswindata = (struct KeysWinData *) world->keyswindata;
+  struct KeyBinding * keybindings = world->keybindings;
+  int offset = 0;
+  if (keyswindata->max >= win->height) {
+    if (keyswindata->select > win->height / 2) {
+      if (keyswindata->select < (keyswindata->max - (win->height / 2)))
+        offset = keyswindata->select - (win->height / 2);
+      else
+        offset = keyswindata->max - win->height + 1; } }
+  int keydescwidth = 9 + 1; // max length assured by get_keyname() + \0
+  char * keydesc = malloc(keydescwidth);
+  attr_t attri;
+  int y, x;
+  char * keyname;
+  for (y = 0; y <= keyswindata->max && y < win->height; y++) {
+    attri = 0;
+    if (y == keyswindata->select - offset) {
+      attri = A_REVERSE;
+      if (1 == keyswindata->edit)
+        attri = attri | A_BLINK; }
+    keyname = get_keyname(keybindings[y + offset].key);
+    snprintf(keydesc, keydescwidth, "%-9s", keyname);
+    free(keyname);
+    for (x = 0; x < win->width; x++)
+      if (x < strlen(keydesc))
+        mvwaddch(win->curses, y, x, keydesc[x] | attri);
+      else if (strlen(keydesc) < x && x < strlen(keybindings[y + offset].name) + strlen(keydesc) + 1)
+        mvwaddch(win->curses, y, x, keybindings[y + offset].name[x - strlen(keydesc) - 1] | attri);
+      else
+        mvwaddch(win->curses, y, x, ' ' | attri); }
+  free(keydesc); }
diff --git a/draw_wins.h b/draw_wins.h
new file mode 100644
index 0000000..39c5ce9
--- /dev/null
+++ b/draw_wins.h
@@ -0,0 +1,6 @@
+void draw_with_linebreaks (struct Win *, char *, int);
+void draw_text_from_bottom (struct Win *, char *);
+void draw_log_win (struct Win *);
+void draw_map_win (struct Win *);
+void draw_info_win (struct Win *);
+void draw_keys_win (struct Win *);
diff --git a/draw_wins.o b/draw_wins.o
new file mode 100644
index 0000000000000000000000000000000000000000..e373125946f0d58d764e68c335c72ff349bcb793
GIT binary patch
literal 13352
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

literal 0
HcmV?d00001

diff --git a/roguelike.c b/roguelike.c
index e387daf..8235d7c 100644
--- a/roguelike.c
+++ b/roguelike.c
@@ -1,190 +1,9 @@
 #include <ncurses.h>
 #include <string.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include "windows.h"
-
-struct World {
-  struct KeyBinding * keybindings;
-  struct KeysWinData * keyswindata;
-  int turn;
-  char * log;
-  struct Map * map;
-  struct Monster * monster;
-  struct Player * player; };
-
-struct KeyBinding {
-  char * name;
-  int key; };
-
-struct KeysWinData {
-  int max;
-  char edit;
-  int select; };
-
-struct Map {
-  int width;
-  int height;
-  int offset_x;
-  int offset_y;
-  char * cells; };
-
-struct Player {
-  int y;
-  int x; };
-
-struct Monster {
-  int y;
-  int x; };
-
-void draw_with_linebreaks (struct Win *, char *, int);
-void draw_text_from_bottom (struct Win *, char *);
-void draw_log_win (struct Win *);
-void draw_map_win (struct Win *);
-void draw_info_win (struct Win *);
-void draw_keys_win (struct Win *);
-void toggle_window (struct WinMeta *, struct Win *);
-void growshrink_active_window (struct WinMeta *, char);
-void init_keybindings(struct World *);
-struct Map init_map ();
-void map_scroll (struct Map *, char);
-void next_turn (struct World *);
-void update_log (struct World *, char *);
-void save_keybindings(struct World *);
-int get_action_key (struct KeyBinding *, char *);
-char * get_keyname(int);
-void keyswin_mod_key (struct World *, struct WinMeta *);
-void keyswin_move_selection (struct World *, char);
-char is_passable (struct World *, int, int);
-void move_player (struct World *, char);
-void player_wait(struct World *);
-
-void draw_with_linebreaks (struct Win * win, char * text, int start_y) {
-// Write text into window content space. Start on row start_y. Fill unused rows with whitespace.
-  int x, y;
-  char toggle;
-  char fin = 0;
-  int z = -1;
-  for (y = start_y; y < win->height; y++) {
-    if (0 == fin)
-      toggle = 0;
-    for (x = 0; x < win->width; x++) {
-       if (0 == toggle) {
-         z++;
-         if ('\n' == text[z]) {
-           toggle = 1;
-           continue; }
-         else
-           mvwaddch(win->curses, y, x, text[z]);
-         if ('\n' == text[z+1]) {
-           z++;
-           toggle = 1; }
-         else if (0 == text[z+1]) {
-            toggle = 1;
-            fin = 1; } } } } }
-
-void draw_text_from_bottom (struct Win * win, char * text) {
-// Draw text from end/bottom to the top.
-  char toggle = 0;
-  int x, y, offset;
-  int z = -1;
-  for (y = 0; 0 == toggle; y++)                           // Determine number of lines text would have in
-    for (x = 0; x < win->width; x++) {                    // a window of available width, but infinite height.
-      z++;
-      if ('\n' == text[z])            // Treat \n and \0 as control characters for incrementing y and stopping
-        break;                        // the loop. Make sure they don't count as cell space themselves.
-      if ('\n' == text[z+1]) {
-        z++;
-        break; }
-      else if (0 == text[z+1]) {
-        toggle = 1;
-        break; } }
-  z = -1;
-  int start_y = 0;
-  if (y < win->height)             // Depending on what is bigger, determine start point in window or in text.
-    start_y = win->height - y;
-  else if (y > win->height) {
-    offset = y - win->height;
-    for (y = 0; y < offset; y++)
-      for (x = 0; x < win->width; x++) {
-        z++;
-        if ('\n' == text[z])
-          break;
-        if ('\n' == text[z+1]) {
-          z++;
-          break; } }
-    text = text + (sizeof(char) * (z + 1)); }
-  draw_with_linebreaks(win, text, start_y); }
-
-void draw_log_win (struct Win * win) {
-// Draw log text from world struct in win->data from bottom to top.
-  struct World * world = (struct World *) win->data;
-  draw_text_from_bottom(win, world->log); }
-
-void draw_map_win (struct Win * win) {
-// Draw map determined by win->data Map struct into window. Respect offset.
-  struct World * world = (struct World *) win->data;
-  struct Map * map = world->map;
-  struct Player * player = world->player;
-  struct Monster * monster = world->monster;
-  char * cells = map->cells;
-  int width_map_av = map->width - map->offset_x;
-  int height_map_av = map->height - map->offset_y;
-  int x, y, z;
-  for (y = 0; y < win->height; y++) {
-    z = map->offset_x + (map->offset_y + y) * (map->width);
-    for (x = 0; x < win->width; x++) {
-      if (y < height_map_av && x < width_map_av) {
-        if (z == (map->width * player->y) + player->x)
-          mvwaddch(win->curses, y, x, '@');
-        else if (z == (map->width * monster->y) + monster->x)
-          mvwaddch(win->curses, y, x, 'M');
-        else
-          mvwaddch(win->curses, y, x, cells[z]);
-        z++; } } } }
-
-void draw_info_win (struct Win * win) {
-// Draw info window by appending win->data integer value to "Turn: " display.
-  struct World * world = (struct World *) win->data;
-  int count = world->turn;
-  char text[100];
-  snprintf(text, 100, "Turn: %d", count);
-  draw_with_linebreaks(win, text, 0); }
-
-void draw_keys_win (struct Win * win) {
-// Draw keybinding window.
-  struct World * world = (struct World *) win->data;
-  struct KeysWinData * keyswindata = (struct KeysWinData *) world->keyswindata;
-  struct KeyBinding * keybindings = world->keybindings;
-  int offset = 0;
-  if (keyswindata->max >= win->height) {
-    if (keyswindata->select > win->height / 2) {
-      if (keyswindata->select < (keyswindata->max - (win->height / 2)))
-        offset = keyswindata->select - (win->height / 2);
-      else
-        offset = keyswindata->max - win->height + 1; } }
-  int keydescwidth = 9 + 1; // max length assured by get_keyname() + \0
-  char * keydesc = malloc(keydescwidth);
-  attr_t attri;
-  int y, x;
-  char * keyname;
-  for (y = 0; y <= keyswindata->max && y < win->height; y++) {
-    attri = 0;
-    if (y == keyswindata->select - offset) {
-      attri = A_REVERSE;
-      if (1 == keyswindata->edit)
-        attri = attri | A_BLINK; }
-    keyname = get_keyname(keybindings[y + offset].key);
-    snprintf(keydesc, keydescwidth, "%-9s", keyname);
-    free(keyname);
-    for (x = 0; x < win->width; x++)
-      if (x < strlen(keydesc))
-        mvwaddch(win->curses, y, x, keydesc[x] | attri);
-      else if (strlen(keydesc) < x && x < strlen(keybindings[y + offset].name) + strlen(keydesc) + 1)
-        mvwaddch(win->curses, y, x, keybindings[y + offset].name[x - strlen(keydesc) - 1] | attri);
-      else
-        mvwaddch(win->curses, y, x, ' ' | attri); }
-  free(keydesc); }
+#include "draw_wins.h"
+#include "roguelike.h"
 
 void toggle_window (struct WinMeta * win_meta, struct Win * win) {
 // Toggle display of window win.
-- 
2.30.2