X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?a=blobdiff_plain;f=main.cc;h=1d618d8eb4d667eb42d5c3525c20d9e9c50bdbb6;hb=5609af651ece7980e4170c9bc0e99e35ed5c13cf;hp=cb94b7f005c70250e78ec48110f8438326a94122;hpb=ba46b057f3e2613a86f2dea7fa8022990482c735;p=universe.git diff --git a/main.cc b/main.cc index cb94b7f..1d618d8 100644 --- a/main.cc +++ b/main.cc @@ -1,17 +1,6 @@ -//////////////////////////////////////////////////////////////////////////////// -// This program is free software; you can redistribute it and/or // -// modify it under the terms of the GNU General Public License // -// version 2 as published by the Free Software Foundation. // -// // -// This program is distributed in the hope that it will be useful, but // -// WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // -// General Public License for more details. // -// // -// Written and (C) by François Fleuret // -// Contact for comments & bug reports // -//////////////////////////////////////////////////////////////////////////////// +// Written and (C) by Francois Fleuret +// Contact for comments & bug reports #include #include @@ -31,6 +20,56 @@ using namespace std; #include "retina.h" #include "manipulator.h" #include "intelligence.h" +#include "xfig_tracer.h" + +#ifdef CAIRO_SUPPORT +#include + +static cairo_status_t write_cairo_to_file(void *closure, + const unsigned char *data, + unsigned int length) { + fwrite(data, 1, length, (FILE *) closure); + return CAIRO_STATUS_SUCCESS; +} + +void generate_png(Universe *universe, scalar_t scale, FILE *file) { + const int depth = 4; + const int width = int(universe->width() * scale); + const int height = int(universe->height() * scale); + + cairo_surface_t *image; + cairo_t* context_resource; + unsigned char *data; + + data = new unsigned char [width * height * depth]; + + image = cairo_image_surface_create_for_data(data, + CAIRO_FORMAT_RGB24, + width, + height, + width * depth); + + context_resource = cairo_create(image); + + cairo_scale(context_resource, scale, scale); + + cairo_set_source_rgb(context_resource, 1.0, 1.0, 1.0); + + cairo_rectangle(context_resource, 0, 0, + universe->width(), universe->height()); + + cairo_fill(context_resource); + + universe->draw(context_resource); + + cairo_surface_write_to_png_stream(image, write_cairo_to_file, file); + + cairo_destroy(context_resource); + cairo_surface_destroy(image); + + delete[] data; +} +#endif // To train // ./main --task hit_shape.task 0 --action-mode=random --nb-ticks=5000 --proportion-for-training=0.5 --save-file=dump.mem --no-window @@ -40,7 +79,7 @@ using namespace std; ////////////////////////////////////////////////////////////////////// -void check_opt(int argc, char **argv, int n_opt, int n, char *help) { +void check_opt(int argc, char **argv, int n_opt, int n, const char *help) { if(n_opt + n >= argc) { cerr << "Missing argument for " << argv[n_opt] << "." << endl; cerr << "Expecting " << help << "." << endl; @@ -49,8 +88,6 @@ void check_opt(int argc, char **argv, int n_opt, int n, char *help) { } void print_help_and_exit(int e) { - cout << "$Id: main.cc,v 1.89 2007-06-16 13:51:53 fleuret Exp $" << endl; - cout << endl; cout << "Arguments:" << endl; cout << " --no-window" << endl; cout << " --nb-ticks=" << endl; @@ -154,10 +191,9 @@ int main(int argc, char **argv) { } cout << "FlatLand, a toy universe for goal-planning experiments." << endl; - cout << "$Id: main.cc,v 1.89 2007-06-16 13:51:53 fleuret Exp $" << endl; if(!task) { - task = load_task("dummy.task"); + task = load_task("dummy.so"); task_degree = 0; } @@ -182,8 +218,11 @@ int main(int argc, char **argv) { retina.set_location(manipulator.hand_x(), manipulator.hand_y()); SimpleWindow *window_main = 0, *window_brain = 0; +#ifdef CAIRO_SUPPORT + cairo_t *cairo_cr = 0; +#endif - int winfd = -1; + int window_main_fd = -1; MapConcatener sensory_map(2); sensory_map.add_map(&retina); @@ -209,18 +248,21 @@ int main(int argc, char **argv) { cout << "done." << endl ; } - if(!no_window) { + if(no_window) { + cout << "Started without windows." << endl; + } else { window_main = new SimpleWindow("Universe (main window)", 4, 4, task->width(), task->height()); - winfd = window_main->file_descriptor(); + window_main_fd = window_main->file_descriptor(); window_main->map(); +#ifdef CAIRO_SUPPORT + cairo_cr = window_main->get_cairo_context_resource(); +#endif cout << "When the main window has the focus, press `q' to quit and click and drag to move" << endl << "objects." << endl; window_brain = new SimpleWindow("Universe (brain)", - 12 + task->width(), 4, - retina.width(), retina.height() + manipulator.parameter_height()); + 12 + task->width(), 4, + retina.width(), retina.height() + manipulator.parameter_height()); window_brain->map(); - } else { - cout << "Started without windows." << endl; } int tick = 0; @@ -240,10 +282,10 @@ int main(int argc, char **argv) { if(window_main) { struct timeval tv; FD_ZERO (&fds); - FD_SET (winfd, &fds); + FD_SET (window_main_fd, &fds); tv.tv_sec = 0; tv.tv_usec = 5000; // 0.05s - r = select(winfd + 1, &fds, 0, 0, &tv); + r = select(window_main_fd + 1, &fds, 0, 0, &tv); } else r = 0; time_t t = time(0); @@ -297,13 +339,22 @@ int main(int argc, char **argv) { last_hand_x = manipulator.hand_x(); last_hand_y = manipulator.hand_y(); last_grabbing = manipulator.grabbing(); - retina.set_location(manipulator.hand_x(), manipulator.hand_y()); + + retina.set_location(manipulator.hand_x(), + manipulator.hand_y()); if(window_main) { window_main->color(0.0, 0.0, 0.0); + window_main->color(1.0, 1.0, 1.0); window_main->fill(); task->draw(window_main); + +#ifdef CAIRO_SUPPORT + universe.draw(cairo_cr); +#else universe.draw(window_main); +#endif + manipulator.draw_on_universe(window_main); retina.draw_on_universe(window_main); @@ -330,7 +381,7 @@ int main(int argc, char **argv) { got_event = true; - if(FD_ISSET(winfd, &fds)) { + if(FD_ISSET(window_main_fd, &fds)) { SimpleEvent se; @@ -383,18 +434,17 @@ int main(int argc, char **argv) { case SimpleEvent::MOUSE_MOTION: { - if(press_shift) manipulator.force_move(se.x, se.y); - else { - if(grabbed_polygon) { - scalar_t xf, yf, force_x, force_y, f, fmax = 100; - xf = grabbed_polygon->absolute_x(relative_grab_x, relative_grab_y); - yf = grabbed_polygon->absolute_y(relative_grab_x, relative_grab_y); - force_x = se.x - xf; - force_y = se.y - yf; - f = sqrt(sq(force_x) + sq(force_y)); - if(f > fmax) { force_x = (force_x * fmax)/f; force_y = (force_y * fmax)/f; } - grabbed_polygon->apply_force(0.1, xf, yf, force_x, force_y); - } + if(press_shift) { + manipulator.force_move(se.x, se.y); + } else if(grabbed_polygon) { + scalar_t xf, yf, force_x, force_y, f, fmax = 100; + xf = grabbed_polygon->absolute_x(relative_grab_x, relative_grab_y); + yf = grabbed_polygon->absolute_y(relative_grab_x, relative_grab_y); + force_x = se.x - xf; + force_y = se.y - yf; + f = sqrt(sq(force_x) + sq(force_y)); + if(f > fmax) { force_x = (force_x * fmax)/f; force_y = (force_y * fmax)/f; } + grabbed_polygon->apply_force(0.1, xf, yf, force_x, force_y); } break; } @@ -402,23 +452,58 @@ int main(int argc, char **argv) { case SimpleEvent::KEY_PRESS: { - if(strcmp(se.key, "q") == 0) quit = true; + if(strcmp(se.key, "q") == 0) { + quit = true; + } + else if(strcmp(se.key, "s") == 0) { + retina.save_as_ppm("/tmp/retina.ppm"); cout << "Retina screen shot saved in /tmp/retina.ppm" << endl; + + { + XFigTracer tracer("/tmp/universe.fig"); + universe.print_xfig(&tracer); + } + +#ifdef CAIRO_SUPPORT { - ofstream out("/tmp/universe.fig"); - universe.print_fig(out); + FILE *file = fopen("/tmp/universe.png", "w"); + generate_png(&universe, 0.25, file); + // generate_png(task->width(), task->height(), &universe, "/tmp/universe.png"); + cout << "Universe image saved in /tmp/universe.png" << endl; } +#endif + + } + + else if(strcmp(se.key, "Shift_L") == 0 || strcmp(se.key, "Shift_R") == 0) { + press_shift = true; + } + + else if(strcmp(se.key, "Up") == 0) { + manipulator.do_action(Manipulator::ACTION_MOVE_UP); + } + + else if(strcmp(se.key, "Right") == 0) { + manipulator.do_action(Manipulator::ACTION_MOVE_RIGHT); + } + + else if(strcmp(se.key, "Down") == 0) { + manipulator.do_action(Manipulator::ACTION_MOVE_DOWN); + } + + else if(strcmp(se.key, "Left") == 0) { + manipulator.do_action(Manipulator::ACTION_MOVE_LEFT); + } + + else if(strcmp(se.key, "g") == 0) { + manipulator.do_action(Manipulator::ACTION_GRAB); + } + + else if(strcmp(se.key, "r") == 0) { + manipulator.do_action(Manipulator::ACTION_RELEASE); } - else if(strcmp(se.key, "Shift_L") == 0 || strcmp(se.key, "Shift_R") == 0) press_shift = true; - - else if(strcmp(se.key, "Up") == 0) manipulator.do_action(Manipulator::ACTION_MOVE_UP); - else if(strcmp(se.key, "Right") == 0) manipulator.do_action(Manipulator::ACTION_MOVE_RIGHT); - else if(strcmp(se.key, "Down") == 0) manipulator.do_action(Manipulator::ACTION_MOVE_DOWN); - else if(strcmp(se.key, "Left") == 0) manipulator.do_action(Manipulator::ACTION_MOVE_LEFT); - else if(strcmp(se.key, "g") == 0) manipulator.do_action(Manipulator::ACTION_GRAB); - else if(strcmp(se.key, "r") == 0) manipulator.do_action(Manipulator::ACTION_RELEASE); else if(strcmp(se.key, "space") == 0) { switch(action_mode) {