2007-01-15 12:09:25 -08:00
/*
This file is part of Warzone 2100.
Copyright ( C ) 1999 - 2004 Eidos Interactive
Copyright ( C ) 2005 - 2007 Warzone Resurrection Project
Warzone 2100 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 .
Warzone 2100 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 Warzone 2100 ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2007-04-11 07:21:45 -07:00
# include "lib/framework/frame.h"
2006-08-12 03:45:49 -07:00
# include <SDL/SDL_opengl.h>
2006-08-15 09:33:48 -07:00
# ifdef __APPLE__
# include <opengl/glu.h>
# else
2005-11-29 08:20:35 -08:00
# include <GL/glu.h>
2006-08-15 09:33:48 -07:00
# endif
2007-06-28 10:47:08 -07:00
2006-06-02 12:34:58 -07:00
# include "lib/ivis_common/ivisdef.h"
# include "lib/ivis_common/piestate.h"
# include "lib/ivis_common/tex.h"
# include "lib/ivis_common/rendmode.h"
# include "lib/ivis_common/piepalette.h"
# include "lib/ivis_common/ivispatch.h"
2007-06-28 10:47:08 -07:00
2007-03-28 08:08:57 -07:00
# include "screen.h"
2007-06-28 10:47:08 -07:00
//*************************************************************************
iTexPage _TEX_PAGE [ iV_TEX_MAX ] ;
2007-04-23 15:08:53 -07:00
unsigned int _TEX_INDEX ;
2007-06-28 10:47:08 -07:00
//*************************************************************************
/**************************************************************************
Add an image buffer given in s as a new texture page in the texture
table . We check first if the given image has already been loaded ,
as a sanity check ( should never happen ) . The texture numbers are
stored in a special texture table , not in the resource system , for
some unknown reason .
Returns the texture number of the image .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-03-16 09:20:16 -07:00
int pie_AddBMPtoTexPages ( iTexture * s , const char * filename , int type , BOOL bResource )
2007-02-16 15:19:33 -08:00
{
2007-04-19 11:04:41 -07:00
unsigned int i = 0 ;
2007-06-28 10:47:08 -07:00
2007-04-19 11:04:41 -07:00
debug ( LOG_TEXTURE , " pie_AddBMPtoTexPages: %s type=%d resource=%s page=%d " , filename , type , bResource ? " true " : " false " , _TEX_INDEX ) ;
2007-06-28 10:47:08 -07:00
assert ( s ! = NULL ) ;
/* Have we already loaded this one? (Should generally not happen here.) */
while ( i < _TEX_INDEX ) {
2007-04-19 11:04:41 -07:00
if ( strncmp ( filename , _TEX_PAGE [ i ] . name , iV_TEXNAME_MAX ) = = 0 ) {
2007-06-28 10:47:08 -07:00
// this happens with terrain for some reason, which is necessary
debug ( LOG_TEXTURE , " pie_AddBMPtoTexPages: %s loaded again " , filename ) ;
}
i + + ;
}
/* Get next available texture page */
i = _TEX_INDEX ;
/* Have we used up too many? */
if ( _TEX_INDEX > = iV_TEX_MAX ) {
debug ( LOG_ERROR , " pie_AddBMPtoTexPages: too many texture pages " ) ;
assert ( FALSE ) ;
return - 1 ;
}
/* Stick the name into the tex page structures */
2007-04-19 11:04:41 -07:00
strncpy ( _TEX_PAGE [ i ] . name , filename , iV_TEXNAME_MAX ) ;
2007-06-28 10:47:08 -07:00
/* Store away all the info */
/* DID come from a resource */
_TEX_PAGE [ i ] . bResource = bResource ;
_TEX_PAGE [ i ] . tex . bmp = s - > bmp ;
_TEX_PAGE [ i ] . tex . width = s - > width ;
_TEX_PAGE [ i ] . tex . height = s - > height ;
_TEX_PAGE [ i ] . type = type ;
glGenTextures ( 1 , & _TEX_PAGE [ i ] . textPage3dfx ) ;
2007-02-10 06:34:12 -08:00
glBindTexture ( GL_TEXTURE_2D , _TEX_PAGE [ i ] . textPage3dfx ) ;
2007-06-28 10:47:08 -07:00
2007-02-16 15:19:33 -08:00
if ( ( s - > width & ( s - > width - 1 ) ) = = 0 & & ( s - > height & ( s - > height - 1 ) ) = = 0 )
{
2007-03-28 08:08:57 -07:00
gluBuild2DMipmaps ( GL_TEXTURE_2D , wz_texture_compression , s - > width , s - > height ,
2005-11-29 08:20:35 -08:00
GL_RGBA , GL_UNSIGNED_BYTE , s - > bmp ) ;
} else {
2007-02-16 15:19:33 -08:00
debug ( LOG_ERROR , " pie_AddBMPtoTexPages: non POT texture %s. " , filename ) ;
2007-06-28 10:47:08 -07:00
}
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2006-12-17 10:18:06 -08:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR ) ;
2007-06-28 10:47:08 -07:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
2007-03-30 10:38:35 -07:00
if ( i = = SKY_TEXPAGE )
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT ) ;
}
else
{
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP ) ;
}
2007-06-28 10:47:08 -07:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP ) ;
/* Send back the texpage number so we can store it in the IMD */
_TEX_INDEX + + ;
return i ;
}
2007-04-19 11:04:41 -07:00
void pie_Pagename ( char * filename )
{
if ( strncmp ( filename , " page- " , 5 ) = = 0 )
{
int i ;
for ( i = 5 ; i < iV_TEXNAME_MAX - 1 & & isdigit ( filename [ i ] ) ; i + + ) ;
filename [ i ] = ' \0 ' ;
}
}
2007-03-16 09:20:16 -07:00
void pie_ChangeTexPage ( int tex_index , iTexture * s , int type , BOOL bResource )
2007-06-28 10:47:08 -07:00
{
assert ( s ! = NULL ) ;
/* DID come from a resource */
_TEX_PAGE [ tex_index ] . bResource = bResource ;
// Default values
_TEX_PAGE [ tex_index ] . tex . bmp = s - > bmp ;
_TEX_PAGE [ tex_index ] . tex . width = s - > width ;
_TEX_PAGE [ tex_index ] . tex . height = s - > height ;
_TEX_PAGE [ tex_index ] . type = type ;
2007-02-10 06:34:12 -08:00
glBindTexture ( GL_TEXTURE_2D , _TEX_PAGE [ tex_index ] . textPage3dfx ) ;
2007-02-05 06:32:31 -08:00
2007-02-16 15:19:33 -08:00
if ( ( s - > width & ( s - > width - 1 ) ) = = 0 & & ( s - > height & ( s - > height - 1 ) ) = = 0 )
{
2007-03-28 08:08:57 -07:00
gluBuild2DMipmaps ( GL_TEXTURE_2D , wz_texture_compression , s - > width , s - > height ,
2007-02-05 06:32:31 -08:00
GL_RGBA , GL_UNSIGNED_BYTE , s - > bmp ) ;
} else {
2007-02-16 15:19:33 -08:00
debug ( LOG_ERROR , " pie_ChangeTexPage: non POT texture %i " , tex_index ) ;
2007-02-05 06:32:31 -08:00
}
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP ) ;
2007-06-28 10:47:08 -07:00
}
2007-04-19 11:04:41 -07:00
/*!
* Print the names of all loaded textures to LOG_ERROR
*/
void pie_PrintLoadedTextures ( void )
{
unsigned int i = 0 ;
debug ( LOG_ERROR , " Available texture pages in memory (%d out of %d max): " , _TEX_INDEX , iV_TEX_MAX ) ;
for ( i = 0 ; i < iV_TEX_MAX ; i + + ) {
debug ( LOG_ERROR , " %02d : %s " , i , _TEX_PAGE [ i ] . name ) ;
}
}
2007-06-28 10:47:08 -07:00
/**************************************************************************
Return the texture number for a given texture resource . We keep
textures in a separate data structure _TEX_PAGE apart from the
normal resource system .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-04-16 13:07:56 -07:00
int iV_GetTexture ( const char * filename )
2007-06-28 10:47:08 -07:00
{
2007-04-19 11:04:41 -07:00
unsigned int i = 0 ;
2007-06-28 10:47:08 -07:00
2007-03-16 10:33:20 -07:00
/* Have we already loaded this one then? */
2007-04-19 11:04:41 -07:00
for ( i = 0 ; i < iV_TEX_MAX ; i + + ) {
if ( strncmp ( filename , _TEX_PAGE [ i ] . name , iV_TEXNAME_MAX ) = = 0 ) {
2007-06-28 10:47:08 -07:00
return i ;
}
}
/* This should never happen - by now all textures should have been loaded. */
2005-12-28 03:46:45 -08:00
debug ( LOG_ERROR , " *** texture %s not loaded! *** " , filename ) ;
2007-04-19 11:04:41 -07:00
debug ( LOG_ERROR , " This error probably means you did not specify this texture to be preloaded in the appropriate wrf files before referencing it in some pie file " ) ;
debug ( LOG_ERROR , " Remember that patches override several standard wrf files as well " ) ;
pie_PrintLoadedTextures ( ) ;
2007-03-16 10:33:20 -07:00
2007-06-28 10:47:08 -07:00
return - 1 ;
}
2007-04-19 11:04:41 -07:00
2007-04-16 15:29:44 -07:00
int pie_ReloadTexPage ( const char * texpageName , const char * fileName )
2007-06-28 10:47:08 -07:00
{
2007-04-16 15:29:44 -07:00
int i = iV_GetTexture ( texpageName ) ;
2006-07-03 12:43:12 -07:00
2007-04-19 11:04:41 -07:00
if ( i < 0 )
2007-03-16 10:33:20 -07:00
{
return - 1 ;
2007-06-28 10:47:08 -07:00
}
2007-04-19 11:04:41 -07:00
2007-04-16 15:29:44 -07:00
debug ( LOG_TEXTURE , " Reloading texture %s from index %d, max is %d " , texpageName , i , _TEX_INDEX ) ;
2007-06-28 10:47:08 -07:00
2007-03-16 10:33:20 -07:00
if ( _TEX_PAGE [ i ] . tex . bmp )
{
free ( _TEX_PAGE [ i ] . tex . bmp ) ;
}
2007-04-16 15:29:44 -07:00
pie_PNGLoadFile ( fileName , & _TEX_PAGE [ i ] . tex ) ;
2007-06-28 10:47:08 -07:00
return i ;
}
/*
Alex - fixed this so it doesn ' t try to free up the memory if it got the page from resource
handler - this is because the resource handler will deal with freeing it , and in all probability
will have already done so by the time this is called , thus avoiding an ' already freed ' moan .
*/
2007-03-15 15:49:54 -07:00
void pie_TexShutDown ( void )
2007-02-16 15:19:33 -08:00
{
2007-04-23 15:08:53 -07:00
unsigned int i = 0 , j = 0 ;
2007-06-28 10:47:08 -07:00
while ( i < _TEX_INDEX ) {
/* Only free up the ones that were NOT allocated through resource handler cos they'll already
be free */
if ( _TEX_PAGE [ i ] . bResource = = FALSE )
{
if ( _TEX_PAGE [ i ] . tex . bmp ) {
j + + ;
2007-04-15 03:43:05 -07:00
free ( _TEX_PAGE [ i ] . tex . bmp ) ;
2007-06-28 10:47:08 -07:00
}
}
i + + ;
}
2007-04-23 15:08:53 -07:00
debug ( LOG_TEXTURE , " pie_TexShutDown successful - did free %u texture pages \n " , j ) ;
2007-06-28 10:47:08 -07:00
}
2007-03-15 15:49:54 -07:00
void pie_TexInit ( void )
2007-02-16 15:19:33 -08:00
{
2007-03-16 10:33:20 -07:00
int i = 0 ;
2007-06-28 10:47:08 -07:00
2007-03-16 10:33:20 -07:00
while ( i < iV_TEX_MAX ) {
_TEX_PAGE [ i ] . name [ 0 ] = ' \0 ' ;
2007-06-28 10:47:08 -07:00
_TEX_PAGE [ i ] . tex . bmp = NULL ;
_TEX_PAGE [ i ] . tex . width = 0 ;
_TEX_PAGE [ i ] . tex . height = 0 ;
i + + ;
}
2007-03-16 10:33:20 -07:00
debug ( LOG_TEXTURE , " pie_TexInit successful - initialized %d texture pages \n " , i ) ;
2007-06-28 10:47:08 -07:00
}