transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / radiant / points.cpp
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 #include "stdafx.h"\r
23 \r
24 #define MAX_POINTFILE   8192\r
25 static vec3_t   s_pointvecs[MAX_POINTFILE];\r
26 static int              s_num_points, s_check_point;\r
27 \r
28 CPointfile g_pointfile;\r
29 \r
30 // CPointfile routine used by the standard code ---------------------------------\r
31 \r
32 void CPointfile::Init()\r
33 {\r
34   s_num_points = 0;\r
35 }\r
36 \r
37 void CPointfile::PushPoint (vec3_t v)\r
38 {\r
39         if (s_num_points < MAX_POINTFILE)\r
40         {\r
41                 VectorCopy (v, s_pointvecs[s_num_points]);\r
42                 s_num_points++;\r
43         }\r
44 }\r
45 \r
46 // create the display list at the end\r
47 void CPointfile::GenerateDisplayList()\r
48 {\r
49   int i;\r
50 \r
51         if (!g_qeglobals.d_pointfile_display_list)\r
52                 g_qeglobals.d_pointfile_display_list = qglGenLists(1);\r
53 \r
54   qglNewList (g_qeglobals.d_pointfile_display_list,  GL_COMPILE);\r
55   \r
56         qglColor3f (1, 0, 0);\r
57         qglDisable(GL_TEXTURE_2D);\r
58         qglDisable(GL_TEXTURE_1D);\r
59         qglLineWidth (4);\r
60         qglBegin(GL_LINE_STRIP);\r
61         for (i=0;i<s_num_points;i++)\r
62         {\r
63           if (s_num_points < MAX_POINTFILE)\r
64           {\r
65             qglVertex3fv (s_pointvecs[i]);\r
66           }\r
67         }\r
68         qglEnd();\r
69         qglLineWidth (1);\r
70         \r
71         qglEndList ();\r
72         \r
73         s_check_point = 0;\r
74 }\r
75 \r
76 // old (but still relevant) pointfile code -------------------------------------\r
77 \r
78 void Pointfile_Delete (void)\r
79 {\r
80         char    name[1024];\r
81 \r
82         strcpy (name, currentmap);\r
83         StripExtension (name);\r
84         strcat (name, ".lin");\r
85 \r
86         remove(name);\r
87 }\r
88 \r
89 // advance camera to next point\r
90 void Pointfile_Next (void)\r
91 {\r
92         vec3_t  dir;\r
93 \r
94         if (s_check_point >= s_num_points-2)\r
95         {\r
96                 Sys_Status ("End of pointfile", 0);\r
97                 return;\r
98         }\r
99         s_check_point++;\r
100         VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetCamWnd()->Camera()->origin);\r
101         VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin());\r
102         VectorSubtract (s_pointvecs[s_check_point+1], g_pParentWnd->GetCamWnd()->Camera()->origin, dir);\r
103         VectorNormalize (dir, dir);\r
104         g_pParentWnd->GetCamWnd()->Camera()->angles[1] = atan2 (dir[1], dir[0])*180/3.14159;\r
105         g_pParentWnd->GetCamWnd()->Camera()->angles[0] = asin (dir[2])*180/3.14159;\r
106 \r
107         Sys_UpdateWindows (W_ALL);\r
108 }\r
109 \r
110 // advance camera to previous point\r
111 void Pointfile_Prev (void)\r
112 {\r
113         vec3_t  dir;\r
114 \r
115         if ( s_check_point == 0)\r
116         {\r
117                 Sys_Status ("Start of pointfile", 0);\r
118                 return;\r
119         }\r
120         s_check_point--;\r
121         VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetCamWnd()->Camera()->origin);\r
122         VectorCopy (s_pointvecs[s_check_point], g_pParentWnd->GetXYWnd()->GetOrigin());\r
123         VectorSubtract (s_pointvecs[s_check_point+1], g_pParentWnd->GetCamWnd()->Camera()->origin, dir);\r
124         VectorNormalize (dir, dir);\r
125         g_pParentWnd->GetCamWnd()->Camera()->angles[1] = atan2 (dir[1], dir[0])*180/3.14159;\r
126         g_pParentWnd->GetCamWnd()->Camera()->angles[0] = asin (dir[2])*180/3.14159;\r
127 \r
128         Sys_UpdateWindows (W_ALL);\r
129 }\r
130 \r
131 void WINAPI Pointfile_Check (void)\r
132 {\r
133         char    name[1024];\r
134         int             size;\r
135         char    *data;\r
136   char  *text;\r
137   int   line = 1;\r
138         vec3_t v;\r
139 \r
140         strcpy (name, currentmap);\r
141         StripExtension (name);\r
142         strcat (name, ".lin");\r
143 \r
144         size = vfsLoadFullPathFile (name, (void**)&data);\r
145   if (size <= 0)\r
146   {\r
147     Sys_FPrintf (SYS_ERR, "Pointfile %s not found\n", name);\r
148                 return;\r
149   }\r
150 \r
151   // store a pointer\r
152   text = data;\r
153 \r
154         Sys_Printf ("Reading pointfile %s\n", name);\r
155 \r
156   g_pointfile.Init();\r
157 \r
158         while (*data)\r
159         {\r
160     if (sscanf(data,"%f %f %f", &v[0], &v[1], &v[2]) != 3)\r
161     {\r
162       Sys_Printf("Corrupt point file, line %d\n",line);\r
163                         break;\r
164     }\r
165 \r
166         while (*data && *data != '\n')\r
167     {\r
168       if (*(data-1) == ' ' && *(data) == '-' && *(data+1) == ' ')\r
169         break;\r
170                   data++;\r
171     }\r
172     // deal with zhlt style point files.\r
173     if (*data == '-')\r
174     {\r
175       if (sscanf(data,"- %f %f %f", &v[0], &v[1], &v[2]) != 3)\r
176       {\r
177         Sys_Printf("Corrupt point file, line %d\n",line);\r
178         break;\r
179       }\r
180 \r
181       while (*data && *data != '\n')\r
182                     data++;\r
183 \r
184     }\r
185     while (*data == '\n')\r
186     {\r
187       data++; // skip the \n\r
188       line++;\r
189     }\r
190                 g_pointfile.PushPoint (v);\r
191         }\r
192 \r
193   g_free(text);\r
194         \r
195         g_pointfile.GenerateDisplayList();\r
196 \r
197   Sys_UpdateWindows (W_ALL);\r
198 }\r
199 \r
200 void Pointfile_Draw( void )\r
201 {\r
202   qglCallList (g_qeglobals.d_pointfile_display_list);\r
203 }\r
204 \r
205 void Pointfile_Clear (void)\r
206 {\r
207         if (!g_qeglobals.d_pointfile_display_list)\r
208                 return;\r
209 \r
210         qglDeleteLists (g_qeglobals.d_pointfile_display_list, 1);\r
211         g_qeglobals.d_pointfile_display_list = 0;\r
212         Sys_UpdateWindows (W_ALL);\r
213 }\r
214 \r
215 // CPointfile implementation for SAX speicific stuff -------------------------------\r
216 void CPointfile::saxStartElement (message_info_t *ctx, const xmlChar *name, const xmlChar **attrs)\r
217 {\r
218   if (strcmp ((char *)name, "polyline")==0)\r
219   {\r
220     Init();\r
221     // there's a prefs setting to avoid stopping on leak\r
222     if (!g_PrefsDlg.m_bLeakStop)\r
223       ctx->stop_depth = 0;\r
224   }\r
225 }\r
226 \r
227 void CPointfile::saxEndElement (message_info_t *ctx, const xmlChar *name)\r
228 {\r
229   if (strcmp ((char *)name, "polyline")==0)\r
230   {\r
231     // we are done\r
232     GenerateDisplayList();\r
233     ctx->bGeometry = false;\r
234   }\r
235 }\r
236 \r
237 // only "point" is expected to have characters around here\r
238 void CPointfile::saxCharacters (message_info_t *ctx, const xmlChar *ch, int len)\r
239 {\r
240   vec3_t v;\r
241   \r
242   sscanf ((char *)ch, "%f %f %f\n", &v[0], &v[1], &v[2]);\r
243   PushPoint (v);\r
244 }\r
245 \r
246 char * CPointfile::getName()\r
247 {\r
248   return "Map is leaked";\r
249 }\r