Example #1
0
void Projectile::CreateAnimations(Animation **anims, const ieResRef bamres, int Seq)
{
	AnimationFactory* af = ( AnimationFactory* )
		gamedata->GetFactoryResource( bamres,
				IE_BAM_CLASS_ID, IE_NORMAL );

	if (!af) {
		return;
	}

	int Max = af->GetCycleCount();
	if (!Max) {
		return;
	}

	if((ExtFlags&PEF_CYCLE) && !Seq) {
		Seq=rand()%Max;
	}

	//this hack is needed because bioware .pro files are sometimes
	//reporting bigger face count than possible by the animation
	if (Aim>Max) Aim=Max;

	if(ExtFlags&PEF_PILLAR) {
		CreateCompositeAnimation(anims, af, Seq);
	} else {
		CreateOrientedAnimations(anims, af, Seq);
	}
}
Example #2
0
AnimationFactory* BAMImporter::GetAnimationFactory(const char* ResRef, unsigned char mode)
{
	unsigned int i, count;
	AnimationFactory* af = new AnimationFactory( ResRef );
	ieWord *FLT = CacheFLT( count );

	bool videoBAMsupport = core->GetVideoDriver()->SupportsBAMSprites();
	unsigned char* data = NULL;

	if (videoBAMsupport) {
		str->Seek( DataStart, GEM_STREAM_START );
		unsigned long length = str->Remains();
		if (length == 0) return af;
		//data = new unsigned char[length];
		data = (unsigned char *) malloc(length);
		str->Read( data, length );
		af->SetFrameData(data);
	}

	for (i = 0; i < FramesCount; ++i) {
		Sprite2D* frame = GetFrameInternal(i, mode, videoBAMsupport, data, af);
		assert(!videoBAMsupport || frame->BAM);
		af->AddFrame(frame);
	}
	for (i = 0; i < CyclesCount; ++i) {
		af->AddCycle( cycles[i] );
	}
	af->LoadFLT ( FLT, count );
	free (FLT);
	return af;
}
Example #3
0
Font* BAMFontManager::GetFont(ieWord FirstChar,
			  ieWord LastChar,
			  unsigned short /*ptSize*/,
			  FontStyle /*style*/, Palette* pal)
{
	AnimationFactory* af = bamImp->GetAnimationFactory("dummy"); // FIXME: how does this get released?
	unsigned int i = 0, glyphIndexOffset = 0, limit = 0, Count = 0, glyphCount = 0;
	unsigned int CyclesCount = af->GetCycleCount();

	// Numeric fonts have all frames in single cycle
	if (CyclesCount > 1) {
		Count = CyclesCount;
		glyphCount = (LastChar - FirstChar + 1);
		if (Count < glyphCount){
			LastChar = LastChar - (glyphCount - Count);
			glyphCount = Count;
		}
		i = (FirstChar) ? FirstChar - 1 : FirstChar;
		limit = (FirstChar) ? LastChar - 1 : LastChar;
		glyphIndexOffset = i;
	} else { //numeric font
		Count = af->GetFrameCount();
		glyphCount = Count;
		if (FirstChar+Count != (unsigned int) LastChar+1) {
			Log(ERROR, "BAMFontManager", "inconsistent font %s: FirstChar=%d LastChar=%d Count=%d",
				str->filename, FirstChar, LastChar, Count);
			return NULL;
		}
		limit = glyphCount - 1;
	}

	Sprite2D** glyphs = (Sprite2D**)malloc( glyphCount * sizeof(Sprite2D*) );

	for (; i <= limit; i++) {
		if (CyclesCount > 1) {
			glyphs[i - glyphIndexOffset] = af->GetFrame(0, i);

			// Hack to work around original data where some status icons have inverted x and y positions (ie level up icon)
			// isStateFont is set in Open() and simply compares the first 6 characters of the file with "STATES"
			if (isStateFont) {
				// since initials and state icons should all be the same size/position we can just take the position of the first one
				glyphs[i - glyphIndexOffset]->YPos = glyphs[0]->YPos;
			}
		} else {
			glyphs[i - glyphIndexOffset] = af->GetFrameWithoutCycle(i);
			glyphs[i - glyphIndexOffset]->YPos = 13 - glyphs[i - glyphIndexOffset]->Height;
		}
	}

	// assume all sprites have same palette
	Palette* palette = glyphs[0]->GetPalette();
	Font* fnt = new Font(glyphs, FirstChar, LastChar, palette);
	palette->Release();
	if (pal) {
		fnt->SetPalette(pal);
	}
	return fnt;
}
Example #4
0
// Return single BAM frame as a sprite. Use if you want one frame only,
// otherwise it's not efficient
Sprite2D* GameData::GetBAMSprite(const ieResRef ResRef, int cycle, int frame, bool silent)
{
	Sprite2D *tspr;
	AnimationFactory* af = ( AnimationFactory* )
		GetFactoryResource( ResRef, IE_BAM_CLASS_ID, IE_NORMAL, silent );
	if (!af) return 0;
	if (cycle == -1)
		tspr = af->GetFrameWithoutCycle( (unsigned short) frame );
	else
		tspr = af->GetFrame( (unsigned short) frame, (unsigned char) cycle );
	return tspr;
}
Example #5
0
/* static */
AnimationFactory*
AnimationFactory::GetFactory(uint16 animationID)
{
	std::string baseName = IDTable::AniSndAt(animationID);

	std::cout << "AnimationFactory::GetFactory(";
	std::cout << baseName << ", " << std::hex;
	std::cout << animationID << ")" << std::endl;
	AnimationFactory* factory = NULL;
	std::map<uint16, AnimationFactory*>::const_iterator i
		= sAnimationFactory.find(animationID);
	if (i != sAnimationFactory.end())
		factory = i->second;
	else {
		switch (Core::Get()->Game()) {
			case GAME_BALDURSGATE:
				if (animationID >= 0x5000 && animationID < 0x8000)
					factory = new BGCharachterAnimationFactory(baseName.c_str(), animationID);
				else if (animationID >= 0xc000 && animationID <= 0xca00)
					factory = new SplitAnimationFactory(baseName.c_str(), animationID);
				else if (animationID >= 0xb000 && animationID <= 0xd300)
					factory = new SimpleAnimationFactory(baseName.c_str(), animationID);
				break;
			case GAME_BALDURSGATE2:
				if (animationID >= 0x7f03 && animationID <= 0x7f37)
					factory = new BGMonsterAnimationFactory(baseName.c_str(), animationID);
				else if (animationID >= 0x5000 && animationID <= 0x9000 )
					factory = new BG2CharachterAnimationFactory(baseName.c_str(), animationID);
				else if (animationID >= 0xc000 && animationID <= 0xca00)
					factory = new SplitAnimationFactory(baseName.c_str(), animationID);
				else if (animationID == 0x2300 || animationID == 0x2000
					|| (animationID >= 0xb000 && animationID <= 0xd300))
					factory = new SimpleAnimationFactory(baseName.c_str(), animationID);
				else if (animationID >= 0xe400 && animationID <= 0xe430)
					factory = new IWDAnimationFactory(baseName.c_str(), animationID);
				break;

			default:
				break;
		}
	}

	if (factory != NULL)
		factory->Acquire();

	return factory;
}
Example #6
0
Font* BAMFontManager::GetFont(unsigned short /*ptSize*/,
							  FontStyle /*style*/, Palette* pal)
{
	AnimationFactory* af = bamImp->GetAnimationFactory(resRef); // released by BAMFont

	Font* fnt = NULL;
	if (isStateFont) {
		// Hack to work around original data where some status icons have inverted x and y positions (ie level up icon)
		// isStateFont is set in Open() and simply compares the first 6 characters of the file with "STATES"

		// since state icons should all be the same size/position we can just take the position of the first one
		Sprite2D* first = af->GetFrame(0, 0);
		int pos = first->YPos; // baseline
		first->release();
		fnt = new BAMFont(af, &pos);
	} else {
		fnt = new BAMFont(af, NULL);
	}

	if (pal) {
		fnt->SetPalette(pal);
	}
	return fnt;
}
/* Creating animation from VVC */
ScriptedAnimation::ScriptedAnimation(DataStream* stream)
{
	Init();
	if (!stream) {
		return;
	}

	char Signature[8];

	stream->Read( Signature, 8);
	if (strncmp( Signature, "VVC V1.0", 8 ) != 0) {
		print("Not a valid VVC File");
		delete stream;
		return;
	}
	ieResRef Anim1ResRef;
	ieDword seq1, seq2, seq3;
	stream->ReadResRef( Anim1ResRef );
	//there is no proof it is a second resref
	//stream->ReadResRef( Anim2ResRef );
	stream->Seek( 8, GEM_CURRENT_POS );
	stream->ReadDword( &Transparency );
	stream->Seek( 4, GEM_CURRENT_POS );
	stream->ReadDword( &SequenceFlags );
	stream->Seek( 4, GEM_CURRENT_POS );
	ieDword tmp;
	stream->ReadDword( &tmp );
	XPos = (signed) tmp;
	stream->ReadDword( &tmp );  //this affects visibility
	ZPos = (signed) tmp;
	stream->Seek( 4, GEM_CURRENT_POS );
	stream->ReadDword( &FrameRate );

	if (!FrameRate) FrameRate = DEFAULT_FRAMERATE;

	stream->ReadDword( &FaceTarget );
	stream->Seek( 16, GEM_CURRENT_POS );
	stream->ReadDword( &tmp );  //this doesn't affect visibility
	YPos = (signed) tmp;
	stream->ReadDword( &LightX );
	stream->ReadDword( &LightY );
	stream->ReadDword( &LightZ );
	stream->ReadDword( &Duration );
	stream->Seek( 8, GEM_CURRENT_POS );
	stream->ReadDword( &seq1 );
	if (seq1>0) seq1--; //hack but apparently it works this way
	stream->ReadDword( &seq2 );
	stream->Seek( 8, GEM_CURRENT_POS );
	stream->ReadResRef( sounds[P_ONSET] );
	stream->ReadResRef( sounds[P_HOLD] );
	stream->Seek( 8, GEM_CURRENT_POS );
	stream->ReadDword( &seq3 );
	stream->ReadResRef( sounds[P_RELEASE] );

	//if there are no separate phases, then fill the p_hold fields
	bool phases = (seq2 || seq3);

	// hacks for seq2/seq3, same as for seq1 above
	// (not sure if seq3 is needed)
	if (seq2>0) seq2--;
	if (seq3>0) seq3--;

	if (SequenceFlags&IE_VVC_BAM) {
		AnimationFactory* af = ( AnimationFactory* )
			gamedata->GetFactoryResource( Anim1ResRef, IE_BAM_CLASS_ID );
		//no idea about vvc phases, i think they got no endphase?
		//they certainly got onset and hold phases
		//the face target flag should be handled too
		for (int i=0;i<MAX_ORIENT;i++) {
			unsigned int p_hold = P_HOLD*MAX_ORIENT+i;
			unsigned int p_onset = P_ONSET*MAX_ORIENT+i;
			unsigned int p_release = P_RELEASE*MAX_ORIENT+i;

			int c = seq1;
			if (phases) {
				switch (FaceTarget) {
				case 5:
					c=SixteenToFive[i];
					break;
				case 9:
					c=SixteenToNine[i];
					break;
				case 16:
					//this is an uglybugly hack, i still have to
					//figure out what 'FaceTarget' really is
					if ( (int) af->GetCycleCount()>i) c=i;
					break;
				}
				anims[p_onset] = af->GetCycle( c );
				if (anims[p_onset]) {
					PrepareAnimation(anims[p_onset], Transparency);
					//creature anims may start at random position, vvcs always start on 0
					anims[p_onset]->pos=0;
					//vvcs are always paused
					anims[p_onset]->gameAnimation=true;
					anims[p_onset]->Flags |= S_ANI_PLAYONCE;
				}
			}

			c = phases ? seq2 : seq1;
			if (c || !phases) {
				switch (FaceTarget) {
				case 5:
					c=SixteenToFive[i];
					break;
				case 9:
					c=SixteenToNine[i];
					break;
				case 16:
					//this is an uglybugly hack, i still have to
					//figure out what 'FaceTarget' really is
					if ((int) af->GetCycleCount()>i) c=i;
					break;
				}
				anims[p_hold] = af->GetCycle( c );
				if (anims[p_hold]) {
					PrepareAnimation(anims[p_hold], Transparency);

					anims[p_hold]->pos=0;
					anims[p_hold]->gameAnimation=true;
					if (!(SequenceFlags&IE_VVC_LOOP) ) {
						anims[p_hold]->Flags |= S_ANI_PLAYONCE;
					}
				}
			}

			c = seq3;
			if (c) {
				switch (FaceTarget) {
				case 5:
					c=SixteenToFive[i];
					break;
				case 9:
					c=SixteenToNine[i];
					break;
				case 16:
					//this is an uglybugly hack, i still have to
					//figure out what 'FaceTarget' really is
					if ( (int) af->GetCycleCount()>i) c=i;
					break;
				}
				anims[p_release] = af->GetCycle( ( unsigned char ) c );
				if (anims[p_release]) {
					PrepareAnimation(anims[p_release], Transparency);

					anims[p_release]->pos=0;
					anims[p_release]->gameAnimation=true;
					anims[p_release]->Flags |= S_ANI_PLAYONCE;
				}
			}
		}
		PreparePalette();
	}

	SetPhase(P_ONSET);

	delete stream;
}
/** Returns the i-th window in the Previously Loaded Stream */
Window* CHUImporter::GetWindow(unsigned int wid)
{
    ieWord WindowID, XPos, YPos, Width, Height, BackGround;
    ieWord ControlsCount, FirstControl;
    ieResRef MosFile;
    unsigned int i;

    bool found = false;
    for (unsigned int c = 0; c < WindowCount; c++) {
        str->Seek( WEOffset + ( 0x1c * c ), GEM_STREAM_START );
        str->ReadWord( &WindowID );
        if (WindowID == wid) {
            found = true;
            break;
        }
    }
    if (!found) {
        return NULL;
    }
    str->Seek( 2, GEM_CURRENT_POS );
    str->ReadWord( &XPos );
    str->ReadWord( &YPos );
    str->ReadWord( &Width );
    str->ReadWord( &Height );
    str->ReadWord( &BackGround );
    str->ReadWord( &ControlsCount );
    str->ReadResRef( MosFile );
    str->ReadWord( &FirstControl );

    Window* win = new Window( WindowID, XPos, YPos, Width, Height );
    if (BackGround == 1) {
        ResourceHolder<ImageMgr> mos(MosFile);
        if (mos != NULL) {
            win->SetBackGround( mos->GetSprite2D(), true );
        } else
            printMessage( "CHUImporter","Cannot Load BackGround, skipping\n",YELLOW );
    }
    if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
        printMessage( "CHUImporter","No BAM Importer Available, skipping controls\n",LIGHT_RED );
        return win;
    }
    for (i = 0; i < ControlsCount; i++) {
        str->Seek( CTOffset + ( ( FirstControl + i ) * 8 ), GEM_STREAM_START );
        ieDword COffset, CLength, ControlID;
        ieWord XPos, YPos, Width, Height;
        ieByte ControlType, temp;
        str->ReadDword( &COffset );
        str->ReadDword( &CLength );
        str->Seek( COffset, GEM_STREAM_START );
        str->ReadDword( &ControlID );
        str->ReadWord( &XPos );
        str->ReadWord( &YPos );
        str->ReadWord( &Width );
        str->ReadWord( &Height );
        str->Read( &ControlType, 1 );
        str->Read( &temp, 1 );
        switch (ControlType) {
        case IE_GUI_BUTTON:
        {
            //Button
            Button* btn = new Button( );
            btn->ControlID = ControlID;
            btn->XPos = XPos;
            btn->YPos = YPos;
            btn->Width = Width;
            btn->Height = Height;
            btn->ControlType = ControlType;
            ieResRef BAMFile;
            ieWord Cycle, UnpressedIndex, PressedIndex,
                   SelectedIndex, DisabledIndex;
            str->ReadResRef( BAMFile );
            str->ReadWord( &Cycle );
            str->ReadWord( &UnpressedIndex );
            str->ReadWord( &PressedIndex );
            str->ReadWord( &SelectedIndex );
            str->ReadWord( &DisabledIndex );
            btn->Owner = win;
            /** Justification comes from the .chu, other bits are set by script */
            if (!Width) {
                btn->SetFlags(IE_GUI_BUTTON_NO_IMAGE, BM_OR);
            }
            if (core->HasFeature(GF_UPPER_BUTTON_TEXT)) {
                btn->SetFlags(IE_GUI_BUTTON_CAPS, BM_OR);
            }

            btn->SetFlags( Cycle&0xff00, BM_OR );
            if (strnicmp( BAMFile, "guictrl\0", 8 ) == 0) {
                if (UnpressedIndex == 0) {
                    printMessage("CHUImporter", "Special Button Control, Skipping Image Loading\n",GREEN );
                    win->AddControl( btn );
                    break;
                }
            }
            AnimationFactory* bam = ( AnimationFactory* )
                                    gamedata->GetFactoryResource( BAMFile,
                                            IE_BAM_CLASS_ID, IE_NORMAL );
            if (!bam ) {
                printMessage( "CHUImporter","Cannot Load Button Images, skipping control\n",LIGHT_RED );
                /* IceWind Dale 2 has fake BAM ResRefs for some Buttons,
                   this will handle bad ResRefs */
                win->AddControl( btn );
                break;
            }
            /** Cycle is only a byte for buttons */
            Sprite2D* tspr = bam->GetFrame( UnpressedIndex, (unsigned char) Cycle );
            btn->SetImage( IE_GUI_BUTTON_UNPRESSED, tspr );
            tspr = bam->GetFrame( PressedIndex, (unsigned char) Cycle );
            btn->SetImage( IE_GUI_BUTTON_PRESSED, tspr );
            //ignorebuttonframes is a terrible hack
            if (core->HasFeature( GF_IGNORE_BUTTON_FRAMES) ) {
                if (bam->GetCycleSize( (unsigned char) Cycle) == 4 )
                    SelectedIndex=2;
            }
            tspr = bam->GetFrame( SelectedIndex, (unsigned char) Cycle );
            btn->SetImage( IE_GUI_BUTTON_SELECTED, tspr );
            if (core->HasFeature( GF_IGNORE_BUTTON_FRAMES) ) {
                if (bam->GetCycleSize( (unsigned char) Cycle) == 4 )
                    DisabledIndex=3;
            }
            tspr = bam->GetFrame( DisabledIndex, (unsigned char) Cycle );
            btn->SetImage( IE_GUI_BUTTON_DISABLED, tspr );
            win->AddControl( btn );
        }
        break;

        case IE_GUI_PROGRESSBAR:
        {
            //GemRB specific, progressbar
            ieResRef MOSFile, MOSFile2;
            ieResRef BAMFile;
            ieWord KnobXPos, KnobYPos;
            ieWord CapXPos, CapYPos;
            ieWord KnobStepsCount;
            ieWord Cycle;

            str->ReadResRef( MOSFile );
            str->ReadResRef( MOSFile2 );
            str->ReadResRef( BAMFile );
            str->ReadWord( &KnobStepsCount );
            str->ReadWord( &Cycle );
            str->ReadWord( &KnobXPos );
            str->ReadWord( &KnobYPos );
            str->ReadWord( &CapXPos );
            str->ReadWord( &CapYPos );
            Progressbar* pbar = new Progressbar(KnobStepsCount, true );
            pbar->ControlID = ControlID;
            pbar->XPos = XPos;
            pbar->YPos = YPos;
            pbar->ControlType = ControlType;
            pbar->Width = Width;
            pbar->Height = Height;
            pbar->SetSliderPos( KnobXPos, KnobYPos, CapXPos, CapYPos );

            Sprite2D* img = NULL;
            Sprite2D* img2 = NULL;
            if ( MOSFile[0] ) {
                ResourceHolder<ImageMgr> mos(MOSFile);
                img = mos->GetSprite2D();
            }
            if ( MOSFile2[0] ) {
                ResourceHolder<ImageMgr> mos(MOSFile2);
                img2 = mos->GetSprite2D();
            }

            pbar->SetImage( img, img2 );
            if( KnobStepsCount ) {
                /* getting the bam */
                AnimationFactory *af = (AnimationFactory *)
                                       gamedata->GetFactoryResource(BAMFile, IE_BAM_CLASS_ID );
                /* Getting the Cycle of the bam */
                pbar->SetAnimation(af->GetCycle( Cycle & 0xff ) );
            }
            else {
                ResourceHolder<ImageMgr> mos(BAMFile);
                Sprite2D* img3 = mos->GetSprite2D();
                pbar->SetBarCap( img3 );
            }
            win->AddControl( pbar );
        }
        break;
        case IE_GUI_SLIDER:
        {
            //Slider
            ieResRef MOSFile, BAMFile;
            ieWord Cycle, Knob, GrabbedKnob;
            ieWord KnobXPos, KnobYPos, KnobStep, KnobStepsCount;
            str->ReadResRef( MOSFile );
            str->ReadResRef( BAMFile );
            str->ReadWord( &Cycle );
            str->ReadWord( &Knob );
            str->ReadWord( &GrabbedKnob );
            str->ReadWord( &KnobXPos );
            str->ReadWord( &KnobYPos );
            str->ReadWord( &KnobStep );
            str->ReadWord( &KnobStepsCount );
            Slider* sldr = new Slider( KnobXPos, KnobYPos, KnobStep, KnobStepsCount, true );
            sldr->ControlID = ControlID;
            sldr->XPos = XPos;
            sldr->YPos = YPos;
            sldr->ControlType = ControlType;
            sldr->Width = Width;
            sldr->Height = Height;
            ResourceHolder<ImageMgr> mos(MOSFile);
            Sprite2D* img = mos->GetSprite2D();
            sldr->SetImage( IE_GUI_SLIDER_BACKGROUND, img);

            AnimationFactory* bam = ( AnimationFactory* )
                                    gamedata->GetFactoryResource( BAMFile,
                                            IE_BAM_CLASS_ID, IE_NORMAL );
            if( bam ) {
                img = bam->GetFrame( Knob, 0 );
                sldr->SetImage( IE_GUI_SLIDER_KNOB, img );
                img = bam->GetFrame( GrabbedKnob, 0 );
                sldr->SetImage( IE_GUI_SLIDER_GRABBEDKNOB, img );
            }
            else {
                sldr->SetState(IE_GUI_SLIDER_BACKGROUND);
            }
            win->AddControl( sldr );
        }
        break;

        case IE_GUI_EDIT:
        {
            //Text Edit
            ieResRef BGMos;
            ieResRef FontResRef, CursorResRef;
            ieWord maxInput;
            ieWord CurCycle, CurFrame;
            ieWord PosX, PosY;

            str->ReadResRef( BGMos );
            str->Seek( 16, GEM_CURRENT_POS );
            str->ReadResRef( CursorResRef );
            str->ReadWord( &CurCycle );
            str->ReadWord( &CurFrame );
            str->ReadWord( &PosX );
            str->ReadWord( &PosY );
            str->Seek( 4, GEM_CURRENT_POS );
            str->ReadResRef( FontResRef );
            str->Seek( 34, GEM_CURRENT_POS );
            str->ReadWord( &maxInput );
            Font* fnt = core->GetFont( FontResRef );

            AnimationFactory* bam = ( AnimationFactory* )
                                    gamedata->GetFactoryResource( CursorResRef,
                                            IE_BAM_CLASS_ID,
                                            IE_NORMAL );
            Sprite2D *cursor = NULL;
            if (bam) {
                cursor = bam->GetFrame( CurCycle, CurFrame );
            }

            ResourceHolder<ImageMgr> mos(BGMos);
            Sprite2D *img = NULL;
            if(mos) {
                img = mos->GetSprite2D();
            }

            TextEdit* te = new TextEdit( maxInput, PosX, PosY );
            te->ControlID = ControlID;
            te->XPos = XPos;
            te->YPos = YPos;
            te->Width = Width;
            te->Height = Height;
            te->ControlType = ControlType;
            te->SetFont( fnt );
            te->SetCursor( cursor );
            te->SetBackGround( img );
            win->AddControl( te );
        }
        break;

        case IE_GUI_TEXTAREA:
        {
            //Text Area
            ieResRef FontResRef, InitResRef;
            Color fore, init, back;
            ieWord SBID;
            str->ReadResRef( FontResRef );
            str->ReadResRef( InitResRef );
            Font* fnt = core->GetFont( FontResRef );
            Font* ini = core->GetFont( InitResRef );
            str->Read( &fore, 4 );
            str->Read( &init, 4 );
            str->Read( &back, 4 );
            str->ReadWord( &SBID );
            TextArea* ta = new TextArea( fore, init, back );
            ta->ControlID = ControlID;
            ta->XPos = XPos;
            ta->YPos = YPos;
            ta->Width = Width;
            ta->Height = Height;
            ta->ControlType = ControlType;
            ta->SetFonts( ini, fnt );
            win->AddControl( ta );
            if (SBID != 0xffff)
                win->Link( SBID, ( unsigned short ) ControlID );
        }
        break;

        case IE_GUI_LABEL:
        {
            //Label
            ieResRef FontResRef;
            ieStrRef StrRef;
            RevColor fore, back;
            ieWord alignment;
            str->ReadDword( &StrRef );
            str->ReadResRef( FontResRef );
            Font* fnt = core->GetFont( FontResRef );
            str->Read( &fore, 4 );
            str->Read( &back, 4 );
            str->ReadWord( &alignment );
            Label* lab = new Label( fnt );
            lab->ControlID = ControlID;
            lab->XPos = XPos;
            lab->YPos = YPos;
            lab->Width = Width;
            lab->Height = Height;
            lab->ControlType = ControlType;
            char* str = core->GetString( StrRef );
            lab->SetText( str );
            core->FreeString( str );
            if (alignment & 1) {
                lab->useRGB = true;
                Color f, b;
                f.r = fore.b;
                f.g = fore.g;
                f.b = fore.r;
                f.a = 0;
                b.r = back.b;
                b.g = back.g;
                b.b = back.r;
                b.a = 0;
                lab->SetColor( f, b );
            }
            int align = IE_FONT_ALIGN_CENTER;
            if (( alignment & 0x10 ) != 0) {
                align = IE_FONT_ALIGN_RIGHT;
                goto endvertical;
            }
            if (( alignment & 0x04 ) != 0) {
                goto endvertical;
            }
            if (( alignment & 0x08 ) != 0) {
                align = IE_FONT_ALIGN_LEFT;
                goto endvertical;
            }
endvertical:
            if (( alignment & 0x20 ) != 0) {
                align |= IE_FONT_ALIGN_TOP;
                goto endalign;
            }
            if (( alignment & 0x80 ) != 0) {
                align |= IE_FONT_ALIGN_BOTTOM;
            } else {
                align |= IE_FONT_ALIGN_MIDDLE;
            }
endalign:
            lab->SetAlignment( align );
            win->AddControl( lab );
        }
        break;

        case IE_GUI_SCROLLBAR:
        {
            //ScrollBar
            ieResRef BAMResRef;
            ieWord Cycle, Trough, Slider, TAID;
            ieWord UpUnPressed, UpPressed;
            ieWord DownUnPressed, DownPressed;

            str->ReadResRef( BAMResRef );
            str->ReadWord( &Cycle );
            str->ReadWord( &UpUnPressed );
            str->ReadWord( &UpPressed );
            str->ReadWord( &DownUnPressed );
            str->ReadWord( &DownPressed );
            str->ReadWord( &Trough );
            str->ReadWord( &Slider );
            str->ReadWord( &TAID );
            ScrollBar* sbar = new ScrollBar();
            sbar->ControlID = ControlID;
            sbar->XPos = XPos;
            sbar->YPos = YPos;
            sbar->Width = Width;
            sbar->Height = Height;
            sbar->ControlType = ControlType;

            AnimationFactory* bam = ( AnimationFactory* )
                                    gamedata->GetFactoryResource( BAMResRef,
                                            IE_BAM_CLASS_ID, IE_NORMAL );
            if (bam) {
                sbar->SetImage( IE_GUI_SCROLLBAR_UP_UNPRESSED,
                                bam->GetFrame( UpUnPressed, Cycle ) );
                sbar->SetImage( IE_GUI_SCROLLBAR_UP_PRESSED,
                                bam->GetFrame( UpPressed, Cycle ) );
                sbar->SetImage( IE_GUI_SCROLLBAR_DOWN_UNPRESSED,
                                bam->GetFrame( DownUnPressed, Cycle ) );
                sbar->SetImage( IE_GUI_SCROLLBAR_DOWN_PRESSED,
                                bam->GetFrame( DownPressed, Cycle ) );
                sbar->SetImage( IE_GUI_SCROLLBAR_TROUGH,
                                bam->GetFrame( Trough, Cycle ) );
                sbar->SetImage( IE_GUI_SCROLLBAR_SLIDER,
                                bam->GetFrame( Slider, Cycle ) );
            }
            win->AddControl( sbar );
            if (TAID != 0xffff)
                win->Link( ( unsigned short ) ControlID, TAID );
        }
        break;

        default:
            printMessage( "CHUImporter","Control Not Supported\n",LIGHT_RED );
        }
    }
    return win;
}
Example #9
0
/** Returns the i-th window in the Previously Loaded Stream */
Window* CHUImporter::GetWindow(unsigned int wid)
{
	ieWord WindowID, XPos, YPos, Width, Height, BackGround;
	ieWord ControlsCount, FirstControl;
	ieResRef MosFile;
	unsigned int i;

	if (!str) {
		Log(ERROR, "CHUImporter", "No data stream to read from, skipping controls");
		return NULL;
	}

	bool found = false;
	for (unsigned int c = 0; c < WindowCount; c++) {
		str->Seek( WEOffset + ( 0x1c * c ), GEM_STREAM_START );
		str->ReadWord( &WindowID );
		if (WindowID == wid) {
			found = true;
			break;
		}
	}
	if (!found) {
		return NULL;
	}
	str->Seek( 2, GEM_CURRENT_POS );
	str->ReadWord( &XPos );
	str->ReadWord( &YPos );
	str->ReadWord( &Width );
	str->ReadWord( &Height );
	str->ReadWord( &BackGround );
	str->ReadWord( &ControlsCount );
	str->ReadResRef( MosFile );
	str->ReadWord( &FirstControl );

	Window* win = new Window( WindowID, XPos, YPos, Width, Height );
	if (BackGround == 1) {
		ResourceHolder<ImageMgr> mos(MosFile);
		if (mos != NULL) {
			win->SetBackGround( mos->GetSprite2D(), true );
		}
	}
	if (!core->IsAvailable( IE_BAM_CLASS_ID )) {
		Log(ERROR, "CHUImporter", "No BAM Importer Available, skipping controls");
		return win;
	}
	for (i = 0; i < ControlsCount; i++) {
		str->Seek( CTOffset + ( ( FirstControl + i ) * 8 ), GEM_STREAM_START );
		ieDword COffset, CLength, ControlID;
		Region ctrlFrame;
		ieWord tmp;
		ieByte ControlType, temp;
		str->ReadDword( &COffset );
		str->ReadDword( &CLength );
		str->Seek( COffset, GEM_STREAM_START );
		str->ReadDword( &ControlID );
		str->ReadWord( &tmp );
		ctrlFrame.x = tmp;
		str->ReadWord( &tmp);
		ctrlFrame.y = tmp;
		str->ReadWord( &tmp );
		ctrlFrame.w = tmp;
		str->ReadWord( &tmp );
		ctrlFrame.h = tmp;
		str->Read( &ControlType, 1 );
		str->Read( &temp, 1 );
		switch (ControlType) {
			case IE_GUI_BUTTON:
			{
				//Button
				Button* btn = new Button(ctrlFrame);
				btn->ControlID = ControlID;
				ieResRef BAMFile;
				ieByte Cycle, tmp;
				ieDword Flags;
				ieByte UnpressedIndex, x1;
				ieByte PressedIndex, x2;
				ieByte SelectedIndex, y1;
				ieByte DisabledIndex, y2;
				str->ReadResRef( BAMFile );
				str->Read( &Cycle, 1 );
				str->Read( &tmp, 1 );
				Flags = ((ieDword) tmp)<<8;
				str->Read( &UnpressedIndex, 1 );
				str->Read( &x1, 1 );
				str->Read( &PressedIndex, 1 );
				str->Read( &x2, 1 );
				str->Read( &SelectedIndex, 1 );
				str->Read( &y1, 1 );
				str->Read( &DisabledIndex, 1 );
				str->Read( &y2, 1 );
				btn->Owner = win;
				/** Justification comes from the .chu, other bits are set by script */
				if (!Width) {
					btn->SetFlags(IE_GUI_BUTTON_NO_IMAGE, BM_OR);
				}
				if (core->HasFeature(GF_UPPER_BUTTON_TEXT)) {
					btn->SetFlags(IE_GUI_BUTTON_CAPS, BM_OR);
				}

				btn->SetFlags( Flags, BM_OR );
				if (Flags & IE_GUI_BUTTON_ANCHOR) {
					btn->SetAnchor(x1 | (x2<<8), y1 | (y2<<8));
				}

				if (strnicmp( BAMFile, "guictrl\0", 8 ) == 0) {
					if (UnpressedIndex == 0) {
						//printMessage("CHUImporter", "Special Button Control, Skipping Image Loading\n",GREEN );
						win->AddControl( btn );
						break;
					}
				}
				AnimationFactory* bam = ( AnimationFactory* )
					gamedata->GetFactoryResource( BAMFile,
							IE_BAM_CLASS_ID, IE_NORMAL );
				if (!bam ) {
					Log(ERROR, "CHUImporter", "Cannot Load Button Images, skipping control");
					/* IceWind Dale 2 has fake BAM ResRefs for some Buttons,
					this will handle bad ResRefs */
					win->AddControl( btn );
					break;
				}
				/** Cycle is only a byte for buttons */
				Sprite2D* tspr = bam->GetFrame( UnpressedIndex, (unsigned char) Cycle );
				btn->SetImage( BUTTON_IMAGE_UNPRESSED, tspr );
				tspr = bam->GetFrame( PressedIndex, Cycle );
				btn->SetImage( BUTTON_IMAGE_PRESSED, tspr );
				//ignorebuttonframes is a terrible hack
				if (core->HasFeature( GF_IGNORE_BUTTON_FRAMES) ) {
					if (bam->GetCycleSize(Cycle) == 4 )
						SelectedIndex=2;
				}
				tspr = bam->GetFrame( SelectedIndex, (unsigned char) Cycle );
				btn->SetImage( BUTTON_IMAGE_SELECTED, tspr );
				if (core->HasFeature( GF_IGNORE_BUTTON_FRAMES) ) {
					if (bam->GetCycleSize( (unsigned char) Cycle) == 4 )
						DisabledIndex=3;
				}
				tspr = bam->GetFrame( DisabledIndex, (unsigned char) Cycle );
				btn->SetImage( BUTTON_IMAGE_DISABLED, tspr );
				win->AddControl( btn );
			}
			break;

			case IE_GUI_PROGRESSBAR:
			{
				//GemRB specific, progressbar
				ieResRef MOSFile, MOSFile2;
				ieResRef BAMFile;
				ieWord KnobXPos, KnobYPos;
				ieWord CapXPos, CapYPos;
				ieWord KnobStepsCount;
				ieWord Cycle;

				str->ReadResRef( MOSFile );
				str->ReadResRef( MOSFile2 );
				str->ReadResRef( BAMFile );
				str->ReadWord( &KnobStepsCount );
				str->ReadWord( &Cycle );
				str->ReadWord( &KnobXPos );
				str->ReadWord( &KnobYPos );
				str->ReadWord( &CapXPos );
				str->ReadWord( &CapYPos );
				Progressbar* pbar = new Progressbar(ctrlFrame, KnobStepsCount, true );
				pbar->ControlID = ControlID;
				pbar->SetSliderPos( KnobXPos, KnobYPos, CapXPos, CapYPos );

				Sprite2D* img = NULL;
				Sprite2D* img2 = NULL;
				if ( MOSFile[0] ) {
					ResourceHolder<ImageMgr> mos(MOSFile);
					img = mos->GetSprite2D();
				}
				if ( MOSFile2[0] ) {
					ResourceHolder<ImageMgr> mos(MOSFile2);
					img2 = mos->GetSprite2D();
				}

				pbar->SetImage( img, img2 );
				if( KnobStepsCount ) {
					/* getting the bam */
					AnimationFactory *af = (AnimationFactory *)
						gamedata->GetFactoryResource(BAMFile, IE_BAM_CLASS_ID );
					/* Getting the Cycle of the bam */
						pbar->SetAnimation(af->GetCycle( Cycle & 0xff ) );
				}
				else {
					ResourceHolder<ImageMgr> mos(BAMFile);
					Sprite2D* img3 = mos->GetSprite2D();
					pbar->SetBarCap( img3 );
				}
				win->AddControl( pbar );
			}
			break;
			case IE_GUI_SLIDER:
			{
				//Slider
				ieResRef MOSFile, BAMFile;
				ieWord Cycle, Knob, GrabbedKnob;
				ieWord KnobXPos, KnobYPos, KnobStep, KnobStepsCount;
				str->ReadResRef( MOSFile );
				str->ReadResRef( BAMFile );
				str->ReadWord( &Cycle );
				str->ReadWord( &Knob );
				str->ReadWord( &GrabbedKnob );
				str->ReadWord( &KnobXPos );
				str->ReadWord( &KnobYPos );
				str->ReadWord( &KnobStep );
				str->ReadWord( &KnobStepsCount );
				Slider* sldr = new Slider( ctrlFrame, KnobXPos, KnobYPos, KnobStep, KnobStepsCount, true );
				sldr->ControlID = ControlID;
				ResourceHolder<ImageMgr> mos(MOSFile);
				Sprite2D* img = mos->GetSprite2D();
				sldr->SetImage( IE_GUI_SLIDER_BACKGROUND, img);

				AnimationFactory* bam = ( AnimationFactory* )
					gamedata->GetFactoryResource( BAMFile,
							IE_BAM_CLASS_ID, IE_NORMAL );
				if( bam ) {
					img = bam->GetFrame( Knob, 0 );
					sldr->SetImage( IE_GUI_SLIDER_KNOB, img );
					img = bam->GetFrame( GrabbedKnob, 0 );
					sldr->SetImage( IE_GUI_SLIDER_GRABBEDKNOB, img );
				}
				else {
					sldr->SetState(IE_GUI_SLIDER_BACKGROUND);
				}
				win->AddControl( sldr );
			}
			break;

			case IE_GUI_EDIT:
			{
				//Text Edit
				ieResRef BGMos;
				ieResRef FontResRef, CursorResRef;
				ieWord maxInput;
				ieWord CurCycle, CurFrame;
				ieWord PosX, PosY;
				ieWord Pos2X, Pos2Y;
				ieVariable Initial;

				str->ReadResRef( BGMos );
				//These are two more MOS resrefs, probably unused
				str->Seek( 16, GEM_CURRENT_POS );
				str->ReadResRef( CursorResRef );
				str->ReadWord( &CurCycle );
				str->ReadWord( &CurFrame );
				str->ReadWord( &PosX );
				str->ReadWord( &PosY );
				//FIXME: I still don't know what to do with this point
				//Contrary to forum posts, it is definitely not a scrollbar ID
				str->ReadWord( &Pos2X );
				str->ReadWord( &Pos2Y );
				str->ReadResRef( FontResRef );
				//this field is still unknown or unused
				str->Seek( 2, GEM_CURRENT_POS );
				//This is really a text field, but apparently the original engine
				//always writes it over, and never uses it
				str->Read( Initial, 32 );
				Initial[32]=0;
				str->ReadWord( &maxInput );
				Font* fnt = core->GetFont( FontResRef );

				AnimationFactory* bam = ( AnimationFactory* )
					gamedata->GetFactoryResource( CursorResRef,
							IE_BAM_CLASS_ID,
							IE_NORMAL );
				Sprite2D *cursor = NULL;
				if (bam) {
					cursor = bam->GetFrame( CurCycle, CurFrame );
				}

				ResourceHolder<ImageMgr> mos(BGMos);
				Sprite2D *img = NULL;
				if(mos) {
					img = mos->GetSprite2D();
				}

				TextEdit* te = new TextEdit( ctrlFrame, maxInput, PosX, PosY );
				te->ControlID = ControlID;
				te->SetFont( fnt );
				te->SetCursor( cursor );
				te->SetBackGround( img );
				//The original engine always seems to ignore this textfield
				//te->SetText (Initial );
				win->AddControl( te );
			}
			break;

			case IE_GUI_TEXTAREA:
			{
				//Text Area
				ieResRef FontResRef, InitResRef;
				Color fore, init, back;
				ieWord SBID;
				str->ReadResRef( FontResRef );
				str->ReadResRef( InitResRef );
				Font* fnt = core->GetFont( FontResRef );
				Font* ini = core->GetFont( InitResRef );
				str->Read( &fore, 4 );
				str->Read( &init, 4 );
				str->Read( &back, 4 );
				str->ReadWord( &SBID );
				TextArea* ta = new TextArea( ctrlFrame, fore, init, back );
				ta->ControlID = ControlID;
				ta->SetFonts( ini, fnt );
				win->AddControl( ta );
				if (SBID != 0xffff)
					win->Link( SBID, ( unsigned short ) ControlID );
			}
			break;

			case IE_GUI_LABEL:
			{
				//Label
				ieResRef FontResRef;
				ieStrRef StrRef;
				RevColor fore, back;
				ieWord alignment;
				str->ReadDword( &StrRef );
				str->ReadResRef( FontResRef );
				Font* fnt = core->GetFont( FontResRef );
				str->Read( &fore, 4 );
				str->Read( &back, 4 );
				str->ReadWord( &alignment );
				char* str = core->GetString( StrRef );
				Label* lab = new Label( ctrlFrame, fnt, str );
				core->FreeString( str );
				lab->ControlID = ControlID;

				if (alignment & 1) {
					lab->useRGB = true;
					Color f, b;
					f.r = fore.b;
					f.g = fore.g;
					f.b = fore.r;
					f.a = 0;
					b.r = back.b;
					b.g = back.g;
					b.b = back.r;
					b.a = 0;
					lab->SetColor( f, b );
				}
				int align = IE_FONT_ALIGN_CENTER;
				if (( alignment & 0x10 ) != 0) {
					align = IE_FONT_ALIGN_RIGHT;
					goto endvertical;
				}
				if (( alignment & 0x04 ) != 0) {
					goto endvertical;
				}
				if (( alignment & 0x08 ) != 0) {
					align = IE_FONT_ALIGN_LEFT;
					goto endvertical;
				}
endvertical:
				if (( alignment & 0x20 ) != 0) {
					align |= IE_FONT_ALIGN_TOP;
					goto endalign;
				}
				if (( alignment & 0x80 ) != 0) {
					align |= IE_FONT_ALIGN_BOTTOM;
				} else {
					align |= IE_FONT_ALIGN_MIDDLE;
				}
endalign:
				lab->SetAlignment( align );
				win->AddControl( lab );
			}
			break;

			case IE_GUI_SCROLLBAR:
			{
				//ScrollBar
				ieResRef BAMResRef;
				ieWord Cycle, TAID, imgIdx;
				str->ReadResRef( BAMResRef );
				str->ReadWord( &Cycle );

				AnimationFactory* bam = ( AnimationFactory* )
				gamedata->GetFactoryResource( BAMResRef,
											 IE_BAM_CLASS_ID, IE_NORMAL );
				if (!bam) {
					Log(ERROR, "CHUImporter", "Unable to create scrollbar, no BAM: %s", BAMResRef);
					break;
				}
				Sprite2D* images[IE_SCROLLBAR_IMAGE_COUNT];
				for (int i=0; i < IE_SCROLLBAR_IMAGE_COUNT; i++) {
					str->ReadWord( &imgIdx );
					images[i] = bam->GetFrame( imgIdx, Cycle );
				}
				str->ReadWord( &TAID );

				ScrollBar* sbar = new ScrollBar(ctrlFrame, images);
				sbar->ControlID = ControlID;

				win->AddControl( sbar );
				if (TAID != 0xffff)
					win->Link( ( unsigned short ) ControlID, TAID );
			}
			break;

			default:
				Log(ERROR, "CHUImporter", "Control Not Supported");
		}
	}
	return win;
}