/** 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; }
/* 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; 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; }