]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/extra/texpaint/texpaint.c
Q2Tools source - didn't import this in initially
[xonotic/netradiant.git] / tools / quake2 / extra / texpaint / texpaint.c
1 /*
2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
4
5 This file is part of Quake 2 Tools source code.
6
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22
23 #include "texpaint.h"
24
25 triangle_t      *faces;
26 int             numfaces;
27
28 int             skinwidth, skinheight;
29 int             picwidth, picheight;
30 int             width, height;
31 int             iwidth, iheight;
32 int             width2, height2;                // padded to ^2
33
34 float   tmcoords[10000][3][2];
35
36 byte            pic[1024*512];
37 unsigned        rgb[1024*512];
38
39 float   scale;
40 float   s_scale, t_scale;
41
42 char    filename[1024];
43 char    picfilename[1024];
44
45
46 /*
47 ================
48 BoundFaces
49 ================
50 */
51 vec3_t  mins, maxs;
52
53 void BoundFaces (void)
54 {
55         int             i,j,k;
56         triangle_t      *pol;
57         float   v;
58
59         for (i=0 ; i<3 ; i++)
60         {
61                 mins[i] = 9999;
62                 maxs[i] = -9999;
63         }
64
65         for (i=0 ; i<numfaces ; i++)
66         {
67                 pol = &faces[i];
68                 for (j=0 ; j<3 ; j++)
69                         for (k=0 ; k<3 ; k++)
70                         {
71                                 v = pol->verts[j][k];
72                                 if (v<mins[k])
73                                         mins[k] = v;
74                                 if (v>maxs[k])
75                                         maxs[k] = v;
76                         }
77         }
78
79         for (i=0 ; i<3 ; i++)
80         {
81                 mins[i] = floor(mins[i]);
82                 maxs[i] = ceil(maxs[i]);
83         }
84
85         width = maxs[0] - mins[0];
86         height = maxs[2] - mins[2];
87
88         printf ("width: %i  height: %i\n",width, height);
89
90         if (!skinwidth)
91         {       // old way
92                 scale = 8;
93                 if (width*scale >= 150)
94                         scale = 150.0 / width;
95                 if (height*scale >= 190)
96                         scale = 190.0 / height;
97                 s_scale = t_scale = scale;
98                 iwidth = ceil(width*scale) + 4;
99                 iheight = ceil(height*scale) + 4;
100         }
101         else
102         {       // new way
103                 s_scale = (skinwidth/2-4)/(float)width;
104                 t_scale = (skinheight-4)/(float)height;
105                 iwidth = skinwidth/2;
106                 iheight = skinheight;
107         }
108
109         printf ("scale: %f\n",scale);
110         printf ("iwidth: %i  iheight: %i\n",iwidth, iheight);
111 }
112
113
114
115 /*
116 ============
117 AddFace
118 ============
119 */
120 void AddFace (int facenum, triangle_t *f)
121 {
122         vec3_t          v1, v2, normal;
123         int             basex, basey;
124         int                     i, j;
125         int             coords[3][2];
126
127 //
128 // determine which side to map the teture to
129 //
130         VectorSubtract (f->verts[0], f->verts[1], v1);
131         VectorSubtract (f->verts[2], f->verts[1], v2);
132         CrossProduct (v1, v2, normal);
133
134         if (normal[1] > 0)
135                 basex = iwidth + 2;
136         else
137                 basex = 2;
138         basey = 2;
139
140         for (i=0 ; i<3 ; i++)
141         {
142                 coords[i][0] = Q_rint((f->verts[i][0] - mins[0])*s_scale + basex);
143                 coords[i][1] = Q_rint( (maxs[2] - f->verts[i][2])*t_scale + basey);
144 tmcoords[facenum][i][0] = coords[i][0]/(float)width2;
145 tmcoords[facenum][i][1] = coords[i][1]/(float)height2;
146         }
147
148 }
149
150
151 void CalcTmCoords (void)
152 {
153         int             j;
154
155         BoundFaces ();
156
157         for (j=0 ; j<numfaces ; j++)
158                 AddFace (j, &faces[j]);
159
160         printf ("numfaces: %i\n",numfaces);
161 }
162
163 //===============================================================================
164
165
166
167 #define MAX_NUM_ARGVS   32
168 int             argc;
169 char    *argv[MAX_NUM_ARGVS];
170
171 /*
172 ============
173 ParseCommandLine
174 ============
175 */
176 void ParseCommandLine (char *lpCmdLine)
177 {
178         argc = 1;
179         argv[0] = "programname";
180
181         while (*lpCmdLine && (argc < MAX_NUM_ARGVS))
182         {
183                 while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126)))
184                         lpCmdLine++;
185
186                 if (*lpCmdLine)
187                 {
188                         argv[argc] = lpCmdLine;
189                         argc++;
190
191                         while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126)))
192                                 lpCmdLine++;
193
194                         if (*lpCmdLine)
195                         {
196                                 *lpCmdLine = 0;
197                                 lpCmdLine++;
198                         }
199
200                 }
201         }
202 }
203
204 /*
205 =================
206 LoadTriFile
207 =================
208 */
209 void LoadTriFile (char *name)
210 {
211         strcpy (tri_filename, name);
212         SetWindowText (camerawindow, tri_filename);
213
214         LoadTriangleList (tri_filename, &faces, &numfaces);
215         InvalidateRect (camerawindow, NULL, false);
216 }
217
218 /*
219 ==================
220 TimerProc
221
222 ==================
223 */
224 int CALLBACK TimerProc(
225     HWND hwnd,  // handle of window for timer messages
226     UINT uMsg,  // WM_TIMER message
227     UINT idEvent,       // timer identifier
228     DWORD dwTime        // current system time
229    )
230 {
231         static int      counter;
232         char            name[1024];
233
234         if (!skin_filename[0])
235                 return 0;
236
237         if (!modified_past_autosave)
238         {
239                 counter = 0;
240                 return 0;
241         }
242
243         counter++;
244
245         if (counter < 3*5)
246                 return 0;               // save every five minutes
247
248         strcpy (name, skin_filename);
249         StripExtension (name);
250         strcat (name, "_autosave.lbm");
251         Skin_SaveFile (name);
252
253         modified_past_autosave = false;
254         counter = 0;
255
256         return 0;
257 }
258
259 /*
260 ==================
261 WinMain
262
263 ==================
264 */
265 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance
266                                         ,LPSTR lpCmdLine, int nCmdShow)
267 {
268     MSG                 msg;
269         HACCEL          accelerators;
270
271         main_instance = hInstance;
272
273         ParseCommandLine (lpCmdLine);
274
275         screen_width = GetSystemMetrics (SM_CXFULLSCREEN);
276         screen_height = GetSystemMetrics (SM_CYFULLSCREEN);
277
278         // hack for broken NT 4.0 dual screen
279         if (screen_width > 2*screen_height)
280                 screen_width /= 2;
281
282         accelerators = LoadAccelerators (hInstance
283                 , MAKEINTRESOURCE(IDR_ACCELERATOR1));
284         if (!accelerators)
285                 Sys_Error ("LoadAccelerators failed");
286
287         Main_Create (hInstance);
288         WCam_Create (hInstance);
289         WPal_Create (hInstance);
290         WSkin_Create (hInstance);
291
292         if (argc == 2)
293                 Skin_LoadFile (argv[1]);
294
295         SetTimer ( mainwindow, 1, 1000*20, TimerProc );
296
297         while (1)
298         {
299                 if (!GetMessage (&msg, mainwindow, 0, 0))
300                         break;
301                 if (!TranslateAccelerator(mainwindow, accelerators, &msg) )
302                 {
303                 TranslateMessage (&msg);
304                 DispatchMessage (&msg);
305                 }
306         }
307
308     /* return success of application */
309     return TRUE;
310 }
311