Filter:   InfoImg
download gumps.cc
Language: C++
LOC: 244
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

#include "uop.h"
#include <SDL/SDL.h>
#include <SDL/SDL_endian.h>
#include <iostream>
#include <fstream>
#include "gumps.h"
#include "uopconfig.h"

extern UOPConfig *config;
extern Gumps *gumps;
extern SDL_Surface *screen;

Hue::Hue()
{
	loaded=false;
}
Hue::~Hue()
{
}

Hue &Gumps::getHue(Uint16 hue)
{
	if (hue) hue--;
	Hue &idx=hues[hue];
	if (idx.loaded) return idx;
	Uint16 num=hue>>3;
	Uint32 offset=num*708+(hue&7)*88+4;
	huefile.seekg(offset);
	char source[88];
	huefile.read(source,44*2);
	Uint16 *src=(Uint16*)source;

	for (int i=0;i<32;i++)
		idx.colors[i]=SDL_SwapLE16(*src++);
	idx.start=SDL_SwapLE16(*src++);
	idx.end=SDL_SwapLE16(*src++);
	idx.loaded=true;
	return idx;
}

GumpIndex::GumpIndex()
{
	offset=size=0xffffffff;
	x=y=width=height=0;
}
GumpIndex::~GumpIndex()
{
}


Gumps::Gumps()
{
	string gumpfname=config->encapDatLoc("gumpidx.mul");
	idxfile.open(gumpfname.c_str(),ios::in|ios::binary);
         if (!idxfile.is_open())
 	{
	        cerr<<"Couldn't open "<<gumpfname<<endl;
 		exit(1);
 	}
	string huefname=config->encapDatLoc("hues.mul");
 	huefile.open(huefname.c_str(),ios::in|ios::binary);
 	if (!huefile.is_open())
 	{
	        cerr<<"Couldn't open "<<huefname<<endl;
 		exit(1);
 	}
}

Gumps::~Gumps()
{
	idxfile.close();
	huefile.close();
}

GumpIndex &Gumps::getIndex(int gump)
{
	GumpIndex &idx=gumps[gump];
	if (idx.offset!=0xffffffff)
		return idx;
	idx.width=idx.height=0;
	if (!gump)
		return idx;
	Uint32 offset=gump*12;
	Uint8 buffer[12];
	idxfile.seekg(offset);
	idxfile.read((char *)buffer,12);

	idx.offset=SDL_SwapLE32(*(Uint32 *)buffer);
	idx.size=SDL_SwapLE32(*(Uint32 *)(buffer+4));
	idx.height=SDL_SwapLE16(*(Uint16 *)(buffer+8));
	idx.width=SDL_SwapLE16(*(Uint16 *)(buffer+10));
	idx.patched=false;
	return idx;
}

void Gumps::setIndex(int gump,GumpIndex &index)
{
	GumpIndex &idx=gumps[gump];
	idx.offset=index.offset;
	idx.size=index.size;
	idx.height=index.height;
	idx.width=index.width;
	idx.patched=true;
}

Gump::Gump()
{
	width=-1;
	height=-1;
	for (int i=0;i<9;i++)
		children[i]=NULL;
}
Gump::~Gump()
{
	for (int i=0;i<9;i++)
		if (children[i])
			delete children[i];
}

