- build system has to use 32bit (the code is not 64bit safe)
[genesis3d.git] / GBSPLib / TEXTURE.CPP
1 /****************************************************************************************/\r
2 /*  Texture.cpp                                                                         */\r
3 /*                                                                                      */\r
4 /*  Author: John Pollard                                                                */\r
5 /*  Description: This code keeps a list of shared textures.                             */\r
6 /*                                                                                      */\r
7 /*  The contents of this file are subject to the Genesis3D Public License               */\r
8 /*  Version 1.01 (the "License"); you may not use this file except in                   */\r
9 /*  compliance with the License. You may obtain a copy of the License at                */\r
10 /*  http://www.genesis3d.com                                                            */\r
11 /*                                                                                      */\r
12 /*  Software distributed under the License is distributed on an "AS IS"                 */\r
13 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */\r
14 /*  the License for the specific language governing rights and limitations              */\r
15 /*  under the License.                                                                  */\r
16 /*                                                                                      */\r
17 /*  The Original Code is Genesis3D, released March 25, 1999.                            */\r
18 /*Genesis3D Version 1.1 released November 15, 1999                            */\r
19 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */\r
20 /*                                                                                      */\r
21 /****************************************************************************************/\r
22 #include <Windows.h>\r
23 \r
24 #include <Stdio.h>\r
25 #include <Assert.h>\r
26 \r
27 #include "Map.h"\r
28 #include "BSP.h"\r
29 #include "Texture.h"\r
30 #include "Utils.h"\r
31 \r
32 #include        "vfile.h"\r
33 #include        "bitmap.h"\r
34 #include        "ram.h"\r
35 \r
36 int32           NumTextures;\r
37 GFX_Texture     Textures[MAX_MAP_TEXTURES];\r
38 int32           NumTexInfo;\r
39 GFX_TexInfo     TexInfo[MAX_MAP_TEXINFO];\r
40 \r
41 typedef struct  NamedBitmap\r
42 {\r
43         char *          Name;\r
44         geBitmap *      Bitmap;\r
45 }       NamedBitmap;\r
46 \r
47 static  int                             NumBitmaps;\r
48 static  NamedBitmap *   Bitmaps;\r
49 \r
50 //========================================================================================\r
51 //      FindTextureIndex\r
52 //========================================================================================\r
53 int32 FindTextureIndex(char *Name, uint32 Flags)\r
54 {\r
55         int32           i;\r
56 \r
57         for (i=0; i< NumTextures; i++)\r
58         {\r
59                 if (!stricmp(Name, Textures[i].Name) && Textures[i].Flags == Flags)\r
60                         return i;\r
61         }\r
62 \r
63         if (NumTextures >= MAX_MAP_TEXTURES)\r
64         {\r
65                 GHook.Error("FindTextureIndex:  Too many Textures in map.");\r
66                 return -1;\r
67         }\r
68 \r
69         strcpy(Textures[NumTextures].Name, Name);\r
70         Textures[NumTextures].Flags = Flags;\r
71 \r
72         NumTextures++;\r
73 \r
74         //Hook.Printf("Adding Texture: %s\n", Name);\r
75 \r
76         return(NumTextures-1);\r
77 }\r
78 \r
79 int32 NumSurfaceLights;\r
80 \r
81 //========================================================================================\r
82 //      FindTexInfo\r
83 //========================================================================================\r
84 int32 FindTexInfo(GFX_TexInfo *Tex2)\r
85 {\r
86         int32                   i;\r
87         GFX_TexInfo     *Tex1;\r
88 \r
89         if ((Tex2->Flags & TEXINFO_FLAT))\r
90                 Tex2->Flags |= TEXINFO_GOURAUD;\r
91 \r
92         if (Tex2->Flags & TEXINFO_SKY)                          // Force sky to fullbright\r
93                 Tex2->Flags |= TEXINFO_FULLBRIGHT;\r
94 \r
95         if ((Tex2->Flags & TEXINFO_SKY) || (Tex2->Flags & TEXINFO_FULLBRIGHT))  \r
96                 Tex2->Flags |= TEXINFO_NO_LIGHTMAP;\r
97 \r
98         if ((Tex2->Flags & TEXINFO_GOURAUD))\r
99                 Tex2->Flags |= TEXINFO_NO_LIGHTMAP;\r
100 \r
101         for (i=0; i< NumTexInfo; i++)\r
102         {\r
103                 Tex1 = &TexInfo[i];\r
104 \r
105                 if (Tex1->Vecs[0].X == Tex2->Vecs[0].X)\r
106                 if (Tex1->Vecs[0].Y == Tex2->Vecs[0].Y)\r
107                 if (Tex1->Vecs[0].Z == Tex2->Vecs[0].Z)\r
108                 if (Tex1->Vecs[1].X == Tex2->Vecs[1].X)\r
109                 if (Tex1->Vecs[1].Y == Tex2->Vecs[1].Y)\r
110                 if (Tex1->Vecs[1].Z == Tex2->Vecs[1].Z)\r
111                 if (Tex1->Shift[0] == Tex2->Shift[0])\r
112                 if (Tex1->Shift[1] == Tex2->Shift[1])\r
113                 if (Tex1->DrawScale[0] == Tex2->DrawScale[0])\r
114                 if (Tex1->DrawScale[1] == Tex2->DrawScale[1])\r
115                 if (Tex1->Flags == Tex2->Flags)\r
116                 if (Tex1->FaceLight == Tex2->FaceLight)\r
117                 if (Tex1->ReflectiveScale == Tex2->ReflectiveScale)\r
118                 if (Tex1->Alpha == Tex2->Alpha)\r
119                 if (Tex1->MipMapBias == Tex2->MipMapBias)\r
120                 if (Tex1->Texture == Tex2->Texture)\r
121                         return i;\r
122         }\r
123 \r
124         if (NumTexInfo >= MAX_MAP_TEXINFO)\r
125         {\r
126                 GHook.Error("FindTexInfo:  Too much texture information...\n");\r
127                 return -1;\r
128         }\r
129 \r
130         TexInfo[i] = *Tex2;\r
131         NumTexInfo++;\r
132 \r
133         return i;\r
134 }\r
135 \r
136 geBoolean InitTextureLib(char *FileName)\r
137 {\r
138         char                            Buff[_MAX_PATH];\r
139         geVFile *                       VFS;\r
140         geVFile_Finder *        Finder;\r
141         int                                     i;\r
142 \r
143         Finder = NULL;\r
144 \r
145         strcpy(Buff, FileName);\r
146         StripExtension(Buff);\r
147         DefaultExtension(Buff, ".txl");\r
148 \r
149         VFS = geVFile_OpenNewSystem(NULL,\r
150                                                                 GE_VFILE_TYPE_VIRTUAL,\r
151                                                                 Buff,\r
152                                                                 NULL,\r
153                                                                 GE_VFILE_OPEN_DIRECTORY | GE_VFILE_OPEN_READONLY);\r
154         if      (!VFS)\r
155                 goto fail;\r
156 \r
157         Finder = geVFile_CreateFinder(VFS, "*.*");\r
158         if      (!Finder)\r
159                 goto fail;\r
160 \r
161         i = 0;\r
162         while   (geVFile_FinderGetNextFile(Finder) == GE_TRUE)\r
163         {\r
164                 i++;\r
165         }\r
166 \r
167         geVFile_DestroyFinder(Finder);\r
168 \r
169         Finder = geVFile_CreateFinder(VFS, "*.*");\r
170 \r
171         if      (!Finder)\r
172                 goto fail;\r
173 \r
174         NumBitmaps = i;\r
175         Bitmaps = (NamedBitmap *)geRam_Allocate(sizeof(*Bitmaps) * NumBitmaps);\r
176 \r
177         if      (!Bitmaps)\r
178                 goto fail;\r
179 \r
180         memset(Bitmaps, 0, sizeof(*Bitmaps) * NumBitmaps);\r
181 \r
182         i = 0;\r
183         while   (geVFile_FinderGetNextFile(Finder) == GE_TRUE)\r
184         {\r
185                 geVFile_Properties      Properties;\r
186                 geVFile *                       File;\r
187 \r
188                 geVFile_FinderGetProperties(Finder, &Properties);\r
189                 Bitmaps[i].Name = strdup(Properties.Name);\r
190                 if      (!Bitmaps[i].Name)\r
191                 {\r
192 //              GHook.Error("InitTextures:  5 Unable to load texture library '%s'.\n", Buff);\r
193                         goto fail;\r
194                 }\r
195                 File = geVFile_Open(VFS, Properties.Name, GE_VFILE_OPEN_READONLY);\r
196                 if      (!File)\r
197                 {\r
198                         GHook.Error("InitTextures:  Unable to load texture file '%s'.\n", Properties.Name);\r
199                         goto fail;\r
200                 }\r
201                 Bitmaps[i].Bitmap = geBitmap_CreateFromFile(File);\r
202                 geVFile_Close(File);\r
203                 if      (!Bitmaps[i].Bitmap)\r
204                 {\r
205                         GHook.Error("InitTextures:  Unable to load texture '%s'.\n", Properties.Name);\r
206                         goto fail;\r
207                 }\r
208 //              GHook.Printf("InitTextures:  Loaded texture '%s'.\n", Properties.Name);\r
209                 i++;\r
210         }\r
211 \r
212         geVFile_Close(VFS);\r
213         return GE_TRUE;\r
214 \r
215 fail:\r
216         if      (VFS)\r
217                 geVFile_Close(VFS);\r
218 \r
219         if      (Finder)\r
220                 geVFile_DestroyFinder(Finder);\r
221         \r
222         ShutdownTextureLib();\r
223 \r
224         GHook.Error("InitTextures:  Unable to load texture library '%s'.\n", Buff);\r
225 \r
226         return GE_FALSE;\r
227 }\r
228 \r
229 //========================================================================================\r
230 //========================================================================================\r
231 void ShutdownTextureLib(void)\r
232 {\r
233         if      (Bitmaps)\r
234         {\r
235                 int     i;\r
236 \r
237                 for     (i = 0; i < NumBitmaps; i++)\r
238                 {\r
239                         if      (Bitmaps[i].Name)\r
240                                 free(Bitmaps[i].Name);\r
241                         if      (Bitmaps[i].Bitmap)\r
242                                 geBitmap_Destroy(&Bitmaps[i].Bitmap);\r
243                 }\r
244                 geRam_Free(Bitmaps);\r
245                 Bitmaps = NULL;\r
246         }\r
247 \r
248         NumBitmaps = 0;\r
249 }\r
250 \r
251 static  NamedBitmap *   FindBitmapByName(const char *Name)\r
252 {\r
253         if      (Bitmaps)\r
254         {\r
255                 int     i;\r
256 \r
257                 for     (i = 0; i < NumBitmaps; i++)\r
258                 {\r
259                         if      (!stricmp(Bitmaps[i].Name, Name))\r
260                         {\r
261                                 return &Bitmaps[i];\r
262                         }\r
263                 }\r
264         }\r
265 \r
266         return NULL;\r
267 }\r
268 \r
269 // added transparent textures\r
270 geBoolean HasTextureAlpha(char *Name)\r
271 {\r
272         geBitmap *              Image;\r
273         NamedBitmap *   Bitmap;\r
274 \r
275         Bitmap = FindBitmapByName(Name);\r
276         \r
277         if      (Bitmap == NULL)\r
278         {\r
279                 GHook.Printf("Could not find texture alpha'%s' in texture library.\n", Name);\r
280                 if      (!Bitmaps)\r
281                 {\r
282                         GHook.Error("Could not find any textures in texture library.\n");\r
283                         return GE_FALSE;\r
284                 }\r
285 \r
286                 assert(NumBitmaps > 0);\r
287 \r
288                 Name  = Bitmaps[0].Name;\r
289                 Image = Bitmaps[0].Bitmap;\r
290         }\r
291         else\r
292         {\r
293                 Image = Bitmap->Bitmap;\r
294         }\r
295 \r
296         return geBitmap_HasAlpha(Image);\r
297 }\r
298 // end transparent textures\r
299 \r
300 //========================================================================================\r
301 //========================================================================================\r
302 geBoolean GetTexture(char *Name, uint8 *Data, int32 *Size, int32 *Width, int32 *Height, geVFile *f)\r
303 {\r
304         int32                   i;\r
305         geBitmap *              Image;\r
306         NamedBitmap *   Bitmap;\r
307 \r
308         Bitmap = FindBitmapByName(Name);\r
309         \r
310         if      (Bitmap == NULL)\r
311         {\r
312                 GHook.Printf("Could not find texture '%s' in texture library.\n", Name);\r
313                 if      (!Bitmaps)\r
314                 {\r
315                         GHook.Error("Could not find any textures in texture library.\n");\r
316                         return GE_FALSE;\r
317                 }\r
318 \r
319                 assert(NumBitmaps > 0);\r
320 \r
321                 Name  = Bitmaps[0].Name;\r
322                 Image = Bitmaps[0].Bitmap;\r
323         }\r
324         else\r
325         {\r
326                 Image = Bitmap->Bitmap;\r
327         }\r
328 \r
329         //GHook.Printf("%s\n", Name);\r
330 \r
331         *Width = geBitmap_Width(Image);\r
332         *Height = geBitmap_Height(Image);\r
333 \r
334         if      (*Width > 256 || *Height > 256)\r
335         {\r
336                 GHook.Error("Texture '%s' has a dimension bigger than 256.\n", Name);\r
337                 return GE_FALSE;\r
338         }\r
339 \r
340         *Size = 0;\r
341         geBitmap_UpdateMips(Image, 0, 1);\r
342         geBitmap_UpdateMips(Image, 1, 2);\r
343         geBitmap_UpdateMips(Image, 2, 3);\r
344 // added transparent textures - only 1 mip sent\r
345         for     (i = 0; i < 1; i++)\r
346         {\r
347                 int                     MipWidth;\r
348                 int                     MipHeight;\r
349                 geBitmap *      LockedImage;\r
350                 void *          Bits;\r
351 \r
352 //Start Dec2001DCS\r
353 // added transparent textures\r
354           if(geBitmap_LockForRead(Image, &LockedImage, i, i, GE_PIXELFORMAT_32BIT_ARGB, GE_TRUE, 0xffff00ff) == GE_FALSE)\r
355 //End Dec2001DCS\r
356                 {\r
357                         GHook.Error("Could not get mip level %d for texture '%s'.\n", i, Name);\r
358                         return GE_FALSE;\r
359                 }\r
360                 \r
361                 Bits = geBitmap_GetBits(LockedImage);\r
362                 if      (!Bits)\r
363                 {\r
364                         GHook.Error("Could not get mip bits for texture '%s'.\n", i, Name);\r
365                         return GE_FALSE;\r
366                 }\r
367 \r
368                 MipWidth = *Width / (1 << i);\r
369                 MipHeight = *Height / (1 << i);\r
370 \r
371 //Start Dec2001DCS - Added * 4 since textures are now 32 bit\r
372 // added transparent textures\r
373                 if (geVFile_Write(f, Bits, MipWidth * MipHeight * 4) != GE_TRUE)\r
374 //End Dec2001DCS\r
375                 {\r
376                         GHook.Error("Could not write texture data.\n");\r
377                         return GE_FALSE;\r
378                 }\r
379 \r
380                 geBitmap_UnLock(LockedImage);\r
381 \r
382 //Start Dec2001DCS - Added * 4 since textures are now 32 bit\r
383 // added transparent textures\r
384                 *Size += MipWidth * MipHeight * 4;\r
385 //End Dec2001DCS\r
386         }\r
387 \r
388         return GE_TRUE;\r
389 }\r
390 \r
391 geBoolean GetTexturePalette(const char *Name, DRV_Palette Palette)\r
392 {\r
393         geBitmap *                      Image;\r
394         NamedBitmap *           Bitmap;\r
395         geBitmap_Palette *      ImagePalette;\r
396         int                                     i;\r
397 \r
398         assert(Name != NULL);\r
399         assert(Palette != NULL);\r
400 \r
401         Bitmap = FindBitmapByName(Name);\r
402         \r
403         if      (Bitmap == NULL)\r
404         {\r
405                 GHook.Printf("Could not find texture '%s' in texture library.\n", Name);\r
406                 if      (!Bitmaps)\r
407                 {\r
408                         GHook.Error("Could not find any textures in texture library.\n");\r
409                         return GE_FALSE;\r
410                 }\r
411 \r
412                 Name  = Bitmaps[0].Name;\r
413                 Image = Bitmaps[0].Bitmap;\r
414         }\r
415         else\r
416         {\r
417                 Image = Bitmap->Bitmap;\r
418         }\r
419 \r
420         ImagePalette = geBitmap_GetPalette(Image);\r
421         if      (!ImagePalette)\r
422         {\r
423 //Start Dec2001DCS\r
424 //              GHook.Error("Could not find get pallette for texture '%s'.\n", Name);\r
425 //              return GE_FALSE;\r
426 // No palette found is not an error anymore - 24 bit color bitmaps do not have a palette\r
427       return GE_TRUE;\r
428 //End Dec2001DCS\r
429         }\r
430 \r
431         for     (i = 0; i < 255; i++)\r
432         {\r
433                 int     A;\r
434                 int     R;\r
435                 int     G;\r
436                 int     B;\r
437                 geBitmap_Palette_GetEntryColor(ImagePalette, i, &R, &G, &B, &A);\r
438                 Palette[i].r = R;\r
439                 Palette[i].g = G;\r
440                 Palette[i].b = B;\r
441         }\r
442 \r
443         return GE_TRUE;\r
444 }\r
445 \r