local variables ALSO work better when declared
[divverent/netradiant.git] / plugins / imageq2 / wal32.cpp
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
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 #include "wal32.h"
23
24 #include "ifilesystem.h"
25
26 #include "bytestreamutils.h"
27 #include "imagelib.h"
28
29 typedef unsigned char byte;
30
31 const int M32_NAME_LENGTH = 128;
32 const int M32_MIPMAP_COUNT = 16;
33
34 typedef struct m32_header_t
35 {
36   int       version;
37   char      name[M32_NAME_LENGTH];
38   char      altname[M32_NAME_LENGTH];                   // texture substitution
39   char      animname[M32_NAME_LENGTH];                  // next frame in animation chain
40   char      damagename[M32_NAME_LENGTH];                // image that should be shown when damaged
41   unsigned  width[M32_MIPMAP_COUNT], height[M32_MIPMAP_COUNT];
42   unsigned  offsets[M32_MIPMAP_COUNT];
43   int       flags;
44   int       contents;
45   int       value;
46   float     scale_x, scale_y;
47   int       mip_scale;
48
49   // detail texturing info
50   char      dt_name[M32_NAME_LENGTH];           // detailed texture name
51   float     dt_scale_x, dt_scale_y;
52   float     dt_u, dt_v;
53   float     dt_alpha;
54   int       dt_src_blend_mode, dt_dst_blend_mode;
55
56   int       unused[20];                     // future expansion to maintain compatibility with h2
57 } m32_header_t;
58
59
60 Image* LoadM32Buff(byte* buffer)
61 {
62   PointerInputStream inputStream(buffer);
63
64   inputStream.seek(4 // version
65     + M32_NAME_LENGTH // name
66     + M32_NAME_LENGTH // altname
67     + M32_NAME_LENGTH // animname
68     + M32_NAME_LENGTH); // damagename
69   int w = istream_read_uint32_le(inputStream);
70   inputStream.seek(4 * (M32_MIPMAP_COUNT - 1)); // remaining widths
71   int h = istream_read_uint32_le(inputStream);
72   inputStream.seek(4 * (M32_MIPMAP_COUNT - 1)); // remaining heights
73   int offset = istream_read_uint32_le(inputStream);
74   inputStream.seek(4 * (M32_MIPMAP_COUNT - 1)); // remaining offsets
75   int flags = istream_read_uint32_le(inputStream);
76   int contents = istream_read_uint32_le(inputStream);
77   int value = istream_read_uint32_le(inputStream);
78
79   RGBAImageFlags* image = new RGBAImageFlags(w, h, flags, contents, value);
80
81   const byte* source = buffer + offset;
82   std::copy(source, source + (w * h * 4), image->getRGBAPixels());
83
84   return image;
85 }
86
87 Image* LoadM32(ArchiveFile& file)
88 {
89   ScopedArchiveBuffer buffer(file);
90   return LoadM32Buff(buffer.buffer);
91 }
92