]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/book.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / book.c
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 \r
23 #include "qdata.h"\r
24 \r
25 byte                    *byteimage, *lbmpalette;\r
26 int                             byteimagewidth, byteimageheight;\r
27 \r
28 qboolean                TrueColorImage;\r
29 int                             longimagewidth, longimageheight;\r
30 \r
31 char                    book_prefix[1024];\r
32 byte                    buffer[640 * 480];\r
33 unsigned long   bufferl[640 * 480];\r
34 \r
35 miptex_t *CreateBook8(byte *buffer, int w, int h, byte *palette, int *FinalSize)\r
36 {\r
37         miptex_t        *mp;\r
38         int                     i, j;\r
39         byte            *pos;\r
40         int                     size;\r
41 \r
42         size = sizeof(*mp) + (w * h);\r
43         mp = (miptex_t *)SafeMalloc(size, "CreateBook8");\r
44         memset(mp, 0, size);\r
45 \r
46         mp->version = MIP_VERSION;\r
47 \r
48         for(i=j=0;i<256;i++,j+=3)\r
49         {\r
50                 mp->palette[i].r = palette[j];\r
51                 mp->palette[i].g = palette[j+1];\r
52                 mp->palette[i].b = palette[j+2];\r
53         }\r
54         pos = (byte *)(mp + 1);\r
55 \r
56         mp->width[0] = w;\r
57         mp->height[0] = h;\r
58         mp->offsets[0] = sizeof(*mp);\r
59         memcpy(pos, buffer, w * h);\r
60 \r
61         *FinalSize = size;\r
62         return(mp);\r
63 }\r
64 \r
65 miptex32_t *CreateBook32(long *buffer, int w, int h, int *FinalSize)\r
66 {\r
67         miptex32_t      *mp;\r
68         byte            *pos;\r
69         int                     size;\r
70 \r
71         size = sizeof(*mp) + (w * h * 4);\r
72         mp = (miptex32_t *)SafeMalloc(size, "CreateBook32");\r
73         memset(mp, 0, size);\r
74 \r
75         mp->version = MIP32_VERSION;\r
76 \r
77         pos = (byte *)(mp + 1);\r
78 \r
79         mp->width[0] = w;\r
80         mp->height[0] = h;\r
81         mp->offsets[0] = sizeof(*mp);\r
82         memcpy(pos, buffer, w * h * 4);\r
83 \r
84         *FinalSize = size;\r
85         return(mp);\r
86 }\r
87 \r
88 \r
89 // Routines to chop a random sized image into gl texture friendly chunks\r
90 \r
91 typedef struct rect_s \r
92 {\r
93         int             x, y;\r
94         int             w, h;\r
95         char    name[4];\r
96 } rect_t;\r
97 \r
98 int GetCoords(int x, int store[MAX_MD2SKINS])\r
99 {\r
100         int             index, start, delta;\r
101 \r
102         index = 0;\r
103         start = 0;\r
104         delta = 256;\r
105 \r
106         store[index++] = start;\r
107         while(x)\r
108         {\r
109                 if(x >= delta)\r
110                 {\r
111                         start += delta;\r
112                         store[index++] = start;\r
113                         x -= delta;\r
114                 }\r
115                 else\r
116                 {\r
117                         delta >>= 1;\r
118                 }\r
119         }\r
120         return(index);\r
121 }\r
122 \r
123 int ChopImage(int w, int h, rect_t coords[MAX_MD2SKINS])\r
124 {\r
125         int             xs[MAX_MD2SKINS], ys[MAX_MD2SKINS];\r
126         int             xcount, ycount, x, y, index;\r
127 \r
128         index = 0;\r
129         xcount = GetCoords(w, xs) - 1;\r
130         ycount = GetCoords(h, ys) - 1;\r
131 \r
132         for(y = 0; y < ycount; y++)\r
133         {\r
134                 for(x = 0; x < xcount; x++, index++)\r
135                 {\r
136                         coords[index].x = xs[x];\r
137                         coords[index].y = ys[y];\r
138                         coords[index].w = xs[x + 1] - xs[x];\r
139                         coords[index].h = ys[y + 1] - ys[y];\r
140                         coords[index].name[0] = x + '0';\r
141                         coords[index].name[1] = y + '0';\r
142                         coords[index].name[2] = 0;\r
143                 }\r
144         }\r
145         return(index);\r
146 }\r
147 \r
148 /*\r
149 ===============\r
150 Cmd_Pic\r
151 ===============\r
152 */\r
153 \r
154 void Cmd_Book()\r
155 {\r
156         int             xl,yl,xh,yh,w,h;\r
157         byte            *dest, *source;\r
158         int                             flags, value, contents;\r
159         char                    lumpname[64];\r
160         char                    filename[1024];\r
161         unsigned long   *destl, *sourcel;\r
162         int             linedelta, x, y;\r
163         int                             size;\r
164         miptex_t                *qtex;\r
165         miptex32_t              *qtex32;\r
166         float                   scale_x, scale_y;\r
167         int                             numrects, i;\r
168         rect_t                  coords[MAX_MD2SKINS];\r
169         bookframe_t             bframes[MAX_MD2SKINS];\r
170         bookframe_t             *bf;\r
171         book_t                  book;\r
172 \r
173         GetScriptToken (false);\r
174         strcpy (lumpname, token);\r
175         \r
176         GetScriptToken (false);\r
177         xl = atoi (token);\r
178         GetScriptToken (false);\r
179         yl = atoi (token);\r
180         GetScriptToken (false);\r
181         w = atoi (token);\r
182         GetScriptToken (false);\r
183         h = atoi (token);\r
184 \r
185         total_x += w;\r
186         total_y += h;\r
187         total_textures++;\r
188 \r
189         if ( (w & 7) || (h & 7) )\r
190                 Error ("line %i: miptex sizes must be multiples of 8", scriptline);\r
191 \r
192         flags = 0;\r
193         contents = 0;\r
194         value = 0;\r
195 \r
196         scale_x = scale_y = 0.5;\r
197 \r
198         if (g_release)\r
199                 return;\r
200 \r
201         if(TrueColorImage)\r
202         {\r
203                 xh = xl + w;\r
204                 yh = yl + h;\r
205 \r
206                 if (xl >= longimagewidth || xh > longimagewidth ||\r
207                         yl >= longimageheight || yh > longimageheight)\r
208                 {\r
209                         Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight);\r
210                 }\r
211 \r
212                 sourcel = (unsigned long *) longimage + (yl * longimagewidth) + xl;\r
213                 destl = (unsigned long *) longimage;\r
214                 linedelta = (longimagewidth - w);\r
215 \r
216                 for(y = yl; y < yh; y++)\r
217                 {\r
218                         for(x = xl; x < xh; x++)\r
219                         {\r
220                                 *destl++ = *sourcel++;  // RGBA\r
221                         }\r
222                         sourcel += linedelta;\r
223                 }\r
224 \r
225                 // Get rectangles to chop into\r
226                 numrects = ChopImage(w, h, coords);\r
227 \r
228                 bf = bframes;\r
229                 for(i = 0; i < numrects; i++, bf++)\r
230                 {\r
231                         // Copy section of image to buffer\r
232                         sourcel = (unsigned long *) longimage + (coords[i].y * w) + coords[i].x;\r
233                         destl = bufferl;\r
234                         linedelta = w - coords[i].w;\r
235 \r
236                         for(y = 0; y < coords[i].h; y++)\r
237                         {\r
238                                 for(x = 0; x < coords[i].w; x++)\r
239                                 {\r
240                                         *destl++ = *sourcel++;\r
241                                 }\r
242                                 sourcel += linedelta;\r
243                         }\r
244 \r
245                         qtex32 = CreateBook32(bufferl, coords[i].w, coords[i].h, &size);\r
246 \r
247                         qtex32->flags = flags;\r
248                         qtex32->contents = contents;\r
249                         qtex32->value = value;\r
250                         qtex32->scale_x = scale_x;\r
251                         qtex32->scale_y = scale_y;\r
252 \r
253                         sprintf (filename, "%sbook/%s/%s_%s.m32", gamedir, book_prefix, lumpname, coords[i].name);\r
254                         sprintf (qtex32->name, "%s/%s_%s.m32", book_prefix, lumpname, coords[i].name);\r
255 \r
256                         strcpy(bf->name, qtex32->name);\r
257                         bf->x = coords[i].x;\r
258                         bf->y = coords[i].y;\r
259                         bf->w = coords[i].w;\r
260                         bf->h = coords[i].h;\r
261                 //\r
262                 // write it out\r
263                 //\r
264                         printf ("writing %s\n", filename);\r
265                         SaveFile (filename, (byte *)qtex32, size);\r
266 \r
267                         free (qtex32);\r
268                 }\r
269         }\r
270         else\r
271         {\r
272                 xh = xl + w;\r
273                 yh = yl + h;\r
274 \r
275                 if (xl >= byteimagewidth || xh > byteimagewidth ||\r
276                         yl >= byteimageheight || yh > byteimageheight)\r
277                 {\r
278                         Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight);\r
279                 }\r
280 \r
281                 // Copy image to top left\r
282                 source = byteimage + yl*byteimagewidth + xl;\r
283                 dest = byteimage;\r
284                 linedelta = byteimagewidth - w;\r
285 \r
286                 for(y = yl; y < yh; y++)\r
287                 {\r
288                         for(x = xl; x < xh; x++)\r
289                         {\r
290                                 *dest++ = *source++;\r
291                         }\r
292                         source += linedelta;\r
293                 }\r
294 \r
295                 // Get rectangles to chop into\r
296                 numrects = ChopImage(w, h, coords);\r
297 \r
298                 bf = bframes;\r
299                 for(i = 0; i < numrects; i++, bf++)\r
300                 {\r
301                         // Copy section of image to buffer\r
302                         source = byteimage + (coords[i].y * w) + coords[i].x;\r
303                         dest = buffer;\r
304                         linedelta = w - coords[i].w;\r
305 \r
306                         for(y = 0; y < coords[i].h; y++)\r
307                         {\r
308                                 for(x = 0; x < coords[i].w; x++)\r
309                                 {\r
310                                         *dest++ = *source++;\r
311                                 }\r
312                                 source += linedelta;\r
313                         }\r
314 \r
315                         qtex = CreateBook8(buffer, coords[i].w, coords[i].h, lbmpalette, &size);\r
316 \r
317                         qtex->flags = flags;\r
318                         qtex->contents = contents;\r
319                         qtex->value = value;\r
320 \r
321                         sprintf (filename, "%sbook/%s/%s_%s.m8", gamedir, book_prefix, lumpname, coords[i].name);\r
322                         sprintf (qtex->name, "%s/%s_%s.m8", book_prefix, lumpname, coords[i].name);\r
323 \r
324                         strcpy(bf->name, qtex->name);\r
325                         bf->x = coords[i].x;\r
326                         bf->y = coords[i].y;\r
327                         bf->w = coords[i].w;\r
328                         bf->h = coords[i].h;\r
329                 //\r
330                 // write it out\r
331                 //\r
332                         printf ("writing %s\n", filename);\r
333                         SaveFile (filename, (byte *)qtex, size);\r
334 \r
335                         free (qtex);\r
336                 }\r
337         }\r
338         // Set up descriptor\r
339         size = sizeof(bookframe_t) * numrects;\r
340 \r
341         book.bheader.ident = IDBOOKHEADER;\r
342         book.bheader.version = BOOK_VERSION;\r
343         book.bheader.num_segments = numrects;\r
344         book.bheader.total_w = w;\r
345         book.bheader.total_h = h;\r
346         memcpy(book.bframes, bframes, size);\r
347 \r
348         // Save out segment descriptor\r
349         sprintf (filename, "%sBook/%s/%s.bk", gamedir, book_prefix, lumpname);\r
350         printf ("writing %s\n", filename);\r
351         SaveFile (filename, (byte *)&book, size + sizeof(bookheader_t));\r
352 }\r
353 \r
354 /*\r
355 ===============\r
356 Cmd_picdir\r
357 ===============\r
358 */\r
359 void Cmd_Bookdir (void)\r
360 {\r
361         char    filename[1024];\r
362 \r
363         GetScriptToken (false);\r
364         strcpy (book_prefix, token);\r
365         // create the directory if needed\r
366         sprintf (filename, "%sBook", gamedir);\r
367         Q_mkdir (filename); \r
368         sprintf (filename, "%sBook/%s", gamedir, book_prefix);\r
369         Q_mkdir (filename); \r
370 }\r
371 \r
372 // end\r