Esempio n. 1
0
void loop() {

    // Make sure we don't update the map tile on screen when we don't need to!
    uint8_t update_display_window = 0;

    if ( first_time ) {
        first_time = 0;
        update_display_window = 1;
        }

    // Joystick displacement.
    int16_t dx = 0;
    int16_t dy = 0;
    uint8_t select_button_event = 0;

    // If the map has been zoomed in or out we need to do a redraw,
    // and will center the display window about the cursor.
    // So a zoom in-out will re-center over a mis-positioned cursor!
    
    // if the map changed as a result of a zoom button press
    if (shared_new_map_num != current_map_num) {
        #ifdef DEBUG_SCROLLING
            Serial.print("Zoom from ");
            Serial.print(current_map_num);
            Serial.print(" x ");
            Serial.print(cursor_map_x);
            Serial.print(" y ");
            Serial.print(cursor_map_y);
        #endif

        // change the map and figure out the position of the cursor on
        // the new map.
        set_zoom();

        // center the display window around the cursor 
        move_window_to(
            cursor_map_x - display_window_width/2, 
            cursor_map_y - display_window_height/2);

        #ifdef DEBUG_SCROLLING
            Serial.print(" to ");
            Serial.print(current_map_num);
            Serial.print(" x ");
            Serial.print(cursor_map_x);
            Serial.print(" y ");
            Serial.print(cursor_map_y);
            Serial.println();
        #endif

        // Changed the zoom level, so we want to redraw the window
        update_display_window = 1;
    }


    // Now, see if the joystick has moved, in which case we want to
    // also want to move the visible cursor on the screen.

    // Process joystick input.
    select_button_event = process_joystick(&dx, &dy);

    // the joystick routine filters out small changes, so anything non-0
    // is a real movement
    if ( abs(dx) > 0 || abs(dy) > 0 ) {
        // redraw the path if the cursor moves: (brute force yay)
        // comment out if you find it runs too slowly, and live with the
        // cursor erasing the path
        if ( path_length > 0 ) {
	  draw_path(path_length, path, current_map_num);
        }
        // Is the cursor getting near the edge of the screen?  If so
        // then scroll the map over by re-centering the window.

        uint16_t new_screen_map_x = screen_map_x;
        uint16_t new_screen_map_y = screen_map_y;
        uint8_t need_to_move = 0;

        uint16_t cursor_screen_x;
        uint16_t cursor_screen_y;
        if ( get_cursor_screen_x_y(&cursor_screen_x, &cursor_screen_y) ) {
            // if the cursor is visible, then adjust the display to 
            // to scroll if near the edge.

            if ( cursor_screen_x < screen_left_margin ) {
                new_screen_map_x = screen_map_x - screen_scroll_delta;
		move_cursor_by(3, 0);
                need_to_move = 1;
                }
            else if ( cursor_screen_x > screen_right_margin ) {
                new_screen_map_x = screen_map_x + screen_scroll_delta;
		move_cursor_by(-3, 0);
                need_to_move = 1;
            }

            if ( cursor_screen_y < screen_top_margin ) {
                new_screen_map_y = screen_map_y - screen_scroll_delta;
		move_cursor_by(0, 3);
                need_to_move = 1;
                }
            else if ( cursor_screen_y > screen_bottom_margin ) {
                new_screen_map_y = screen_map_y + screen_scroll_delta;
		move_cursor_by(0, -3);
                need_to_move = 1;
            }

            if ( need_to_move ) {
                // move the display window, leaving cursor at same lat-lon
	        move_window_to(new_screen_map_x, new_screen_map_y);
		
                update_display_window = 1;
                } 
            else {
                // erase old cursor, move, and draw new one, no need to 
                // redraw the underlying map tile
                erase_cursor();
                move_cursor_by(dx, dy);
                draw_cursor();
                }
            }

    }

    // at this point the screen is updated, with a new tile window and
    // cursor position if necessary

    // will only be down once, then waits for a min time before allowing
    // pres again.
    if (select_button_event) {
        // Button was pressed, we are selecting a point!
        #ifdef DEBUG_PATH
            Serial.print("x ");
            Serial.print(cursor_map_x);
            Serial.print(" y ");
            Serial.print(cursor_map_y);
            Serial.println();
        #endif

        // which press is this, the start or the stop selection?

        // If we are making a request to find a shortest path, we will send out
        // the request on the serial port and then wait for a response from the
        // server.  While this is happening, the client user interface is
        // suspended.

        // if the stop point, then we send out the server request and wait.
        if ( request_state == 0 ) {
            // collect the start point
            start_lat = cursor_lat;
            start_lon = cursor_lon;
            request_state = 1;
            }
        else if ( request_state == 1) {
            // collect the stop point
            stop_lat = cursor_lat;
            stop_lon = cursor_lon;
            request_state = 0;

            // send out the start and stop coordinates to the server
            Serial.print(start_lat);
            Serial.print(" "); 
            Serial.print(start_lon);
            Serial.print(" "); 
            Serial.print(stop_lat);
            Serial.print(" "); 
            Serial.print(stop_lon);
            Serial.println();

            // free any existing path
            if ( path_length > 0 ) {
                free(path);
                }

            // read the path from the serial port
            status_msg("WAITING");
            if ( read_path(&path_length, &path) ) {
                #ifdef DEBUG_PATH
                    uint8_t is_visible;
                    for (uint16_t i=0; i < path_length; i++) {
                        is_visible = is_coord_visible(path[i]);
                        Serial.print(i);
                        Serial.print(": ");
                        Serial.print(path[i].lat);
                        Serial.print(",");
                        Serial.print(path[i].lon);
                        Serial.print(is_visible ? "V": "");
                        Serial.println();
                        }
                #endif
                update_display_window = 1;
                }
            else {
                // should display this error on the screen
                Serial.print("Path read error, code ");
                Serial.println(path_errno);
                if ( path_errno == 1 ) {
                    status_msg("Path too long");
                    delay(5000);
                    }
                    
                }

            }
        } // end of select_button_event processing

    // do we have to redraw the map tile?  
    if (update_display_window) {
        #ifdef DEBUG_SCROLLING
            Serial.println("Screen update");
            Serial.print(current_map_num);
            Serial.print(" ");
            Serial.print(cursor_lon);
            Serial.print(" ");
            Serial.print(cursor_lat);
            Serial.println();
        #endif

	    
        draw_map_screen();
        draw_cursor();

        // Need to redraw any other things that are on the screen
        if ( path_length > 0 ) {
	  draw_path(path_length, path, current_map_num);
            }

        // force a redisplay of status message
        clear_status_msg();
        }

    // always update the status message area if message changes
    // Indicate which point we are waiting for
    if ( request_state == 0 ) {
        status_msg("FROM?");
        }
    else {
        status_msg("TO?");
        }
    }
