/* Writes C to the video display and serial port. */ int putchar (int c) { acquire_console (); putchar_have_lock (c); release_console (); return c; }
/* Writes the N characters in BUFFER to the console. */ void putbuf (const char *buffer, size_t n) { acquire_console (); while (n-- > 0) putchar_have_lock (*buffer++); release_console (); }
/* Writes string S to the console, followed by a new-line character. */ int puts (const char *s) { acquire_console (); while (*s != '\0') putchar_have_lock (*s++); putchar_have_lock ('\n'); release_console (); return 0; }
/* The standard vprintf() function, which is like printf() but uses a va_list. Writes its output to both vga display and serial port. */ int vprintf (const char *format, va_list args) { int char_cnt = 0; acquire_console (); __vprintf (format, args, vprintf_helper, &char_cnt); release_console (); return char_cnt; }
static void usage(char **argv) { acquire_console(); fprintf(stderr, "Usage: %s [options] [file]\n" "Interactive exploration and high quality rendering of chaotic maps\n" "\n" "Actions:\n" " -i, --read FILE Load all parameters from the tEXt chunk of any\n" " .png image file generated by this program.\n" " -n, --animate FILE Load an animation from FILE. If an output file is\n" " also specified, this renders the animation.\n" " -o, --output FILE Instead of presenting an interactive GUI, render\n" " an image or animation with the provided settings\n" " noninteractively, and store it in FILE.\n" " -h, --help Display this text.\n" " --version Show the version number and exit.\n" "\n" "Clustering:\n" " -c. --cluster LIST Use a rendering cluster, given as a comma-separated\n" " list of hosts, optionally of the form host:port.\n" " -C, --auto-cluster Automatically search for cluster nodes, adding them\n" " as they become available.\n" " -r, --remote Remote control mode. Fyre will listen by default on\n" " port 7931 for commands, and can act as a rendering\n" " server in a cluster.\n" " -P, --port N Set the TCP port number used for remote control mode.\n" " -v, --verbose In remote control mode, display status messages on the\n" " console and don't run as a daemon.\n" " --hidden In remote control mode, don't reply to broadcast\n" " requests for detecting available Fyre servers.\n" " --pidfile FILE When running in the background under a UNIX-like OS,\n" " save the new process ID to this file.\n" "\n" "Parameters:\n" " -p, --param KEY=VALUE Set a calculation or rendering parameter, using the\n" " same key/value format used to store parameters in\n" " image metadata.\n" "\n" "Quality:\n" " -s, --size X[xY] Set the image size in pixels. If only one value is\n" " given, a square image is produced\n" " -S, --oversample SCALE Calculate the image at some integer multiple of the\n" " output resolution, downsampling when generating the\n" " final image. This improves the quality of sharp\n" " edges on most images, but will increase memory usage\n" " quadratically. Recommended values are between 1\n" " (no oversampling) and 4 (heavy oversampling)\n" " -q, --quality QUALITY In noninteractive rendering, set the quality level at\n" " which we stop rendering. Larger numbers give\n" " smoother and more detailed results, but increase\n" " running time. The default of 1.0 gives roughly one\n" " histogram sample for every final image sample.\n", argv[0]); }
int main(int argc, char ** argv) { IterativeMap* map; Animation* animation; gboolean animate = FALSE; gboolean have_gtk; gboolean verbose = FALSE; gboolean hidden = FALSE; enum {INTERACTIVE, RENDER, SCREENSAVER, REMOTE} mode = INTERACTIVE; const gchar *outputFile = NULL; const gchar *pidfile = NULL; int c, option_index=0; double quality = 1.0; #ifdef HAVE_GNET int port_number = FYRE_DEFAULT_PORT; #endif GError *error = NULL; math_init(); g_type_init(); have_gtk = gtk_init_check(&argc, &argv); #ifdef HAVE_GNET gnet_init(); # ifdef WIN32 gnet_ipv6_set_policy(GIPV6_POLICY_IPV4_ONLY); # endif #endif map = ITERATIVE_MAP(de_jong_new()); animation = animation_new(); while (1) { static struct option long_options[] = { {"help", 0, NULL, 'h'}, {"read", 1, NULL, 'i'}, {"animate", 1, NULL, 'n'}, {"output", 1, NULL, 'o'}, {"param", 1, NULL, 'p'}, {"size", 1, NULL, 's'}, {"oversample", 1, NULL, 'S'}, {"quality", 1, NULL, 'q'}, {"remote", 0, NULL, 'r'}, {"verbose", 0, NULL, 'v'}, {"port", 1, NULL, 'P'}, {"cluster", 1, NULL, 'c'}, {"auto-cluster", 0, NULL, 'C'}, {"screensaver", 0, NULL, 1000}, /* Undocumented, still experimental */ {"hidden", 0, NULL, 1001}, {"chdir", 1, NULL, 1002}, /* Undocumented, used by win32 file associations */ {"pidfile", 1, NULL, 1003}, {"version", 0, NULL, 1004}, {NULL}, }; c = getopt_long(argc, argv, "hi:n:o:p:s:S:q:rvP:c:C", long_options, &option_index); if (c == -1) break; switch (c) { case 'i': { histogram_imager_load_image_file(HISTOGRAM_IMAGER(map), optarg, &error); break; } case 'n': { GtkTreeIter iter; animation_load_file(animation, optarg); animate = TRUE; gtk_tree_model_get_iter_first(GTK_TREE_MODEL(animation->model), &iter); animation_keyframe_load(animation, &iter, PARAMETER_HOLDER(map)); break; } case 'o': mode = RENDER; outputFile = optarg; break; case 'p': parameter_holder_load_string(PARAMETER_HOLDER(map), optarg); break; case 's': parameter_holder_set(PARAMETER_HOLDER(map), "size" , optarg); break; case 'S': parameter_holder_set(PARAMETER_HOLDER(map), "oversample", optarg); break; case 'q': quality = atof(optarg); break; case 'v': verbose = TRUE; break; #ifdef HAVE_GNET case 'c': { ClusterModel *cluster = cluster_model_get(map, TRUE); cluster_model_add_nodes(cluster, optarg); } break; case 'C': { ClusterModel *cluster = cluster_model_get(map, TRUE); cluster_model_enable_discovery(cluster); } break; case 'r': mode = REMOTE; break; case 'P': port_number = atol(optarg); break; #else case 'c': case 'C': case 'P': fprintf(stderr, "This Fyre binary was compiled without gnet support.\n" "Cluster support is not available.\n"); break; case 'r': fprintf(stderr, "This Fyre binary was compiled without gnet support.\n" "Cluster support is not available.\n"); exit(1); break; #endif case 1000: /* --screensaver */ mode = SCREENSAVER; break; case 1001: /* --hidden */ hidden = TRUE; break; case 1002: /* --chdir */ chdir(optarg); break; case 1003: /* --pidfile */ pidfile = optarg; break; case 1004: /* --version */ printf("%s\n", VERSION); return 0; case 'h': default: usage(argv); return 1; } } if (optind + 1 < argc) { usage(argv); return 1; } if (optind != argc) { char *ext = strrchr (argv[optind], '.'); if (ext) { if (g_strcasecmp(ext, ".png") == 0) { histogram_imager_load_image_file(HISTOGRAM_IMAGER(map), argv[optind], &error); } else if (g_strcasecmp(ext, ".fa") == 0) { GtkTreeIter iter; animation_load_file(animation, argv[optind]); animate = TRUE; gtk_tree_model_get_iter_first(GTK_TREE_MODEL(animation->model), &iter); animation_keyframe_load(animation, &iter, PARAMETER_HOLDER(map)); } else { usage(argv); return 1; } } else { usage(argv); return 1; } } switch (mode) { case INTERACTIVE: { Explorer *explorer; if (!have_gtk) { fprintf(stderr, "GTK intiailization failed, can't start in interactive mode\n"); return 1; } explorer = explorer_new (map, animation); if (error) { GtkWidget *dialog, *label; gchar *text; dialog = glade_xml_get_widget (explorer->xml, "error dialog"); label = glade_xml_get_widget (explorer->xml, "error label"); text = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">Error!</span>\n\n%s", error->message); gtk_label_set_markup (GTK_LABEL (label), text); g_free (text); g_error_free (error); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_hide (dialog); } gtk_main(); break; } case RENDER: { acquire_console(); if (error) { g_print ("Error: %s\n", error->message); g_error_free (error); } if (animate) animation_render_main (map, animation, outputFile, quality); else batch_image_render (map, outputFile, quality); break; } case REMOTE: { #ifdef HAVE_GNET if (verbose) { acquire_console(); } else { daemonize_to_pidfile(pidfile); } if (!hidden) discovery_server_new(FYRE_DEFAULT_SERVICE, port_number); remote_server_main_loop(port_number, have_gtk, verbose); #else fprintf(stderr, "This Fyre binary was compiled without gnet support.\n" "Remote control mode is not available.\n"); #endif break; } case SCREENSAVER: { ScreenSaver* screensaver; GtkWidget* window; if (!have_gtk) { fprintf(stderr, "GTK intiailization failed, can't start in screensaver mode\n"); return 1; } screensaver = screensaver_new(map, animation); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); fyre_set_icon_later(window); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_window_set_title(GTK_WINDOW(window), "Fyre Screensaver"); gtk_container_add(GTK_CONTAINER(window), screensaver->view); gtk_widget_show_all(window); gtk_main(); break; } } return 0; }