2731e15ad2003a4462331e2b5488ca55c5d0a8b0
[xonotic/netradiant.git] / plugins / imagehl / hlw.cpp
1 /*
2    Copyright (C) 1999-2006 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 // by Hydra - hydra@hydras-world.com
23 //
24 // HLW = Half-Life-WAD, I don't know if the actual in data in the WAD files
25 // has it's own name, so I'm just calling the individal textures .HLW files :)
26 //
27 // Thanks to the guys that made Wally for releasing an example WAD loader.
28 // without it this would not have been possible.
29
30 #include "hlw.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdio.h>
35
36 typedef unsigned char byte;
37
38 #include "ifilesystem.h"
39
40 #include "imagelib.h"
41
42
43 /*
44    ============================================================================
45
46    HLW IMAGE
47
48    HalfLife WAD files contain files that look like this:
49
50     Mip section
51         First mip
52             Mip header
53             First mip (width * height)
54             Second mip (width * height / 4)
55             Third mip (width * height / 16)
56             Fourth mip (width * height / 64)
57             Palette size (WORD)
58             Palette (Palette size * 3)
59             Padding (WORD)
60
61    ============================================================================
62  */
63
64 #define GET_MIP_DATA_SIZE( WIDTH, HEIGHT ) ( sizeof( WAD3_MIP ) + ( WIDTH * HEIGHT ) + ( WIDTH * HEIGHT / 4 ) + ( WIDTH * HEIGHT / 16 ) + ( WIDTH * HEIGHT / 64 ) )
65
66 typedef struct
67 {
68         char name[16];
69         unsigned int width, height;
70         unsigned int offsets[4];            // four mip maps stored
71 } WAD3_MIP, *LPWAD3_MIP;
72
73 /*
74    =========================================================
75
76    HLW LOADING
77
78    Hydra: this code isn't bullet proof and probably won't
79    like corrupt WAD files, but it works for now.
80
81    TODO: make it more robust.
82    =========================================================
83  */
84
85 /*
86    =============
87    LoadHLW
88    =============
89  */
90
91 Image* LoadHLWBuff( byte* buffer ){
92         byte *buf_p;
93         unsigned long mipdatasize;
94         int columns, rows, numPixels;
95         byte *pixbuf;
96         int row, column;
97         byte *palette;
98         LPWAD3_MIP lpMip;
99         unsigned char red, green, blue, alphabyte;
100
101         lpMip = (LPWAD3_MIP)buffer; //!\todo Make endian-safe.
102
103         mipdatasize = GET_MIP_DATA_SIZE( lpMip->width,lpMip->height );
104
105         palette = buffer + mipdatasize + 2;
106
107         buf_p = buffer + lpMip->offsets[0];
108
109         columns = lpMip->width;
110         rows = lpMip->height;
111         numPixels = columns * rows;
112
113         RGBAImage* image = new RGBAImage( columns, rows );
114
115         for ( row = 0; row < rows; row++ )
116         {
117                 pixbuf = image->getRGBAPixels() + row * columns * 4;
118
119                 for ( column = 0; column < columns; column++ )
120                 {
121                         int palIndex;
122
123                         palIndex = *buf_p++;
124
125                         red = *( palette + ( palIndex * 3 ) );
126                         green = *( palette + ( palIndex * 3 ) + 1 );
127                         blue = *( palette + ( palIndex * 3 ) + 2 );
128
129                         // HalfLife engine makes pixels that are BLUE transparent.
130                         // So show them that way in the editor.
131                         if ( blue == 0xff && red == 0x00 && green == 0x00 ) {
132                                 alphabyte = 0x00;
133                                 blue = 0x00; // don't set the resulting pixel to blue
134                         }
135                         else
136                         {
137                                 alphabyte = 0xff;
138                         }
139
140                         *pixbuf++ = red;
141                         *pixbuf++ = green;
142                         *pixbuf++ = blue;
143
144                         *pixbuf++ = alphabyte;
145                 }
146         }
147
148         return image;
149 }
150
151 Image* LoadHLW( ArchiveFile& file ){
152         ScopedArchiveBuffer buffer( file );
153         return LoadHLWBuff( buffer.buffer );
154 }