37 changes: 4 additions & 33 deletions lib/framework/frameresource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,43 +147,25 @@ static RES_TYPE* resAlloc(const char *pType)
// Check for a duplicate type
for(psT = psResTypes; psT; psT = psT->psNext)
{
ASSERT( strcmp(psT->aType, pType) != 0,
"resAlloc: Duplicate function for type: %s", pType );
ASSERT(strcmp(psT->aType, pType) != 0, "Duplicate function for type: %s", pType);
}
#endif

// Allocate the memory
psT = (RES_TYPE *)malloc(sizeof(RES_TYPE));
if (!psT)
{
debug( LOG_FATAL, "resAlloc: Out of memory" );
abort();
return NULL;
}

// setup the structure
psT = (RES_TYPE *)malloc(sizeof(RES_TYPE));
sstrcpy(psT->aType, pType);

psT->HashedType = HashString(psT->aType); // store a hased version for super speed !

psT->psRes = NULL;

return psT;
}



/* Add a buffer load function for a file type */
bool resAddBufferLoad(const char *pType, RES_BUFFERLOAD buffLoad,
RES_FREE release)
bool resAddBufferLoad(const char *pType, RES_BUFFERLOAD buffLoad, RES_FREE release)
{
RES_TYPE *psT = resAlloc(pType);

if (!psT)
{
return false;
}

psT->buffLoad = buffLoad;
psT->fileLoad = NULL;
psT->release = release;
Expand All @@ -196,16 +178,10 @@ bool resAddBufferLoad(const char *pType, RES_BUFFERLOAD buffLoad,


/* Add a file name load function for a file type */
bool resAddFileLoad(const char *pType, RES_FILELOAD fileLoad,
RES_FREE release)
bool resAddFileLoad(const char *pType, RES_FILELOAD fileLoad, RES_FREE release)
{
RES_TYPE *psT = resAlloc(pType);

if (!psT)
{
return false;
}

psT->buffLoad = NULL;
psT->fileLoad = fileLoad;
psT->release = release;
Expand Down Expand Up @@ -495,11 +471,6 @@ bool resLoadFile(const char *pType, const char *pFile)
return false;
}
}
else
{
ASSERT(false, "No load functions for this type (%s)", pType);
return false;
}

resDoResLoadCallback(); // do callback.

Expand Down
60 changes: 38 additions & 22 deletions lib/ivis_opengl/tex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,30 +269,48 @@ int iV_GetTexture(const char *filename)
return pie_AddTexPage(&sSprite, path, -1, true); // FIXME, -1, use getTextureSize()
}


/**************************************************************************
WRF files may specify overrides for the textures on a map. This
is done through an ugly hack involving cutting the texture name
down to just "page-NN", where NN is the page number, and
replaceing the texture page with the same name if another file
with this prefix is loaded.
**************************************************************************/
int pie_ReplaceTexPage(iV_Image *s, const char *texPage, int maxTextureSize, bool useMipmaping)
bool replaceTexture(const QString &oldfile, const QString &newfile)
{
int i = iV_GetTexture(texPage);
char tmpname[iV_TEXNAME_MAX];

ASSERT(i >= 0, "pie_ReplaceTexPage: Cannot find any %s to replace!", texPage);
if (i < 0)
// Load new one to replace it
iV_Image image;
if (!iV_loadImage_PNG(QString("texpages/" + newfile).toUtf8().constData(), &image))
{
return -1;
debug(LOG_ERROR, "Failed to load image: %s", newfile.toUtf8().constData());
return false;
}

glDeleteTextures(1, &_TEX_PAGE[i].id);
debug(LOG_TEXTURE, "Reloading texture %s from index %d", texPage, i);
_TEX_PAGE[i].name[0] = '\0';
pie_AddTexPage(s, texPage, maxTextureSize, useMipmaping);

return i;
sstrcpy(tmpname, oldfile.toUtf8().constData());
pie_MakeTexPageName(tmpname);
// Have we already loaded this one?
for (int i = 0; i < _TEX_PAGE.size(); i++)
{
if (strcmp(tmpname, _TEX_PAGE[i].name) == 0)
{
GL_DEBUG("Replacing texture");
debug(LOG_TEXTURE, "Replacing texture %s with %s from index %d (tex id %u)", _TEX_PAGE[i].name, newfile.toUtf8().constData(), i, _TEX_PAGE[i].id);
sstrcpy(tmpname, newfile.toUtf8().constData());
pie_MakeTexPageName(tmpname);
pie_SetTexturePage(TEXPAGE_EXTERN);
glDeleteTextures(1, &_TEX_PAGE[i].id);
glGenTextures(1, &_TEX_PAGE[i].id);
glBindTexture(GL_TEXTURE_2D, _TEX_PAGE[i].id);
glErrors();
sstrcpy(_TEX_PAGE[i].name, tmpname);
gluBuild2DMipmaps(GL_TEXTURE_2D, wz_texture_compression, image.width, image.height, iV_getPixelFormat(&image), GL_UNSIGNED_BYTE, image.bmp);
glErrors();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
iV_unloadImage(&image);
glErrors();
return true;
}
}
iV_unloadImage(&image);
debug(LOG_ERROR, "Nothing to replace!");
return false;
}

