ui_node_map.c

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2002-2010 UFO: Alien Invasion.
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016 
00017 See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00023 */
00024 
00025 #include "../ui_nodes.h"
00026 #include "../ui_input.h"
00027 #include "../ui_parse.h"
00028 #include "../ui_actions.h"
00029 #include "ui_node_abstractnode.h"
00030 #include "ui_node_map.h"
00031 
00032 #include "../../client.h"
00033 #include "../../cl_game.h"
00034 #include "../../campaign/cp_campaign.h"
00035 #include "../../campaign/cp_map.h"
00036 #include "../../renderer/r_draw.h"
00037 
00038 #define EXTRADATA_TYPE mapExtraData_t
00039 #define EXTRADATA(node) UI_EXTRADATA(node, EXTRADATA_TYPE)
00040 #define EXTRADATACONST(node) UI_EXTRADATACONST(node, EXTRADATA_TYPE)
00041 
00042 static void UI_MapNodeDraw (uiNode_t *node)
00043 {
00044     if (CP_IsRunning()) {
00045         vec2_t pos;
00046 
00047         UI_GetNodeAbsPos(node, pos);
00048 
00049         /* Draw geoscape */
00050         R_PushClipRect(pos[0], pos[1], node->size[0], node->size[1]);
00051         MAP_DrawMap(node);
00052         R_PopClipRect();
00053     }
00054 }
00055 
00056 typedef enum {
00057     MODE_NULL,
00058     MODE_SHIFT2DMAP,
00059     MODE_SHIFT3DMAP,
00060     MODE_ZOOMMAP,
00061 } mapDragMode_t;
00062 
00063 static int oldMousePosX = 0;
00064 static int oldMousePosY = 0;
00065 static mapDragMode_t mode = MODE_NULL;
00066 
00067 static void UI_MapNodeCapturedMouseMove (uiNode_t *node, int x, int y)
00068 {
00069     switch (mode) {
00070     case MODE_SHIFT2DMAP:
00071     {
00072         int i;
00073         const float zoom = 0.5 / ccs.zoom;
00074         /* shift the map */
00075         ccs.center[0] -= (float) (mousePosX - oldMousePosX) / (ccs.mapSize[0] * ccs.zoom);
00076         ccs.center[1] -= (float) (mousePosY - oldMousePosY) / (ccs.mapSize[1] * ccs.zoom);
00077         for (i = 0; i < 2; i++) {
00078             /* clamp to min/max values */
00079             while (ccs.center[i] < 0.0)
00080                 ccs.center[i] += 1.0;
00081             while (ccs.center[i] > 1.0)
00082                 ccs.center[i] -= 1.0;
00083         }
00084         if (ccs.center[1] < zoom)
00085             ccs.center[1] = zoom;
00086         if (ccs.center[1] > 1.0 - zoom)
00087             ccs.center[1] = 1.0 - zoom;
00088         break;
00089     }
00090 
00091     case MODE_SHIFT3DMAP:
00092         /* rotate a model */
00093         ccs.angles[PITCH] += ROTATE_SPEED * (mousePosX - oldMousePosX) / ccs.zoom;
00094         ccs.angles[YAW] -= ROTATE_SPEED * (mousePosY - oldMousePosY) / ccs.zoom;
00095 
00096         /* clamp the angles */
00097         while (ccs.angles[YAW] > 0.0)
00098             ccs.angles[YAW] = 0.0;
00099         while (ccs.angles[YAW] < -180.0)
00100             ccs.angles[YAW] = -180.0;
00101 
00102         while (ccs.angles[PITCH] > 180.0)
00103             ccs.angles[PITCH] -= 360.0;
00104         while (ccs.angles[PITCH] < -180.0)
00105             ccs.angles[PITCH] += 360.0;
00106         break;
00107     case MODE_ZOOMMAP:
00108     {
00109         const float zoom = 0.5 / ccs.zoom;
00110         /* zoom the map */
00111         ccs.zoom *= pow(0.995, mousePosY - oldMousePosY);
00112         if (ccs.zoom < cl_mapzoommin->value)
00113             ccs.zoom = cl_mapzoommin->value;
00114         else if (ccs.zoom > cl_mapzoommax->value)
00115             ccs.zoom = cl_mapzoommax->value;
00116 
00117         if (ccs.center[1] < zoom)
00118             ccs.center[1] = zoom;
00119         if (ccs.center[1] > 1.0 - zoom)
00120             ccs.center[1] = 1.0 - zoom;
00121         break;
00122     }
00123     default:
00124         assert(qfalse);
00125     }
00126     oldMousePosX = x;
00127     oldMousePosY = y;
00128 }
00129 
00130 static void UI_MapNodeMouseDown (uiNode_t *node, int x, int y, int button)
00131 {
00132     /* finish the last drag before */
00133     if (mode != MODE_NULL)
00134         return;
00135 
00136     switch (button) {
00137     case K_MOUSE2:
00138         UI_SetMouseCapture(node);
00139         if (!cl_3dmap->integer)
00140             mode = MODE_SHIFT2DMAP;
00141         else
00142             mode = MODE_SHIFT3DMAP;
00143         MAP_StopSmoothMovement();
00144         oldMousePosX = x;
00145         oldMousePosY = y;
00146         break;
00147     case K_MOUSE3:
00148         UI_SetMouseCapture(node);
00149         mode = MODE_ZOOMMAP;
00150         oldMousePosX = x;
00151         oldMousePosY = y;
00152         break;
00153     }
00154 }
00155 
00156 static void UI_MapNodeMouseUp (uiNode_t *node, int x, int y, int button)
00157 {
00158     if (mode == MODE_NULL)
00159         return;
00160 
00161     switch (button) {
00162     case K_MOUSE2:
00163         if (mode == MODE_SHIFT3DMAP || mode == MODE_SHIFT2DMAP) {
00164             UI_MouseRelease();
00165         }
00166         break;
00167     case K_MOUSE3:
00168         if (mode == MODE_ZOOMMAP) {
00169             UI_MouseRelease();
00170         }
00171         break;
00172     }
00173 }
00174 
00179 static void UI_MapNodeCapturedMouseLost (uiNode_t *node)
00180 {
00181     mode = MODE_NULL;
00182 }
00183 
00184 static void UI_MapNodeZoom (uiNode_t *node, qboolean out)
00185 {
00186     ccs.zoom *= pow(0.995, (out ? 10: -10));
00187     if (ccs.zoom < cl_mapzoommin->value)
00188         ccs.zoom = cl_mapzoommin->value;
00189     else if (ccs.zoom > cl_mapzoommax->value)
00190         ccs.zoom = cl_mapzoommax->value;
00191 
00192     if (!cl_3dmap->integer) {
00193         if (ccs.center[1] < 0.5 / ccs.zoom)
00194             ccs.center[1] = 0.5 / ccs.zoom;
00195         if (ccs.center[1] > 1.0 - 0.5 / ccs.zoom)
00196             ccs.center[1] = 1.0 - 0.5 / ccs.zoom;
00197     }
00198     MAP_StopSmoothMovement();
00199 }
00200 
00201 static void UI_MapNodeMouseWheel (uiNode_t *node, qboolean down, int x, int y)
00202 {
00203     UI_MapNodeZoom(node, down);
00204 }
00205 
00206 static void UI_MapNodeZoomIn (uiNode_t *node, const uiCallContext_t *context)
00207 {
00208     UI_MapNodeZoom(node, qfalse);
00209 }
00210 
00211 static void UI_MapNodeZoomOut (uiNode_t *node, const uiCallContext_t *context)
00212 {
00213     UI_MapNodeZoom(node, qtrue);
00214 }
00215 
00219 static void UI_MapNodeLoading (uiNode_t *node)
00220 {
00221     Vector4Set(node->color, 1, 1, 1, 1);
00222 }
00223 
00224 
00225 static const value_t properties[] = {
00226     /* Use a right padding. */
00227     {"padding-right", V_FLOAT, UI_EXTRADATA_OFFSETOF(EXTRADATA_TYPE, paddingRight), MEMBER_SIZEOF(EXTRADATA_TYPE, paddingRight)},
00228     /* Call it to zoom out of the map */
00229     {"zoomin", V_UI_NODEMETHOD, ((size_t) UI_MapNodeZoomIn), 0},
00230     /* Call it to zoom into the map */
00231     {"zoomout", V_UI_NODEMETHOD, ((size_t) UI_MapNodeZoomOut), 0},
00232     {NULL, V_NULL, 0, 0}
00233 };
00234 
00235 void UI_RegisterMapNode (uiBehaviour_t *behaviour)
00236 {
00237     behaviour->name = "map";
00238     behaviour->properties = properties;
00239     behaviour->draw = UI_MapNodeDraw;
00240     behaviour->leftClick = MAP_MapClick;
00241     behaviour->mouseDown = UI_MapNodeMouseDown;
00242     behaviour->mouseUp = UI_MapNodeMouseUp;
00243     behaviour->capturedMouseMove = UI_MapNodeCapturedMouseMove;
00244     behaviour->capturedMouseLost = UI_MapNodeCapturedMouseLost;
00245     behaviour->mouseWheel = UI_MapNodeMouseWheel;
00246     behaviour->loading = UI_MapNodeLoading;
00247     behaviour->extraDataSize = sizeof(EXTRADATA_TYPE);
00248 }

Generated by  doxygen 1.6.2