Esempio n. 2
0
/****** Handle Input From Keyboard ******/
void DMG_GamePad::handle_input(SDL_Event &event)
{
	//Key Presses
	if(event.type == SDL_KEYDOWN)
	{
		pad = event.key.keysym.sym;
		process_keyboard(pad, true);
	}

	//Key Releases
	else if(event.type == SDL_KEYUP)
	{
		pad = event.key.keysym.sym;
		process_keyboard(pad, false);
	}

	//Joystick Button Presses
	else if(event.type == SDL_JOYBUTTONDOWN)
	{
		pad = 100 + event.jbutton.button;
		process_joystick(pad, true);
	}

	//Joystick Button Releases
	else if(event.type == SDL_JOYBUTTONUP)
	{
		pad = 100 + event.jbutton.button;
		process_joystick(pad, false);
	}

	//Joystick axes
	else if(event.type == SDL_JOYAXISMOTION)
	{
		pad = 200 + (event.jaxis.axis * 2);
		int axis_pos = event.jaxis.value;
		if(axis_pos > 0) { pad++; }
		else { axis_pos *= -1; }

		if(axis_pos > config::dead_zone) { process_joystick(pad, true); }
		else { process_joystick(pad, false); }
	}

	//Joystick hats
        else if(event.type == SDL_JOYHATMOTION)
	{
		pad = 300;
		pad += event.jhat.hat * 4;

		switch(event.jhat.value)
		{
			case SDL_HAT_LEFT:
				process_joystick(pad, true);
				process_joystick(pad+2, false);
				break;

			case SDL_HAT_LEFTUP:
				process_joystick(pad, true);
				process_joystick(pad+2, true);
				break;

			case SDL_HAT_LEFTDOWN:
				process_joystick(pad, true);
				process_joystick(pad+3, true);
				break;

			case SDL_HAT_RIGHT:
				process_joystick(pad+1, true);
				process_joystick(pad+2, false);
				break;

			case SDL_HAT_RIGHTUP:
				process_joystick(pad+1, true);
				process_joystick(pad+2, true);
				break;

			case SDL_HAT_RIGHTDOWN:
				process_joystick(pad+1, true);
				process_joystick(pad+3, true);
				break;

			case SDL_HAT_UP:
				process_joystick(pad+2, true);
				process_joystick(pad, false);
				break;

			case SDL_HAT_DOWN:
				process_joystick(pad+3, true);
				process_joystick(pad, false);
				break;

			case SDL_HAT_CENTERED:
				process_joystick(pad, false);
				process_joystick(pad+2, false);
				break;
		}
	}
}