void pie_TexShutDown(void)
Expand All @@ -312,7 +330,6 @@ void pie_TexInit(void)
debug(LOG_TEXTURE, "pie_TexInit successful");
}


void iV_unloadImage(iV_Image *image)
{
if (image)
Expand All @@ -329,7 +346,6 @@ void iV_unloadImage(iV_Image *image)
}
}


unsigned int iV_getPixelFormat(const iV_Image *image)
{
switch (image->depth)
Expand Down
2 changes: 1 addition & 1 deletion lib/ivis_opengl/tex.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern int iV_GetTexture(const char *filename);
extern void iV_unloadImage(iV_Image *image);
extern unsigned int iV_getPixelFormat(const iV_Image *image);

extern int pie_ReplaceTexPage(iV_Image *s, const char *texPage, int maxTextureSize, bool useMipmaping);
bool replaceTexture(const QString &oldfile, const QString &newfile);
extern int pie_AddTexPage(iV_Image *s, const char *filename, int maxTextureSize, bool useMipmaping);
extern void pie_TexInit(void);

Expand Down
77 changes: 3 additions & 74 deletions src/data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include "lib/framework/resly.h"
#include "lib/gamelib/parser.h"
#include "lib/ivis_opengl/bitimage.h"
#include "lib/ivis_opengl/tex.h"
#include "lib/ivis_opengl/png_util.h"
#include "lib/script/script.h"
#include "lib/sound/audio.h"

Expand All @@ -51,9 +51,6 @@
#include "text.h"
#include "texture.h"

#define DT_TEXPAGE "TEXPAGE"
#define DT_TCMASK "TCMASK"

// whether a save game is currently being loaded
static bool saveFlag = false;

Expand Down Expand Up @@ -529,74 +526,6 @@ static void dataIMGRelease(void *pData)
iV_FreeImageFile((IMAGEFILE*)pData);
}


/* Load a texturepage into memory */
static bool dataTexPageLoad(const char *fileName, void **ppData)
{
char texpage[PATH_MAX] = {'\0'};

// This hackery is needed, because fileName will include the directory name, whilst the LastResourceFilename will not, and we need a short name to identify the texpage
sstrcpy(texpage, GetLastResourceFilename());

pie_MakeTexPageName(texpage);
if (!dataImageLoad(fileName, ppData))
{
return false;
}

// see if this texture page has already been loaded
if (resPresent(DT_TEXPAGE, texpage))
{
// replace the old texture page with the new one
debug(LOG_TEXTURE, "replacing %s with new texture %s", texpage, fileName);
pie_ReplaceTexPage((iV_Image *)*ppData, texpage, getTextureSize(), true);
}
else
{
debug(LOG_TEXTURE, "adding page %s with texture %s", texpage, fileName);
SetLastResourceFilename(texpage);
pie_AddTexPage((iV_Image *)*ppData, texpage, 0, getTextureSize(), true);
}

return true;
}

