/* * pawstexturemanager.cpp - Author: Andrew Craig * * Copyright (C) 2001 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * 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 (version 2 of the License) * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ // pawstexturemanager.cpp: implementation of the pawsTextureManager class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include "util/log.h" #include "pawstexturemanager.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// pawsTextureManager::pawsTextureManager( iObjectRegistry* object ) { objectReg = object; vfs = CS_QUERY_REGISTRY( objectReg, iVFS ); xml = csPtr(new csTinyDocumentSystem); } pawsTextureManager::~pawsTextureManager() { imageDescriptions.DeleteAll(); } psImageDescription* pawsTextureManager::GetImageDescription( const char* name ) { if ( name == NULL ) return NULL; for ( size_t x = 0; x < imageDescriptions.Length(); x++ ) { if ( imageDescriptions[x]->resourceName == name ) { imageDescriptions[x]->refCount++; if ( imageDescriptions[x]->texture == NULL ) { if ( !imageDescriptions[x]->CreateTexture(objectReg) ) return NULL; } return imageDescriptions[x]; } } return NULL; } bool pawsTextureManager::LoadImageList( const char* listName ) { csRef buff = vfs->ReadFile( listName ); if ( !buff || !buff->GetSize() ) { return false; } csRef doc = xml->CreateDocument(); const char* error = doc->Parse( buff ); if ( error ) { Error3("Error %s in %s", error, listName); return false; } csRef root = doc->GetRoot(); if (!root) { Error2("XML error in %s", listName); return false; } csRef topNode = root->GetNode("image_list"); if(!topNode) { Error2("Missing tag in %s", listName); return false; } csRef iter = topNode->GetNodes(); while ( iter->HasNext() ) { csRef node = iter->Next(); if ( node->GetType() != CS_NODE_ELEMENT ) continue; if ( strcmp( node->GetValue(), "image" ) == 0 ) { // Do not load 2 of the same name bool found = false; for ( size_t x = 0; x < imageDescriptions.Length(); x++ ) { if ( imageDescriptions[x]->resourceName == node->GetAttributeValue("resource")) { printf("Skipping '%s' because it's already loaded\n",imageDescriptions[x]->resourceName.GetData()); found = true; break; } } // load if(!found) ReadImageDescription( node ); } } return true; } void pawsTextureManager::Remove( const char* resource ) { for ( size_t x = 0; x < imageDescriptions.Length(); x++ ) { if ( imageDescriptions[x]->resourceName == resource ) { imageDescriptions.DeleteIndex(x); return; } } } void pawsTextureManager::AddImageDescription( psImageDescription* desc ) { imageDescriptions.Push(desc); } void pawsTextureManager::ReadImageDescription( iDocumentNode* node ) { psImageDescription *imageDescription = new psImageDescription( this ); // Read off the image and file vars imageDescription->imageFileLocation = node->GetAttributeValue( "file" ); imageDescription->resourceName = node->GetAttributeValue( "resource" ); const char *t = node->GetAttributeValue("tiled"); if (t && !strcmp(t,"true") ) imageDescription->tiled = true; else imageDescription->tiled = false; csRef iter = node->GetNodes(); while ( iter->HasNext() ) { csRef childNode = iter->Next(); // Read the texture rectangle for this image. if ( strcmp( childNode->GetValue(), "texturerect" ) == 0 ) { imageDescription->textureRectangle.xmin = childNode->GetAttributeValueAsInt("x"); imageDescription->textureRectangle.ymin = childNode->GetAttributeValueAsInt("y"); int width = childNode->GetAttributeValueAsInt("width"); int height = childNode->GetAttributeValueAsInt("height"); imageDescription->textureRectangle.SetSize(width, height); } // Read the default alpha value. if ( strcmp( childNode->GetValue(), "alpha" ) == 0 ) { imageDescription->defaultAlphaValue = childNode->GetAttributeValueAsInt("level"); } // Read the default transparent colour. if ( strcmp( childNode->GetValue(), "trans" ) == 0 ) { imageDescription->defaultTransparentColourRed = childNode->GetAttributeValueAsInt("r"); imageDescription->defaultTransparentColourGreen = childNode->GetAttributeValueAsInt("g"); imageDescription->defaultTransparentColourBlue = childNode->GetAttributeValueAsInt("b"); } // Load states if ( strcmp( childNode->GetValue(), "state" ) == 0 ) { csString preload = childNode->GetAttributeValue("preload"); if ( preload == "yes" ) imageDescription->preLoad = true; else imageDescription->preLoad = false; csString stay = childNode->GetAttributeValue("remaininmemory"); if ( stay == "yes" ) imageDescription->stayInMemory = true; else imageDescription->stayInMemory = false; } } imageDescription->refCount = 0; imageDescriptions.Push( imageDescription ); } pawsImage::pawsImage( iObjectRegistry* objectReg ) : csSimplePixmap ( NULL ), alphaValue(0) { imageDesc = NULL; tiled = false; graphics3D = CS_QUERY_REGISTRY( objectReg, iGraphics3D ); } pawsImage::~pawsImage() { } void pawsImage::Description( psImageDescription* desc ) { if ( desc == NULL ) { if ( imageDesc ) imageDesc->DecRef(); imageDesc=NULL; return; } if ( imageDesc ) imageDesc->DecRef(); imageDesc = desc; SetTextureHandle( desc->texture ); SetTextureRectangle( desc->textureRectangle.xmin, desc->textureRectangle.ymin, desc->textureRectangle.Width(), desc->textureRectangle.Height() ); alphaValue = desc->defaultAlphaValue; tiled = desc->tiled; } void pawsImage::Draw( int x, int y ) { if ( imageDesc ) { csSimplePixmap::Draw( graphics3D, x, y, alphaValue ); } } void pawsImage::Draw( csRect rect ) { if ( imageDesc ) { if (!tiled) { csSimplePixmap::DrawScaled( graphics3D, rect.xmin, rect.ymin, rect.Width(), rect.Height(), alphaValue ); } else { csSimplePixmap::DrawTiled( graphics3D, rect.xmin, rect.ymin, rect.Width(), rect.Height(), 0, 0, alphaValue ); } } } void pawsImage::Draw( int x, int y, int newWidth, int newHeight ) { // If 0 then assume default if ( newWidth == 0 ) newWidth = GetWidth(); if ( newHeight == 0 ) newHeight = GetHeight(); if (!tiled) { csSimplePixmap::DrawScaled( graphics3D, x, y, newWidth, newHeight, alphaValue ); } else { csSimplePixmap::DrawTiled( graphics3D, x, y, newWidth, newHeight, 0, 0, alphaValue ); } } psImageDescription::psImageDescription( pawsTextureManager *manager ) { texManager = manager; refCount = 0; defaultTransparentColourBlue = -1; defaultTransparentColourGreen = -1; defaultTransparentColourRed = -1; defaultAlphaValue = 0; } void psImageDescription::DecRef() { if ( refCount == 0 ) { if ( !stayInMemory ) { texManager->Remove( resourceName ); } } } bool psImageDescription::CreateTexture( iObjectRegistry* object ) { csRef imageLoader = CS_QUERY_REGISTRY( object, iImageIO ); csRef vfs = CS_QUERY_REGISTRY( object, iVFS ); csRef graphics3D = CS_QUERY_REGISTRY( object, iGraphics3D ); csRef textureManager = graphics3D->GetTextureManager(); int textureFormat = textureManager->GetTextureFormat(); csRef ifile; csRef buf( vfs->ReadFile( imageFileLocation, false ) ); if ( buf == NULL || buf->GetSize() == 0 ) { Error2( "Could not open image: >%s<", (const char*)imageFileLocation ); return false; } ifile = imageLoader->Load( buf, textureFormat ); if ( !ifile ) { Error2( "Image >%s< could not be loaded by the iImageID", (const char*)imageFileLocation ); return false; } width = ifile->GetWidth(); height = ifile->GetHeight(); texture = textureManager->RegisterTexture( ifile, CS_TEXTURE_2D | CS_TEXTURE_3D | CS_TEXTURE_NOMIPMAPS | // This doesn't seem to have an effect, and crashes some Macs. CS_TEXTURE_CLAMP | CS_TEXTURE_NPOTS); if ( !texture ) { Error1("Failed to Register Texture"); return false; } // If colour key exists. if ( defaultTransparentColourBlue != -1 && defaultTransparentColourGreen != -1 && defaultTransparentColourRed != -1 ) { texture->SetKeyColor( defaultTransparentColourRed, defaultTransparentColourGreen, defaultTransparentColourBlue ); } if ( textureRectangle.Width() == 0 || textureRectangle.Height() == 0 ) { textureRectangle.xmax = width; textureRectangle.ymax = height; } return true; }