]> git.mxchange.org Git - simgear.git/commitdiff
Major shuffling to push basic material management out into FlightGear/Lib/
authorcurt <curt>
Wed, 12 May 1999 04:24:55 +0000 (04:24 +0000)
committercurt <curt>
Wed, 12 May 1999 04:24:55 +0000 (04:24 +0000)
  so it can be accessible from the scenery tools.
Also implimented JIT texture loading to save start time and memory.

Lib/Misc/Makefile.am
Lib/Misc/colours.h [new file with mode: 0644]
Lib/Misc/material.cxx [new file with mode: 0644]
Lib/Misc/material.hxx [new file with mode: 0644]
Lib/Misc/texload.c [new file with mode: 0644]
Lib/Misc/texload.h [new file with mode: 0644]

index 8cab48b372d5f820f962f2f85a01bdc01d1583aa..de3ff96e94b994634b7058382c2752914d4b18cd 100644 (file)
@@ -5,8 +5,10 @@ noinst_LIBRARIES = libMisc.a
 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
diff --git a/Lib/Misc/colours.h b/Lib/Misc/colours.h
new file mode 100644 (file)
index 0000000..ba3b891
--- /dev/null
@@ -0,0 +1,289 @@
+// 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
diff --git a/Lib/Misc/material.cxx b/Lib/Misc/material.cxx
new file mode 100644 (file)
index 0000000..0f1a2e0
--- /dev/null
@@ -0,0 +1,247 @@
+// 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 ) {
+}
diff --git a/Lib/Misc/material.hxx b/Lib/Misc/material.hxx
new file mode 100644 (file)
index 0000000..f973e39
--- /dev/null
@@ -0,0 +1,100 @@
+// 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 
+
+
diff --git a/Lib/Misc/texload.c b/Lib/Misc/texload.c
new file mode 100644 (file)
index 0000000..69701af
--- /dev/null
@@ -0,0 +1,382 @@
+
+/* 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;
+}
diff --git a/Lib/Misc/texload.h b/Lib/Misc/texload.h
new file mode 100644 (file)
index 0000000..29df85c
--- /dev/null
@@ -0,0 +1,32 @@
+
+/* 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 */