support png output, buffered file writing
[dcpu16] / vm-dcpu16.c
index 537452af9af8f11066f00dd43aa0eb33961eb00d..5924074aa468ce5c5370538fd819864ef69d53c2 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "dcpu16.h"
 #include "common.h"
+#include "display.h"
 
 /*
  *  shell-like driver for dcpu16 core
@@ -364,6 +365,63 @@ COMMAND_HELP(run) {
                "May be interrupted with SIGINT.\n");
 }
 
+static const char * const display_filename_default_ =
+#ifdef HAVE_LIBPNG
+    "dcpu16-display.png"
+#else /* HAVE_LIBPNG */
+    "dcpu16-display.pnm"
+#endif /* HAVE_LIBPNG */
+;
+COMMAND_IMPL(display) {
+    static DCPU16_DISPLAY *display = NULL;
+    const char *filename = display_filename_default_;
+
+    if (arg_count == 2) {
+        filename = arg_vector[1];
+    }
+
+    if (display) {
+        printf("display already enabled..\n");
+        return 0;
+    }
+
+    display = display_new(filename);
+
+    if (display == NULL) {
+        fprintf(stderr, "failed to initialize display buffer\n");
+        return 0;
+    }
+
+    if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_WRITE, display_fn, display)) {
+        fprintf(stderr, "failed to register display update callback\n");
+        return 0;
+    }
+
+    if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_RESET, display_reset_fn, display)) {
+        fprintf(stderr, "failed to register display reset callback\n");
+        return 0;
+    }
+
+    if (dcpu16_acct_add(vm, DCPU16_ACCT_EV_CYCLE, display_cycle_fn, display)) {
+        fprintf(stderr, "failed to register display cycle callback\n");
+        return 0;
+    }
+
+    /* init display as if reset occurred */
+    display_reset_fn(vm, DCPU16_ACCT_EV_RESET, 0, display);
+
+    return 0;
+}
+COMMAND_HELP(display) {
+    fprintf(f, "\tdisplay [file]\n");
+    if (summary) return;
+
+    fprintf(f, "Attaches display interface, begins updating an image file of display contents...\n"
+               "Image filename may be specified, defaults to '%s'\n",
+               display_filename_default_
+            );
+}
+
 /* gather all these together into a searchable table */
 
 /* help command gets some assistance in declarations */
@@ -379,6 +437,7 @@ static struct command_ command_table_[] = {
     COMMAND_ENTRY(step, 0, 1),
     COMMAND_ENTRY(run, 0, 0),
     COMMAND_ENTRY(reset, 0, 0),
+    COMMAND_ENTRY(display, 0, 1),
     { NULL, 0, 0, NULL, NULL }
 };