// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // File: main.cpp | // Purpose: program for visualizing artificial neural networks | // Author: Taivo Lints, Estonia | // Date: May, 2003 | // Copyright: see copyright.txt | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #include "allegro.h" #include "visnet/visual_ann.h" #include "visnet/mypalette.h" #include "stdio.h" // For sprintf() and strcat() (Allegro needs char* -s) #include <vector> using namespace std; int main() { // ****************************** // * Setting up the environment * // ****************************** allegro_init(); install_keyboard(); install_mouse(); install_timer(); set_color_depth(8); set_gfx_mode(GFX_AUTODETECT, 800, 600, 0, 0); // Configures the text to be drawn with transparent background. text_mode(-1); // Sets the color of warning texts. int color_of_wtxt = 90; change_color(color_of_wtxt, 63, 5, 0); // Sets the color of notice texts. int color_of_ntxt = 91; change_color(color_of_ntxt, 55, 45, 10); // Sets colors for file loading menu. int color_of_gui_bg = 92, color_of_gui_fg = 93; change_color(color_of_gui_bg, 0, 0, 20); change_color(color_of_gui_fg, 0, 50, 0); gui_bg_color = color_of_gui_bg; gui_fg_color = color_of_gui_fg; // Sets colors for help background. int color_of_help_bg = 94; change_color(color_of_help_bg, 0, 0, 10); // Creates a bitmap object for double buffering (to avoid screen flickering). BITMAP* dblbuf = create_bitmap(SCREEN_W, SCREEN_H); clear_bitmap(dblbuf); // ******************************** // * Initializing other variables * // ******************************** // Initializes variables for loading the configuration file. char config_file[500]; sprintf(config_file, "config_generated.txt"); char message[] = "Load new configuration file"; // Message for load menu. char* ext = "TXT"; // File filter for load menu. char help_msg1[150]; // Creating some help messages. sprintf(help_msg1, "File "); strcat(help_msg1, config_file); strcat(help_msg1, " is missing"); char help_msg2[150]; sprintf(help_msg2, "Quit, fix "); strcat(help_msg2, config_file); strcat(help_msg2, " and restart program"); // Creates a visual network object. VisualANN* pVisNet = new VisualANN(config_file); // Gets the number of input nodes in network. This value is needed // for processing the user input. int num_of_inps = pVisNet->get_number_of_inputs(); // How many of these inputs are accessible by user? If you change this // number, you MUST also change the code in "Processing user interaction" // (in the "switch" statement). int user_accessible_inps = 10; // Creates a vector for feeding inputs into the network (vector size // is num_of_inps and vector is filled with zeros). vector<double> v_dbl_inpvalues(num_of_inps, 0); // Now cuts down the num_of_inps value because of the way this // value is used in a "switch" statement later on. if(num_of_inps > user_accessible_inps) num_of_inps = user_accessible_inps; // Some flags noticing when to print additional help for user. bool flag_no_inputs = false, flag_just_started = true; if(num_of_inps == 0) flag_no_inputs = true; // Program loops while this flag is "true". bool keepgoing = true; // ***************** // * The main loop * // ***************** while(keepgoing) { // ---------------------------- // | Updating & drawing network | // ---------------------------- pVisNet->update(); pVisNet->draw(dblbuf); // ------------------------------- // | Printing some additional help | // ------------------------------- if(flag_no_inputs) { textout(dblbuf, font, "Network has no inputs!", 2, 10, color_of_wtxt); if(flag_just_started) { textout(dblbuf, font, "Possible reasons:", 15, 30, color_of_wtxt); textout(dblbuf, font, help_msg1, 35, 42, color_of_wtxt); textout(dblbuf, font, "or is incorrect", 35, 54, color_of_wtxt); textout(dblbuf, font, "Solutions:", 15, 74, color_of_wtxt); textout(dblbuf, font, help_msg2, 35, 86, color_of_wtxt); textout(dblbuf, font, "or press L and load another configuration file", 35, 98, color_of_wtxt); } else { textout(dblbuf, font, "Possible reasons:", 15, 30, color_of_wtxt); textout(dblbuf, font, "Loaded file is incorrect", 35, 42, color_of_wtxt); textout(dblbuf, font, "or path contains non-english characters", 35, 54, color_of_wtxt); textout(dblbuf, font, "Solutions:", 15, 74, color_of_wtxt); textout(dblbuf, font, "Fix your file and reload it", 35, 86, color_of_wtxt); textout(dblbuf, font, "or press L and load another configuration file", 35, 98, color_of_wtxt); textout(dblbuf, font, "or in case of incorrect path move your file into", 35, 110, color_of_wtxt); textout(dblbuf, font, "correct path and load again", 35, 122, color_of_wtxt); textout(dblbuf, font, "Your selected path was:", 15, 140, color_of_ntxt); textout(dblbuf, font, config_file, 35, 152, color_of_ntxt); } } // ----------------------------- // | Processing user interaction | // ----------------------------- // - - Setting network inputs - - - // Gets mouse y value and normalizes it. double vertical_input = static_cast<double>(mouse_y); vertical_input = 1 - vertical_input / (SCREEN_H - 1); // Now here's an interesting statement. It sets values for feeding // into network. To avoid crashing when there are less than 10 inputs // in network (by indexing out of the vector), it jumps / switches // to the right place. But as there are no "break"-s at the ends of // lines, then it will go all the way down through "case"-s following // the one it jumped to. switch(num_of_inps) { case 10 : if(key[KEY_0]) v_dbl_inpvalues[9] = vertical_input; case 9 : if(key[KEY_9]) v_dbl_inpvalues[8] = vertical_input; case 8 : if(key[KEY_8]) v_dbl_inpvalues[7] = vertical_input; case 7 : if(key[KEY_7]) v_dbl_inpvalues[6] = vertical_input; case 6 : if(key[KEY_6]) v_dbl_inpvalues[5] = vertical_input; case 5 : if(key[KEY_5]) v_dbl_inpvalues[4] = vertical_input; case 4 : if(key[KEY_4]) v_dbl_inpvalues[3] = vertical_input; case 3 : if(key[KEY_3]) v_dbl_inpvalues[2] = vertical_input; case 2 : if(key[KEY_2]) v_dbl_inpvalues[1] = vertical_input; case 1 : if(key[KEY_1]) v_dbl_inpvalues[0] = vertical_input; default:; } // And finally feeds the vector into network. pVisNet->set_inputs(&v_dbl_inpvalues); // - - Loading new network - - - if(key[KEY_L]) { // Calls file selection menu. int i = file_select_ex(message, config_file, ext, 490, 450, 500); rest(250); // In case menu was exited by pressing Esc, this avoids // quitting the program. // If user chose something, then makes a new network of it. if(i != 0) { delete pVisNet; pVisNet = new VisualANN(config_file); num_of_inps = pVisNet->get_number_of_inputs(); v_dbl_inpvalues.assign(num_of_inps, 0); // Resize & write zeros. if(num_of_inps > user_accessible_inps) num_of_inps = user_accessible_inps; flag_just_started = false; if(num_of_inps == 0) flag_no_inputs = true; else flag_no_inputs = false; } } // - - Other user interactions - - - // Press Escape to exit. if(key[KEY_ESC]) { text_mode(0); textout(screen, font, "ESC pressed, will QUIT", 2, 2, color_of_wtxt); rest(2000); keepgoing = false; } // Press F1 for help. if(key[KEY_F1]) { rectfill(screen, 0, 0, 385, 164, color_of_help_bg); textout(screen, font, "Keys:", 5, 8, color_of_ntxt); textout(screen, font, "1 + mouse up/down - change first input", 15, 30, color_of_ntxt); textout(screen, font, "2 + mouse up/down - change second input", 15, 42, color_of_ntxt); textout(screen, font, ".. + mouse up/down - change .. input", 15, 54, color_of_ntxt); textout(screen, font, "L - load network", 15, 78, color_of_ntxt); textout(screen, font, "F1 - this help", 15, 102, color_of_ntxt); textout(screen, font, "F12 - save screenshot (does NOT work in menus)", 15, 114, color_of_ntxt); textout(screen, font, "Esc - quit program", 15, 126, color_of_ntxt); textout(screen, font, "Press any key to leave help", 15, 150, color_of_ntxt); rest(100); clear_keybuf(); while(!keypressed()); rest(250); } // Press F12 to save screenshot. if(key[KEY_F12]) { PALETTE pal; get_palette(pal); save_bitmap("screenshot.bmp", dblbuf, pal); textout(screen, font, "Screenshot saved", 2, 2, color_of_ntxt); rest(2000); } // ---------- // | Blitting | // ---------- // Copies the dblbuf into video memory at the right moment // (when vertical retrace is beginning in monitor). vsync(); blit(dblbuf, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); clear_bitmap(dblbuf); } // *************** // * Cleaning up * // *************** destroy_bitmap(dblbuf); } END_OF_MAIN();