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