]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/camwindow.cpp
Added feature:
[xonotic/netradiant.git] / radiant / camwindow.cpp
index 5d5bea9f4dfb8e116102d2365fa9edafe7d93f68..0c2acb5b483d6c2939d098377a0c61fa2ee2954d 100644 (file)
@@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "renderable.h"
 #include "preferencesystem.h"
 
-#include "generic/callback.h"
+#include "signal/signal.h"
 #include "container/array.h"
 #include "scenelib.h"
 #include "render.h"
@@ -60,16 +60,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #include "timer.h"
 
-std::vector<Callback> g_cameraMoved_callbacks;
+Signal0 g_cameraMoved_callbacks;
 
-void AddCameraMovedCallback(const Callback& callback)
+void AddCameraMovedCallback(const SignalHandler& handler)
 {
-  g_cameraMoved_callbacks.push_back(callback);
+  g_cameraMoved_callbacks.connectLast(handler);
 }
 
 void CameraMovedNotify()
 {
-  std::for_each(g_cameraMoved_callbacks.begin(), g_cameraMoved_callbacks.end(), CallbackInvoke());
+  g_cameraMoved_callbacks();
 }
 
 
@@ -137,6 +137,9 @@ struct camera_t
   Matrix4 projection;
   Matrix4 modelview;
 
+  bool m_strafe; // true when in strafemode toggled by the ctrl-key
+  bool m_strafe_forward; // true when in strafemode by ctrl-key and shift is pressed for forward strafing
+
   unsigned int movementflags;  // movement flags
   Timer m_keycontrol_timer;
   guint m_keymove_handler;
@@ -278,23 +281,38 @@ void Camera_setAngles(camera_t& camera, const Vector3& angles)
 
 void Camera_FreeMove(camera_t& camera, int dx, int dy)
 {
-  float dtime = 0.1f;
-  if (g_camwindow_globals_private.m_bCamInverseMouse)
-    camera.angles[CAMERA_PITCH] -= dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
-  else
-    camera.angles[CAMERA_PITCH] += dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+  // free strafe mode, toggled by the ctrl key with optional shift for forward movement
+  if(camera.m_strafe)
+  {
+         const float strafespeed = 0.65f;
+
+         camera.origin -= camera.vright * strafespeed * dx;
+         if(camera.m_strafe_forward)
+           camera.origin += camera.vpn * strafespeed * dy;
+         else
+           camera.origin += camera.vup * strafespeed * dy;
+  }
+  else// free rotation
+  {
+    const float dtime = 0.1f;
 
-  camera.angles[CAMERA_YAW] += dx * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+    if (g_camwindow_globals_private.m_bCamInverseMouse)
+        camera.angles[CAMERA_PITCH] -= dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
+    else
+        camera.angles[CAMERA_PITCH] += dy * dtime * g_camwindow_globals_private.m_nAngleSpeed;
 
-  if (camera.angles[CAMERA_PITCH] > 90)
-    camera.angles[CAMERA_PITCH] = 90;
-  else if (camera.angles[CAMERA_PITCH] < -90)
-    camera.angles[CAMERA_PITCH] = -90;
+    camera.angles[CAMERA_YAW] += dx * dtime * g_camwindow_globals_private.m_nAngleSpeed;
 
-  if (camera.angles[CAMERA_YAW] >= 360)
-    camera.angles[CAMERA_YAW] -=360;
-  else if (camera.angles[CAMERA_YAW] <= 0)
-    camera.angles[CAMERA_YAW] +=360;
+    if (camera.angles[CAMERA_PITCH] > 90)
+        camera.angles[CAMERA_PITCH] = 90;
+    else if (camera.angles[CAMERA_PITCH] < -90)
+        camera.angles[CAMERA_PITCH] = -90;
+
+    if (camera.angles[CAMERA_YAW] >= 360)
+        camera.angles[CAMERA_YAW] -=360;
+    else if (camera.angles[CAMERA_YAW] <= 0)
+        camera.angles[CAMERA_YAW] +=360;
+  }
 
   Camera_updateModelview(camera);
   Camera_Freemove_updateAxes(camera);
@@ -638,7 +656,15 @@ public:
 
 void Camera_motionDelta(int x, int y, unsigned int state, void* data)
 {
-  reinterpret_cast<camera_t*>(data)->m_mouseMove.motion_delta(x, y, state);
+  camera_t* cam = reinterpret_cast<camera_t*>(data);
+
+  cam->m_mouseMove.motion_delta(x, y, state);
+  cam->m_strafe = (state & GDK_CONTROL_MASK) != 0;
+
+  if(cam->m_strafe)
+    cam->m_strafe_forward = (state & GDK_SHIFT_MASK) != 0;
+  else
+    cam->m_strafe_forward = false;
 }
 
 class CamWnd
@@ -1120,6 +1146,7 @@ void CamWnd_Move_Discrete_Import(bool value)
 }
 
 
