+ fprintf(f, "Begins executing continuously.\n"
+ "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) {
+ struct dcpu16_hw *hw = lem1802_new(vm);
+ const char *renderer = arg_vector[1];
+ const char *renderer_arg = NULL;
+ void *renderer_data = NULL;
+
+ if (arg_count == 3)
+ renderer_arg = arg_vector[2];
+
+ if (hw == NULL) {
+ fprintf(stderr, "failed to initialize new display\n");
+ return 0;
+ }
+
+ /* handle per-renderer setup of data.. */
+ /* FIXME: these are awkward */
+ if (strcmp(renderer, "pnm") == 0) {
+ if (renderer_arg == NULL)
+ renderer_arg = display_filename_default_;
+ renderer_data = (void *)renderer_arg;
+ }
+
+#ifdef HAVE_LIBPNG
+ if (strcmp(renderer, "png") == 0) {
+ if (renderer_arg == NULL)
+ renderer_arg = display_filename_default_;
+ renderer_data = (void *)renderer_arg;
+ }
+#endif /* HAVE_LIBPNG */
+
+#ifdef HAVE_LIBVNCSERVER
+ if (strcmp(renderer, "vnc") == 0) {
+ int argc = 1;
+ char *argv[] = { "vm-dcpu16", NULL };
+
+ renderer_data = lem1802_vnc_init_data(argc, argv, hw);
+
+ /* FIXME: keep refs to vnc displays around somewhere, in global list maybe.. */
+ /* keyboards will want to attach to them as well.. */
+
+ if (renderer_data == NULL) {
+ fprintf(stderr, "failed to initialize vnc\n");
+ lem1802_del(&hw);
+ return 0;
+ }
+ }
+#endif /* HAVE_LIBVNCSERVER */
+
+ if (lem1802_renderer_set(hw, renderer, renderer_data)) {
+ fprintf(stderr, "failed to set back-end renderer for display\n");
+ lem1802_del(&hw);
+ return 0;
+ }
+
+ if (dcpu16_hw_add(vm, hw)) {
+ fprintf(stderr, "failed to attach new display\n");
+ lem1802_del(&hw);
+ return 0;
+ }
+
+ return 0;
+}
+COMMAND_HELP(display) {
+ char *name, *args;
+ void *iter;
+
+ fprintf(f, "\tdisplay renderer [renderer data]\n");
+ if (summary) return;
+
+ fprintf(f, "Attaches new display unit, using 'renderer' as back-end output.\n"
+ );
+
+ fprintf(f, "Supported renderers:\n");
+ iter = NULL;
+ while ( (lem1802_renderers_iter(&iter, &name, &args)) ) {
+ fprintf(f, "\t%s %s\n", name, args);
+ }