aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2014-10-27 18:03:16 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2014-10-27 18:03:16 +0100
commit5cebe379c86133cc532f66f634e94de18ca0cb54 (patch)
treeb7c844a7406f395e3e0538ac436ff63cf0f12f81
parent28a93ad6931f03114ebfaf0c6635fab96ffea186 (diff)
downloadneetdraw-5cebe379c86133cc532f66f634e94de18ca0cb54.tar.gz
neetdraw-5cebe379c86133cc532f66f634e94de18ca0cb54.tar.xz
neetdraw-5cebe379c86133cc532f66f634e94de18ca0cb54.zip
Add some file saving/loading
-rw-r--r--autistdraw.c113
1 files changed, 100 insertions, 13 deletions
diff --git a/autistdraw.c b/autistdraw.c
index 05fdfd9..18ff297 100644
--- a/autistdraw.c
+++ b/autistdraw.c
@@ -518,6 +518,8 @@ end:
*h = my_h - my_y;
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
static const char *
color_to_ansi (uint8_t color)
{
@@ -555,6 +557,7 @@ export_ansi (app_context_t *app)
if (!fp)
{
display ("Error opening file for writing.");
+ beep ();
return;
}
@@ -582,6 +585,8 @@ export_ansi (app_context_t *app)
fclose (fp);
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
enum
{
MIRC_NONE = -1,
@@ -631,6 +636,7 @@ export_irc (app_context_t *app)
if (!fp)
{
display ("Error opening file for writing.");
+ beep ();
return;
}
@@ -655,6 +661,93 @@ export_irc (app_context_t *app)
fclose (fp);
}
+// --- Loading, saving ---------------------------------------------------------
+
+static void
+load (app_context_t *app)
+{
+ FILE *fp = fopen ("drawing.bin", "rb");
+ if (!fp)
+ {
+ display ("Error opening file for reading.");
+ beep ();
+ return;
+ }
+
+ // Client cannot load at all, the server would have send the new bitmap out
+ if (app->mode != NETWORK_MODE_STANDALONE)
+ {
+ display ("Cannot load bitmaps in networked mode.");
+ beep ();
+ return;
+ }
+
+ // Some way of loading/saving is better than no way, let's just do our job.
+ // The format neither standardised nor effective but it works for us.
+ // We just eat everything and make sure to not crash.
+
+ int x, y;
+ size_t w, h;
+ if (fscanf (fp, "%d %d %zu %zu", &x, &y, &w, &h) != 4)
+ goto error;
+
+ size_t size = w * h;
+ uint8_t *bitmap = calloc (size, sizeof *bitmap);
+ if (!bitmap)
+ goto error;
+
+ char c;
+ uint8_t pixel = 0;
+ bool have_nibble = false;
+ size_t loaded = 0;
+
+ while (loaded < size && (c = fgetc (fp)) != EOF)
+ {
+ static const char digits[] = "0123456789abcdef";
+ const char *value = strchr (digits, c);
+ if (value && c != '\0')
+ {
+ pixel = pixel << 4 | (value - digits);
+ if (have_nibble)
+ bitmap[loaded++] = pixel;
+ have_nibble = !have_nibble;
+ }
+ }
+
+ free (app->bitmap);
+ app->bitmap = bitmap;
+ app->bitmap_h = h; app->bitmap_x = x;
+ app->bitmap_w = w; app->bitmap_y = y;
+ redraw_canvas (app);
+
+error:
+ fclose (fp);
+}
+
+static void
+save (app_context_t *app)
+{
+ FILE *fp = fopen ("drawing.bin", "wb");
+ if (!fp)
+ {
+ display ("Error opening file for writing.");
+ return;
+ }
+
+ int x = app->bitmap_x, y = app->bitmap_y;
+ size_t w = app->bitmap_w, h = app->bitmap_h;
+ fprintf (fp, "%d %d %zu %zu\n", x, y, w, h);
+
+ for (size_t row = 0; row < h; row++)
+ {
+ for (size_t column = 0; column < w; column++)
+ fprintf (fp, "%02x", BITMAP_PIXEL (app, column, row));
+ fputc ('\n', fp);
+ }
+
+ fclose (fp);
+}
+
// --- Event handlers ----------------------------------------------------------
static void
@@ -730,19 +823,11 @@ on_key (app_context_t *app, termo_key_t *key)
switch (key->code.sym)
{
- case TERMO_SYM_UP:
- move_canvas (app, 0, -1);
- break;
- case TERMO_SYM_DOWN:
- move_canvas (app, 0, 1);
- break;
- case TERMO_SYM_LEFT:
- move_canvas (app, -1, 0);
- break;
- case TERMO_SYM_RIGHT:
- move_canvas (app, 1, 0);
- default:
- break;
+ case TERMO_SYM_UP: move_canvas (app, 0, -1); break;
+ case TERMO_SYM_DOWN: move_canvas (app, 0, 1); break;
+ case TERMO_SYM_LEFT: move_canvas (app, -1, 0); break;
+ case TERMO_SYM_RIGHT: move_canvas (app, 1, 0); break;
+ default: break;
}
return true;
}
@@ -756,6 +841,8 @@ on_key (app_context_t *app, termo_key_t *key)
if (key->modifiers)
return true;
+ if (key->code.codepoint == 'l') load (app);
+ if (key->code.codepoint == 's') save (app);
if (key->code.codepoint == 'e') export_ansi (app);
if (key->code.codepoint == 'E') export_irc (app);
return true;