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_jump = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Jump", 3);
108 joy_turn = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Turn", 0);
109 joy_forward = hal->GetConfigInt(hal->joyconfigfile,
"Skyscraper.Frontend.Joystick.Forward", 1);
113 panel =
new wxPanel(
this, wxID_ANY, wxDefaultPosition, wxSize(width, height), wxNO_BORDER);
114 panel->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(MainScreen::OnKeyDown), NULL,
this);
115 panel->Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(MainScreen::OnKeyUp), NULL,
this);
116 panel->Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
117 panel->Connect(wxID_ANY, wxEVT_LEFT_UP, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
118 panel->Connect(wxID_ANY, wxEVT_LEFT_DCLICK, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
119 panel->Connect(wxID_ANY, wxEVT_MIDDLE_DOWN, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
120 panel->Connect(wxID_ANY, wxEVT_MIDDLE_UP, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
121 panel->Connect(wxID_ANY, wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
122 panel->Connect(wxID_ANY, wxEVT_RIGHT_DOWN, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
123 panel->Connect(wxID_ANY, wxEVT_RIGHT_UP, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
124 panel->Connect(wxID_ANY, wxEVT_RIGHT_DCLICK, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
125 panel->Connect(wxID_ANY, wxEVT_MOUSEWHEEL, wxMouseEventHandler(MainScreen::OnMouseButton), NULL,
this);
128MainScreen::~MainScreen()
131 joystick->ReleaseCapture();
136void MainScreen::OnIconize(wxIconizeEvent& event)
140 VM *vm = frontend->GetVM();
141 vm->Pause =
event.IsIconized();
143 if (vm->Pause ==
true)
144 vm->GetHAL()->Report(
"Pausing simulator...",
"");
146 vm->GetHAL()->Report(
"Resuming simulator...",
"");
149void MainScreen::OnSize(wxSizeEvent& WXUNUSED(event))
151 VM *vm = frontend->GetVM();
152 HAL *hal = vm->GetHAL();
155 panel->SetSize(this->GetClientSize().GetWidth(), this->GetClientSize().GetHeight());
157 if (hal->GetRenderWindow())
159#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
160 Real scale = this->GetContentScaleFactor();
161 hal->GetRenderWindow()->resize(this->GetClientSize().GetWidth() * scale, this->GetClientSize().GetHeight() * scale);
163 hal->GetRenderWindow()->windowMovedOrResized();
166 for (
size_t i = 0; i < hal->mCameras.size(); i++)
168 hal->mCameras[i]->setAspectRatio(
Real(hal->mViewports[i]->getActualWidth()) /
Real(hal->mViewports[i]->getActualHeight()));
172void MainScreen::OnClose(wxCloseEvent& event)
176 if (frontend->StartupRunning ==
false)
178 int result = wxMessageBox(wxT(
"Are you sure you want to exit?"), wxT(
"Skyscraper"), wxYES_NO | wxCENTER);
187void MainScreen::ShowWindow()
192void MainScreen::OnIdle(wxIdleEvent& event)
199 if (frontend->GetVM()->Pause ==
false)
201 if (this->HasFocus() && !panel->HasFocus())
205 bool result = frontend->Loop();
209 catch (Ogre::Exception &e)
211 frontend->GetVM()->GetHAL()->ReportFatalError(
"Unhandled OGRE exception:\n\n" + e.getFullDescription() +
"\n\nSkyscraper will now exit. Please report this as a bug.",
"");
215 HandleMouseMovement();
223void MainScreen::OnPaint(wxPaintEvent& event)
231void MainScreen::OnActivate(wxActivateEvent &event)
233 Active =
event.GetActive();
237void MainScreen::OnKeyDown(wxKeyEvent& event)
241 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
257 int key =
event.GetKeyCode();
259#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE
261 if (wxGetKeyState((wxKeyCode)key) ==
false)
265 if (key == WXK_ESCAPE)
267 int result = wxMessageBox(wxT(
"Exit and return to the main menu?"), wxT(
"Skyscraper"), wxYES_NO | wxCENTER);
269 frontend->GetVM()->Shutdown =
true;
275 frontend->GetGUI()->ShowControlReference();
281 HAL *hal = frontend->GetVM()->GetHAL();
282 Ogre::RenderSystem *rendersystem = hal->mRoot->getRenderSystem();
284 int batches = (int)rendersystem->_getBatchCount();
285 int triangles = (int)rendersystem->_getFaceCount();
286 int vertices = (int)rendersystem->_getVertexCount();
295 if (event.ControlDown() && key == (wxKeyCode)
'C')
303 if (key == WXK_SPACE)
310 if (key == (wxKeyCode)key_noclip)
318 frontend->GetVM()->GetHAL()->Report(
"Gravity and collision detection on",
"");
320 frontend->GetVM()->GetHAL()->Report(
"Gravity and collision detection off",
"");
323 if (event.ControlDown() ==
true && key == (wxKeyCode)
'R')
325 engine->Reload =
true;
347 frontend->colliders = !frontend->colliders;
353 if (frontend->wireframe == 0)
355 frontend->GetVM()->GetSkySystem()->EnableSky(
false);
357 frontend->wireframe = 1;
359 else if (frontend->wireframe == 1)
362 frontend->wireframe = 2;
364 else if (frontend->wireframe == 2)
366 frontend->GetVM()->GetSkySystem()->EnableSky(
true);
368 frontend->wireframe = 0;
374 std::string prefix = frontend->GetDataPath();
375 frontend->GetVM()->GetHAL()->GetRenderWindow()->writeContentsToTimestampedFile(prefix +
"screenshots/skyscraper-",
".jpg");
380 frontend->GetGUI()->ShowDebugPanel();
392 frontend->SetFullScreen(!frontend->FullScreen);
399 frontend->boxes = !frontend->boxes;
405 frontend->GetVM()->GetHAL()->ToggleStats();
408 if (key == WXK_NUMPAD_SUBTRACT || key == (wxKeyCode)
'[')
415 if (key == WXK_NUMPAD_ADD || key == (wxKeyCode)
']')
423 if (key == (wxKeyCode)key_pickup)
432 if (key == (wxKeyCode)key_load)
434 frontend->GetGUI()->ShowLoadDialog();
439 if (key == (wxKeyCode)
'1')
441 frontend->GetVM()->SetActiveEngine(0);
443 else if (key == (wxKeyCode)
'2')
445 frontend->GetVM()->SetActiveEngine(1);
447 else if (key == (wxKeyCode)
'3')
449 frontend->GetVM()->SetActiveEngine(2);
451 else if (key == (wxKeyCode)
'4')
453 frontend->GetVM()->SetActiveEngine(3);
455 else if (key == (wxKeyCode)
'5')
457 frontend->GetVM()->SetActiveEngine(4);
459 else if (key == (wxKeyCode)
'6')
461 frontend->GetVM()->SetActiveEngine(5);
463 else if (key == (wxKeyCode)
'7')
465 frontend->GetVM()->SetActiveEngine(6);
467 else if (key == (wxKeyCode)
'8')
469 frontend->GetVM()->SetActiveEngine(7);
471 else if (key == (wxKeyCode)
'9')
473 frontend->GetVM()->SetActiveEngine(8);
475 else if (key == (wxKeyCode)
'0')
477 frontend->GetVM()->SetActiveEngine(9);
481 if (key == (wxKeyCode)key_enter)
488 GetKeyStates(engine, event,
true);
490 ProcessMovement(engine, event.ControlDown(), event.ShiftDown());
493void MainScreen::OnKeyUp(wxKeyEvent& event)
497 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
502 GetKeyStates(engine, event,
false);
504 ProcessMovement(engine, event.ControlDown(), event.ShiftDown());
507void MainScreen::GetKeyStates(EngineContext *engine, wxKeyEvent& event,
bool down)
510 Camera *camera = engine->GetSystem()->camera;
515 int key =
event.GetKeyCode();
521 if (key == WXK_RIGHT || key == (wxKeyCode)key_right)
522 frontend->strafe_right = down;
524 else if (key == WXK_LEFT || key == (wxKeyCode)key_left)
525 frontend->strafe_left = down;
527 else if (key == WXK_UP || key == (wxKeyCode)key_up)
528 frontend->float_up = down;
530 else if (key == WXK_DOWN || key == (wxKeyCode)key_down)
531 frontend->float_down = down;
533 else if (key == WXK_PAGEUP || key == (wxKeyCode)key_lookup)
534 frontend->spin_up = down;
536 else if (key == WXK_PAGEDOWN || key == (wxKeyCode)key_lookdown)
537 frontend->spin_down = down;
543 if (key == WXK_RIGHT || key == (wxKeyCode)key_right)
544 frontend->turn_right = down;
546 if (key == WXK_LEFT || key == (wxKeyCode)key_left)
547 frontend->turn_left = down;
549 if (key == (wxKeyCode)key_straferight)
550 frontend->strafe_right = down;
552 if (key == (wxKeyCode)key_strafeleft)
553 frontend->strafe_left = down;
557 if (key == WXK_RIGHT || key == (wxKeyCode)key_right || key == (wxKeyCode)key_straferight)
558 frontend->strafe_right = down;
560 if (key == WXK_LEFT || key == (wxKeyCode)key_left || key == (wxKeyCode)key_strafeleft)
561 frontend->strafe_left = down;
564 if (key == WXK_PAGEUP || key == (wxKeyCode)key_lookup)
565 frontend->look_up = down;
567 if (key == WXK_PAGEDOWN || key == (wxKeyCode)key_lookdown)
568 frontend->look_down = down;
570 if (key == WXK_UP || key == (wxKeyCode)key_up)
571 frontend->step_forward = down;
573 if (key == WXK_DOWN || key == (wxKeyCode)key_down)
574 frontend->step_backward = down;
577 if (key == (wxKeyCode)key_binoculars)
583 if (key == (wxKeyCode)key_crouch)
589 if (key == WXK_HOME || key == (wxKeyCode)key_floatup)
590 frontend->float_up = down;
591 if (key == WXK_END || key == (wxKeyCode)key_floatdown)
592 frontend->float_down = down;
597 if (key == WXK_LEFT || key == (wxKeyCode)key_left)
598 engine->GetSystem()->camera->Drive(
true,
false,
false,
false, down);
599 if (key == WXK_RIGHT || key == (wxKeyCode)key_right)
600 engine->GetSystem()->camera->Drive(
false,
true,
false,
false, down);
601 if (key == WXK_DOWN || key == (wxKeyCode)key_down)
602 engine->GetSystem()->camera->Drive(
false,
false,
true,
false, down);
603 if (key == WXK_UP || key == (wxKeyCode)key_up)
604 engine->GetSystem()->camera->Drive(
false,
false,
false,
true, down);
609void MainScreen::ProcessMovement(EngineContext *engine,
bool control,
bool shift,
bool angle_only)
613 Real strafe = 0, floatval = 0, spin = 0, turn = 0, look = 0, step = 0;
616 Camera *camera = engine->GetSystem()->camera;
625 if (angle_only ==
false)
630 camera->
speed = speed_slow;
631 else if (shift ==
true)
632 camera->
speed = speed_fast;
634 if (frontend->step_forward ==
true)
635 step += speed_normal;
636 if (frontend->step_backward ==
true)
637 step -= speed_normal;
639 if (frontend->strafe_left ==
true)
640 strafe -= speed_normal;
641 if (frontend->strafe_right ==
true)
642 strafe += speed_normal;
644 if (frontend->float_up ==
true)
645 floatval += speed_normal;
646 if (frontend->float_down ==
true)
647 floatval -= speed_normal;
652 camera->
Float(floatval);
655 if (frontend->spin_up ==
true)
656 spin += speed_normal;
657 if (frontend->spin_down ==
true)
658 spin -= speed_normal;
660 if (frontend->turn_left ==
true)
661 turn -= speed_normal;
662 if (frontend->turn_right ==
true)
663 turn += speed_normal;
665 if (frontend->look_up ==
true)
666 look += speed_normal;
667 if (frontend->look_down ==
true)
668 look -= speed_normal;
676void MainScreen::OnMouseButton(wxMouseEvent& event)
681 if (event.GetWheelRotation() > 0)
683 EnableFreelook(
true);
686 else if (event.GetWheelRotation() < 0)
688 EnableFreelook(
false);
693 bool left =
event.LeftDown();
694 bool left_dclick =
event.LeftDClick();
695 bool right =
event.RightDown();
696 bool right_dclick =
event.RightDClick();
698 HAL *hal = frontend->GetVM()->GetHAL();
700 if (left ==
false && right ==
false && left_dclick ==
false && right_dclick ==
false)
702 hal->UnclickedObject();
707 Real scale = frontend->window->GetContentScaleFactor();
709#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
711 if (frontend->GetVM()->macos_major == 10 && frontend->GetVM()->macos_minor < 15)
715 hal->ClickedObject(left, wxGetKeyState(WXK_SHIFT), wxGetKeyState(WXK_CONTROL), wxGetKeyState(WXK_ALT), (right || right_dclick), scale,
false);
719void MainScreen::HandleMouseMovement()
721 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
723 if (!engine || IsActive() ==
false)
726 if (engine->IsRunning() ==
false)
741 int old_mouse_x = camera->
mouse_x;
742 int old_mouse_y = camera->
mouse_y;
745 camera->
mouse_x = ScreenToClient(wxGetMousePosition()).x;
746 camera->
mouse_y = ScreenToClient(wxGetMousePosition()).y;
751 if (frontend->freelook ==
false)
754 frontend->turn_right = 0;
755 frontend->turn_left = 0;
757 EnableFreelook(
true);
760 frontend->freelook =
true;
763 Real width = GetClientSize().GetWidth();
764 Real height = GetClientSize().GetHeight();
767 if (old_mouse_x != camera->
mouse_x || old_mouse_y != camera->
mouse_y)
769 WarpPointer(width * 0.5, height * 0.5);
772 rotational.x = -(((
Real)camera->
mouse_y - (height / 2))) / (height * 2);
773 rotational.y = -((width / 2) - (
Real)camera->
mouse_x) / (width * 2);
776 Real fps_adjust = Simcore->
FPS / 60;
777 rotational *= fps_adjust;
785 ProcessMovement(engine,
false,
false,
true);
790 if (frontend->freelook ==
true)
793 frontend->strafe_right = 0;
794 frontend->strafe_left = 0;
795 if (old_mouse_x != camera->
mouse_x || old_mouse_y != camera->
mouse_y)
797 ProcessMovement(engine,
false,
false,
true);
799 frontend->freelook =
false;
803void MainScreen::EnableFreelook(
bool value)
807 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
822#if defined(__WXMSW__)
824 SetCursor(wxCURSOR_CROSS);
826 SetCursor(wxNullCursor);
830 bool wayland =
false;
831 const char * val = std::getenv(
"WAYLAND_DISPLAY");
837 if (wayland ==
false)
838 wxSetCursor(wxCURSOR_CROSS);
840 wxSetCursor(wxCURSOR_BLANK);
843 wxSetCursor(wxNullCursor);
848void MainScreen::OnJoystickEvent(wxJoystickEvent &event)
853 EngineContext *engine = frontend->GetVM()->GetActiveEngine();
870 Real step = 0, turn = 0, strafe = 0;
872 Real speed = speed_normal;
874 int MinX = joystick->GetXMin();
875 int MaxX = joystick->GetXMax();
876 int MinY = joystick->GetYMin();
877 int MaxY = joystick->GetYMax();
879 int CenterX = (MaxX + MinX) / 2;
880 int CenterY = (MaxY + MinY) / 2;
881 int range = (MaxX - MinX) / 8;
883 if (joystick->GetButtonState(joy_fast))
886 if (joystick->GetPosition(joy_forward) < (CenterY - range))
888 if (joystick->GetPosition(joy_forward) > (CenterY + range))
891 if (joystick->GetButtonState(joy_strafe))
893 if (joystick->GetPosition(joy_turn) > (CenterX + range))
895 if (joystick->GetPosition(joy_turn) < (CenterX - range))
900 if (joystick->GetPosition(joy_turn) > (CenterX + range))
902 if (joystick->GetPosition(joy_turn) < (CenterX - range))
910 if (joystick->GetButtonState(joy_click))
911 engine->GetVM()->GetHAL()->ClickedObject(
true,
false,
false,
false,
false, 0.0,
true);
913 if (joystick->GetButtonState(joy_jump) && camera->
IsOnGround() ==
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)