📄 main.cpp
字号:
/*
Robot Simulator
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(C) 2006 Jason Hunt
nulluser@gmail.gom
*/
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include "resource.h"
#include "main.h"
#include "display.h"
#include "console.h"
#include "world.h"
#include "robot.h"
extern world_type world;
HDC memdc; // Device context for offscreen drawing
HBITMAP mem_bitmap; // Bitmap for memdc
int display_x, display_y; // Current Size of the client area
bool keys[256] = { false }; // Key array, true if pressed
int updates = 0; // Number of updates since last second
int updates_per_second = 0; // Number of updates per second
bool manual_mode = false;
int timer_val = 10;
HWND neuron_window;
bool neuron_window_active = false;
robot_type *cur_robot = NULL;
unsigned int mouse_x_start;
unsigned int mouse_y_start;
bool mouse_is_down = false;
bool right_mouse_down = false;
bool show_stats = false;
/* Init the entire system */
void system_startup( HWND hwnd )
{
srand(time(NULL));
memdc_setup(hwnd);
world_setup();
world_update();
world_draw(memdc);
SetTimer(hwnd, UPDATE_ID, timer_val, NULL);
SetTimer(hwnd, SECOND_ID, 1000, NULL);
}
/* End of system_startup */
/* De-Init the entire system */
void system_shutdown( void )
{
world_destroy();
DeleteObject(mem_bitmap);
DeleteDC(memdc);
}
/* End of system_shutdown */
/* Called when a key is pressed */
void key_down(HWND hwnd, WPARAM w)
{
// Mark key as pressed
keys[w & 0xff] = true;
// Deal with single press events herex
if (keys['N'])
{
world_free_markers();
world_free_impacts();
}
if (keys['V']) robot.draw_vision = !robot.draw_vision;
if (keys[27]) PostQuitMessage(0);
if (keys[VK_DOWN])
{
timer_val++;
SetTimer(hwnd, UPDATE_ID, timer_val, NULL);
}
if (keys[VK_UP])
{
timer_val --;
if (timer_val < 0) timer_val = 0;
SetTimer(hwnd, UPDATE_ID, timer_val, NULL);
}
if (keys['R']) world_setup();
if (keys['T']) world.show_walls = !world.show_walls;
if (keys['M']) manual_mode = !manual_mode;
if (keys['G']) world.draw_grad = !world.draw_grad;
if (keys['1']) world.scale1 -= 0.01;
if (keys['2']) world.scale1 += 0.01;
if (keys['3']) world.scale2 -= 0.01;
if (keys['4']) world.scale2 += 0.01;
if (keys['5']) world.scale3 -= 0.001;
if (keys['6']) world.scale3 += 0.001;
if (keys[VK_SPACE]) show_stats = !show_stats;
if (keys['P']) world_compute_map_grid();
}
/* End of key_down */
/* Deal with main menu commands */
void main_menu(HWND hwnd, unsigned int id)
{
switch(id)
{
case ID_EXIT:
DestroyWindow(hwnd);
return;
case ID_SAVE:
world_save();
return;
case ID_OPEN:
world_load();
return;
}
}
/* End of main menu */
void mouse_down(LPARAM l)
{
mouse_is_down = true;
double world_x1 = (LOWORD(l) / (double)display_x) * world.x_size;
double world_y1 = (HIWORD(l) / (double)display_y) * world.y_size;
world_add_wall(world_x1, world_y1, 0, 0);
}
void mouse_up(LPARAM l)
{
mouse_is_down = false;
}
void mouse_move(LPARAM l)
{
if (mouse_is_down)
{
wall_type *w = world.walls;
if (w == NULL) return;
double world_x2 = (LOWORD(l) / (double)display_x) * world.x_size;
double world_y2 = (HIWORD(l) / (double)display_y) * world.y_size;
if (world_x2 < w->x) return;
if (world_y2 < w->y) return;
w->x_size = world_x2 - w->x;
w->y_size = world_y2 - w->y;
}
if (right_mouse_down)
{
world_set_target(get_world_x(LOWORD(l)),
get_world_y(HIWORD(l)));
}
}
/* Called when a key is released */
void key_up(WPARAM w)
{
keys[w & 0xff] = false;
}
/* End of key up */
void manual_motion(double speed, double dir)
{
if(!manual_mode) return;
robot.speed = speed;
robot.ddir = dir;
}
/* Process currently pressed keys */
void check_keys( void )
{
// Decode WASD keys for manual override
if (!manual_mode) return;
// Forward
if (keys['W'])
{
if (keys['A']) manual_motion(0.03, -0.03); else // Forward + left
if (keys['D']) manual_motion(0.03, 0.03); else // Forward + right
manual_motion(0.03, 0.00); // Normal forward
} else
// Reverse
if (keys['S'])
{
if (keys['A']) manual_motion(-0.015, 0.03); else // Reverse + left
if (keys['D']) manual_motion(-0.03, -0.03); else // Reverse + right
manual_motion(-0.03, 0); // Normal reverse
} else
if (keys['A']) manual_motion(0.0, -0.03); else // Rotate left
if (keys['D']) manual_motion(0.0, 0.03); else // Rotate right
manual_motion(0.0, 0.0); // No key, stop
}
/* End of check keys */
/* Deal with the system timer */
void timer_message(HWND hwnd, WPARAM wparam)
{
if (wparam == UPDATE_ID)
{
check_keys();
world_update();
world_draw(memdc);
updates++;
InvalidateRect(hwnd, NULL, 0);
return;
}
if (wparam == SECOND_ID)
{
updates_per_second = updates;
updates = 0;
// world_debug_update();
}
}
/* End of timer_message */
/* Deal with paint message */
void window_paint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
char buff[400];
if (show_stats)
{
sprintf(buff, "Update rate: %3d scale1 %f scale2 %f scale3: %f",
updates_per_second, world.scale1, world.scale2, world.scale3);
TextOut(memdc, 1, 1, buff, strlen(buff));
}
// Copy memory device context to display
BitBlt(hdc, 0, 0, display_x, display_y, memdc, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
// InvalidateRect(neuron_window, NULL, 0);
}
/* Wnd of window_paint */
/* Setup the off screen drawing system */
void memdc_setup( HWND hwnd )
{
RECT r;
GetClientRect(hwnd, &r);
// Update stored client area size
display_x = r.right;
display_y = r.bottom;
HDC hdc = GetDC(hwnd);
// Create memory device context and bitmap
memdc = CreateCompatibleDC(hdc);
mem_bitmap = CreateCompatibleBitmap(hdc, r.right, r.bottom);
// Select the bitmap into the memort dc
SelectObject(memdc, mem_bitmap);
ReleaseDC(hwnd, hdc);
}
/* End of memdc_setup */
/* Chhose the correct brush color for the neuron */
void set_neuron_brush(HDC hdc, double val)
{
if (val == 0)
SelectObject(hdc, (HBRUSH)world.white_brush);
else
if (val > 0)
SelectObject(hdc, (HBRUSH)world.blue_brush);
else
SelectObject(hdc, (HBRUSH)world.red_brush);
}
/* End of set_neuron_brush */
/* Window function */
LRESULT CALLBACK main_win_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message)
{
case WM_TIMER: timer_message(hwnd, wparam); return(0);
case WM_CREATE: system_startup(hwnd); return(0);
case WM_PAINT: window_paint(hwnd); return(0);
case WM_DESTROY:
system_shutdown();
PostQuitMessage(0);
return(0);
case WM_SIZE: // Process size message
// These are alreadt setup, delete them
DeleteObject(mem_bitmap);
DeleteDC(memdc);
// Setup again with the new size
memdc_setup(hwnd);
return(0);
case WM_KEYDOWN: // Process keydown
key_down(hwnd, wparam);
return(0);
case WM_KEYUP: // Process keyup
key_up(wparam);
return(0);
case WM_LBUTTONDOWN:
mouse_down(lparam);
return(0);
case WM_LBUTTONUP:
mouse_up(lparam);
return(0);
case WM_MOUSEMOVE:
mouse_move(lparam);
return(0);
case WM_RBUTTONDOWN:
world_set_target(get_world_x(LOWORD(lparam)),
get_world_y(HIWORD(lparam)));
right_mouse_down = true;
return(0);
case WM_RBUTTONUP:
right_mouse_down = false;
return(0);
case WM_COMMAND:
main_menu(hwnd, LOWORD(wparam));
return(0);
default:
return(DefWindowProc(hwnd, message, wparam, lparam));
}
return(0);
}
/* Wnd of window function */
/* Winmain */
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE pinst, LPSTR args, int mode)
{
char name[] = "Robot Simulator";
WNDCLASS wc;
wc.hInstance = hinst;
wc.lpszClassName = name;
wc.lpfnWndProc = main_win_proc;
wc.style = 0;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = "MAINMENU";
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = NULL;
if (!RegisterClass(&wc)) return(0);
HWND hwnd = CreateWindow(name, name, WS_OVERLAPPEDWINDOW,
120, 120, // x, y
640,480, // height, width
HWND_DESKTOP, NULL, hinst, NULL);
ShowWindow( hwnd, mode);
UpdateWindow( hwnd );
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
/* End of winmain */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -