]> git.jsancho.org Git - lugaru.git/blob - Source/TGALoader.cpp
Cleanning up Sprite class. More can be done, but it's already prettier.
[lugaru.git] / Source / TGALoader.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (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.  
14
15 See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */
21
22 /**> HEADER FILES <**/
23 #include "Game.h"
24 #include "TGALoader.h"
25
26 extern float texdetail;
27 extern TGAImageRec texture;
28 extern short vRefNum;
29 extern long dirID;
30 extern bool visibleloading;
31 extern Game * pgame;
32 extern int loadscreencolor;
33
34 extern bool LoadImage(const char * fname, TGAImageRec & tex);
35 /********************> LoadTGA() <*****/
36 bool upload_image(const unsigned char* filePath, bool hasalpha)
37 {
38         if(visibleloading) {
39                 loadscreencolor=1;
40                 pgame->LoadingScreen();
41         }
42
43 #if !PLATFORM_MACOSX
44
45         // for Windows, just use TGA loader for now
46         char fileName[ 256];
47         CopyPascalStringToC( filePath, fileName);
48 /*
49         // change extension to .TGA
50         int len = strlen( fileName);
51         if (len > 3)
52         {
53                 fileName[ len - 3] = 't';
54                 fileName[ len - 2] = 'g';
55                 fileName[ len - 1] = 'a';
56         }
57 */
58 //      return (LoadTGA( fileName) != NULL);
59         return (LoadImage(fileName, texture));
60
61 #else
62
63         OSStatus err;
64         ComponentResult cr;
65
66         /*FSRef fsref;
67         Boolean isdir;
68         err = FSPathMakeRef((const UInt8*)filePath, &fsref, &isdir);
69         if(err)return;
70
71         FSSpec fsspec;
72         err = FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL);
73         if(err)return;
74         */
75
76         //Boolean isdir;
77         FSSpec fsspec;
78         //err = FSMakeFSSpec (0, 0, (const unsigned char*)filePath, &fsspec);
79         err = FSMakeFSSpec (0, 0, filePath, &fsspec);
80         //err=FSPathMakeFSSpec((const UInt8*)filePath,&fsspec,&isdir);*/
81         if(err)return;
82
83         GraphicsImportComponent gi;
84         err = GetGraphicsImporterForFile(&fsspec, &gi);
85         if(err)return;
86
87         Rect natbounds;
88         cr = GraphicsImportGetNaturalBounds(gi, &natbounds);
89
90         size_t buffersize = 4 * natbounds.bottom * natbounds.right;
91         //void* buf = malloc(buffersize);
92         texture.sizeX=natbounds.right;
93         texture.sizeY=natbounds.bottom;
94         /*if(hasalpha)*/texture.bpp = 32;
95         //if(!hasalpha)texture.bpp = 24;
96
97         GWorldPtr gw;
98         err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &natbounds, NULL, NULL,
99                 0, texture.data, 4 * natbounds.right);
100         if(err)return;
101
102         cr = GraphicsImportSetGWorld(gi, gw, NULL);
103
104         natbounds.top = natbounds.bottom;
105         natbounds.bottom = 0;
106
107         cr = GraphicsImportSetBoundsRect(gi, &natbounds);
108
109         cr = GraphicsImportDraw(gi);
110
111         err = CloseComponent(gi);
112         if(err)return;
113
114         /*glTexImage2D(textureTarget, 0, GL_RGBA, natbounds.right, natbounds.top, 0,
115         GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf);
116         */
117
118         //free(buf);
119         DisposeGWorld(gw);
120
121         // Loop Through The Image Data
122         GLuint                  imageSize;                                                                      // Used To Store The Image Size When Setting Aside Ram
123         GLuint                  temp;                                                                           // Temporary Variable
124         GLuint                  bytesPerPixel;                                                                          // Temporary Variable
125         bytesPerPixel=texture.bpp/8;
126         imageSize = texture.sizeX * texture.sizeY * bytesPerPixel;
127         int alltrans=10;
128
129         for( GLuint i = 0; i < int( imageSize ); i += 4 )
130         {
131                 // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
132                 temp = texture.data[i];                                 // Temporarily Store The Value At Image Data 'i'
133                 texture.data[i] = texture.data[i + 1];  // Set The 1st Byte To The Value Of The 3rd Byte
134                 texture.data[i + 1] = texture.data[i + 2];                              // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
135                 texture.data[i + 2] = texture.data[i + 3];
136                 texture.data[i + 3] = temp;
137         }
138
139         int tempplace;
140         tempplace=0;
141         if(!hasalpha){
142                 for( GLuint i = 0; i < int( imageSize ); i += 4 )
143                 {
144                         texture.data[i + 3] = 255;
145                         /*texture.data[tempplace] = texture.data[i];    // Set The 1st Byte To The Value Of The 3rd Byte
146                         texture.data[tempplace + 1] = texture.data[i + 1];                              // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
147                         texture.data[tempplace + 2] = texture.data[i + 2];
148                         tempplace+=3;*/
149                 }
150         }
151
152         if(texdetail>1){
153                 int which=0;
154                 float temp;
155                 float howmany;
156                 for( GLuint k = 0; k < int( imageSize); k += bytesPerPixel*texture.sizeX*texdetail )
157                 {
158                         for( GLuint i = 0; i < int( imageSize/texture.sizeY ); i += bytesPerPixel*texdetail )
159                         {
160                                 for( GLuint b = 0; b < bytesPerPixel ; b ++ ){  
161                                         temp=0;
162                                         howmany=0;
163                                         for( GLuint l = 0; l < texdetail*texture.sizeX ; l +=texture.sizeX ){
164                                                 for( GLuint j = 0; j < texdetail ; j ++ )
165                                                 {
166                                                         temp += (int)texture.data[k+i+j*bytesPerPixel+l*bytesPerPixel+b];       // Set The 1st Byte To The Value Of The 3rd Byte
167                                                         howmany++;
168                                                 }
169                                         }
170                                         texture.data[which+b]=GLubyte(temp/howmany);
171                                 }
172                                 which+=bytesPerPixel;
173                         }
174                 }
175                 texture.sizeX/=texdetail;
176                 texture.sizeY/=texdetail;
177         }
178
179         return true;
180
181 #endif
182 }
183
184
185 TGAImageRec*    LoadTGA( char *filename )
186 {    
187         GLubyte                 TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};        // Uncompressed TGA Header
188         GLubyte                 TGAcompare[12];                                                         // Used To Compare TGA Header
189         GLubyte                 header[6];                                                                      // First 6 Useful Bytes From The Header
190         GLuint                  bytesPerPixel;                                                          // Holds Number Of Bytes Per Pixel Used In The TGA File
191         GLuint                  imageSize;                                                                      // Used To Store The Image Size When Setting Aside Ram
192         GLuint                  temp;                                                                           // Temporary Variable
193         GLuint                  type = GL_RGBA;                                                         // Set The Default GL Mode To RBGA (32 BPP)
194         //TGAImageRec           *texture;
195         FILE                    *file;
196
197         // Open The TGA File
198         file = fopen( filename, "rb" );
199
200         if( ( file == NULL ) || // Does File Even Exist?
201                 ( fread( TGAcompare, 1, sizeof( TGAcompare ), file ) != sizeof( TGAcompare ) ) ||       // Are There 12 Bytes To Read?
202                 ( memcmp( TGAheader, TGAcompare, sizeof( TGAheader ) ) != 0 ) ||        // Does The Header Match What We Want?
203                 ( fread( header, 1, sizeof( header ), file ) != sizeof( header ) ) )// If So Read Next 6 Header Bytes
204         {
205                 // If anything failed then close the file and return false
206                 if (file) fclose( file );
207                 return NULL;
208         }
209
210         // Create a new RGBAImageRec
211         //texture = ( TGAImageRec* )malloc( sizeof( TGAImageRec ) );
212
213         // Determine the TGA width (highbyte*256+lowbyte) and height (highbyte*256+lowbyte)
214         texture.sizeX  = (header[1] * 256 + header[0]);
215         texture.sizeY = (header[3] * 256 + header[2]);
216
217         // Make sure the height, width, and bit depth are valid
218         if(     ( texture.sizeX <= 0 ) || ( texture.sizeY <= 0 ) || ( ( header[4] != 24 ) && ( header[4] != 32 ) ) )
219         {
220                 // If anything failed then close the file, free up memory for the image, and return NULL
221                 fclose( file );
222                 //free( texture );
223                 return NULL;
224         }
225
226         // Grab The TGA's Bits Per Pixel (24 or 32)
227         texture.bpp = header[4];                                                        
228         bytesPerPixel = texture.bpp/8;  // Divide By 8 To Get The Bytes Per Pixel
229
230         // Calculate The Memory Required For The TGA Data
231         imageSize = texture.sizeX * texture.sizeY * bytesPerPixel;
232
233         // Reserve Memory To Hold The TGA Data
234         //texture.data = ( GLubyte* )malloc( imageSize );               
235
236         // Make sure the right amount of memory was allocated
237         if(     ( texture.data == NULL ) || ( fread( texture.data, 1, imageSize, file ) != imageSize ) )
238         {
239                 // Free up the image data if there was any
240                 //              if( texture.data != NULL )
241                 //                      free( texture.data );
242
243                 // If anything failed then close the file, free up memory for the image, and return NULL
244                 fclose( file );
245                 //              free( texture );
246                 return NULL;
247         }
248
249         // Loop Through The Image Data
250         for( GLuint i = 0; i < int( imageSize ); i += bytesPerPixel )
251         {
252                 // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
253                 temp = texture.data[i];                                 // Temporarily Store The Value At Image Data 'i'
254                 texture.data[i] = texture.data[i + 2];  // Set The 1st Byte To The Value Of The 3rd Byte
255                 texture.data[i + 2] = temp;                             // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
256         }
257
258         if(texdetail>1){
259                 int which=0;
260                 float temp;
261                 float howmany;
262                 for( GLuint k = 0; k < int( imageSize); k += bytesPerPixel*texture.sizeX*texdetail )
263                 {
264                         for( GLuint i = 0; i < int( imageSize/texture.sizeY ); i += bytesPerPixel*texdetail )
265                         {
266                                 for( GLuint b = 0; b < bytesPerPixel ; b ++ ){  
267                                         temp=0;
268                                         howmany=0;
269                                         for( GLuint l = 0; l < texdetail*texture.sizeX ; l +=texture.sizeX ){
270                                                 for( GLuint j = 0; j < texdetail ; j ++ )
271                                                 {
272                                                         temp += (int)texture.data[k+i+j*bytesPerPixel+l*bytesPerPixel+b];       // Set The 1st Byte To The Value Of The 3rd Byte
273                                                         howmany++;
274                                                 }
275                                         }
276                                         texture.data[which+b]=GLubyte(temp/howmany);
277                                 }
278                                 which+=bytesPerPixel;
279                         }
280                 }
281                 texture.sizeX/=texdetail;
282                 texture.sizeY/=texdetail;
283         }
284
285         // Close The File
286         fclose( file );
287         return &texture;
288 }