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