void DrawScreen(cv::Mat& screen) { screen.setTo(0); // Draw target robot pose draw_robot(screen, pose_target_x, pose_target_y, pose_target_theta, 0,255,0); // Draw estimated robot pose draw_robot(screen, pose_x, pose_y, pose_theta, 0,0,255); cv::imshow("Human Interface", screen); cv::waitKey(1); }
void CCanvas::draw() { Fl_Box::draw(); draw_sensor_beam(); draw_odom(); draw_robot(); }
/* Puts robot in (0,0) * * * LOGS the movement */ void move_robot_origin() { draw_info(ENERGY,ENERGY_STAT, 0, 0, DIRECTION); draw_log("--Ir al origen "); draw_robot(0, 0, DIRECTION); origin(); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } X=0; Y=0; if( DIRECTION == UP) { BOARD[X][Y] = UROBOT; } else if( DIRECTION == DOWN) { BOARD[X][Y] = DROBOT; } else if( DIRECTION == RIGHT) { BOARD[X][Y] = RROBOT; } else if( DIRECTION == LEFT) { BOARD[X][Y] = LROBOT; } }
GLvoid draw_robots() { u_int i; tile* t; for (i = 0; i < COLORS; i++) { t = robots[i]; if (NULL != t) { glPushMatrix(); tile_center(t); draw_robot(i, 1.0f); glPopMatrix(); } if (robots[i] != robots_v[i]) { t = robots_v[i]; glPushMatrix(); tile_center(t); draw_robot(i, 0.3f); glPopMatrix(); } } }
void robot_finds_kitten::instructions(WINDOW *w) { mvwprintw (w,0,0,"robotfindskitten v22July2008\n" "Originally by the illustrious Leonard Richardson\n" "ReWritten in PDCurses by Joseph Larson,\n" "Ported to CDDA gaming system by a nutcase.\n" "In this game, you are robot ("); draw_robot(w); wprintw (w,"). Your job is to find kitten.\n" "This task is complicated by the existance of various\n" "things which are not kitten. Robot must touch items\n" "to determine if they are kitten or not. The game\n" "ends when robotfindskitten. Alternatively, you\n" "may end the game by hitting 'q'\n" " Press any key to start.\n"); wrefresh(w); getch(); }
void draw(cairo_t* cr) { cairo_save(cr); cairo_set_source_rgb(cr, 1, 1, 1); cairo_paint(cr); cairo_scale(cr, WIN_HEIGHT / 1000.0, WIN_HEIGHT / 1000.0); for (unsigned int i = 0; i < n_robots; i++) { draw_robot(cr, robots[i], 0.4); } cairo_restore(cr); draw_stats(cr, robots); /* cairo_save (cairo_context); * cairo_set_operator (cairo_context, CAIRO_OPERATOR_SOURCE); * cairo_set_source_surface (cairo_context, cairo_get_target * (map_context), 0, * 0); * cairo_paint (cairo_context); * cairo_restore (cairo_context);*/ }
void robot_finds_kitten::instructions(WINDOW *w) { int pos = 1; pos += fold_and_print(w, 0, 1, getmaxx(w) - 4, c_ltgray, _("robotfindskitten v22July2008")); pos += 1 + fold_and_print(w, pos, 1, getmaxx(w) - 4, c_ltgray, _("\ Originally by the illustrious Leonard Richardson, \ rewritten in PDCurses by Joseph Larson, \ ported to CDDA gaming system by a nutcase.")); pos += 1 + fold_and_print(w, pos, 1, getmaxx(w) - 4, c_ltgray, _("In this game, you are robot (")); draw_robot(w); wprintz(w, c_ltgray, _(").")); pos += 1 + fold_and_print(w, pos, 1, getmaxx(w) - 4, c_ltgray, _("\ Your job is to find kitten. This task is complicated by the existance of various things \ which are not kitten. Robot must touch items to determine if they are kitten or not. \ The game ends when robotfindskitten. Alternatively, you may end the game by hitting \ 'q', 'Q' or the escape key.")); fold_and_print(w, pos, 1, getmaxx(w) - 4, c_ltgray, _("Press any key to start.")); wrefresh(w); getch(); }
void robot_finds_kitten::process_input(int input, WINDOW *w) { timespec ts; ts.tv_sec = 1; ts.tv_nsec = 0; int check_x = robot.x; int check_y = robot.y; switch (input) { case KEY_UP: /* up */ check_y--; break; case KEY_DOWN: /* down */ check_y++; break; case KEY_LEFT: /* left */ check_x--; break; case KEY_RIGHT: /* right */ check_x++; break; case 0: break; default: { /* invalid command */ for (int c = 0; c < rfkCOLS; c++) { mvwputch (w, 0, c, c_white, ' '); mvwputch (w, 1, c, c_white, ' '); } mvwprintz (w, 0, 0, c_white, _("Invalid command: Use direction keys or press 'q'.")); return; } } if (check_y < 3 || check_y > rfkLINES - 1 || check_x < 0 || check_x > rfkCOLS - 1) { return; } if (rfkscreen[check_x][check_y] != EMPTY) { switch (rfkscreen[check_x][check_y]) { case ROBOT: /* We didn't move. */ break; case KITTEN: {/* Found it! */ for (int c = 0; c < rfkCOLS; c++) { mvwputch (w, 0, c, c_white, ' '); } /* The grand cinema scene. */ for (int c = 0; c <= 3; c++) { wmove(w, 1, (rfkCOLS / 2) - 5 + c); wputch(w, c_white, ' '); wmove(w, 1, (rfkCOLS / 2) + 4 - c); wputch(w, c_white, ' '); wmove(w, 1, (rfkCOLS / 2) - 4 + c); if (input == KEY_LEFT || input == KEY_UP) { draw_kitten(w); } else { draw_robot(w); } wmove(w, 1, (rfkCOLS / 2) + 3 - c); if (input == KEY_LEFT || input == KEY_UP) { draw_robot(w); } else { draw_kitten(w); } wrefresh (w); nanosleep(&ts, NULL); } /* They're in love! */ mvwprintz(w, 0, ((rfkCOLS - 6) / 2) - 1, c_ltred, "<3<3<3"); wrefresh(w); nanosleep(&ts, NULL); for (int c = 0; c < rfkCOLS; c++) { mvwputch (w, 0, c, c_white, ' '); mvwputch (w, 1, c, c_white, ' '); } mvwprintz (w, 0, 0, c_white, _("You found kitten! Way to go, robot!")); wrefresh(w); ret = true; int ech = input; do { ech = getch (); } while ( ech == input ); } break; default: { for (int c = 0; c < rfkCOLS; c++) { mvwputch (w, 0, c, c_white, ' '); mvwputch (w, 1, c, c_white, ' '); } std::vector<std::string> bogusvstr = foldstring( getmessage( bogus_messages[rfkscreen[check_x][check_y] - 2]), rfkCOLS); for (size_t c = 0; c < bogusvstr.size(); c++) { mvwprintw (w, c, 0, "%s", bogusvstr[c].c_str()); } wrefresh(w); } break; } wmove(w, 2, 0); return; } /* Otherwise, move the robot. */ robot.x = check_x; robot.y = check_y; }
robot_finds_kitten::robot_finds_kitten(WINDOW *w) { ret = false; char ktile[83] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#&()*+./:;=?![]{|}y"; int used_messages[MAXMESSAGES]; rfkLINES = 20; rfkCOLS = 60; const int numbogus = 20; nummessages = 201; empty.x = -1; empty.y = -1; empty.color = (nc_color)0; empty.character = ' '; for (int c = 0; c < rfkCOLS; c++) { for (int c2 = 0; c2 < rfkLINES; c2++) { rfkscreen[c][c2] = EMPTY; } } /* Create an array to ensure we don't get duplicate messages. */ for (int c = 0; c < nummessages; c++) { used_messages[c] = 0; bogus_messages[c] = 0; bogus[c] = empty; } /* Now we initialize the various game OBJECTs. * Assign a position to the player. */ robot.x = rand() % rfkCOLS; robot.y = rand() % (rfkLINES - 3) + 3; robot.character = '#'; robot.color = c_white; rfkscreen[robot.x][robot.y] = ROBOT; /* Assign the kitten a unique position. */ do { kitten.x = rand() % rfkCOLS; kitten.y = rand() % (rfkLINES - 3) + 3; } while (rfkscreen[kitten.x][kitten.y] != EMPTY); /* Assign the kitten a character and a color. */ do { kitten.character = ktile[rand() % 82]; } while (kitten.character == '#' || kitten.character == ' '); do { kitten.color = all_colors.get_random(); } while ( kitten.color == c_black ); rfkscreen[kitten.x][kitten.y] = KITTEN; /* Now, initialize non-kitten OBJECTs. */ for (int c = 0; c < numbogus; c++) { /* Assign a unique position. */ do { bogus[c].x = rand() % rfkCOLS; bogus[c].y = (rand() % (rfkLINES - 3)) + 3; } while (rfkscreen[bogus[c].x][bogus[c].y] != EMPTY); rfkscreen[bogus[c].x][bogus[c].y] = c + 2; /* Assign a character. */ do { bogus[c].character = ktile[rand() % 82]; } while (bogus[c].character == '#' || bogus[c].character == ' '); do { bogus[c].color = all_colors.get_random(); } while ( bogus[c].color == c_black ); /* Assign a unique message. */ int index = 0; do { index = rand() % nummessages; } while (used_messages[index] != 0); bogus_messages[c] = index; used_messages[index] = 1; } instructions(w); werase(w); mvwprintz (w, 0, 0, c_white, _("robotfindskitten v22July2008 - press q to quit.")); for (int c = 0; c < rfkCOLS; c++) { mvwputch (w, 2, c, BORDER_COLOR, '_'); } wmove(w, kitten.y, kitten.x); draw_kitten(w); for (int c = 0; c < numbogus; c++) { mvwputch(w, bogus[c].y, bogus[c].x, bogus[c].color, bogus[c].character); } wmove(w, robot.y, robot.x); draw_robot(w); int old_x = robot.x; int old_y = robot.y; wrefresh(w); /* Now the fun begins. */ int input = '.'; input = getch(); while (input != 'q' && input != 'Q' && input != 27 /*escape*/) { process_input(input, w); if(ret == true) { break; } /* Redraw robot, where avaliable */ if (!(old_x == robot.x && old_y == robot.y)) { wmove(w, old_y, old_x); wputch(w, c_white, ' '); wmove(w, robot.y, robot.x); draw_robot(w); rfkscreen[old_x][old_y] = EMPTY; rfkscreen[robot.x][robot.y] = ROBOT; old_x = robot.x; old_y = robot.y; } wrefresh(w); input = getch(); } }
/* Empty the BOARD, fills it and draw with game elements * * Put Robot at 0,0 * Put N_BARRIERS barriers randomly * Put [1, ( (N_BARRIERS*10)/100 )] charge stations randomly * Put the exit at (EXIT_X, EXIT_Y) */ void new_game(int n_barriers, int exit_x, int exit_y) { int rand_x, rand_y; int barriers_allocated=0; int stations_allocated=0; int n_stations; // Adjust EXIT coordinates to [0-7] exit_x--; exit_y--; // Empty the BOARD and blank it reset_game_values(); /* Put Robot, always start at 0,0 ponting to the rigth */ BOARD[0][0] = RROBOT; draw_robot(0,0,DIRECTION); /* Put Exit */ BOARD[exit_x][exit_y] = EXIT; draw_object(exit_x, exit_y, 'e'); /* Restart energy, refresh INFO window and inform in LOG window */ draw_info(ENERGY,'g', 0, 0, DIRECTION); draw_log("*** NEW GAME ***"); /* Put Barriers */ while( barriers_allocated != n_barriers ) { rand_x = (rand()%8); rand_y = (rand()%8); // Barrires can't jail the robot if( !((rand_x==1 && rand_y==0) || (rand_x==0 && rand_y==1)) ) { if( BOARD[rand_x][rand_y] == EMPTY ) { BOARD[rand_x][rand_y] = BARRIER; draw_object(rand_x, rand_y, 'b'); barriers_allocated++; } } } /* Put Charge Stations */ n_stations = (n_barriers*40)/100; if( n_stations < 0) n_stations = 1; while( stations_allocated != n_stations ) { rand_x = (rand()%8); rand_y = (rand()%8); if( BOARD[rand_x][rand_y] == EMPTY ) { BOARD[rand_x][rand_y] = STATION; draw_object(rand_x, rand_y, 's'); stations_allocated++; } } // Enable runing game GAME_RUNING=1; // Init Hardware if possible serial_init(); origin(); }
/* Interchange robot coordinates * * If possible return 1, else return 0 * * LOGS the movement * Charge robot energy when arrives a charge station * Invokes WIN and NEW GAME routines whe robot arrive the exit */ int teleport_robot() { if( !GAME_RUNING ){ return 0; } int new_x, new_y; // Interchange coordinates new_x = Y; new_y = X; if( BOARD[new_x][new_y] == BARRIER ) { draw_log("[!] Imposible [!] "); return 0; } // Charge station found else if( BOARD[new_x][new_y] == STATION ) { draw_log("[!] Imposible [!] "); return 0; } // Exit found else if( BOARD[new_x][new_y] == EXIT ) { draw_log("[!] Imposible [!] "); return 0; } // Empty box found else if( BOARD[new_x][new_y] == EMPTY ) { draw_robot(new_x, new_y, DIRECTION); to(new_x, new_y); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } X = new_x; Y = new_y; if( DIRECTION == UP) { BOARD[X][Y] = UROBOT; } else if( DIRECTION == DOWN) { BOARD[X][Y] = DROBOT; } else if( DIRECTION == RIGHT) { BOARD[X][Y] = RROBOT; } else if( DIRECTION == LEFT) { BOARD[X][Y] = LROBOT; } ENERGY--; if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else if( ENERGY > 0 ) { ENERGY_STAT = BAD; } else { draw_log("--Teletransportar "); draw_log("### PARTIDA PERDIDA ###"); // Show LOSE pop-up get_losepopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } draw_info(ENERGY,ENERGY_STAT, X, Y, DIRECTION); draw_log("--Teletransportar "); return 1; } }
/* Moves the robot 1 step * * If possible return 1, else return 0 * * LOGS the movement * Charge robot energy when arrives a charge station * Invokes WIN and NEW GAME routines whe robot arrive the exit */ int move_robot() { if( !GAME_RUNING ){ return 0; } // UP step if( DIRECTION == UP && Y<7 ) { // Barrier found if( BOARD[X][Y+1] == BARRIER ) { return 0; } // Charge station found else if( BOARD[X][Y+1] == STATION ) { draw_robot(X, Y+1, UP); // Hardware move step('y','f'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } Y++; BOARD[X][Y] = UROBOT; ENERGY+=ENERGY_STATIONS; draw_log("-| Cargando |- "); if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else { ENERGY_STAT = BAD; } is_station_below=1; draw_info(ENERGY,ENERGY_STAT, X, Y, UP); draw_log("--Avanzar "); return 1; } // Exit found else if( BOARD[X][Y+1] == EXIT ) { draw_log("--Avanzar "); draw_log("*** PARTIDA GANADA ***"); // Show WIN pop-up get_winpopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } // Empty box found else if( BOARD[X][Y+1] == EMPTY ) { draw_robot(X, Y+1, UP); // Hardware move step('y','f'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } Y++; BOARD[X][Y] = UROBOT; ENERGY--; if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else if( ENERGY > 0 ) { ENERGY_STAT = BAD; } else { draw_log("--Avanzar "); draw_log("### PARTIDA PERDIDA ###"); // Show LOSE pop-up get_losepopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } draw_info(ENERGY,ENERGY_STAT, X, Y, UP); draw_log("--Avanzar "); return 1; } return 0; } // DOWN step else if( DIRECTION == DOWN && Y>0 ) { // Barrier found if( BOARD[X][Y-1] == BARRIER ) { return 0; } // Charge station found else if( BOARD[X][Y-1] == STATION ) { draw_robot(X, Y-1, DOWN); // Hardware move step('y','b'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } Y--; BOARD[X][Y] = DROBOT; ENERGY+=ENERGY_STATIONS; draw_log("-| Cargando |- "); if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else { ENERGY_STAT = BAD; } is_station_below=1; draw_info(ENERGY,ENERGY_STAT, X, Y, DOWN); draw_log("--Avanzar "); return 1; } // Exit found else if( BOARD[X][Y-1] == EXIT ) { draw_log("--Avanzar "); draw_log("*** PARTIDA GANADA ***"); // Show WIN pop-up get_winpopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } // Empty box found else if( BOARD[X][Y-1] == EMPTY ) { draw_robot(X, Y-1, DOWN); // Hardware move step('y','b'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } Y--; BOARD[X][Y] = DROBOT; ENERGY--; if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else if( ENERGY > 0 ) { ENERGY_STAT = BAD; } else { draw_log("--Avanzar "); draw_log("### PARTIDA PERDIDA ###"); // Show LOSE pop-up get_losepopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } draw_info(ENERGY,ENERGY_STAT, X, Y, DOWN); draw_log("--Avanzar "); return 1; } return 0; } // RIGHT step else if( DIRECTION == RIGHT && X<7 ) { // Barrier found if( BOARD[X+1][Y] == BARRIER ) { return 0; } // Charge station found else if( BOARD[X+1][Y] == STATION ) { draw_robot(X+1, Y, RIGHT); // Hardware move step('x','f'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } X++; BOARD[X][Y] = RROBOT; ENERGY+=ENERGY_STATIONS; draw_log("-| Cargando |- "); if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else { ENERGY_STAT = BAD; } is_station_below=1; draw_info(ENERGY,ENERGY_STAT, X, Y, RIGHT); draw_log("--Avanzar "); return 1; } // Exit found else if( BOARD[X+1][Y] == EXIT ) { draw_log("--Avanzar "); draw_log("*** PARTIDA GANADA ***"); // Show WIN pop-up get_winpopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } // Empty box found else if( BOARD[X+1][Y] == EMPTY ) { draw_robot(X+1, Y, RIGHT); // Hardware move step('x','f'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } X++; BOARD[X][Y] = RROBOT; ENERGY--; if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else if( ENERGY > 0 ) { ENERGY_STAT = BAD; } else { draw_log("--Avanzar "); draw_log("### PARTIDA PERDIDA ###"); // Show LOSE pop-up get_losepopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } draw_info(ENERGY,ENERGY_STAT, X, Y, RIGHT); draw_log("--Avanzar "); return 1; } return 0; } // LEFT step else if( DIRECTION == LEFT && X>0 ) { // Barrier found if( BOARD[X-1][Y] == BARRIER ) { return 0; } // Charge station found else if( BOARD[X-1][Y] == STATION ) { draw_robot(X-1, Y, LEFT); // Hardware move step('x','b'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } X--; BOARD[X][Y] = LROBOT; ENERGY+=ENERGY_STATIONS; draw_log("-| Cargando |- "); if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else { ENERGY_STAT = BAD; } is_station_below=1; draw_info(ENERGY,ENERGY_STAT, X, Y, LEFT); draw_log("--Avanzar "); return 1; } // Exit found else if( BOARD[X-1][Y] == EXIT ) { draw_log("--Avanzar "); draw_log("*** PARTIDA GANADA ***"); // Show WIN pop-up get_winpopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } // Empty box found else if( BOARD[X-1][Y] == EMPTY ) { draw_robot(X-1, Y, LEFT); // Hardware move step('x','b'); BOARD[X][Y] = EMPTY; if( is_station_below ) { BOARD[X][Y] = STATION; draw_object(X, Y, 's'); is_station_below=0; } X--; BOARD[X][Y] = LROBOT; ENERGY--; if(ENERGY>=INIT_ENERGY) { ENERGY_STAT = GOOD; } else if(ENERGY>=(INIT_ENERGY)/2) { ENERGY_STAT = MEDIUM; } else if( ENERGY > 0 ) { ENERGY_STAT = BAD; } else { draw_log("--Avanzar "); draw_log("### PARTIDA PERDIDA ###"); // Show LOSE pop-up get_losepopup(); // Reset game reset_game_values(); // Stop game GAME_RUNING=0; return 1; } draw_info(ENERGY,ENERGY_STAT, X, Y, LEFT); draw_log("--Avanzar "); return 1; } return 0; } }
/* Rotates the robot in DIR direction * * * LOGS the movement */ void rotate_robot(char dir) { if( !GAME_RUNING ){ return; } if( dir == RIGHT ) { draw_log("--Girar Derecha "); if( DIRECTION == UP ) { draw_robot(X, Y, RIGHT); draw_info(ENERGY,ENERGY_STAT, X, Y, RIGHT); DIRECTION = RIGHT; } else if( DIRECTION == DOWN ) { draw_robot(X, Y, LEFT); draw_info(ENERGY,ENERGY_STAT, X, Y, LEFT); DIRECTION = LEFT; } else if( DIRECTION == LEFT ) { draw_robot(X, Y, UP); draw_info(ENERGY,ENERGY_STAT, X, Y, UP); DIRECTION = UP; } else if( DIRECTION == RIGHT ) { draw_robot(X, Y, DOWN); draw_info(ENERGY,ENERGY_STAT, X, Y, DOWN); DIRECTION = DOWN; } } else if( dir == LEFT ) { draw_log("--Girar Izquierda "); if( DIRECTION == UP ) { draw_robot(X, Y, LEFT); draw_info(ENERGY,ENERGY_STAT, X, Y, LEFT); DIRECTION = LEFT; } else if( DIRECTION == DOWN ) { draw_robot(X, Y, RIGHT); draw_info(ENERGY,ENERGY_STAT, X, Y, RIGHT); DIRECTION = RIGHT; } else if( DIRECTION == LEFT ) { draw_robot(X, Y, DOWN); draw_info(ENERGY,ENERGY_STAT, X, Y, DOWN); DIRECTION = DOWN; } else if( DIRECTION == RIGHT ) { draw_robot(X, Y, UP); draw_info(ENERGY,ENERGY_STAT, X, Y, UP); DIRECTION = UP; } } }
void gui_tick(VideoMode mode, r32 gui_time, r32 gui_dt) { persist bool flag_DrawDroneGoto = true; persist bool flag_DrawDrone = true; persist bool flag_DrawVisibleRegion = true; persist bool flag_DrawTargets = true; persist bool flag_DrawObstacles = true; persist bool flag_Paused = false; persist bool flag_Recording = false; persist bool flag_SetupRecord = false; persist int record_from = 0; persist int record_to = 0; persist int record_frame_skip = 1; persist int record_width = 0; persist int record_height = 0; persist float record_region_x = -1.0f; persist float record_region_y = -1.0f; persist float record_region_scale = 2.0f; persist jo_gif_t record_gif; persist int seek_cursor = 0; persist int selected_target = -1; persist Color color_Clear = { 0.00f, 0.00f, 0.00f, 1.00f }; persist Color color_Tiles = { 0.20f, 0.35f, 0.46f, 0.66f }; persist Color color_Grid = { 0.00f, 0.00f, 0.00f, 1.00f }; persist Color color_VisibleRegion = { 0.87f, 0.93f, 0.84f, 0.50f }; persist Color color_GreenLine = { 0.10f, 1.00f, 0.20f, 1.00f }; persist Color color_SelectedTarget = { 0.85f, 0.34f, 0.32f, 1.00f }; persist Color color_Targets = { 0.85f, 0.83f, 0.37f, 1.00f }; persist Color color_Obstacles = { 0.43f, 0.76f, 0.79f, 1.00f }; persist Color color_Drone = { 0.87f, 0.93f, 0.84f, 0.50f }; persist Color color_DroneGoto = { 0.87f, 0.93f, 0.84f, 0.50f }; #define RGBA(C) C.r, C.g, C.b, C.a persist float send_timer = 0.0f; persist float send_interval = 1.0f; // In simulation time units NDC_SCALE_X = (mode.height / (r32)mode.width) / 12.0f; NDC_SCALE_Y = 1.0f / 12.0f; if (flag_Recording || flag_SetupRecord) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); float Ax = 2.0f / record_region_scale; float Bx = -1.0f - Ax*record_region_x; float Ay = 2.0f / record_region_scale; float By = -1.0f - Ay*record_region_y; float modelview[] = { Ax, 0.0f, 0.0f, 0.0f, 0.0f, Ay, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, Bx, By, 0.0f, 1.0f }; glLoadMatrixf(modelview); } else { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } if (!flag_Paused) { if (flag_Recording) { if (seek_cursor >= record_to) { flag_Paused = true; flag_Recording = false; seek_cursor = record_from; jo_gif_end(&record_gif); } else if (seek_cursor + record_frame_skip >= record_to) { // clamp to end seek_cursor = record_to; } else { seek_cursor += record_frame_skip; } } else if (seek_cursor < HISTORY_LENGTH-1) { seek_cursor++; } else { sim_Command cmd; if (!sim_recv_cmd(&cmd)) { cmd.type = sim_CommandType_NoCommand; cmd.x = 0.0f; cmd.y = 0.0f; cmd.i = 0; } STATE = sim_tick(STATE, cmd); add_history(cmd, STATE); seek_cursor = HISTORY_LENGTH-1; send_timer -= Sim_Timestep; if (send_timer <= 0.0f) { sim_send_state(&STATE); send_timer += send_interval; } } } sim_State draw_state = HISTORY_STATE[seek_cursor]; sim_Drone drone = draw_state.drone; sim_Robot *robots = draw_state.robots; sim_Robot *targets = draw_state.robots; sim_Robot *obstacles = draw_state.robots + Num_Targets; if (flag_Recording || flag_SetupRecord) { glViewport(0, 0, record_width, record_height); } else { glViewport(0, 0, mode.width, mode.height); } glClearColor(RGBA(color_Clear)); glClear(GL_COLOR_BUFFER_BIT); glLineWidth(2.0f); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // draw grid tiles glBegin(GL_TRIANGLES); { color4f(color_Tiles); for (int yi = 0; yi < 20; yi++) for (int xi = 0; xi < 20; xi++) { r32 x = xi*1.0f; r32 y = yi*1.0f; fill_square(x, y, x+1.0f, y+1.0f); } } glEnd(); glBegin(GL_LINES); { // draw grid lines color4f(color_Grid); for (int i = 0; i <= 20; i++) { r32 x = (r32)i; draw_line(x, 0.0f, x, 20.0f); draw_line(0.0f, x, 20.0f, x); } // draw visible region if (flag_DrawVisibleRegion) { color4f(color_VisibleRegion); draw_circle(drone.x, drone.y, 2.5f); } // draw green line color4f(color_GreenLine); draw_line(0.0f, 20.0f, 20.0f, 20.0f); // draw targets if (flag_DrawTargets) { color4f(color_Targets); for (int i = 0; i < Num_Targets; i++) draw_robot(targets[i]); if (selected_target >= 0) { color4f(color_SelectedTarget); draw_robot(targets[selected_target]); } } // draw obstacles if (flag_DrawObstacles) { color4f(color_Obstacles); for (int i = 0; i < Num_Obstacles; i++) draw_robot(obstacles[i]); } // draw drone if (flag_DrawDrone) { color4f(color_Drone); draw_line(drone.x - 0.5f, drone.y, drone.x + 0.5f, drone.y); draw_line(drone.x, drone.y - 0.5f, drone.x, drone.y + 0.5f); } // draw drone goto if (flag_DrawDroneGoto) { color4f(color_DroneGoto); draw_circle(drone.xr, drone.yr, 0.45f); } // draw indicators of magnet or bumper activations for (int i = 0; i < Num_Targets; i++) { r32 x = targets[i].x; r32 y = targets[i].y; if (targets[i].action.was_bumped) { glColor4f(1.0f, 0.3f, 0.1f, 1.0f); draw_circle(x, y, 0.5f); } else if (targets[i].action.was_top_touched) { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); draw_circle(x, y, 0.5f); } } } glEnd(); // TODO: Change capture res? if (flag_Recording) { static unsigned char capture_data[1024*1024*4]; Assert(sizeof(capture_data) >= record_width*record_height*4); glReadPixels(0, 0, record_width, record_height, GL_RGBA, GL_UNSIGNED_BYTE, capture_data); jo_gif_frame(&record_gif, capture_data, 2, false); } ImGui_ImplSdl_NewFrame(mode.window); // DRAW FLAGS if (ImGui::CollapsingHeader("Rendering")) { ImGui::Checkbox("Drone goto", &flag_DrawDroneGoto); ImGui::Checkbox("Drone", &flag_DrawDrone); ImGui::Checkbox("Visible region", &flag_DrawVisibleRegion); ImGui::Checkbox("Targets", &flag_DrawTargets); ImGui::Checkbox("Obstacles", &flag_DrawObstacles); } // END DRAW FLAGS // COLORS if (ImGui::CollapsingHeader("Colors")) { ImGui::ColorEdit4("Clear", &color_Clear.r); ImGui::ColorEdit4("Grid", &color_Grid.r); ImGui::ColorEdit4("VisibleRegion", &color_VisibleRegion.r); ImGui::ColorEdit4("GreenLine", &color_GreenLine.r); ImGui::ColorEdit4("Targets", &color_Targets.r); ImGui::ColorEdit4("Obstacles", &color_Obstacles.r); ImGui::ColorEdit4("Drone", &color_Drone.r); ImGui::ColorEdit4("DroneGoto", &color_DroneGoto.r); } // END COLORS // REWIND HISTORY if (ImGui::CollapsingHeader("Seek##header")) { ImGui::Checkbox("Paused", &flag_Paused); ImGui::SliderInt("Seek##bar", &seek_cursor, 0, HISTORY_LENGTH-1); ImGui::InputInt("Seek frame", &seek_cursor); if (seek_cursor < 0) seek_cursor = 0; if (seek_cursor > HISTORY_LENGTH-1) seek_cursor = HISTORY_LENGTH-1; ImGui::Text("Time: %.2f seconds", (seek_cursor+1) * Sim_Timestep); } // END REWIND HISTORY // ROBOTS if (ImGui::CollapsingHeader("Robots")) { ImGui::Columns(4, "RobotsColumns"); ImGui::Separator(); ImGui::Text("ID"); ImGui::NextColumn(); ImGui::Text("X"); ImGui::NextColumn(); ImGui::Text("Y"); ImGui::NextColumn(); ImGui::Text("Angle"); ImGui::NextColumn(); ImGui::Separator(); for (int i = 0; i < Num_Targets; i++) { char label[32]; sprintf(label, "%02d", i); if (ImGui::Selectable(label, selected_target == i, ImGuiSelectableFlags_SpanAllColumns)) selected_target = i; ImGui::NextColumn(); ImGui::Text("%.2f", robots[i].x); ImGui::NextColumn(); ImGui::Text("%.2f", robots[i].y); ImGui::NextColumn(); ImGui::Text("%.2f", robots[i].q); ImGui::NextColumn(); } ImGui::Columns(1); ImGui::Separator(); } else { selected_target = -1; } // END ROBOTS // COMMUNICATION if (ImGui::CollapsingHeader("Communication")) { ImGui::TextWrapped("The rate at which the state is " "sent can be changed using this slider. " "The slider value represents the time " "interval (in simulation time) " "between each send."); ImGui::SliderFloat("Send interval", &send_interval, Sim_Timestep, 1.0f); ImGui::Separator(); ImGui::Text("Last 10 non-trivial commands received:"); ImGui::Columns(5, "CommunicationColumns"); ImGui::Separator(); ImGui::Text("Time"); ImGui::NextColumn(); ImGui::Text("type"); ImGui::NextColumn(); ImGui::Text("x"); ImGui::NextColumn(); ImGui::Text("y"); ImGui::NextColumn(); ImGui::Text("i"); ImGui::NextColumn(); ImGui::Separator(); int count = 0; for (int i = 0; count < 10 && i <= seek_cursor; i++) { sim_State state_i = HISTORY_STATE[seek_cursor-i]; sim_Command cmd_i = HISTORY_CMD[seek_cursor-i]; if (cmd_i.type == sim_CommandType_NoCommand) continue; char label[32]; sprintf(label, "%.2f", state_i.elapsed_time); ImGui::Selectable(label, false, ImGuiSelectableFlags_SpanAllColumns); ImGui::NextColumn(); switch (cmd_i.type) { case sim_CommandType_NoCommand: { ImGui::Text("Nothing"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); } break; case sim_CommandType_LandInFrontOf: { ImGui::Text("Land 180"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("%d", cmd_i.i); ImGui::NextColumn(); } break; case sim_CommandType_LandOnTopOf: { ImGui::Text("Land 45"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("%d", cmd_i.i); ImGui::NextColumn(); } break; case sim_CommandType_Track: { ImGui::Text("Track"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); ImGui::Text("%d", cmd_i.i); ImGui::NextColumn(); } break; case sim_CommandType_Search: { ImGui::Text("Search"); ImGui::NextColumn(); ImGui::Text("%.2f", cmd_i.x); ImGui::NextColumn(); ImGui::Text("%.2f", cmd_i.y); ImGui::NextColumn(); ImGui::Text("-"); ImGui::NextColumn(); } break; } count++; } ImGui::Columns(1); ImGui::Separator(); } // END COMMUNICATION // RECORDING GIFS if (ImGui::CollapsingHeader("Recording")) { flag_SetupRecord = true; if (ImGui::Button("Mark frame as begin")) { record_from = seek_cursor; } ImGui::SameLine(); ImGui::Text("Record from: %d", record_from); if (ImGui::Button("Mark frame as end")) { record_to = seek_cursor; } ImGui::SameLine(); ImGui::Text("Record to: %d", record_to); ImGui::InputInt("Frame skip", &record_frame_skip); ImGui::InputInt("Record width", &record_width); ImGui::InputInt("Record height", &record_height); if (record_width <= 0) record_width = mode.width; if (record_height <= 0) record_height = mode.height; ImGui::SliderFloat("Record x", &record_region_x, -1.0f, 1.0f); ImGui::SliderFloat("Record y", &record_region_y, -1.0f, 1.0f); ImGui::SliderFloat("Record scale", &record_region_scale, 0.0f, 2.0f); if (ImGui::Button("Start recording") && !flag_Recording) ImGui::OpenPopup("Save recording as?"); if (ImGui::BeginPopupModal("Save recording as?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { persist char filename[1024]; persist bool init_filename = true; if (init_filename) { sprintf(filename, "recording%u.gif", STATE.seed); init_filename = false; } ImGui::InputText("Filename", filename, sizeof(filename)); ImGui::Separator(); if (ImGui::Button("OK", ImVec2(120,0))) { flag_Recording = true; flag_Paused = false; seek_cursor = record_from-1; record_gif = jo_gif_start(filename, (short)record_width, (short)record_height, 0, 32); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("Cancel", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } if (ImGui::Button("Stop recording") && flag_Recording) { flag_Recording = false; flag_Paused = true; jo_gif_end(&record_gif); } if (record_from < 0) record_from = 0; if (record_from > HISTORY_LENGTH-1) record_from = HISTORY_LENGTH-1; if (record_to < record_from) record_to = record_from; if (record_to > HISTORY_LENGTH-1) record_to = HISTORY_LENGTH-1; if (record_frame_skip < 1) record_frame_skip = 1; ImGui::Separator(); } else { flag_SetupRecord = false; } // END RECORDING GIFS // RESET AND SET SEED persist int custom_seed = 0; if (ImGui::Button("Reset")) { if (custom_seed > 0) STATE = sim_init((u32)custom_seed); else STATE = sim_init((u32)get_tick()); HISTORY_LENGTH = 0; sim_Command cmd; cmd.type = sim_CommandType_NoCommand; add_history(cmd, STATE); } ImGui::SameLine(); ImGui::InputInt("Seed", &custom_seed); // END RESET AND SET SEED // SAVE SIMULATION if (ImGui::Button("Save..")) ImGui::OpenPopup("Save as?"); if (ImGui::BeginPopupModal("Save as?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { persist char filename[1024]; persist bool init_filename = true; if (init_filename) { sprintf(filename, "simulation%u", STATE.seed); init_filename = false; } ImGui::InputText("Filename", filename, sizeof(filename)); ImGui::Separator(); if (ImGui::Button("OK", ImVec2(120,0))) { write_history(filename); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("Cancel", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } // END SAVE SIMULATION ImGui::SameLine(); // SAVE SINGLE SNAPSHOT persist bool init_snapshot_filename = true; if (ImGui::Button("Save snapshot..")) ImGui::OpenPopup("Save snapshot as?"); if (ImGui::BeginPopupModal("Save snapshot as?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { persist char filename[1024]; ImGui::TextWrapped("The filename is relative to the executable," "unless you write an absolute path."); if (init_snapshot_filename) { sprintf(filename, "snapshot%u-%u", STATE.seed, seek_cursor); init_snapshot_filename = false; } ImGui::InputText("Filename", filename, sizeof(filename)); ImGui::Separator(); if (ImGui::Button("OK", ImVec2(120,0))) { sim_Observed_State snapshot = sim_observe_state(HISTORY_STATE[seek_cursor]); printf("%.2f\n", snapshot.obstacle_q[0]); sim_write_snapshot(filename, snapshot); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("Cancel", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } else { init_snapshot_filename = true; } // END SAVE SIMULATION ImGui::SameLine(); // LOAD SIMULATION if (ImGui::Button("Load..")) ImGui::OpenPopup("Load file?"); if (ImGui::BeginPopupModal("Load file?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { persist char filename[1024]; persist bool init_filename = true; if (init_filename) { sprintf(filename, "simulation%u", STATE.seed); init_filename = false; } ImGui::InputText("Filename", filename, sizeof(filename)); ImGui::Separator(); if (ImGui::Button("OK", ImVec2(120,0))) { read_history(filename); seek_cursor = 0; flag_Paused = true; ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("Cancel", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } // END LOAD SIMULATION ImGui::Render(); } // END gui_tick