25#include "wx/joystick.h"
27#include <OgreRenderWindow.h>
28#include <OgreViewport.h>
29#include <OgreCamera.h>
30#include <OgreRTShaderSystem.h>
48BEGIN_EVENT_TABLE(MainScreen, wxFrame)
49 EVT_ICONIZE(MainScreen::OnIconize)
50 EVT_SIZE(MainScreen::OnSize)
51 EVT_CLOSE(MainScreen::OnClose)
52 EVT_IDLE(MainScreen::OnIdle)
53 EVT_PAINT(MainScreen::OnPaint)
54 EVT_ACTIVATE(MainScreen::OnActivate)
56 EVT_JOYSTICK_EVENTS(MainScreen::OnJoystickEvent)
60MainScreen::MainScreen(
Skyscraper *parent,
int width,
int height) : wxFrame(0, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE)
68 title = wxT(
"Skyscraper " + frontend->GetVM()->version +
" " + frontend->GetVM()->version_state);
70 SetClientSize(width, height);
71 SetExtraStyle(wxWS_EX_PROCESS_IDLE);
74 joystick =
new wxJoystick(wxJOYSTICK1);
77 joy_buttons = joystick->GetNumberButtons();
78 joystick->SetCapture(
this, 10);
84 HAL *hal = frontend->GetVM()->GetHAL();
86 key_right = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Right",
"D")[0];
87 key_left = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Left",
"A")[0];
88 key_up = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Up",
"W")[0];
89 key_down = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Down",
"S")[0];
90 key_strafeleft = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.StrafeLeft",
"Q")[0];
91 key_straferight = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.StrafeRight",
"E")[0];
92 key_lookup = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.LookUp",
"P")[0];
93 key_lookdown = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.LookDown",
"L")[0];
94 key_binoculars = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Binoculars",
"B")[0];
95 key_crouch = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Crouch",
"X")[0];
96 key_floatup = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.FloatUp",
"O")[0];
97 key_floatdown = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.FloatDown",
"K")[0];
98 key_noclip = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.NoClip",
"V")[0];
99 key_pickup = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.PickUp",
"C")[0];
100 key_load = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Load",
";")[0];
101 key_enter = hal->GetConfigString(hal->keyconfigfile,
"Skyscraper.Frontend.Keyboard.Enter",
"E")[0];
104 joy_click = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Click", 0);
105 joy_fast = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Fast", 1);
106 joy_strafe = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Strafe", 2);
107 joy_turn = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Turn", 0);
108 joy_forward = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Forward", 1);
112 panel =
new wxPanel(
this, wxID_ANY, wxDefaultPosition, wxSize(width, height), wxNO_BORDER);
113 panel->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(MainScreen::OnKeyDown), NULL,
this);
114 panel->Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(MainScreen::OnKeyUp), NULL,
this);
115 panel->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
116 panel->Connect(wxID_ANY, wxEVT_LEFT_UP, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
117 panel->Connect(wxID_ANY, wxEVT_LEFT_DCLICK, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
118 panel->Connect(wxID_ANY, wxEVT_MIDDLE_DOWN, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
119 panel->Connect(wxID_ANY, wxEVT_MIDDLE_UP, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
120 panel->Connect(wxID_ANY, wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
121 panel->Connect(wxID_ANY, wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
122 panel->Connect(wxID_ANY, wxEVT_RIGHT_UP, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
123 panel->Connect(wxID_ANY, wxEVT_RIGHT_DCLICK, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
124 panel->Connect(wxID_ANY, wxEVT_MOUSEWHEEL, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
127MainScreen::~MainScreen()
130 joystick->ReleaseCapture();
135void MainScreen::OnIconize(wxIconizeEvent& event)
139 VM *vm = frontend->GetVM();
140 vm->Pause =
event.IsIconized();
142 if (vm->Pause ==
true)
143 vm->GetHAL()->Report(
"Pausing simulator...",
"");
145 vm->GetHAL()->Report(
"Resuming simulator...",
"");
148void MainScreen::OnSize(wxSizeEvent& WXUNUSED(event))
150 VM *vm = frontend->GetVM();
151 HAL *hal = vm->GetHAL();
154 panel->SetSize(this->GetClientSize().GetWidth(), this->GetClientSize().GetHeight());
156 if (hal->GetRenderWindow())
158#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
159 Real scale = this->GetContentScaleFactor();
160 hal->GetRenderWindow()->resize(this->GetClientSize().GetWidth() * scale, this->GetClientSize().GetHeight() * scale);
162 hal->GetRenderWindow()->windowMovedOrResized();
165 for (
size_t i = 0; i < hal->mCameras.size(); i++)
167 hal->mCameras[i]->setAspectRatio(
Real(hal->mViewports[i]->getActualWidth()) /
Real(hal->mViewports[i]->getActualHeight()));
171void MainScreen::OnClose(wxCloseEvent& event)
175 if (frontend->StartupRunning ==
false)
177 int result = wxMessageBox(wxT(
"Are you sure you want to exit?"), wxT(
"Skyscraper"), wxYES_NO | wxCENTER);
186void MainScreen::ShowWindow()
191void MainScreen::OnIdle(wxIdleEvent& event)
198 if (frontend->GetVM()->Pause ==
false)
200 if (this->HasFocus() && !panel->HasFocus())
204 bool result = frontend->Loop();
208 catch (Ogre::Exception &e)
210 frontend->GetVM()->GetHAL()->ReportFatalError(
"Unhandled OGRE exception:\n\n" + e.getFullDescription() +
"\n\nSkyscraper will now exit. Please report this as a bug.",
"");
214 HandleMouseMovement();
222void MainScreen::OnPaint(wxPaintEvent& event)
230void MainScreen::OnActivate(wxActivateEvent &event)
232 Active =
event.GetActive();
236void MainScreen::OnKeyDown(wxKeyEvent& event)
240 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
256 int key =
event.GetKeyCode();
258#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE
260 if (wxGetKeyState((wxKeyCode)key) ==
false)
264 if (key == WXK_ESCAPE)
266 int result = wxMessageBox(wxT(
"Exit and return to the main menu?"), wxT(
"Skyscraper"), wxYES_NO | wxCENTER);
268 frontend->GetVM()->Shutdown =
true;
274 frontend->GetGUI()->ShowControlReference();
280 HAL *hal = frontend->GetVM()->GetHAL();
281 Ogre::RenderSystem *rendersystem = hal->mRoot->getRenderSystem();
283 int batches = (int)rendersystem->_getBatchCount();
284 int triangles = (int)rendersystem->_getFaceCount();
285 int vertices = (int)rendersystem->_getVertexCount();
294 if (event.ControlDown() && key == (wxKeyCode)
'C')
302 if (key == WXK_SPACE)
309 if (key == (wxKeyCode)key_noclip)
317 frontend->GetVM()->GetHAL()->Report(
"Gravity and collision detection on",
"");
319 frontend->GetVM()->GetHAL()->Report(
"Gravity and collision detection off",
"");
322 if (event.ControlDown() ==
true && key == (wxKeyCode)
'R')
324 engine->Reload =
true;
346 frontend->colliders = !frontend->colliders;
352 if (frontend->wireframe == 0)
354 frontend->GetVM()->GetSkySystem()->EnableSky(
false);
356 frontend->wireframe = 1;
358 else if (frontend->wireframe == 1)
361 frontend->wireframe = 2;
363 else if (frontend->wireframe == 2)
365 frontend->GetVM()->GetSkySystem()->EnableSky(
true);
367 frontend->wireframe = 0;
373 std::string prefix = frontend->GetDataPath();
374 frontend->GetVM()->GetHAL()->GetRenderWindow()->writeContentsToTimestampedFile(prefix +
"screenshots/skyscraper-",
".jpg");
379 frontend->GetGUI()->ShowDebugPanel();
391 frontend->SetFullScreen(!frontend->FullScreen);
398 frontend->boxes = !frontend->boxes;
404 frontend->GetVM()->GetHAL()->ToggleStats();
407 if (key == WXK_NUMPAD_SUBTRACT || key == (wxKeyCode)
'[')
414 if (key == WXK_NUMPAD_ADD || key == (wxKeyCode)
']')
422 if (key == (wxKeyCode)key_pickup)
431 if (key == (wxKeyCode)key_load)
433 frontend->GetGUI()->ShowLoadDialog();
438 if (key == (wxKeyCode)
'1')
440 frontend->GetVM()->SetActiveEngine(0);
442 else if (key == (wxKeyCode)
'2')
444 frontend->GetVM()->SetActiveEngine(1);
446 else if (key == (wxKeyCode)
'3')
448 frontend->GetVM()->SetActiveEngine(2);
450 else if (key == (wxKeyCode)
'4')
452 frontend->GetVM()->SetActiveEngine(3);
454 else if (key == (wxKeyCode)
'5')
456 frontend->GetVM()->SetActiveEngine(4);
458 else if (key == (wxKeyCode)
'6')
460 frontend->GetVM()->SetActiveEngine(5);
462 else if (key == (wxKeyCode)
'7')
464 frontend->GetVM()->SetActiveEngine(6);
466 else if (key == (wxKeyCode)
'8')
468 frontend->GetVM()->SetActiveEngine(7);
470 else if (key == (wxKeyCode)
'9')
472 frontend->GetVM()->SetActiveEngine(8);
474 else if (key == (wxKeyCode)
'0')
476 frontend->GetVM()->SetActiveEngine(9);
480 if (key == (wxKeyCode)key_enter)
487 GetKeyStates(engine, event,
true);
489 ProcessMovement(engine, event.ControlDown(), event.ShiftDown());
492void MainScreen::OnKeyUp(wxKeyEvent& event)
496 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
501 GetKeyStates(engine, event,
false);
503 ProcessMovement(engine, event.ControlDown(), event.ShiftDown());
506void MainScreen::GetKeyStates(EngineContext *engine, wxKeyEvent& event,
bool down)
509 Camera *camera = engine->GetSystem()->camera;
514 int key =
event.GetKeyCode();
520 if (key == WXK_RIGHT || key == (wxKeyCode)key_right)
521 frontend->strafe_right = down;
523 else if (key == WXK_LEFT || key == (wxKeyCode)key_left)
524 frontend->strafe_left = down;
526 else if (key == WXK_UP || key == (wxKeyCode)key_up)
527 frontend->float_up = down;
529 else if (key == WXK_DOWN || key == (wxKeyCode)key_down)
530 frontend->float_down = down;
532 else if (key == WXK_PAGEUP || key == (wxKeyCode)key_lookup)
533 frontend->spin_up = down;
535 else if (key == WXK_PAGEDOWN || key == (wxKeyCode)key_lookdown)
536 frontend->spin_down = down;
542 if (key == WXK_RIGHT || key == (wxKeyCode)key_right)
543 frontend->turn_right = down;
545 if (key == WXK_LEFT || key == (wxKeyCode)key_left)
546 frontend->turn_left = down;
548 if (key == (wxKeyCode)key_straferight)
549 frontend->strafe_right = down;
551 if (key == (wxKeyCode)key_strafeleft)
552 frontend->strafe_left = down;
556 if (key == WXK_RIGHT || key == (wxKeyCode)key_right || key == (wxKeyCode)key_straferight)
557 frontend->strafe_right = down;
559 if (key == WXK_LEFT || key == (wxKeyCode)key_left || key == (wxKeyCode)key_strafeleft)
560 frontend->strafe_left = down;
563 if (key == WXK_PAGEUP || key == (wxKeyCode)key_lookup)
564 frontend->look_up = down;
566 if (key == WXK_PAGEDOWN || key == (wxKeyCode)key_lookdown)
567 frontend->look_down = down;
569 if (key == WXK_UP || key == (wxKeyCode)key_up)
570 frontend->step_forward = down;
572 if (key == WXK_DOWN || key == (wxKeyCode)key_down)
573 frontend->step_backward = down;
576 if (key == (wxKeyCode)key_binoculars)
582 if (key == (wxKeyCode)key_crouch)
588 if (key == WXK_HOME || key == (wxKeyCode)key_floatup)
589 frontend->float_up = down;
590 if (key == WXK_END || key == (wxKeyCode)key_floatdown)
591 frontend->float_down = down;
596 if (key == WXK_LEFT || key == (wxKeyCode)key_left)
597 engine->GetSystem()->camera->Drive(
true,
false,
false,
false, down);
598 if (key == WXK_RIGHT || key == (wxKeyCode)key_right)
599 engine->GetSystem()->camera->Drive(
false,
true,
false,
false, down);
600 if (key == WXK_DOWN || key == (wxKeyCode)key_down)
601 engine->GetSystem()->camera->Drive(
false,
false,
true,
false, down);
602 if (key == WXK_UP || key == (wxKeyCode)key_up)
603 engine->GetSystem()->camera->Drive(
false,
false,
false,
true, down);
608void MainScreen::ProcessMovement(EngineContext *engine,
bool control,
bool shift,
bool angle_only)
612 Real strafe = 0, floatval = 0, spin = 0, turn = 0, look = 0, step = 0;
615 Camera *camera = engine->GetSystem()->camera;
624 if (angle_only ==
false)
629 camera->
speed = speed_slow;
630 else if (shift ==
true)
631 camera->
speed = speed_fast;
633 if (frontend->step_forward ==
true)
634 step += speed_normal;
635 if (frontend->step_backward ==
true)
636 step -= speed_normal;
638 if (frontend->strafe_left ==
true)
639 strafe -= speed_normal;
640 if (frontend->strafe_right ==
true)
641 strafe += speed_normal;
643 if (frontend->float_up ==
true)
644 floatval += speed_normal;
645 if (frontend->float_down ==
true)
646 floatval -= speed_normal;
651 camera->
Float(floatval);
654 if (frontend->spin_up ==
true)
655 spin += speed_normal;
656 if (frontend->spin_down ==
true)
657 spin -= speed_normal;
659 if (frontend->turn_left ==
true)
660 turn -= speed_normal;
661 if (frontend->turn_right ==
true)
662 turn += speed_normal;
664 if (frontend->look_up ==
true)
665 look += speed_normal;
666 if (frontend->look_down ==
true)
667 look -= speed_normal;
675void MainScreen::OnMouseButton(wxMouseEvent& event)
680 if (event.GetWheelRotation() > 0)
682 EnableFreelook(
true);
685 else if (event.GetWheelRotation() < 0)
687 EnableFreelook(
false);
692 bool left =
event.LeftDown();
693 bool left_dclick =
event.LeftDClick();
694 bool right =
event.RightDown();
695 bool right_dclick =
event.RightDClick();
697 HAL *hal = frontend->GetVM()->GetHAL();
699 if (left ==
false && right ==
false && left_dclick ==
false && right_dclick ==
false)
701 hal->UnclickedObject();
706 Real scale = frontend->window->GetContentScaleFactor();
708#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
710 if (frontend->GetVM()->macos_major == 10 && frontend->GetVM()->macos_minor < 15)
714 hal->ClickedObject(left, wxGetKeyState(WXK_SHIFT), wxGetKeyState(WXK_CONTROL), wxGetKeyState(WXK_ALT), (right || right_dclick), scale,
false);
718void MainScreen::HandleMouseMovement()
720 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
722 if (!engine || IsActive() ==
false)
725 if (engine->IsRunning() ==
false)
740 int old_mouse_x = camera->
mouse_x;
741 int old_mouse_y = camera->
mouse_y;
744 camera->
mouse_x = ScreenToClient(wxGetMousePosition()).x;
745 camera->
mouse_y = ScreenToClient(wxGetMousePosition()).y;
750 if (frontend->freelook ==
false)
753 frontend->turn_right = 0;
754 frontend->turn_left = 0;
756 EnableFreelook(
true);
759 frontend->freelook =
true;
762 Real width = GetClientSize().GetWidth();
763 Real height = GetClientSize().GetHeight();
766 if (old_mouse_x != camera->
mouse_x || old_mouse_y != camera->
mouse_y)
768 WarpPointer(width * 0.5, height * 0.5);
771 rotational.x = -(((
Real)camera->
mouse_y - (height / 2))) / (height * 2);
772 rotational.y = -((width / 2) - (
Real)camera->
mouse_x) / (width * 2);
775 Real fps_adjust = Simcore->
FPS / 60;
776 rotational *= fps_adjust;
784 ProcessMovement(engine,
false,
false,
true);
789 if (frontend->freelook ==
true)
792 frontend->strafe_right = 0;
793 frontend->strafe_left = 0;
794 if (old_mouse_x != camera->
mouse_x || old_mouse_y != camera->
mouse_y)
796 ProcessMovement(engine,
false,
false,
true);
798 frontend->freelook =
false;
802void MainScreen::EnableFreelook(
bool value)
806 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
821#if defined(__WXMSW__)
823 SetCursor(wxCURSOR_CROSS);
825 SetCursor(wxNullCursor);
829 bool wayland =
false;
830 const char * val = std::getenv(
"WAYLAND_DISPLAY");
836 if (wayland ==
false)
837 wxSetCursor(wxCURSOR_CROSS);
839 wxSetCursor(wxCURSOR_BLANK);
842 wxSetCursor(wxNullCursor);
847void MainScreen::OnJoystickEvent(wxJoystickEvent &event)
852 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
869 Real step = 0, turn = 0, strafe = 0;
871 Real speed = speed_normal;
873 int MinX = joystick->GetXMin();
874 int MaxX = joystick->GetXMax();
875 int MinY = joystick->GetYMin();
876 int MaxY = joystick->GetYMax();
878 int CenterX = (MaxX + MinX) / 2;
879 int CenterY = (MaxY + MinY) / 2;
881 if (joystick->GetButtonState(joy_fast))
884 if (joystick->GetPosition(joy_forward) < CenterY)
886 if (joystick->GetPosition(joy_forward) > CenterY)
889 if (joystick->GetButtonState(joy_strafe))
891 if (joystick->GetPosition(joy_turn) > CenterX)
893 if (joystick->GetPosition(joy_turn) < CenterX)
898 if (joystick->GetPosition(joy_turn) > CenterX)
900 if (joystick->GetPosition(joy_turn) < CenterX)
908 if (joystick->GetButtonState(joy_click))
909 engine->GetVM()->GetHAL()->ClickedObject(
true,
false,
false,
false,
false, 0.0,
true);
void Strafe(Real speed=1.0)
void Binoculars(bool value)
void AttachToVehicle(bool value)
void FreelookMove(const Vector3 &rotation)
void SetViewMode(int mode)
void Turn(Real speed=1.0)
void SetFOVAngle(Real angle)
void Step(Real speed=1.0)
void Float(Real speed=1.0)
void Look(Real speed=1.0)
void Spin(Real speed=1.0)
void EnableGravity(bool value)
void EnableCollisions(bool value)
void ShowBoundingBoxes(bool value)
void ShowColliders(bool value)
std::string ToString(int number)