so it can be accessible from the scenery tools.
Also implimented JIT texture loading to save start time and memory.
libMisc_a_SOURCES = \
fgpath.cxx fgpath.hxx \
fgstream.cxx fgstream.hxx \
+ material.cxx material.hxx \
stopwatch.hxx \
strutils.cxx strutils.hxx \
+ texload.c texload.h colours.h \
zfstream.cxx zfstream.hxx
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib
--- /dev/null
+// colours.h -- This header file contains colour definitions in the
+// same way as MS FS5 does
+//
+// Contributed by "Christian Mayer" <Vader@t-online.de>, started April 1999.
+//
+// Copyright (C) 1998 Christian Mayer - Vader@t-online.de
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef COLOURS_H
+#define COLOURS_H
+
+unsigned char msfs_colour[256][3]=
+{
+ { 0, 0, 0},
+ { 8, 8, 8},
+ { 16, 16, 16},
+ { 24, 24, 24},
+ { 32, 32, 32},
+ { 40, 40, 40},
+ { 48, 48, 48},
+ { 56, 56, 56},
+ { 65, 65, 65},
+ { 73, 73, 73},
+ { 81, 81, 81},
+ { 89, 89, 89},
+ { 97, 97, 97},
+ {105, 105, 105},
+ {113, 113, 113},
+ {121, 121, 121},
+ {130, 130, 130},
+ {138, 138, 138},
+ {146, 146, 146},
+ {154, 154, 154},
+ {162, 162, 162},
+ {170, 170, 170},
+ {178, 178, 178},
+ {186, 186, 186},
+ {195, 195, 195},
+ {203, 203, 203},
+ {211, 211, 211},
+ {219, 219, 219},
+ {227, 227, 227},
+ {235, 235, 235},
+ {247, 247, 247},
+ {255, 255, 255},
+ { 21, 5, 5},
+ { 42, 10, 10},
+ { 63, 15, 15},
+ { 84, 20, 20},
+ {105, 25, 25},
+ {126, 30, 30},
+ {147, 35, 35},
+ {168, 40, 40},
+ {189, 45, 45},
+ {210, 50, 50},
+ {231, 55, 55},
+ {252, 60, 60},
+ { 5, 21, 5},
+ { 10, 42, 10},
+ { 15, 63, 15},
+ { 20, 84, 20},
+ { 25, 105, 25},
+ { 30, 126, 30},
+ { 35, 147, 35},
+ { 40, 168, 40},
+ { 45, 189, 45},
+ { 50, 210, 50},
+ { 55, 231, 55},
+ { 60, 252, 60},
+ { 0, 7, 23},
+ { 0, 15, 40},
+ { 0, 23, 58},
+ { 0, 40, 84},
+ { 0, 64, 104},
+ { 0, 71, 122},
+ { 0, 87, 143},
+ { 0, 99, 156},
+ { 0, 112, 179},
+ { 0, 128, 199},
+ { 0, 143, 215},
+ { 0, 153, 230},
+ { 28, 14, 0},
+ { 56, 28, 0},
+ { 84, 42, 0},
+ {112, 56, 0},
+ {140, 70, 0},
+ {168, 84, 0},
+ {196, 98, 0},
+ {224, 112, 0},
+ {252, 126, 0},
+ { 28, 28, 0},
+ { 56, 56, 0},
+ { 84, 84, 0},
+ {112, 112, 0},
+ {140, 140, 0},
+ {168, 168, 0},
+ {196, 196, 0},
+ {224, 224, 0},
+ {252, 252, 0},
+ { 25, 21, 16},
+ { 50, 42, 32},
+ { 75, 63, 48},
+ {100, 84, 64},
+ {125, 105, 80},
+ {150, 126, 96},
+ {175, 147, 112},
+ {200, 168, 128},
+ {225, 189, 144},
+ { 28, 11, 7},
+ { 56, 22, 14},
+ { 84, 33, 21},
+ {112, 44, 28},
+ {140, 55, 35},
+ {168, 66, 42},
+ {196, 77, 49},
+ {224, 88, 56},
+ {252, 99, 63},
+ { 17, 22, 9},
+ { 34, 44, 18},
+ { 51, 66, 27},
+ { 68, 88, 36},
+ { 85, 110, 45},
+ {102, 132, 54},
+ {119, 154, 63},
+ {136, 176, 72},
+ {153, 198, 81},
+ { 0, 58, 104},
+ { 0, 87, 112},
+ { 43, 112, 128},
+ {255, 0, 0},
+ { 64, 255, 64},
+ { 0, 0, 192},
+ { 0, 105, 105},
+ {255, 128, 0},
+ {255, 255, 0},
+ { 81, 81, 81},
+ {121, 121, 121},
+ {146, 146, 146},
+ {170, 170, 170},
+ {195, 195, 195},
+ {227, 227, 227},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ { 0, 0, 0},
+ {192, 192, 255},
+ {200, 200, 255},
+ {208, 208, 255},
+ {216, 216, 255},
+ {224, 224, 255},
+ {232, 232, 255},
+ {240, 240, 255},
+ {248, 248, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ {255, 255, 255},
+ { 16, 72, 16},
+ { 32, 80, 32},
+ { 48, 88, 48},
+ { 64, 96, 64},
+ { 80, 104, 80},
+ { 96, 112, 96},
+ {112, 120, 112},
+ {120, 124, 120},
+ {128, 128, 128},
+ {128, 128, 128},
+ {128, 128, 128},
+ {128, 128, 128},
+ {128, 128, 128},
+ {128, 128, 128},
+ {128, 128, 128},
+ {128, 128, 128},
+ { 33, 140, 189},
+ { 57, 132, 165},
+ {189, 66, 66},
+ {156, 66, 66},
+ {132, 74, 74},
+ { 33, 82, 107},
+ {214, 90, 82},
+ {189, 90, 82},
+ {165, 90, 82},
+ {123, 57, 49},
+ { 99, 57, 49},
+ {107, 74, 66},
+ {123, 90, 82},
+ {181, 90, 66},
+ { 74, 49, 41},
+ {189, 115, 90},
+ {140, 90, 49},
+ { 33, 49, 74},
+ {181, 115, 49},
+ { 99, 66, 33},
+ {165, 115, 66},
+ { 49, 41, 33},
+ {165, 140, 115},
+ {189, 165, 140},
+ { 57, 99, 123},
+ {181, 107, 24},
+ {206, 123, 33},
+ {156, 99, 33},
+ {148, 107, 49},
+ {107, 82, 49},
+ { 33, 33, 57},
+ { 33, 115, 165},
+ {214, 214, 33},
+ {173, 173, 33},
+ {198, 198, 41},
+ {140, 140, 33},
+ {115, 115, 33},
+ {189, 189, 57},
+ {156, 156, 49},
+ {173, 173, 57},
+ {123, 123, 49},
+ {123, 123, 66},
+ { 74, 74, 49},
+ {123, 123, 90},
+ { 41, 41, 33},
+ { 90, 99, 57},
+ {107, 115, 74},
+ {123, 148, 82},
+ {140, 173, 99},
+ {132, 156, 99},
+ { 49, 66, 41},
+ { 99, 165, 90},
+ { 74, 214, 74},
+ { 57, 140, 57},
+ { 74, 181, 74},
+ { 90, 198, 90},
+ { 57, 123, 57},
+ { 49, 99, 49},
+ { 90, 165, 90},
+ { 82, 148, 82},
+ { 74, 99, 74},
+ { 57, 115, 132},
+ { 33, 99, 123},
+ { 74, 115, 132}
+};
+
+
+#endif
--- /dev/null
+// material.cxx -- class to handle material properties
+//
+// Written by Curtis Olson, started May 1998.
+//
+// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Include/compiler.h>
+
+#ifdef FG_MATH_EXCEPTION_CLASH
+# include <math.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+
+#include <GL/glut.h>
+#include <XGL/xgl.h>
+
+#include STL_STRING
+
+#include <Debug/logstream.hxx>
+#include <Misc/fgpath.hxx>
+#include <Misc/fgstream.hxx>
+
+#include "material.hxx"
+#include "texload.h"
+
+FG_USING_STD(string);
+
+
+// Constructor
+FGMaterial::FGMaterial ( void )
+ : loaded(false),
+ texture_name(""),
+ alpha(0)
+ // , list_size(0)
+{
+ ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0;
+ diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0;
+ specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
+ emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
+}
+
+
+istream&
+operator >> ( istream& in, FGMaterial& m )
+{
+ string token;
+
+ for (;;) {
+ in >> token;
+ if ( token == "texture" ) {
+ in >> token >> m.texture_name;
+ } else if ( token == "xsize" ) {
+ in >> token >> m.xsize;
+ } else if ( token == "ysize" ) {
+ in >> token >> m.ysize;
+ } else if ( token == "ambient" ) {
+ in >> token >> m.ambient[0] >> m.ambient[1]
+ >> m.ambient[2] >> m.ambient[3];
+ } else if ( token == "diffuse" ) {
+ in >> token >> m.diffuse[0] >> m.diffuse[1]
+ >> m.diffuse[2] >> m.diffuse[3];
+ } else if ( token == "specular" ) {
+ in >> token >> m.specular[0] >> m.specular[1]
+ >> m.specular[2] >> m.specular[3];
+ } else if ( token == "emissive" ) {
+ in >> token >> m.emissive[0] >> m.emissive[1]
+ >> m.emissive[2] >> m.emissive[3];
+ } else if ( token == "alpha" ) {
+ in >> token >> token;
+ if ( token == "yes" ) {
+ m.alpha = 1;
+ } else if ( token == "no" ) {
+ m.alpha = 0;
+ } else {
+ FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
+ }
+ } else if ( token[0] == '}' ) {
+ break;
+ }
+ }
+
+ return in;
+}
+
+void
+FGMaterial::load_texture( const string& root )
+{
+ GLubyte *texbuf;
+ int width, height;
+
+ FG_LOG( FG_TERRAIN, FG_INFO,
+ " Loading texture for material " << texture_name );
+
+ // create the texture object and bind it
+#ifdef GL_VERSION_1_1
+ xglGenTextures(1, &texture_id );
+ xglBindTexture(GL_TEXTURE_2D, texture_id );
+#elif GL_EXT_texture_object
+ xglGenTexturesEXT(1, &texture_id );
+ xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
+#else
+# error port me
+#endif
+
+ // set the texture parameters for this texture
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ GL_LINEAR );
+ // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ // GL_NEAREST_MIPMAP_NEAREST );
+ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ /* GL_LINEAR */
+ /* GL_NEAREST_MIPMAP_LINEAR */
+ GL_LINEAR_MIPMAP_LINEAR ) ;
+
+ // load in the texture data
+ FGPath base_path( root );
+ base_path.append( "Textures" );
+ base_path.append( texture_name );
+
+ FGPath tpath = base_path;
+ tpath.concat( ".rgb" );
+
+ FGPath fg_tpath = tpath;
+ fg_tpath.concat( ".gz" );
+
+ FGPath fg_raw_tpath = base_path;
+ fg_raw_tpath.concat( ".raw" );
+
+ // create string names for msfs compatible textures
+ FGPath fg_r8_tpath = base_path;
+ fg_r8_tpath.concat( ".r8" );
+
+ FGPath fg_tex_tpath = base_path;
+ fg_tex_tpath.concat( ".txt" );
+
+ FGPath fg_pat_tpath = base_path;
+ fg_pat_tpath.concat( ".pat" );
+
+ FGPath fg_oav_tpath = base_path;
+ fg_oav_tpath.concat( ".oav" );
+
+ if ( alpha == 0 ) {
+ // load rgb texture
+
+ // Try uncompressed
+ if ( (texbuf =
+ read_rgb_texture(tpath.c_str(), &width, &height)) !=
+ NULL )
+ ;
+ // Try compressed
+ else if ( (texbuf =
+ read_rgb_texture(fg_tpath.c_str(), &width, &height))
+ != NULL )
+ ;
+ // Try raw
+ else if ( (texbuf =
+ read_raw_texture(fg_raw_tpath.c_str(), &width, &height))
+ != NULL )
+ ;
+ // Try r8
+ else if ( (texbuf =
+ read_r8_texture(fg_r8_tpath.c_str(), &width, &height))
+ != NULL )
+ ;
+ // Try tex
+ else if ( (texbuf =
+ read_r8_texture(fg_tex_tpath.c_str(), &width, &height))
+ != NULL )
+ ;
+ // Try pat
+ else if ( (texbuf =
+ read_r8_texture(fg_pat_tpath.c_str(), &width, &height))
+ != NULL )
+ ;
+ // Try oav
+ else if ( (texbuf =
+ read_r8_texture(fg_oav_tpath.c_str(), &width, &height))
+ != NULL )
+ ;
+ else
+ {
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "Error in loading texture " << tpath.str() );
+ exit(-1);
+ }
+
+ /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
+ GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
+ GL_RGB, GL_UNSIGNED_BYTE, texbuf );
+ } else if ( alpha == 1 ) {
+ // load rgba (alpha) texture
+
+ // Try uncompressed
+ if ( (texbuf =
+ read_alpha_texture(tpath.c_str(), &width, &height))
+ == NULL )
+ {
+ // Try compressed
+ if ((texbuf =
+ read_alpha_texture(fg_tpath.c_str(), &width, &height))
+ == NULL )
+ {
+ FG_LOG( FG_GENERAL, FG_ALERT,
+ "Error in loading texture " << tpath.str() );
+ exit(-1);
+ }
+ }
+
+ xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
+ }
+
+ loaded = true;
+}
+
+
+// Destructor
+FGMaterial::~FGMaterial ( void ) {
+}
--- /dev/null
+// material.hxx -- class to handle material properties
+//
+// Written by Curtis Olson, started May 1998.
+//
+// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef _MATERIAL_HXX
+#define _MATERIAL_HXX
+
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+
+#include "Include/compiler.h"
+
+#include <GL/glut.h>
+#include <XGL/xgl.h>
+
+#include STL_STRING // Standard C++ string library
+
+FG_USING_STD(string);
+
+
+// MSVC++ 6.0 kuldge - Need forward declaration of friends.
+class fgMATERIAL;
+istream& operator >> ( istream& in, fgMATERIAL& m );
+
+// Material property class
+class FGMaterial {
+
+private:
+ // texture loaded
+ bool loaded;
+
+ // OpenGL texture name
+ GLuint texture_id;
+
+ // file name of texture
+ string texture_name;
+
+ // alpha texture?
+ int alpha;
+
+ // texture size
+ double xsize, ysize;
+
+ // material properties
+ GLfloat ambient[4], diffuse[4], specular[4], emissive[4];
+ GLint texture_ptr;
+
+public:
+
+ // Constructor
+ FGMaterial ( void );
+
+ // Destructor
+ ~FGMaterial ( void );
+
+ void load_texture( const string& root );
+
+ friend istream& operator >> ( istream& in, FGMaterial& m );
+
+ inline bool is_loaded() const { return loaded; }
+ inline GLuint get_texture_id() const { return texture_id; }
+ inline GLfloat *get_ambient() { return ambient; }
+ inline GLfloat *get_diffuse() { return diffuse; }
+ inline GLfloat *get_specular() { return specular; }
+ inline GLfloat *get_emissive() { return emissive; }
+};
+
+
+#endif // _MATERIAL_HXX
+
+
--- /dev/null
+
+/* texture.c - by David Blythe, SGI */
+
+/* texload is a simplistic routine for reading an SGI .rgb image file. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <Include/fg_zlib.h>
+
+#include "texload.h"
+#include "colours.h"
+
+typedef struct _ImageRec {
+ unsigned short imagic;
+ unsigned short type;
+ unsigned short dim;
+ unsigned short xsize, ysize, zsize;
+ unsigned int min, max;
+ unsigned int wasteBytes;
+ char name[80];
+ unsigned long colorMap;
+ fgFile file;
+ unsigned char *tmp;
+ unsigned long rleEnd;
+ unsigned int *rowStart;
+ int *rowSize;
+} ImageRec;
+
+void
+rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
+ while(n--) {
+ l[0] = r[0];
+ l[1] = g[0];
+ l[2] = b[0];
+ l += 3; r++; g++; b++;
+ }
+}
+
+static void
+ConvertShort(unsigned short *array, unsigned int length) {
+ unsigned short b1, b2;
+ unsigned char *ptr;
+
+ ptr = (unsigned char *)array;
+ while (length--) {
+ b1 = *ptr++;
+ b2 = *ptr++;
+ *array++ = (b1 << 8) | (b2);
+ }
+}
+
+static void
+ConvertUint(unsigned *array, unsigned int length) {
+ unsigned int b1, b2, b3, b4;
+ unsigned char *ptr;
+
+ ptr = (unsigned char *)array;
+ while (length--) {
+ b1 = *ptr++;
+ b2 = *ptr++;
+ b3 = *ptr++;
+ b4 = *ptr++;
+ *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
+ }
+}
+
+static ImageRec *ImageOpen(const char *fileName)
+{
+ union {
+ int testWord;
+ char testByte[4];
+ } endianTest;
+
+ ImageRec *image;
+ int swapFlag;
+ int x;
+
+ endianTest.testWord = 1;
+ if (endianTest.testByte[0] == 1) {
+ swapFlag = 1;
+ } else {
+ swapFlag = 0;
+ }
+
+ image = (ImageRec *)malloc(sizeof(ImageRec));
+ if (image == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+ if ((image->file = fgopen(fileName, "rb")) == NULL) {
+ return NULL;
+ }
+
+ // fread(image, 1, 12, image->file);
+ fgread(image->file, image, 12);
+
+ if (swapFlag) {
+ ConvertShort(&image->imagic, 6);
+ }
+
+ image->tmp = (unsigned char *)malloc(image->xsize*256);
+ if (image->tmp == NULL) {
+ fprintf(stderr, "\nOut of memory!\n");
+ exit(1);
+ }
+
+ if ((image->type & 0xFF00) == 0x0100) {
+ x = image->ysize * image->zsize * (int) sizeof(unsigned);
+ image->rowStart = (unsigned *)malloc(x);
+ image->rowSize = (int *)malloc(x);
+ if (image->rowStart == NULL || image->rowSize == NULL) {
+ fprintf(stderr, "\nOut of memory!\n");
+ exit(1);
+ }
+ image->rleEnd = 512 + (2 * x);
+ fgseek(image->file, 512, SEEK_SET);
+ // fread(image->rowStart, 1, x, image->file);
+ fgread(image->file, image->rowStart, x);
+ // fread(image->rowSize, 1, x, image->file);
+ fgread(image->file, image->rowSize, x);
+ if (swapFlag) {
+ ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
+ ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
+ }
+ }
+ return image;
+}
+
+static void
+ImageClose(ImageRec *image) {
+ fgclose(image->file);
+ free(image->tmp);
+ free(image);
+}
+
+static void
+ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
+ unsigned char *iPtr, *oPtr, pixel;
+ int count;
+
+ if ((image->type & 0xFF00) == 0x0100) {
+ fgseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
+ // fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
+ // image->file);
+ fgread(image->file, image->tmp,
+ (unsigned int)image->rowSize[y+z*image->ysize]);
+
+ iPtr = image->tmp;
+ oPtr = buf;
+ for (;;) {
+ pixel = *iPtr++;
+ count = (int)(pixel & 0x7F);
+ if (!count) {
+ return;
+ }
+ if (pixel & 0x80) {
+ while (count--) {
+ *oPtr++ = *iPtr++;
+ }
+ } else {
+ pixel = *iPtr++;
+ while (count--) {
+ *oPtr++ = pixel;
+ }
+ }
+ }
+ } else {
+ fgseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
+ SEEK_SET);
+ // fread(buf, 1, image->xsize, image->file);
+ fgread(image->file, buf, image->xsize);
+ }
+}
+
+GLubyte *
+read_alpha_texture(const char *name, int *width, int *height)
+{
+ unsigned char *base, *lptr;
+ ImageRec *image;
+ int y;
+
+ image = ImageOpen(name);
+ if(!image) {
+ return NULL;
+ }
+
+ (*width)=image->xsize;
+ (*height)=image->ysize;
+
+ printf("image->zsize = %d\n", image->zsize);
+
+ if (image->zsize != 1) {
+ ImageClose(image);
+ return NULL;
+ }
+
+ base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
+ lptr = base;
+ for(y=0; y<image->ysize; y++) {
+ ImageGetRow(image,lptr,y,0);
+ lptr += image->xsize;
+ }
+ ImageClose(image);
+
+ return (unsigned char *) base;
+}
+
+GLubyte *
+read_rgb_texture(const char *name, int *width, int *height)
+{
+ unsigned char *base, *ptr;
+ unsigned char *rbuf, *gbuf, *bbuf, *abuf;
+ ImageRec *image;
+ int y;
+
+ image = ImageOpen(name);
+
+ if(!image)
+ return NULL;
+ (*width)=image->xsize;
+ (*height)=image->ysize;
+ if (image->zsize != 3 && image->zsize != 4) {
+ ImageClose(image);
+ return NULL;
+ }
+
+ base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
+ rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+ gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+ bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+ abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
+ if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
+ if (base) free(base);
+ if (rbuf) free(rbuf);
+ if (gbuf) free(gbuf);
+ if (bbuf) free(bbuf);
+ if (abuf) free(abuf);
+ return NULL;
+ }
+ ptr = base;
+ for(y=0; y<image->ysize; y++) {
+ if(image->zsize == 4) {
+ ImageGetRow(image,rbuf,y,0);
+ ImageGetRow(image,gbuf,y,1);
+ ImageGetRow(image,bbuf,y,2);
+ ImageGetRow(image,abuf,y,3); /* Discard. */
+ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
+ ptr += (image->xsize * 3);
+ } else {
+ ImageGetRow(image,rbuf,y,0);
+ ImageGetRow(image,gbuf,y,1);
+ ImageGetRow(image,bbuf,y,2);
+ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
+ ptr += (image->xsize * 3);
+ }
+ }
+ ImageClose(image);
+ free(rbuf);
+ free(gbuf);
+ free(bbuf);
+ free(abuf);
+
+ return (GLubyte *) base;
+}
+
+
+static ImageRec *RawImageOpen(const char *fileName)
+{
+ union {
+ int testWord;
+ char testByte[4];
+ } endianTest;
+
+ ImageRec *image;
+ int swapFlag;
+
+ endianTest.testWord = 1;
+ if (endianTest.testByte[0] == 1) {
+ swapFlag = 1;
+ } else {
+ swapFlag = 0;
+ }
+
+ image = (ImageRec *)malloc(sizeof(ImageRec));
+ if (image == NULL) {
+ fprintf(stderr, "Out of memory!\n");
+ exit(1);
+ }
+ if ((image->file = fgopen(fileName, "rb")) == NULL) {
+ return NULL;
+ }
+
+ fgread(image->file, image, 12);
+
+ if (swapFlag) {
+ ConvertShort(&image->imagic, 6);
+ }
+
+
+ image->tmp = (unsigned char *)malloc(1); //just allocate a pseudo value as I'm too lazy to change ImageClose()...
+ if (image->tmp == NULL) {
+ fprintf(stderr, "\nOut of memory!\n");
+ exit(1);
+ }
+
+ return image;
+}
+
+
+GLubyte *
+read_raw_texture(const char *name, int *width, int *height)
+{
+ unsigned char *base, *ptr;
+ ImageRec *image;
+ int y;
+
+ image = RawImageOpen(name);
+
+ if(!image)
+ return NULL;
+ (*width)=256;
+ (*height)=256;
+
+ base = (unsigned char*)malloc(256*256*sizeof(unsigned char)*3);
+ if(!base) {
+ if (base) free(base);
+ return NULL;
+ }
+ ptr = base;
+ for(y=0; y<256; y++) {
+ fgread(image->file, ptr, 256*3);
+ ptr+=256*3;
+ }
+ ImageClose(image);
+
+ return (GLubyte *) base;
+}
+
+
+GLubyte *
+read_r8_texture(const char *name, int *width, int *height)
+{
+ unsigned char *base, *ptr;
+ ImageRec *image;
+ int xy;
+ unsigned char c[1];
+
+ image = RawImageOpen(name); //it wouldn't make sense to write a new function...
+
+ if(!image)
+ return NULL;
+ (*width)=256;
+ (*height)=256;
+
+ base = (unsigned char*)malloc(256*256*sizeof(unsigned char)*3);
+ if(!base) {
+ if (base) free(base);
+ return NULL;
+ }
+ ptr = base;
+ for(xy=0; xy<(256*256); xy++) {
+ fgread(image->file,c,1);
+ ptr[0]=msfs_colour[c[0]][0]; //look in the table for the right colours
+ ptr[1]=msfs_colour[c[0]][1];
+ ptr[2]=msfs_colour[c[0]][2];
+
+ ptr+=3;
+ }
+ ImageClose(image);
+
+ return (GLubyte *) base;
+}
--- /dev/null
+
+/* Copyright (c) Mark J. Kilgard, 1997. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+
+#ifndef _TEXLOAD_H
+#define _TEXLOAD_H
+
+
+#include <GL/glut.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern GLubyte *read_alpha_texture(const char *name, int *width, int *height);
+extern GLubyte *read_rgb_texture(const char *name, int *width, int *height);
+extern GLubyte *read_raw_texture(const char *name, int *width, int *height);
+extern GLubyte *read_r8_texture(const char *name, int *width, int *height);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _TEXLOAD_H */