download animation.cc
Language: C++
License: GPL
LOC: 177
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

/**
 *  @class Frame
 *	@brief Contains information about the drawing of an animation frame.
 *	@note All black (0x000000) pixels are transparent.
 *  @author Samuel Kaufman
 *  @date 2002
 */
/*****
 *
 *  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 <string.h>
#include <assert.h>
#include <iostream>
#include <fstream>
#include <string>
#include "uopconfig.h"
#include "animation.h"
#include "sprite.h"
#include "gumps.h"

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

Frame::Frame()
{
	width = height = 0;
	centerY = centerX = 0;
}

Frame::~Frame()
{
	for (vector<Uint8*>::iterator i = runs.begin(); i != runs.end(); i++)
	{
		delete [] (*i);
	}
}

/**
 * @todo Support hues.
 */
void Frame::blit(Sint16 x, Sint16 y, Uint16 *palette)
{
  if (width<=0 || height<=0)
    return;
	//cout << "drawing frame: " << flush;
	for (vector<Uint8*>::iterator i = runs.begin(); i != runs.end(); i++)
	{		
		Sint32 header = *((Uint32*)(*i));
		Sint16 xOffset = header >> 22;
		Sint16 yOffset = (header & 0x003FFFFF) >> 12;
		if(yOffset & 0x0200)
			yOffset |= 0xFC00;
		Uint16 xRun = header & 0x00000FFF;
		if(y+yOffset>=480 || x+xOffset>=640){
			continue;
		}
		Uint16 *pixels = (Uint16*)screen->pixels+(screen->pitch>>1)*(y+yOffset)+(x+xOffset);
		
		for (Uint16 pix = 0; pix < xRun; pix++, pixels++)
		{
			Uint16 victim = palette[*((*i)+4+pix)];
			Uint16 red = (victim >> 10)&0x1f;
			Uint16 green = (victim >> 5)&0x1f;
			Uint16 blue = victim&0x1f;
			*pixels = (red << 11) | (green << 6) | blue;
		}
	}
	//cout << endl;
}

Animation::Animation()
{
	frames = 0;
}

Animation::~Animation()
{
	if (frames)
		delete [] frames;
}

void Animation::produce(Uint32 index, Animation &anim) throw (string)
{
	Uint32 animfilelookup;
	Uint32 size;
	Uint32 *lookupTable;
	
	cout << "animation loading:\t" << index << ", " << flush;
	anims->animidx.seekg(index*12);
	assert(anims->animidx.tellg() == index*12);
	anims->animidx.read((char*)&animfilelookup, 4);
	anims->animidx.read((char*)&size, 4);
	
	if (animfilelookup == 0xffffffff){
		cerr << "Animation not found:" << index << endl;
		throw string("Animation not found");
		return;
	}

	anims->animfile.seekg(animfilelookup);
	
	anims->animfile.read((char*)anim.palette, 0x200);
	anims->animfile.read((char*)&anim.frameCount, 4);
	cout << "frames:\t" << anim.frameCount << "; " << flush;
	if (anim.frames)
		delete [] anim.frames;
	anim.frames = new Frame[anim.frameCount];
	lookupTable = new Uint32[anim.frameCount];
	anims->animfile.read((char*)lookupTable, anim.frameCount*4);
	// Debugging values
	// TODO: Make these REAL values from animdata.mul
	anim.delay = 0;
	anim.interval = 500;

	cout << "  producing frames: " << flush;
	
	for (Uint32 f = 0; f < anim.frameCount; f++)
	{
		cout << "#" << f  << " " << flush;
		anims->animfile.seekg(animfilelookup+0x200+lookupTable[f]);
		anims->animfile.read((char*)&anim.frames[f].centerX, 2);
		anims->animfile.read((char*)&anim.frames[f].centerY, 2);
		anims->animfile.read((char*)&anim.frames[f].width, 2);
		anims->animfile.read((char*)&anim.frames[f].height, 2);
		
		while (true)
		{
			Uint32 *storageBuf;
			Uint32 header;
			anims->animfile.read((char*)&header, 4);
			if ((header >> 16) == 0x00007fff || (header & 0x0000FFFF) == 0x00007fff )
				break;

			Uint16 xRun = header & 0x00000fff;
			storageBuf = (Uint32*)new Uint8[4+xRun];
			*storageBuf = header;
			anims->animfile.read(((char*)storageBuf)+4, xRun);
			anim.frames[f].runs.push_back((Uint8*)storageBuf);
		}
	}
		
	cout << endl;

	delete [] lookupTable;
}

void Animation::recycle(Animation &anim)
{
	anim.~Animation();
}

AnimationState::AnimationState()
{
	this->animIndex = animIndex;
	startedAt = 0;
}

bool AnimationState::hasEnded()
{
	Animation &anim = anims->anims[animIndex];
	return (SDL_GetTicks() - startedAt > anim.runningTime());
}

void AnimationState::blit(int x, int y)
{
	Animation &anim = anims->anims[animIndex];
	if (!anim.frames)
		return;
	if (hasEnded())
	{
		if (timesLeft)
			startedAt = SDL_GetTicks();
		else
			anim.frames[0].blit(x, y, anim.palette);
	}
	anim.frames[(SDL_GetTicks()-startedAt-anim.delay)/anim.interval].blit(x, y, anim.palette);
}

void AnimationState::start(unsigned int times)
{
	startedAt = SDL_GetTicks();
	timesLeft = times-1;
}

Animations::Animations() : anims(*(new Animation()))
{
	string file1 = config->encapDatLoc("anim.mul");
	animfile.open(file1.c_str(), ios::in|ios::binary);
	if (!animfile.is_open())
	{
		cerr << "Couldn't open " << file1 << endl;
		exit(1);
	}
	string file2 = config->encapDatLoc("anim.idx");
	animidx.open(file2.c_str(), ios::in|ios::binary);
	if (!animidx.is_open())
	{
		cerr << "Couldn't open " << file2 << endl;
		exit(1);
	}
	string file3 = config->encapDatLoc("animdata.mul");
	adatafile.open(file3.c_str(), ios::in|ios::binary);
	if (!adatafile.is_open())
	{
		cerr << "Couldn't open " << file3 << endl;
		exit(1);
	}
}

Animations::~Animations()
{
	adatafile.close();
	animidx.close();
	animfile.close();
}

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