--- /dev/null
+#include <curses.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.h"
+#include "function.h"
+#include "type.h"
+
+#include "display.h"
+
+typedef enum {
+ white = 1,
+ red,
+ green,
+ blue,
+ cyan,
+ magenta,
+ yellow,
+ bred,
+ bgreen,
+ bblue,
+ bcyan,
+ bmagenta,
+ byellow,
+ black,
+ wred,
+ wgreen,
+ wblue,
+ wcyan,
+ wmagenta,
+ wyellow,
+} color_t;
+
+void set_color (color_t color)
+{
+ static int init = 1;
+
+ if (init) {
+ init_pair (white, COLOR_WHITE, COLOR_BLACK);
+ init_pair (red, COLOR_RED, COLOR_BLACK);
+ init_pair (green, COLOR_GREEN, COLOR_BLACK);
+ init_pair (blue, COLOR_BLUE, COLOR_BLACK);
+ init_pair (magenta, COLOR_MAGENTA, COLOR_BLACK);
+ init_pair (yellow, COLOR_YELLOW, COLOR_BLACK);
+ init_pair (cyan, COLOR_CYAN, COLOR_BLACK);
+ init_pair (bred, COLOR_BLACK, COLOR_RED);
+ init_pair (bgreen, COLOR_BLACK, COLOR_GREEN);
+ init_pair (bblue, COLOR_BLACK, COLOR_BLUE);
+ init_pair (bmagenta, COLOR_BLACK, COLOR_MAGENTA);
+ init_pair (byellow, COLOR_BLACK, COLOR_YELLOW);
+ init_pair (bcyan, COLOR_BLACK, COLOR_CYAN);
+ init_pair (black, COLOR_BLACK, COLOR_WHITE);
+ init_pair (wred, COLOR_WHITE, COLOR_RED);
+ init_pair (wgreen, COLOR_WHITE, COLOR_GREEN);
+ init_pair (wblue, COLOR_WHITE, COLOR_BLUE);
+ init_pair (wcyan, COLOR_WHITE, COLOR_CYAN);
+ init_pair (wmagenta, COLOR_WHITE, COLOR_MAGENTA);
+ init_pair (wyellow, COLOR_WHITE, COLOR_YELLOW);
+ init = 0;
+ }
+
+ attrset (COLOR_PAIR(color));
+}
+
+int _helpwindow (char *msg, int xoffset, int yoffset, int length)
+{
+ int i = 0;
+ int j = 0;
+ while ((msg) && (*msg != '\0')) {
+ if ((*msg == '\n') || (i == length)) {
+ i = 0;
+ j++;
+ }
+ if (*msg != '\n') {
+ mvaddch (yoffset + j, xoffset + i, *msg);
+ i++;
+ }
+ msg++;
+ }
+ return j;
+}
+
+void _displaytitle (char *title, int xoffset, int yoffset)
+{
+ int i;
+ for (i = 0; title[i] != '\0'; i++) {
+ mvaddch (yoffset, xoffset + i, title[i]);
+ mvaddch (yoffset + 1, xoffset + i, ACS_HLINE);
+ }
+}
+
+void _dobound (int xsize, int ysize, int xoffset, int yoffset)
+{
+ int i, j;
+
+ for (i = 0; i < xsize; i++) {
+ mvaddch (yoffset - 1, xoffset + i, ACS_HLINE);
+ mvaddch (yoffset + ysize, xoffset + i, ACS_HLINE);
+ }
+ for (j = 0; j < ysize; j++) {
+ mvaddch (yoffset + j, xoffset - 1, ACS_VLINE);
+ mvaddch (yoffset + j, xoffset + xsize, ACS_VLINE);
+ }
+ mvaddch (yoffset - 1, xoffset - 1, ACS_ULCORNER);
+ mvaddch (yoffset + ysize, xoffset - 1, ACS_LLCORNER);
+ mvaddch (yoffset - 1, xoffset + xsize, ACS_URCORNER);
+ mvaddch (yoffset + ysize, xoffset + xsize, ACS_LRCORNER);
+}
+
+int helpwindow (char *msg, int xoffset, int yoffset)
+{
+ _displaytitle ("Help message", xoffset, yoffset);
+ int length = strmaxlen (msg, '\n');
+ int j = 2;
+ j += _helpwindow (msg, xoffset, yoffset + j, length);
+
+ return j;
+}
+
+void _set_symb_color (int symb)
+{
+ set_color (white);
+ switch (symb) {
+ case '$': /* box */
+ set_color (red);
+ break;
+ case '*': /* box docked */
+ case '+': /* sokoban on dock */
+ set_color (cyan);
+ break;
+ case '@': /* sokoban */
+ set_color (green);
+ break;
+ case '#': /* wall */
+ set_color (black);
+ break;
+ }
+}
+
+void _element0 (board_t *board, int x, int y, int symb)
+{
+ int element = ' ';
+ switch (symb) {
+ case '$': /* box */
+ case '*': /* box docked */
+ element = ACS_DIAMOND;
+ break;
+ case '.': /* empty dock */
+ element = 'X';
+ break;
+ }
+ _set_symb_color (symb);
+ mvaddch (board->yoffset + y, board->xoffset + x, element);
+ set_color (white);
+}
+
+void _element1 (board_t *board, int x, int y, int symb)
+{
+ int element0 = ' ';
+ int element1 = ' ';
+ switch (symb) {
+ case '$':
+ case '*':
+ element0 = ACS_LARROW;
+ element1 = ACS_RARROW;
+ break;
+ case '.':
+ element0 = '-';
+ element1 = '-';
+ }
+ _set_symb_color (symb);
+ mvaddch (board->yoffset + y, board->xoffset + 2 * x, element0);
+ mvaddch (board->yoffset + y, board->xoffset + 2 * x + 1, element1);
+ set_color (white);
+}
+
+void _element2 (board_t *board, int x, int y, int symb)
+{
+ int element00 = ' ';
+ int element10 = ' ';
+ int element01 = ' ';
+ int element11 = ' ';
+ switch (symb) {
+ case '$':
+ case '*':
+ element00 = ACS_ULCORNER;
+ element01 = ACS_URCORNER;
+ element10 = ACS_LLCORNER;
+ element11 = ACS_LRCORNER;
+ break;
+ case '.':
+ element00 = '.';
+ element01 = '.';
+ element10 = '.';
+ element11 = '.';
+ }
+ _set_symb_color (symb);
+ mvaddch (board->yoffset + 2 * y, board->xoffset + 2 * x, element00);
+ mvaddch (board->yoffset + 2 * y, board->xoffset + 2 * x + 1, element01);
+ mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 2 * x, element10);
+ mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 2 * x + 1, element11);
+ set_color (white);
+}
+
+void _element3 (board_t *board, int x, int y, int symb)
+{
+ int element00 = ' ';
+ int element10 = ' ';
+ int element01 = ' ';
+ int element11 = ' ';
+ int element02 = ' ';
+ int element12 = ' ';
+ switch (symb) {
+ case '$':
+ case '*':
+ element00 = ACS_ULCORNER;
+ element01 = ACS_HLINE;
+ element02 = ACS_URCORNER;
+ element10 = ACS_LLCORNER;
+ element11 = ACS_HLINE;
+ element12 = ACS_LRCORNER;
+ break;
+ case '.':
+ element00 = ACS_VLINE;
+ element01 = ' ';
+ element02 = ACS_VLINE;
+ element10 = ACS_LLCORNER;
+ element11 = ACS_HLINE;
+ element12 = ACS_LRCORNER;
+ break;
+ }
+ _set_symb_color (symb);
+ mvaddch (board->yoffset + 2 * y, board->xoffset + 3 * x, element00);
+ mvaddch (board->yoffset + 2 * y, board->xoffset + 3 * x + 1, element01);
+ mvaddch (board->yoffset + 2 * y, board->xoffset + 3 * x + 2, element02);
+ mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 3 * x, element10);
+ mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 3 * x + 1, element11);
+ mvaddch (board->yoffset + 2 * y + 1, board->xoffset + 3 * x + 2, element12);
+ set_color (white);
+}
+
+void _element (board_t *board, int x, int y, int symb)
+{
+ switch (board->scale) {
+ case 0:
+ _element0 (board, x, y, symb);
+ break;
+ case 1:
+ _element1 (board, x, y, symb);
+ break;
+ case 2:
+ _element2 (board, x, y, symb);
+ break;
+ case 3:
+ _element3 (board, x, y, symb);
+ break;
+ }
+}
+
+void boardwindow (board_t *board)
+{
+ int i, j;
+
+ set_color (black);
+ _dobound (board->xsize, board->ysize, board->xoffset, board->yoffset);
+ set_color (white);
+
+ for (i = 0; i < board->width; i++) {
+ for (j = 0; j < board->height; j++) {
+ _element (board, i, j, getvalue (board, i, j));
+ }
+ }
+}
+
+char *savewindow (int length, int xoffset, int yoffset)
+{
+ char *name = (char *) calloc (1, length + 1);
+ CHECKALLOC (name);
+ memset (name, ' ', length);
+
+ set_color (black);
+ _dobound (length, 1, xoffset, yoffset);
+ set_color (white);
+
+ int i = 0, j;
+ int stop = 0;
+ while (!stop) {
+ for (j = 0; j < length; j++) {
+ set_color ((j == i) ? yellow : black);
+ mvaddch (yoffset, xoffset + j, name[j]);
+ set_color (white);
+ }
+ int ch = getch ();
+ switch (ch) {
+ case '\n':
+ case '\r':
+ stop = 1;
+ break;
+ case KEY_BACKSPACE:
+ case KEY_DELETE:
+ case 127:
+ case '\b':
+ name[i] = ' ';
+ i--;
+ break;
+ case KEY_LEFT:
+ i--;
+ break;
+ case KEY_RIGHT:
+ i++;
+ break;
+ case KEY_ESC:
+ free (name);
+ name = NULL;
+ stop = 1;
+ break;
+ default:
+ if ((ch >= 32) && ( ch < 128)) {
+ name[i] = ch;
+ i++;
+ }
+ }
+
+ if (i < 0) {
+ i = 0;
+ }
+ if (i >= length) {
+ i = length - 1;
+ }
+ }
+
+ if (name) {
+ for (j = length - 1; j >= 0; j--) {
+ if (name[j] == ' ') {
+ name[j] = '\0';
+ }
+ }
+ if (*name == '\0') {
+ free (name);
+ name = NULL;
+ }
+ }
+
+ return name;
+}
+
+void msgwindow (char *msg, int xoffset, int yoffset, int length)
+{
+ set_color (white);
+ _dobound ((length > 0) ? length : (int)strlen (msg), 1, xoffset, yoffset);
+ mvaddstr (yoffset, xoffset + ((length > 0) ? (length - (int)strlen (msg)) / 2 : 0), msg);
+ set_color (black);
+}
+
+/* vim: set ts=4 sw=4 et: */
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "debug.h"
+#include "type.h"
+
+#include "function.h"
+
+int strmaxlen (char *str, char ch)
+{
+ int len = 0;
+ char *end = NULL;
+ while ((end = strchr (str, ch)) != NULL) {
+ int l = (int)(end - str);
+ if (l > len) {
+ len = l;
+ }
+ str = end + 1;
+ }
+ return len;
+}
+
+board_t *initboard (int width, int height)
+{
+ board_t *board = (board_t *) malloc (sizeof (board_t));
+ CHECKALLOC (board);
+ board->tab = (char *) calloc (1, width * height + 1);
+ CHECKALLOC (board->tab);
+ memset (board->tab, ' ', width * height);
+ board->scale = 0;
+ board->xsize = board->width = width;
+ board->ysize = board->height = height;
+ board->xoffset = 0;
+ board->yoffset = 0;
+ return board;
+}
+
+board_t *copyboard (board_t *board)
+{
+ board_t *newboard = (board_t *) malloc (sizeof (board_t));
+ CHECKALLOC (board);
+ memcpy (newboard, board, sizeof (board_t));
+ newboard->tab = (char *) calloc (1, board->width * board->height + 1);
+ CHECKALLOC (newboard->tab);
+ memcpy (newboard->tab, board->tab, board->width * board->height + 1);
+ return newboard;
+}
+
+board_t *setscale (board_t *board, int scale)
+{
+ board->scale = scale;
+ switch (scale) {
+ case 0:
+ board->xsize = board->width;
+ board->ysize = board->height;
+ break;
+ case 1:
+ board->xsize = board->width * 2;
+ board->ysize = board->height;
+ break;
+ case 2:
+ board->xsize = board->width * 2;
+ board->ysize = board->height * 2;
+ break;
+ case 3:
+ board->xsize = board->width * 3;
+ board->ysize = board->height * 2;
+ break;
+ }
+ return board;
+}
+
+void freeboard (board_t *board)
+{
+ if (board) {
+ free (board->tab);
+ }
+ free (board);
+}
+
+int _makecomments (char *buffer, board_t *board)
+{
+ int i, j, l = 0;
+ for (j = 0; j < board->height; j++) {
+ l += sprintf (buffer + l, "rem: \"");
+ for (i = 0; i < board->width; i++) {
+ l += sprintf (buffer + l, "%c", getvalue (board, i, j));
+ }
+ l += sprintf (buffer + l, "\"\n");
+ }
+ return l;
+}
+
+char *saveboard (board_t *board)
+{
+ int size = 2 * (8 + 3) + 8 + board->width * board->height + 1;
+ VERBOSE (INFO, size += board->height * (8 + board->width));
+
+ char *buffer = (char *) calloc (size, 1);
+ CHECKALLOC (buffer);
+
+ int l = sprintf (buffer, "width: %d\n", board->width);
+ l += sprintf (buffer + l, "height: %d\n", board->height);
+ l += sprintf (buffer + l, "tab: \"%s\"\n", board->tab);
+
+ VERBOSE (INFO, _makecomments (buffer + l, board));
+
+ return buffer;
+}
+
+int writedata (char *filename, char *data)
+{
+ int ret = 0;
+
+ FILE *fd = fopen (filename, "w");
+ if (fd) {
+ size_t n = fwrite (data, strlen (data), 1, fd);
+ fclose (fd);
+ ret = (n == strlen (data));
+ } else {
+ VERBOSE (WARNING, printf ("can't write file (%s)\n", filename));
+ }
+
+ return ret;
+}
+
+char *readdata (char *filename)
+{
+ char *buffer = NULL;
+ FILE *fd = fopen (filename, "r");
+ if (fd) {
+ fseek (fd, 0, SEEK_END);
+ int size = ftell (fd);
+ buffer = (char *) calloc (size + 1, 1);
+ CHECKALLOC (buffer);
+
+ fseek (fd, 0, SEEK_SET);
+ int nb = fread (buffer, 1, size, fd);
+ if (nb != size) {
+ VERBOSE (WARNING, printf ("can't fully read file (%s)\n", filename));
+ }
+ fclose (fd);
+ }
+
+ return buffer;
+}
+
+char *atos (char *str)
+{
+ char *ret = NULL;
+
+ if (*str == '"') {
+ char *ptr = ++str;
+ while ((*ptr != '"') && (*ptr != '\0')) {
+ ptr++;
+ }
+ if (*ptr == '"') {
+ *ptr = '\0';
+ ret = str;
+ }
+ }
+
+ return ret;
+}
+
+board_t *loadboard (char *str)
+{
+ int width = 0;
+ int height = 0;
+ char *tab = NULL;
+
+ char *saveptr1, *saveptr2;
+
+ char *line = strtok_r (str, "\n", &saveptr1);
+ while (line) {
+
+ char *keyword = strtok_r (line, ":", &saveptr2);
+
+ char *value = line + strlen (keyword) + 1;
+ while (*value == ' ') {
+ value++;
+ }
+
+ if (strcmp (keyword, "width") == 0) {
+ width = atoi (value);
+ } else if (strcmp (keyword, "height") == 0) {
+ height = atoi (value);
+ } else if (strcmp (keyword, "tab") == 0) {
+ tab = atos (value);
+ } else if (strcmp (keyword, "rem") == 0) {
+ /* nothing to do with remark */
+ } else {
+ VERBOSE (WARNING, printf ("unknown keyword: %s\n", keyword));
+ }
+
+ line = strtok_r (NULL, "\n", &saveptr1);
+ }
+
+ board_t *board = NULL;
+ if ((tab) && (strlen (tab) == (size_t)(width * height))) {
+ board = initboard (width, height);
+ memcpy (board->tab, tab, width * height);
+ }
+
+ return board;
+}
+
+char *getcell (board_t *board, int x, int y)
+{
+ return board->tab + x + board->width * y;
+}
+
+char getvalue (board_t *board, int x, int y)
+{
+ return (x >= 0) && (x < board->width) && (y >= 0) && (y < board->height) ? *getcell (board, x, y) : 0;
+}
+
+/* vim: set ts=4 sw=4 et: */