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