1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "CHUImporter.h"
23 #include "RGBAColor.h"
26 #include "AnimationFactory.h"
29 #include "Interface.h"
30 #include "GUI/Button.h"
31 #include "GUI/Label.h"
32 #include "GUI/Progressbar.h"
33 #include "GUI/ScrollBar.h"
34 #include "GUI/Slider.h"
35 #include "GUI/TextArea.h"
36 #include "GUI/TextEdit.h"
38 CHUImporter::CHUImporter()
44 CHUImporter::~CHUImporter()
51 /** This function loads all available windows from the 'stream' parameter. */
52 bool CHUImporter::Open(DataStream
* stream
, bool autoFree
)
61 this->autoFree
= autoFree
;
63 str
->Read( Signature
, 8 );
64 if (strncmp( Signature
, "CHUIV1 ", 8 ) != 0) {
65 printMessage( "CHUImporter","Not a Valid CHU File\n",LIGHT_RED
);
68 str
->ReadDword( &WindowCount
);
69 str
->ReadDword( &CTOffset
);
70 str
->ReadDword( &WEOffset
);
74 /** Returns the i-th window in the Previously Loaded Stream */
75 Window
* CHUImporter::GetWindow(unsigned int wid
)
77 ieWord WindowID
, XPos
, YPos
, Width
, Height
, BackGround
;
78 ieWord ControlsCount
, FirstControl
;
83 for (unsigned int c
= 0; c
< WindowCount
; c
++) {
84 str
->Seek( WEOffset
+ ( 0x1c * c
), GEM_STREAM_START
);
85 str
->ReadWord( &WindowID
);
86 if (WindowID
== wid
) {
94 str
->Seek( 2, GEM_CURRENT_POS
);
95 str
->ReadWord( &XPos
);
96 str
->ReadWord( &YPos
);
97 str
->ReadWord( &Width
);
98 str
->ReadWord( &Height
);
99 str
->ReadWord( &BackGround
);
100 str
->ReadWord( &ControlsCount
);
101 str
->ReadResRef( MosFile
);
102 str
->ReadWord( &FirstControl
);
104 Window
* win
= new Window( WindowID
, XPos
, YPos
, Width
, Height
);
105 if (BackGround
== 1) {
106 ResourceHolder
<ImageMgr
> mos(MosFile
);
108 win
->SetBackGround( mos
->GetSprite2D(), true );
110 printMessage( "CHUImporter","Cannot Load BackGround, skipping\n",YELLOW
);
112 if (!core
->IsAvailable( IE_BAM_CLASS_ID
)) {
113 printMessage( "CHUImporter","No BAM Importer Available, skipping controls\n",LIGHT_RED
);
116 for (i
= 0; i
< ControlsCount
; i
++) {
117 str
->Seek( CTOffset
+ ( ( FirstControl
+ i
) * 8 ), GEM_STREAM_START
);
118 ieDword COffset
, CLength
, ControlID
;
119 ieWord XPos
, YPos
, Width
, Height
;
120 ieByte ControlType
, temp
;
121 str
->ReadDword( &COffset
);
122 str
->ReadDword( &CLength
);
123 str
->Seek( COffset
, GEM_STREAM_START
);
124 str
->ReadDword( &ControlID
);
125 str
->ReadWord( &XPos
);
126 str
->ReadWord( &YPos
);
127 str
->ReadWord( &Width
);
128 str
->ReadWord( &Height
);
129 str
->Read( &ControlType
, 1 );
130 str
->Read( &temp
, 1 );
131 switch (ControlType
) {
135 Button
* btn
= new Button( );
136 btn
->ControlID
= ControlID
;
140 btn
->Height
= Height
;
141 btn
->ControlType
= ControlType
;
145 ieByte UnpressedIndex
, x1
;
146 ieByte PressedIndex
, x2
;
147 ieByte SelectedIndex
, y1
;
148 ieByte DisabledIndex
, y2
;
149 str
->ReadResRef( BAMFile
);
150 str
->Read( &Cycle
, 1 );
151 str
->Read( &tmp
, 1 );
152 Flags
= ((ieDword
) tmp
)<<8;
153 str
->Read( &UnpressedIndex
, 1 );
155 str
->Read( &PressedIndex
, 1 );
157 str
->Read( &SelectedIndex
, 1 );
159 str
->Read( &DisabledIndex
, 1 );
162 /** Justification comes from the .chu, other bits are set by script */
164 btn
->SetFlags(IE_GUI_BUTTON_NO_IMAGE
, BM_OR
);
166 if (core
->HasFeature(GF_UPPER_BUTTON_TEXT
)) {
167 btn
->SetFlags(IE_GUI_BUTTON_CAPS
, BM_OR
);
170 btn
->SetFlags( Flags
, BM_OR
);
171 if (Flags
& IE_GUI_BUTTON_ANCHOR
) {
172 btn
->SetAnchor(x1
| (x2
<<8), y1
| (y2
<<8));
175 if (strnicmp( BAMFile
, "guictrl\0", 8 ) == 0) {
176 if (UnpressedIndex
== 0) {
177 //printMessage("CHUImporter", "Special Button Control, Skipping Image Loading\n",GREEN );
178 win
->AddControl( btn
);
182 AnimationFactory
* bam
= ( AnimationFactory
* )
183 gamedata
->GetFactoryResource( BAMFile
,
184 IE_BAM_CLASS_ID
, IE_NORMAL
);
186 printMessage( "CHUImporter","Cannot Load Button Images, skipping control\n",LIGHT_RED
);
187 /* IceWind Dale 2 has fake BAM ResRefs for some Buttons,
188 this will handle bad ResRefs */
189 win
->AddControl( btn
);
192 /** Cycle is only a byte for buttons */
193 Sprite2D
* tspr
= bam
->GetFrame( UnpressedIndex
, (unsigned char) Cycle
);
194 btn
->SetImage( IE_GUI_BUTTON_UNPRESSED
, tspr
);
195 tspr
= bam
->GetFrame( PressedIndex
, Cycle
);
196 btn
->SetImage( IE_GUI_BUTTON_PRESSED
, tspr
);
197 //ignorebuttonframes is a terrible hack
198 if (core
->HasFeature( GF_IGNORE_BUTTON_FRAMES
) ) {
199 if (bam
->GetCycleSize(Cycle
) == 4 )
202 tspr
= bam
->GetFrame( SelectedIndex
, (unsigned char) Cycle
);
203 btn
->SetImage( IE_GUI_BUTTON_SELECTED
, tspr
);
204 if (core
->HasFeature( GF_IGNORE_BUTTON_FRAMES
) ) {
205 if (bam
->GetCycleSize( (unsigned char) Cycle
) == 4 )
208 tspr
= bam
->GetFrame( DisabledIndex
, (unsigned char) Cycle
);
209 btn
->SetImage( IE_GUI_BUTTON_DISABLED
, tspr
);
210 win
->AddControl( btn
);
214 case IE_GUI_PROGRESSBAR
:
216 //GemRB specific, progressbar
217 ieResRef MOSFile
, MOSFile2
;
219 ieWord KnobXPos
, KnobYPos
;
220 ieWord CapXPos
, CapYPos
;
221 ieWord KnobStepsCount
;
224 str
->ReadResRef( MOSFile
);
225 str
->ReadResRef( MOSFile2
);
226 str
->ReadResRef( BAMFile
);
227 str
->ReadWord( &KnobStepsCount
);
228 str
->ReadWord( &Cycle
);
229 str
->ReadWord( &KnobXPos
);
230 str
->ReadWord( &KnobYPos
);
231 str
->ReadWord( &CapXPos
);
232 str
->ReadWord( &CapYPos
);
233 Progressbar
* pbar
= new Progressbar(KnobStepsCount
, true );
234 pbar
->ControlID
= ControlID
;
237 pbar
->ControlType
= ControlType
;
239 pbar
->Height
= Height
;
240 pbar
->SetSliderPos( KnobXPos
, KnobYPos
, CapXPos
, CapYPos
);
242 Sprite2D
* img
= NULL
;
243 Sprite2D
* img2
= NULL
;
245 ResourceHolder
<ImageMgr
> mos(MOSFile
);
246 img
= mos
->GetSprite2D();
249 ResourceHolder
<ImageMgr
> mos(MOSFile2
);
250 img2
= mos
->GetSprite2D();
253 pbar
->SetImage( img
, img2
);
254 if( KnobStepsCount
) {
255 /* getting the bam */
256 AnimationFactory
*af
= (AnimationFactory
*)
257 gamedata
->GetFactoryResource(BAMFile
, IE_BAM_CLASS_ID
);
258 /* Getting the Cycle of the bam */
259 pbar
->SetAnimation(af
->GetCycle( Cycle
& 0xff ) );
262 ResourceHolder
<ImageMgr
> mos(BAMFile
);
263 Sprite2D
* img3
= mos
->GetSprite2D();
264 pbar
->SetBarCap( img3
);
266 win
->AddControl( pbar
);
272 ieResRef MOSFile
, BAMFile
;
273 ieWord Cycle
, Knob
, GrabbedKnob
;
274 ieWord KnobXPos
, KnobYPos
, KnobStep
, KnobStepsCount
;
275 str
->ReadResRef( MOSFile
);
276 str
->ReadResRef( BAMFile
);
277 str
->ReadWord( &Cycle
);
278 str
->ReadWord( &Knob
);
279 str
->ReadWord( &GrabbedKnob
);
280 str
->ReadWord( &KnobXPos
);
281 str
->ReadWord( &KnobYPos
);
282 str
->ReadWord( &KnobStep
);
283 str
->ReadWord( &KnobStepsCount
);
284 Slider
* sldr
= new Slider( KnobXPos
, KnobYPos
, KnobStep
, KnobStepsCount
, true );
285 sldr
->ControlID
= ControlID
;
288 sldr
->ControlType
= ControlType
;
290 sldr
->Height
= Height
;
291 ResourceHolder
<ImageMgr
> mos(MOSFile
);
292 Sprite2D
* img
= mos
->GetSprite2D();
293 sldr
->SetImage( IE_GUI_SLIDER_BACKGROUND
, img
);
295 AnimationFactory
* bam
= ( AnimationFactory
* )
296 gamedata
->GetFactoryResource( BAMFile
,
297 IE_BAM_CLASS_ID
, IE_NORMAL
);
299 img
= bam
->GetFrame( Knob
, 0 );
300 sldr
->SetImage( IE_GUI_SLIDER_KNOB
, img
);
301 img
= bam
->GetFrame( GrabbedKnob
, 0 );
302 sldr
->SetImage( IE_GUI_SLIDER_GRABBEDKNOB
, img
);
305 sldr
->SetState(IE_GUI_SLIDER_BACKGROUND
);
307 win
->AddControl( sldr
);
315 ieResRef FontResRef
, CursorResRef
;
317 ieWord CurCycle
, CurFrame
;
320 str
->ReadResRef( BGMos
);
321 str
->Seek( 16, GEM_CURRENT_POS
);
322 str
->ReadResRef( CursorResRef
);
323 str
->ReadWord( &CurCycle
);
324 str
->ReadWord( &CurFrame
);
325 str
->ReadWord( &PosX
);
326 str
->ReadWord( &PosY
);
327 str
->Seek( 4, GEM_CURRENT_POS
);
328 str
->ReadResRef( FontResRef
);
329 str
->Seek( 34, GEM_CURRENT_POS
);
330 str
->ReadWord( &maxInput
);
331 Font
* fnt
= core
->GetFont( FontResRef
);
333 AnimationFactory
* bam
= ( AnimationFactory
* )
334 gamedata
->GetFactoryResource( CursorResRef
,
337 Sprite2D
*cursor
= NULL
;
339 cursor
= bam
->GetFrame( CurCycle
, CurFrame
);
342 ResourceHolder
<ImageMgr
> mos(BGMos
);
343 Sprite2D
*img
= NULL
;
345 img
= mos
->GetSprite2D();
348 TextEdit
* te
= new TextEdit( maxInput
, PosX
, PosY
);
349 te
->ControlID
= ControlID
;
354 te
->ControlType
= ControlType
;
356 te
->SetCursor( cursor
);
357 te
->SetBackGround( img
);
358 win
->AddControl( te
);
362 case IE_GUI_TEXTAREA
:
365 ieResRef FontResRef
, InitResRef
;
366 Color fore
, init
, back
;
368 str
->ReadResRef( FontResRef
);
369 str
->ReadResRef( InitResRef
);
370 Font
* fnt
= core
->GetFont( FontResRef
);
371 Font
* ini
= core
->GetFont( InitResRef
);
372 str
->Read( &fore
, 4 );
373 str
->Read( &init
, 4 );
374 str
->Read( &back
, 4 );
375 str
->ReadWord( &SBID
);
376 TextArea
* ta
= new TextArea( fore
, init
, back
);
377 ta
->ControlID
= ControlID
;
382 ta
->ControlType
= ControlType
;
383 ta
->SetFonts( ini
, fnt
);
384 win
->AddControl( ta
);
386 win
->Link( SBID
, ( unsigned short ) ControlID
);
397 str
->ReadDword( &StrRef
);
398 str
->ReadResRef( FontResRef
);
399 Font
* fnt
= core
->GetFont( FontResRef
);
400 str
->Read( &fore
, 4 );
401 str
->Read( &back
, 4 );
402 str
->ReadWord( &alignment
);
403 Label
* lab
= new Label( fnt
);
404 lab
->ControlID
= ControlID
;
408 lab
->Height
= Height
;
409 lab
->ControlType
= ControlType
;
410 char* str
= core
->GetString( StrRef
);
412 core
->FreeString( str
);
424 lab
->SetColor( f
, b
);
426 int align
= IE_FONT_ALIGN_CENTER
;
427 if (( alignment
& 0x10 ) != 0) {
428 align
= IE_FONT_ALIGN_RIGHT
;
431 if (( alignment
& 0x04 ) != 0) {
434 if (( alignment
& 0x08 ) != 0) {
435 align
= IE_FONT_ALIGN_LEFT
;
439 if (( alignment
& 0x20 ) != 0) {
440 align
|= IE_FONT_ALIGN_TOP
;
443 if (( alignment
& 0x80 ) != 0) {
444 align
|= IE_FONT_ALIGN_BOTTOM
;
446 align
|= IE_FONT_ALIGN_MIDDLE
;
449 lab
->SetAlignment( align
);
450 win
->AddControl( lab
);
454 case IE_GUI_SCROLLBAR
:
458 ieWord Cycle
, Trough
, Slider
, TAID
;
459 ieWord UpUnPressed
, UpPressed
;
460 ieWord DownUnPressed
, DownPressed
;
462 str
->ReadResRef( BAMResRef
);
463 str
->ReadWord( &Cycle
);
464 str
->ReadWord( &UpUnPressed
);
465 str
->ReadWord( &UpPressed
);
466 str
->ReadWord( &DownUnPressed
);
467 str
->ReadWord( &DownPressed
);
468 str
->ReadWord( &Trough
);
469 str
->ReadWord( &Slider
);
470 str
->ReadWord( &TAID
);
471 ScrollBar
* sbar
= new ScrollBar();
472 sbar
->ControlID
= ControlID
;
476 sbar
->Height
= Height
;
477 sbar
->ControlType
= ControlType
;
479 AnimationFactory
* bam
= ( AnimationFactory
* )
480 gamedata
->GetFactoryResource( BAMResRef
,
481 IE_BAM_CLASS_ID
, IE_NORMAL
);
483 sbar
->SetImage( IE_GUI_SCROLLBAR_UP_UNPRESSED
,
484 bam
->GetFrame( UpUnPressed
, Cycle
) );
485 sbar
->SetImage( IE_GUI_SCROLLBAR_UP_PRESSED
,
486 bam
->GetFrame( UpPressed
, Cycle
) );
487 sbar
->SetImage( IE_GUI_SCROLLBAR_DOWN_UNPRESSED
,
488 bam
->GetFrame( DownUnPressed
, Cycle
) );
489 sbar
->SetImage( IE_GUI_SCROLLBAR_DOWN_PRESSED
,
490 bam
->GetFrame( DownPressed
, Cycle
) );
491 sbar
->SetImage( IE_GUI_SCROLLBAR_TROUGH
,
492 bam
->GetFrame( Trough
, Cycle
) );
493 sbar
->SetImage( IE_GUI_SCROLLBAR_SLIDER
,
494 bam
->GetFrame( Slider
, Cycle
) );
496 win
->AddControl( sbar
);
498 win
->Link( ( unsigned short ) ControlID
, TAID
);
503 printMessage( "CHUImporter","Control Not Supported\n",LIGHT_RED
);
508 /** Returns the number of available windows */
509 unsigned int CHUImporter::GetWindowsCount()
514 #include "plugindef.h"
516 GEMRB_PLUGIN(0x23A7F6CA, "CHU File Importer")
517 PLUGIN_CLASS(IE_CHU_CLASS_ID
, CHUImporter
)