1 /*
2 
3 	Copyright (C) 1991-2001 and beyond by Bungie Studios, Inc.
4 	and the "Aleph One" developers.
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 3 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	This license is contained in the file "COPYING",
17 	which is included with this source code; it is available online at
18 	http://www.gnu.org/licenses/gpl.html
19 
20 	OpenGL Substitute-Texture-Definition File
21 	by Loren Petrich,
22 	March 12, 2000
23 
24 	This contains implementations of functions for handling
25 	the OpenGL substitute textures for the walls and the sprites
26 */
27 
28 #include "cseries.h"
29 #include "OGL_Subst_Texture_Def.h"
30 #include "Logging.h"
31 #include "InfoTree.h"
32 
33 #include <set>
34 #include <string>
35 #include <boost/unordered_map.hpp>
36 
37 #ifdef HAVE_OPENGL
38 
39 // Texture-options stuff;
40 // defaults for whatever might need them
41 static OGL_TextureOptions DefaultTextureOptions;
42 
43 typedef std::pair<short, short> TOKey;
44 typedef boost::unordered_map<TOKey, OGL_TextureOptions> TOHash;
45 static TOHash Collections[NUMBER_OF_COLLECTIONS];
46 
47 // Deletes a collection's texture-options sequences
TODelete(short Collection)48 void TODelete(short Collection)
49 {
50 	Collections[Collection].clear();
51 }
52 
53 // Deletes all of them
TODelete_All()54 static void TODelete_All()
55 {
56 	for (int c = 0; c < NUMBER_OF_COLLECTIONS; c++) TODelete(c);
57 }
58 
OGL_CountTextures(short Collection)59 int OGL_CountTextures(short Collection)
60 {
61 	return Collections[Collection].size();
62 }
63 
64 extern void OGL_ProgressCallback(int);
65 
OGL_LoadTextures(short Collection)66 void OGL_LoadTextures(short Collection)
67 {
68 
69 	for (TOHash::iterator it = Collections[Collection].begin(); it != Collections[Collection].end(); ++it)
70 	{
71 		it->second.Load();
72 		OGL_ProgressCallback(1);
73 
74 	}
75 }
76 
77 
OGL_UnloadTextures(short Collection)78 void OGL_UnloadTextures(short Collection)
79 {
80 	for (TOHash::iterator it = Collections[Collection].begin(); it != Collections[Collection].end(); ++it)
81 	{
82 		it->second.Unload();
83 	}
84 }
85 
86 
OGL_GetTextureOptions(short Collection,short CLUT,short Bitmap)87 OGL_TextureOptions *OGL_GetTextureOptions(short Collection, short CLUT, short Bitmap)
88 {
89 	TOHash::iterator it = Collections[Collection].find(TOKey(CLUT, Bitmap));
90 	if (it != Collections[Collection].end())
91 	{
92 		return &it->second;
93 	}
94 
95 	if (IsInfravisionTable(CLUT) && CLUT != INFRAVISION_BITMAP_SET)
96 	{
97 		it = Collections[Collection].find(TOKey(INFRAVISION_BITMAP_SET, Bitmap));
98 		if (it != Collections[Collection].end())
99 		{
100 			return &it->second;
101 		}
102 	}
103 
104 	if (IsSilhouetteTable(CLUT) && CLUT != SILHOUETTE_BITMAP_SET)
105 	{
106 		it = Collections[Collection].find(TOKey(SILHOUETTE_BITMAP_SET, Bitmap));
107 		if (it != Collections[Collection].end())
108 		{
109 			return &it->second;
110 		}
111 	}
112 
113 	it = Collections[Collection].find(TOKey(ALL_CLUTS, Bitmap));
114 	if (it != Collections[Collection].end())
115 	{
116 		return &it->second;
117 	}
118 
119 	return &DefaultTextureOptions;
120 }
121 
122 
reset_mml_opengl_texture()123 void reset_mml_opengl_texture()
124 {
125 	TODelete_All();
126 }
127 
parse_mml_opengl_texture(const InfoTree & root)128 void parse_mml_opengl_texture(const InfoTree& root)
129 {
130 	int16 coll;
131 	if (!root.read_indexed("coll", coll, NUMBER_OF_COLLECTIONS))
132 		return;
133 
134 	int16 bitmap;
135 	if (!root.read_indexed("bitmap", bitmap, INT16_MAX+1))
136 		return;
137 
138 	int16 clut = ALL_CLUTS;
139 	root.read_attr_bounded<int16>("clut", clut, ALL_CLUTS, SILHOUETTE_BITMAP_SET);
140 
141 	int16 clut_variant = CLUT_VARIANT_NORMAL;
142 	root.read_attr_bounded<int16>("clut_variant", clut_variant, ALL_CLUT_VARIANTS, NUMBER_OF_CLUT_VARIANTS-1);
143 
144 	// translate deprecated clut options
145 	if (clut == INFRAVISION_BITMAP_SET)
146 	{
147 		clut = ALL_CLUTS;
148 		clut_variant = CLUT_VARIANT_INFRAVISION;
149 	}
150 	else if (clut == SILHOUETTE_BITMAP_SET)
151 	{
152 		clut = ALL_CLUTS;
153 		clut_variant = CLUT_VARIANT_SILHOUETTE;
154 	}
155 
156 	// loop so we can apply "all variants" mode if needed
157 	for (short var = CLUT_VARIANT_NORMAL; var < NUMBER_OF_CLUT_VARIANTS; var++)
158 	{
159 		if (clut_variant != ALL_CLUT_VARIANTS && clut_variant != var)
160 			continue;
161 
162 		// translate clut+variant to internal clut number
163 		short actual_clut = clut;
164 		if (var == CLUT_VARIANT_INFRAVISION)
165 		{
166 			if (clut == ALL_CLUTS)
167 				actual_clut = INFRAVISION_BITMAP_SET;
168 			else
169 				actual_clut = INFRAVISION_BITMAP_CLUTSPECIFIC + clut;
170 		}
171 		else if (var == CLUT_VARIANT_SILHOUETTE)
172 		{
173 			if (clut == ALL_CLUTS)
174 				actual_clut = SILHOUETTE_BITMAP_SET;
175 			else
176 				actual_clut = SILHOUETTE_BITMAP_CLUTSPECIFIC + clut;
177 		}
178 
179 		TOHash::iterator it = Collections[coll].find(TOKey(actual_clut, bitmap));
180 		if (it == Collections[coll].end())
181 		{
182 			Collections[coll][TOKey(actual_clut, bitmap)] = DefaultTextureOptions;
183 			it = Collections[coll].find(TOKey(actual_clut, bitmap));
184 		}
185 
186 		OGL_TextureOptions& def = it->second;
187 		root.read_indexed("opac_type", def.OpacityType, OGL_NUMBER_OF_OPACITY_TYPES);
188 		root.read_attr("opac_scale", def.OpacityScale);
189 		root.read_attr("opac_shift", def.OpacityShift);
190 		root.read_attr("void_visible", def.VoidVisible);
191 		root.read_path("normal_image", def.NormalColors);
192 		root.read_path("offset_image", def.OffsetMap);
193 		root.read_path("normal_mask", def.NormalMask);
194 		root.read_path("glow_image", def.GlowColors);
195 		root.read_path("glow_mask", def.GlowMask);
196 		root.read_indexed("normal_blend", def.NormalBlend, OGL_NUMBER_OF_BLEND_TYPES);
197 		root.read_indexed("glow_blend", def.GlowBlend, OGL_NUMBER_OF_BLEND_TYPES);
198 		root.read_attr("actual_height", def.actual_height);
199 		root.read_attr("actual_width", def.actual_width);
200 		root.read_attr("type", def.Type);
201 		root.read_attr("normal_premultiply", def.NormalIsPremultiplied);
202 		root.read_attr("glow_premultiply", def.GlowIsPremultiplied);
203 		root.read_attr("normal_bloom_scale", def.BloomScale);
204 		root.read_attr("normal_bloom_shift", def.BloomShift);
205 		root.read_attr("glow_bloom_scale", def.GlowBloomScale);
206 		root.read_attr("glow_bloom_shift", def.GlowBloomShift);
207 		root.read_attr("landscape_bloom", def.LandscapeBloom);
208 		root.read_attr("minimum_glow_intensity", def.MinGlowIntensity);
209 	}
210 }
211 
parse_mml_opengl_txtr_clear(const InfoTree & root)212 void parse_mml_opengl_txtr_clear(const InfoTree& root)
213 {
214 	int16 coll;
215 	if (root.read_indexed("coll", coll, NUMBER_OF_COLLECTIONS))
216 		TODelete(coll);
217 	else
218 		TODelete_All();
219 }
220 
221 #endif
222