/* Load a team colour mask texturepage into memory */
static bool dataTexPageTCMaskLoad(const char *fileName, void **ppData)
{
char texpage[PATH_MAX] = {'\0'};

// This hackery is needed, because fileName will include the directory name, whilst the LastResourceFilename will not, and we need a short name to identify the texpage
sstrcpy(texpage, GetLastResourceFilename());

// Check if a corresponding texpage exists, exit if no
pie_MakeTexPageName(texpage);
ASSERT_OR_RETURN(false, resPresent(DT_TEXPAGE, texpage), "Corresponding texpage %s doesn't exists!", texpage);

pie_MakeTexPageTCMaskName(texpage);

if (!dataImageLoad(fileName, ppData))
{
return false;
}

// see if this texture page has already been loaded
if (resPresent(DT_TCMASK, texpage))
{
// replace the old texture page with the new one
debug(LOG_TEXTURE, "replacing %s with new tcmask %s", texpage, fileName);
pie_ReplaceTexPage((iV_Image *)*ppData, texpage, getTextureSize(), false);
}
else
{
debug(LOG_TEXTURE, "adding page %s with tcmask %s", texpage, fileName);
SetLastResourceFilename(texpage);
pie_AddTexPage((iV_Image *)*ppData, texpage, 0, getTextureSize(), false);
}

return true;
}

/*!
* Release an Image
*/
Expand Down Expand Up @@ -890,8 +819,8 @@ static const RES_TYPE_MIN_FILE FileResourceTypes[] =
{"IMGPAGE", dataImageLoad, dataImageRelease},
{"TERTILES", dataTERTILESLoad, NULL},
{"IMG", dataIMGLoad, dataIMGRelease},
{DT_TEXPAGE, dataTexPageLoad, dataImageRelease},
{DT_TCMASK, dataTexPageTCMaskLoad, dataImageRelease},
{"TEXPAGE", NULL, NULL}, // ignored
{"TCMASK", NULL, NULL}, // ignored
{"SCRIPT", dataScriptLoad, dataScriptRelease},
{"SCRIPTVAL", dataScriptLoadVals, NULL},
{"STR_RES", dataStrResLoad, dataStrResRelease},
Expand Down
12 changes: 12 additions & 0 deletions src/qtscriptfuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3857,6 +3857,17 @@ static QScriptValue js_syncRequest(QScriptContext *context, QScriptEngine *)
return QScriptValue();
}

//-- \subsection{replaceTexture(old_filename, new_filename)}
//-- Replace one texture with another. This can be used to for example give buildings on a specific tileset different
//-- looks, or to add variety to the looks of droids in campaign missions.
static QScriptValue js_replaceTexture(QScriptContext *context, QScriptEngine *)
{
QString oldfile = context->argument(0).toString();
QString newfile = context->argument(1).toString();
replaceTexture(oldfile, newfile);
return QScriptValue();
}

// ----------------------------------------------------------------------------------------
// Register functions with scripting system

Expand Down Expand Up @@ -4458,6 +4469,7 @@ bool registerFunctions(QScriptEngine *engine, QString scriptName)
engine->globalObject().setProperty("addSpotter", engine->newFunction(js_addSpotter));
engine->globalObject().setProperty("removeSpotter", engine->newFunction(js_removeSpotter));
engine->globalObject().setProperty("syncRequest", engine->newFunction(js_syncRequest));
engine->globalObject().setProperty("replaceTexture", engine->newFunction(js_replaceTexture));

// horrible hacks follow -- do not rely on these being present!
engine->globalObject().setProperty("hackNetOff", engine->newFunction(js_hackNetOff));
Expand Down
4 changes: 2 additions & 2 deletions src/terrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ void drawWater(void)
}

// first texture unit
pie_SetTexturePage(iV_GetTexture("page-80")); glError();
pie_SetTexturePage(iV_GetTexture("page-80-water-1.png")); glError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
Expand All @@ -1432,7 +1432,7 @@ void drawWater(void)

// second texture unit
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, pie_Texture(iV_GetTexture("page-81")));
glBindTexture(GL_TEXTURE_2D, pie_Texture(iV_GetTexture("page-81-water-2.png")));
glError();
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S); glError();
Expand Down