1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: r_tex_raw.cpp 4297 2010-06-03 22:49:00Z firebrand_kh $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "gamedefs.h"
29 #include "r_tex.h"
30
31 // MACROS ------------------------------------------------------------------
32
33 // TYPES -------------------------------------------------------------------
34
35 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
36
37 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
38
39 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
40
41 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
42
43 // PUBLIC DATA DEFINITIONS -------------------------------------------------
44
45 // PRIVATE DATA DEFINITIONS ------------------------------------------------
46
47 // CODE --------------------------------------------------------------------
48
49 //==========================================================================
50 //
51 // VRawPicTexture::Create
52 //
53 //==========================================================================
54
Create(VStream & Strm,int LumpNum)55 VTexture* VRawPicTexture::Create(VStream& Strm, int LumpNum)
56 {
57 guard(VRawPicTexture::Create);
58 if (Strm.TotalSize() != 64000)
59 {
60 // Wrong size.
61 return NULL;
62 }
63
64 // Do an extra check to see if it's a valid patch
65 vint16 Width;
66 vint16 Height;
67 vint16 SOffset;
68 vint16 TOffset;
69
70 Strm.Seek(0);
71 Strm << Width << Height << SOffset << TOffset;
72 if (Width > 0 && Height > 0 && Width <= 2048 && Height < 510)
73 {
74 // Dimensions seem to be valid. Check column directory to see if
75 // it's valid. We expect at least one column to start exactly right
76 // after the directory.
77 bool GapAtStart = true;
78 bool IsValid = true;
79 vint32* Offsets = new vint32[Width];
80 for (int i = 0; i < Width; i++)
81 {
82 Strm << Offsets[i];
83 if (Offsets[i] == 8 + Width * 4)
84 {
85 GapAtStart = false;
86 }
87 else if (Offsets[i] < 8 + Width * 4 ||
88 Offsets[i] >= Strm.TotalSize())
89 {
90 IsValid = false;
91 break;
92 }
93 }
94 if (IsValid && !GapAtStart)
95 {
96 // Offsets seem to be valid.
97 delete[] Offsets;
98 Offsets = NULL;
99 return NULL;
100 }
101 delete[] Offsets;
102 Offsets = NULL;
103 }
104
105 return new VRawPicTexture(LumpNum, -1);
106 unguard;
107 }
108
109 //==========================================================================
110 //
111 // VRawPicTexture::VRawPicTexture
112 //
113 //==========================================================================
114
VRawPicTexture(int ALumpNum,int APalLumpNum)115 VRawPicTexture::VRawPicTexture(int ALumpNum, int APalLumpNum)
116 : PalLumpNum(APalLumpNum)
117 , Pixels(0)
118 , Palette(0)
119 {
120 SourceLump = ALumpNum;
121 Type = TEXTYPE_Pic;
122 Name = W_LumpName(SourceLump);
123 Width = 320;
124 Height = 200;
125 Format = PalLumpNum >= 0 ? TEXFMT_8Pal : TEXFMT_8;
126 }
127
128 //==========================================================================
129 //
130 // VRawPicTexture::~VRawPicTexture
131 //
132 //==========================================================================
133
~VRawPicTexture()134 VRawPicTexture::~VRawPicTexture()
135 {
136 guard(VRawPicTexture::~VRawPicTexture);
137 if (Pixels)
138 {
139 delete[] Pixels;
140 Pixels = NULL;
141 }
142 if (Palette)
143 {
144 delete[] Palette;
145 Palette = NULL;
146 }
147 unguard;
148 }
149
150 //==========================================================================
151 //
152 // VRawPicTexture::GetPixels
153 //
154 //==========================================================================
155
GetPixels()156 vuint8* VRawPicTexture::GetPixels()
157 {
158 guard(VRawPicTexture::GetPixels);
159 // If already got pixels, then just return them.
160 if (Pixels)
161 {
162 return Pixels;
163 }
164
165 Pixels = new vuint8[64000];
166
167 // Set up palette.
168 int black;
169 if (PalLumpNum < 0)
170 {
171 black = r_black_colour;
172 }
173 else
174 {
175 // Load palette and find black colour for remaping.
176 Palette = new rgba_t[256];
177 VStream* PStrm = W_CreateLumpReaderNum(PalLumpNum);
178 int best_dist = 0x10000;
179 black = 0;
180 for (int i = 0; i < 256; i++)
181 {
182 *PStrm << Palette[i].r
183 << Palette[i].g
184 << Palette[i].b;
185 if (i == 0)
186 {
187 Palette[i].a = 0;
188 }
189 else
190 {
191 Palette[i].a = 255;
192 int dist = Palette[i].r * Palette[i].r + Palette[i].g *
193 Palette[i].g + Palette[i].b * Palette[i].b;
194 if (dist < best_dist)
195 {
196 black = i;
197 best_dist = dist;
198 }
199 }
200 }
201 delete PStrm;
202 PStrm = NULL;
203 }
204
205 // Read data.
206 VStream* Strm = W_CreateLumpReaderNum(SourceLump);
207 vuint8* dst = Pixels;
208 for (int i = 0; i < 64000; i++, dst++)
209 {
210 *Strm << *dst;
211 if (!*dst)
212 *dst = black;
213 }
214 delete Strm;
215 Strm = NULL;
216
217 return Pixels;
218 unguard;
219 }
220
221 //==========================================================================
222 //
223 // VRawPicTexture::GetPalette
224 //
225 //==========================================================================
226
GetPalette()227 rgba_t* VRawPicTexture::GetPalette()
228 {
229 guardSlow(VRawPicTexture::GetPalette);
230 return Palette ? Palette : r_palette;
231 unguardSlow;
232 }
233
234 //==========================================================================
235 //
236 // VRawPicTexture::Unload
237 //
238 //==========================================================================
239
Unload()240 void VRawPicTexture::Unload()
241 {
242 guard(VRawPicTexture::Unload);
243 if (Pixels)
244 {
245 delete[] Pixels;
246 Pixels = NULL;
247 }
248 if (Palette)
249 {
250 delete[] Palette;
251 Palette = NULL;
252 }
253 unguard;
254 }
255