+
 void CamWnd_Add_Handlers_Move(CamWnd& camwnd)
 {
   camwnd.m_selection_button_press_handler = g_signal_connect(G_OBJECT(camwnd.m_gl_widget), "button_press_event", G_CALLBACK(selection_button_press), camwnd.m_window_observer);
@@ -1350,9 +1377,8 @@ static gboolean camwindow_freemove_focusout(GtkWidget* widget, GdkEventFocus* ev
 
 void CamWnd::EnableFreeMove()
 {
-#if 0
-  globalOutputStream() << "EnableFreeMove\n";
-#endif
+  //globalOutputStream() << "EnableFreeMove\n";
+
   ASSERT_MESSAGE(!m_bFreeMove, "EnableFreeMove: free-move was already enabled");
   m_bFreeMove = true;
   Camera_clearMovementFlags(getCamera(), MOVE_ALL);
@@ -1369,9 +1395,8 @@ void CamWnd::EnableFreeMove()
 
 void CamWnd::DisableFreeMove()
 {
-#if 0
-  globalOutputStream() << "DisableFreeMove\n";
-#endif
+  //globalOutputStream() << "DisableFreeMove\n";
+
   ASSERT_MESSAGE(m_bFreeMove, "DisableFreeMove: free-move was not enabled");
   m_bFreeMove = false;
   Camera_clearMovementFlags(getCamera(), MOVE_ALL);
@@ -1532,7 +1557,7 @@ void CamWnd::Cam_Draw()
   }
 
 
-  unsigned int globalstate = RENDER_DEPTHTEST|RENDER_COLOURWRITE|RENDER_DEPTHWRITE|RENDER_ALPHATEST|RENDER_BLEND|RENDER_CULLFACE|RENDER_COLOUR|RENDER_OFFSETLINE;
+  unsigned int globalstate = RENDER_DEPTHTEST|RENDER_COLOURWRITE|RENDER_DEPTHWRITE|RENDER_ALPHATEST|RENDER_BLEND|RENDER_CULLFACE|RENDER_COLOURARRAY|RENDER_OFFSETLINE|RENDER_POLYGONSMOOTH|RENDER_LINESMOOTH|RENDER_FOG|RENDER_COLOURCHANGE;
   switch (m_Camera.draw_mode)
   {
   case cd_wire:
@@ -1752,6 +1777,11 @@ void CamWnd_constructToolbar(GtkToolbar* toolbar)
 void CamWnd_registerShortcuts()
 {
   toggle_add_accelerator("ToggleCubicClip");
+  
+  if(g_pGameDescription->mGameType == "doom3")
+  {
+    command_connect_accelerator("TogglePreview");
+  }
 }
 
 
@@ -1781,6 +1811,17 @@ void CamWnd_SetMode(camera_draw_mode mode)
   }
 }
 
+void CamWnd_TogglePreview(void)
+{
+  // gametype must be doom3 for this function to work
+  // if the gametype is not doom3 something is wrong with the
+  // global command list or somebody else calls this function.
+  ASSERT_MESSAGE(g_pGameDescription->mGameType == "doom3", "CamWnd_TogglePreview called although mGameType is not doom3 compatible");
+
+  // switch between textured and lighting mode
+  CamWnd_SetMode((CamWnd_GetMode() == cd_lighting) ? cd_texture : cd_lighting);
+}
+
 
 CameraModel* g_camera_model = 0;
 
@@ -1930,6 +1971,7 @@ void Camera_registerPreferencesPage()
 
 typedef FreeCaller1<bool, CamWnd_Move_Discrete_Import> CamWndMoveDiscreteImportCaller;
 
+/// \brief Initialisation for things that have the same lifespan as this module.
 void CamWnd_Construct()
 {
   GlobalCommands_insert("CenterView", FreeCaller<GlobalCamera_ResetAngles>(), Accelerator(GDK_End));
@@ -1945,6 +1987,11 @@ void CamWnd_Construct()
   GlobalCommands_insert("LookThroughSelected", FreeCaller<GlobalCamera_LookThroughSelected>());
   GlobalCommands_insert("LookThroughCamera", FreeCaller<GlobalCamera_LookThroughCamera>());
 
+  if(g_pGameDescription->mGameType == "doom3")
+  {
+    GlobalCommands_insert("TogglePreview", FreeCaller<CamWnd_TogglePreview>(), Accelerator(GDK_F3));
+  }
+
   GlobalShortcuts_insert("CameraForward", Accelerator(GDK_Up));
   GlobalShortcuts_insert("CameraBack", Accelerator(GDK_Down));
   GlobalShortcuts_insert("CameraLeft", Accelerator(GDK_Left));