download artfactory.cc
Language: C++
License: GPL
LOC: 110
Project Info
Ultima Online Project(uop)
Server: SourceForge
Type: cvs
SourceForge\u\uop\uop\uop\
   acinclude.m4
   aclocal.m4
   action.cc
   action.h
   animation.cc
   animation.h
   artexport.cc
   artfactory.cc
   artfactory.h
   audio.cc
   audio.h
   btree.cc
   btree.h
   cache.h
   cliloc.cc
   cliloc.h
   config.h.in
   configure.in
   cvs2cl.pl
   entity.cc
   entity.h
   gumps.cc
   gumps.h
   interface.cc
   interface.h
   interfacegumps.cc
   interfacegumps.h
   interfacehandler.cc
   interfacehandler.h
   intrface.def
   Makefile.am
   Makefile.in
   message.cc
   message.h
   musicmap.def
   network.cc
   network.h
   patchhandler.cc
   patchhandler.h
   readable.pl
   serverhandler.cc
   serverhandler.h
   sprite.cc
   sprite.h
   stamp-h.in
   texthandler.cc
   texthandler.h
   tiledata.cc
   tiledata.h
   unreadable.pl
   uop.cc
   uop.cfg
   uop.dox
   uop.h
   uopconfig.cc
   uopconfig.h
   uosprite.h
   uostub.pl
   world.cc
   world.h

/*****
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *****/
 
#include "uop.h"
#include <SDL/SDL.h>
#include "artfactory.h"
#include "sprite.h"

/**
 * Factory production function for art.mul.  It will
 * produce anything in art.mul as a Sprite.
 * @param index The index in artidx.mul that references
 * the art you wish to load.
 * @param sprite The sprite that will contain the art.
 * @todo Add code to prevent out-of-file read errors
 * and any catchable cases of error-prone data
 */
ArtFactory::ArtFactory(string indexfilename, string artfilename){
	artidx.open(indexfilename.c_str(), ios::in|ios::binary);
	assert(artidx.is_open());
	artfile.open(artfilename.c_str(), ios::in|ios::binary);
	assert(artfile.is_open());
}

void ArtFactory::produce(Uint32 index, UOSprite &sprite)
{	
	// Find index file size and make sure entry exists
	artidx.seekg(0, ios::end);
	unsigned long idxE = artidx.tellg();
	unsigned long maxIndex = idxE/12;
	
	// Drop out if the entry is invalid
	if (index > maxIndex)
		return;
	
	Uint32 lookup, length;
	
	// Find the lookup
	artidx.seekg(index*12);
	artidx.read((char*)&lookup, 4);
	artidx.read((char*)&length, 4);
	
	if (lookup == 0xFFFFFFFF) // Then it dosen't exist
		return;
	
	// Seek to the lookup
	artfile.seekg(lookup);
	
	// Load either a land tile or static
	if (index < 0x4000)
	{
		// Load a land tile
		
		sprite.resize(44, 44);
		
		Uint8 *buffer = (Uint8*)new Uint16[1024];
		artfile.read((char*)buffer, 1024*2);
		
		// Convert the entire buffer to 16-bit color
		for (Uint16 *cur = (Uint16*)buffer; cur < ((Uint16*)buffer)+1024; cur++)
		{
			Uint16 victim = *cur;
			if (victim)
			{
				Uint8 red = (victim >> 10)&0x1f;
				Uint8 green = (victim >> 5)&0x1f;
				Uint8 blue = victim&0x1f;
				(*cur) = (red << 11) | (green << 6) | blue;
			}
			else
			{
				// Convert to a similar shade of black
				// This will prevent it from being considered
				// transparent.
				(*cur) = (1 << 11) | (1 << 6) | 1;
			}
		}
		
		Uint8 *src = buffer;
		int y;
		
		for (y = 0; y < 22; y++)
		{
			memcpy(sprite.data + (y*44) + (21-y), src, (y+1) << 2);
			src += ((y+1)*4);
		}
		
		for (y = 22; y < 44; y++)
		{
			memcpy(sprite.data + (y*44) + (y-22), src, (44-y) << 2);
			src += ((44-y)*4);
		}
		
		delete [] buffer;
	}
	else
	{
		// Already seeked to lookup, so time to
		// load a static
		Uint16 width, height;
		Uint16 *lookupTable;
		Uint32 orunFileOffset;
		
		artfile.seekg(4, ios::cur);
		artfile.read((char*)&width, 2);
		artfile.read((char*)&height, 2);
		lookupTable = new Uint16[height];
		artfile.read((char*)lookupTable, height*2);

		orunFileOffset = artfile.tellg();

		sprite.resize(width, height);

		artfile.seekg(orunFileOffset + lookupTable[0]*2);

		int dX = 0, cY = 0;
		while (cY < height)
		{
			Uint16 xOffset, xRun;
			
			artfile.read((char*)&xOffset, 2);
			artfile.read((char*)&xRun, 2);

			if (xOffset + xRun)
			{
				dX += xOffset;
				artfile.read((char*)sprite.data + width*cY*2 + dX*2, xRun*2);
				dX += xRun;
			}
			else
			{
				dX = 0;
				cY++;
				artfile.seekg(orunFileOffset + lookupTable[cY]*2);
			}
		}

		// Convert everything to 16-bit color
		for (Uint16 *cur = (Uint16*)sprite.data;
				 cur < ((Uint16*)sprite.data)+width*height;
				 cur++)
		{
			Uint16 victim = *cur;
			if (victim)
			{
				Uint8 red = (victim >> 10)&0x1f;
				Uint8 green = (victim >> 5)&0x1f;
				Uint8 blue = victim&0x1f;
				(*cur) = (red << 11) | (green << 6) | blue;
			}
		}

		delete [] lookupTable;
	}
}

void ArtFactory::recycle(UOSprite &sprite)
{
	sprite.~UOSprite();
}

About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us