void Gump::load(Uint16 gump,Sint16 w,Sint16 h,bool tiled)
{
	load(gump,0,0,w,h,tiled);
}
void Gump::load(Uint16 gump,Sint16 offsetx, Sint16 offsety, Sint16 w,Sint16 h,bool tiled)
{
	//Uint32 offset;
	Uint16 *scr,val,run,y,x,gumpWidth,gumpHeight;
	ifstream gumpfile;

	GumpIndex &idx=gumps->getIndex(gump);
	gumpHeight=idx.height;
	gumpWidth=idx.width;
	
	if (gumpHeight <= 0 || gumpWidth <= 0)
	{
		cerr << "Warning: Gump::load aborted because width/height is less than 1." << endl;
		return;
	}
	
	if (w<0) w=gumpWidth;
	if (h<0) h=gumpHeight;
	if (w<=0 || h<=0) return;

	if (width==w && height==h)
		return;
	if (this->data)
		delete [] this->data;

	this->offsetx=offsetx;
	this->offsety=offsety;

	Uint8 *fdata = new Uint8[idx.size];
	Uint16 *gdata = new Uint16[gumpHeight*gumpWidth];


	string gumpfname;
	if (idx.patched)
		gumpfname=config->encapDatLoc("verdata.mul");
	else
		gumpfname=config->encapDatLoc("gumpart.mul");
	gumpfile.open(gumpfname.c_str(),ios::in|ios::binary);
	if (!gumpfile.is_open())
	{
	        cerr<<"Error opening "<<gumpfname<<endl;
		exit(1);
	}
	gumpfile.seekg(idx.offset);
	gumpfile.read((char *)fdata,idx.size);
	gumpfile.close();
	Uint16 *sdata=gdata;
	Uint32 row;
	Uint16 ty;
	Uint32 *g;

	for (y=0;y<gumpHeight;y++)
	{
		ty=y<<2;
		row=SDL_SwapLE32(*(Uint32*)(fdata+ty));
		g=(Uint32*)(fdata+(row<<2));
		for (x=0;x<gumpWidth;)
		{
			row=SDL_SwapLE32(*g++);
			run=row>>16;
			val=((row&0x7fe0)<<1)|(row&0x1f);
			x+=run;
			while (run--) *sdata++=val;
		}
	}
	delete [] fdata;
	height=h;
	width=w;

	if (tiled)
	{
		data=new Uint16[width*height];
		scr=data;
		for (y=0;y<height;y++)
		{
			sdata=gdata+(y%gumpHeight)*gumpWidth;
			for (x=0;x<width;x++)
				*scr++=sdata[x%gumpWidth];
		}
	}
	else
	{
		if (width>gumpWidth) width=gumpWidth;
		if (height>gumpHeight) height=gumpHeight;
		data=new Uint16[width*height];
		scr=data;
		sdata=gdata;
		Uint16 gdelta=gumpWidth-width;
		for (y=0;y<height;y++,sdata+=gdelta)
			for (x=0;x<width;x++)
				*scr++=*sdata++;
	}
	delete [] gdata;
}

void Gump::load(Uint16 *gumpIDs,Sint16 w,Sint16 h)
{
	if (width==w && height==h)
		return;
	for (int i=0;i<9;i++)
		if (children[i]) delete children[i];
	GumpIndex &UL=gumps->getIndex(gumpIDs[0]);
	GumpIndex &BR=gumps->getIndex(gumpIDs[8]);

	Uint16 topX,topY,topW,topH;
	Uint16 midX,midY,midW,midH;
	Uint16 botX,botY,botW,botH;

	topX=topY=0;
	topW=UL.width;  if (w<topW) topW=w;
	topH=UL.height; if (h<topH) topH=h;
	botX=w-BR.width; if (w<BR.width) botX=0;
	botY=h-BR.height; if (h<BR.height) botY=0;
	botW=w-botX;
	botH=h-botY;
	midX=topW;
	midY=topH;
	midW=botX-midX; if (botX<midX) midW=0;
	midH=botY-midY; if (botY<midY) midH=0;

	children[0]=new Gump();
	children[0]->load(gumpIDs[0],topX,topY,topW,topH,false);
	children[1]=new Gump();
	children[1]->load(gumpIDs[1],midX,topY,midW,topH,true);
	children[2]=new Gump();
	children[2]->load(gumpIDs[2],botX,topY,botW,topH,false);
	children[3]=new Gump();
	children[3]->load(gumpIDs[3],topX,midY,topW,midH,true);
	children[4]=new Gump();
	children[4]->load(gumpIDs[4],midX,midY,midW,midH,true);
	children[5]=new Gump();
	children[5]->load(gumpIDs[5],botX,midY,botW,midH,true);
	children[6]=new Gump();
	children[6]->load(gumpIDs[6],topX,botY,topW,botH,false);
	children[7]=new Gump();
	children[7]->load(gumpIDs[7],midX,botY,midW,botH,true);
	children[8]=new Gump();
	children[8]->load(gumpIDs[8],botX,botY,botW,botH,false);
}

void Gump::blit(Sint16 x,Sint16 y,HueMethod hueMethod,Uint16 hue)
{
	if (children[0])
	{
		for (int i=0;i<9;i++)
			children[i]->blit(x,y,hueMethod,hue);
	}
	else
		Sprite::blit(x+offsetx,y+offsety,hueMethod,hue);
}