📄 display.cpp
字号:
/*
Robot Interface
(C) 2006 Jason Hunt
nulluser@gmail.com
File: display.cpp
*/
#include <windows.h>
#include <stdio.h>
#include "display.h"
#include "types.h"
#include "robot.h"
#include "input.h"
#include "camera.h"
unsigned int display_x = 600; // Initial screen size
unsigned int display_y = 400;
HDC memdc = NULL; // Memory device context
HBITMAP h_mem_bitmap = NULL; // Offscreen bitmap
CRITICAL_SECTION text_lock; // Lock for update speed
static char text_area[text_row][MAX_LINE]; // The data for text display
void display_start( void )
{
InitializeCriticalSection(&text_lock);
}
/* Adds a line to the text buffer */
void add_line(char *line)
{
EnterCriticalSection(&text_lock);
static bool text_clear = false;
if (!text_clear)
{
memset(text_area, 0, text_row * MAX_LINE);
text_clear = true;
}
static unsigned int text_y = 0;
// Scrool the display up
if (text_y == text_row)
{
for (int i = 1; i < text_row; i++)
memcpy(text_area[i-1], text_area[i], MAX_LINE);
}
else
text_y ++;
// Copy the string
unsigned int line_len = strlen(line);
strncpy(text_area[text_y - 1], line, MAX_LINE);
LeaveCriticalSection(&text_lock);
}
/* End of add line */
/* Copy offscreen buffer to display */
void do_paint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
BitBlt(hdc, 0, 0, display_x, display_y, memdc, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
}
/* End of do_paint */
/* Draw a bar graph bounded by the two cords */
void draw_bar_graph(unsigned int x1, unsigned int y1,
unsigned int x2, unsigned int y2, double size, unsigned long color)
{
// Scale sonar into display
unsigned int draw_size = (unsigned int)((y2 - y1) * (1-size));
if (size > y2-y1) size = y2-y1;
HBRUSH color1 = CreateSolidBrush(RGB(150, 150, 150));
HBRUSH color2 = CreateSolidBrush(color);
RECT r;
r.left = x1;
r.right = x2;
r.top = y1;
r.bottom = y1 + draw_size;
FillRect(memdc, &r,color1);
r.top = y1 + draw_size;
r.bottom = y2;
FillRect(memdc, &r,color2);
DeleteObject(color1);
DeleteObject(color2);
}
/* End of draw_bar_graph */
/* Draw motor bar graphs and lables at positon */
void draw_control(unsigned int x, unsigned int y, control_type c)
{
unsigned int l_color = RGB(0, 0, 255);
unsigned int r_color = RGB(0, 0, 255);
if (c.left_motor_dir) l_color = RGB(255, 0, 0);
if (c.right_motor_dir) r_color = RGB(255, 0, 0);
char b[400];
sprintf(b, "Motor Target");
TextOut(memdc, x, y, b, strlen(b));
draw_bar_graph(x, y+20, x+35, y+120, c.left_motor_speed / 255.0, l_color);
draw_bar_graph(x+40, y+20, x+40+35, y+120, c.right_motor_speed / 255.0, r_color);
sprintf(b, "%3.0f", c.left_motor_target);
TextOut(memdc, x, y+120, b, strlen(b));
sprintf(b, "%3.0f", c.right_motor_target);
TextOut(memdc, x+40,y+120, b, strlen(b));
}
/* End of draw_motor_info */
/* Draw graphs and data fro telemetry */
void draw_telemetry(unsigned int x, unsigned int y, telemetry_type t)
{
// Bar graph parameters
unsigned int slice_width = 40;
unsigned int bar_width = 35;
unsigned int base_x = x;
unsigned int start_y = y+20;
unsigned int y_size = 100;
char b[300];
sprintf(b, "Analog Data");
TextOut(memdc, x, y, b, strlen(b));
// Draw graphs for analog
for (int i = 0; i < 8; i++)
{
draw_bar_graph(base_x + i*slice_width, start_y,
base_x+bar_width+i*slice_width,
start_y+y_size,
t.analog_data[i]/1024.0, RGB(0,0,255));
sprintf(b, "%4d ", t.analog_data[i]);
TextOut(memdc, base_x + i*slice_width, start_y + y_size, b, strlen(b));
}
}
/* End of draw_telemetry */
/* Update display */
void update_display(HWND hwnd)
{
telemetry_type t;
control_type c;
robot.get_control(&c);
robot.get_telemetry(&t);
SelectObject(memdc, (HBRUSH) GetStockObject(WHITE_BRUSH));
SelectObject(memdc, (HBRUSH) GetStockObject(WHITE_PEN));
RECT r;
GetClientRect(hwnd, &r);
// Clear old offscreen buffer
Rectangle(memdc, r.left, r.top, r.right, r.bottom);
char b[400];
sprintf(b, "Serial Rate %3.0f ", robot.get_update_speed());
TextOut(memdc, 1, 1, b, strlen(b));
sprintf(b, "Camera Rate %3d ", camera.get_update_rate());
TextOut(memdc, 1, 20, b, strlen(b));
// sprintf(b, "Motion time %4.2f ", motion_time);
// TextOut(memdc, 1, 40, b, strlen(b));
if (remote_mode)
strcpy(b, "Remote mode");
else
strcpy(b, "Local mode");
TextOut(memdc, 0, 40, b, strlen(b));
if (robot.get_auto_mode())
strcpy(b, "Auto mode");
else
strcpy(b, "Manual mode");
TextOut(memdc, 0, 60, b, strlen(b));
// Draw Sensors
draw_telemetry(260, 0, t);
// Draw control data
draw_control(160, 0, c);
unsigned int text_height = font_y_size * text_row;
SelectObject(memdc, (HBRUSH) GetStockObject(BLACK_PEN));
// Clear the old text area
Rectangle(memdc, 0, display_y -text_height, display_x, display_y );
EnterCriticalSection(&text_lock);
// draw text lines
for (unsigned int r = 0; r < text_row; r++)
TextOut(memdc, 2, display_y -text_height + r * font_y_size + 1, text_area[r], strlen(text_area[r]));
LeaveCriticalSection(&text_lock);
}
/* End of update display */
/* Create off screen buffer */
void setup_display( HWND hwnd )
{
// Get main DC
HDC hdc = GetDC(hwnd);
// Create Memory device contextand bitmap
memdc = CreateCompatibleDC(hdc);
// Create off screen buffer
h_mem_bitmap = CreateCompatibleBitmap(hdc, display_x, display_y);
// Select the off screen buffer into the DC
SelectObject(memdc, h_mem_bitmap);
ReleaseDC(hwnd, hdc); // Main DC is no longer needed
}
/* End of setup_display */
/* Resize the display and update buffers */
void resize_display(HWND hwnd, LPARAM l)
{
display_x = LOWORD(l);
display_y = HIWORD(l);
DeleteObject(h_mem_bitmap); // Delete old screen buffer
DeleteDC(memdc); // Delete old memory DC
setup_display(hwnd);
InvalidateRect(hwnd, NULL, true);
}
/* End of resize_display */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -