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
|
|
|
|
*/
|
2006-09-03 14:33:29 -07:00
|
|
|
#include <assert.h>
|
2007-06-28 10:47:08 -07:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#ifdef _MSC_VER //we need windows.h for below inculde. --Qamly
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
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/framework/frame.h"
|
|
|
|
#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
|
|
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
|
|
iTexPage _TEX_PAGE[iV_TEX_MAX];
|
|
|
|
int _TEX_INDEX;
|
|
|
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
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-06-28 10:47:08 -07:00
|
|
|
int i = 0;
|
|
|
|
|
2007-03-15 15:49:54 -07:00
|
|
|
debug(LOG_TEXTURE, "pie_AddBMPtoTexPages: %s type=%d res=%d", filename,
|
2007-02-16 15:19:33 -08:00
|
|
|
type, bResource);
|
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) {
|
2006-09-23 07:56:18 -07:00
|
|
|
if (strcasecmp(filename, _TEX_PAGE[i].name) == 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 */
|
|
|
|
strcpy(_TEX_PAGE[i].name, filename);
|
|
|
|
|
|
|
|
/* 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)
|
|
|
|
{
|
2005-11-29 08:20:35 -08:00
|
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, s->width, s->height,
|
|
|
|
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);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
|
|
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-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-02-05 06:32:31 -08:00
|
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, s->width, s->height,
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
/**************************************************************************
|
|
|
|
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.
|
|
|
|
**************************************************************************/
|
|
|
|
int iV_GetTexture(char *filename)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
/* Have we already loaded this one then? (Yes. Always.) */
|
|
|
|
while (i < _TEX_INDEX) {
|
2006-09-23 07:56:18 -07:00
|
|
|
if (strcasecmp(filename, _TEX_PAGE[i].name) == 0) {
|
2007-06-28 10:47:08 -07:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
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-02-16 15:19:33 -08:00
|
|
|
debug(LOG_ERROR, "Available texture pages in memory:");
|
|
|
|
for (i = 0; i < _TEX_INDEX; i++) {
|
|
|
|
debug(LOG_ERROR, " %02d : %s", i, _TEX_PAGE[i].name);
|
|
|
|
}
|
|
|
|
debug(LOG_ERROR, "This error probably means you did not specify for this texture");
|
|
|
|
debug(LOG_ERROR, "to be preloaded in the appropriate wrf files before referencing");
|
|
|
|
debug(LOG_ERROR, "it in some pie file. Remember that patches override several");
|
|
|
|
debug(LOG_ERROR, "standard wrf files as well.");
|
2007-06-28 10:47:08 -07:00
|
|
|
assert(FALSE);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-07-03 12:43:12 -07:00
|
|
|
// According to logfile not used, deprecating
|
2006-11-03 13:35:50 -08:00
|
|
|
int pie_ReloadTexPage(char *filename, char *pBuffer)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
int i = 0;
|
2007-03-16 09:20:16 -07:00
|
|
|
iTexture s;
|
2006-07-03 12:43:12 -07:00
|
|
|
|
|
|
|
// Log call to check validity of deprecation
|
2007-02-16 15:19:33 -08:00
|
|
|
debug( LOG_ERROR, "pie_ReloadTexPage called for %s, tell Per!", filename );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
/* Have we already loaded this one then? */
|
2006-09-23 07:56:18 -07:00
|
|
|
while (strcasecmp(filename,_TEX_PAGE[i].name) != 0) {
|
2007-06-28 10:47:08 -07:00
|
|
|
i++;
|
|
|
|
if (i >= _TEX_INDEX) {
|
2005-11-30 13:09:38 -08:00
|
|
|
debug(LOG_TEXTURE, "Texture %s not in resources", filename);
|
2007-06-28 10:47:08 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//got the old texture page so load bmp straight in
|
|
|
|
s.width = _TEX_PAGE[i].tex.width;
|
|
|
|
s.height = _TEX_PAGE[i].tex.height;
|
|
|
|
s.bmp = _TEX_PAGE[i].tex.bmp;
|
|
|
|
|
2007-02-07 07:27:17 -08:00
|
|
|
pie_PNGLoadMem(pBuffer, &s);
|
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-06-28 10:47:08 -07:00
|
|
|
int i,j;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
j = 0;
|
|
|
|
|
|
|
|
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++;
|
|
|
|
iV_HeapFree(_TEX_PAGE[i].tex.bmp,_TEX_PAGE[i].tex.width * _TEX_PAGE[i].tex.height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2006-08-22 07:28:49 -07:00
|
|
|
debug( LOG_NEVER, "pie_TexShutDown successful - freed %d 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-06-28 10:47:08 -07:00
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while (i < _TEX_INDEX) {
|
|
|
|
_TEX_PAGE[i].tex.bmp = NULL;
|
|
|
|
_TEX_PAGE[i].tex.width = 0;
|
|
|
|
_TEX_PAGE[i].tex.height = 0;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|