void Window::DrawBackground(const Region* rgn) const { Video* video = core->GetVideoDriver(); if (rgn) { Region toClip = *rgn; toClip.x += XPos; toClip.y += YPos; video->BlitSprite( BackGround, *rgn, toClip); } else { video->BlitSprite( BackGround, XPos, YPos, true ); } }
/** This function Draws the Window on the Output Screen */ void Window::DrawWindow() { if (!Visible) return; // no point in drawing invisible windows Video* video = core->GetVideoDriver(); Region clip( XPos, YPos, Width, Height ); //Frame && Changed if ( (Flags & (WF_FRAME|WF_CHANGED) ) == (WF_FRAME|WF_CHANGED) ) { Region screen( 0, 0, core->Width, core->Height ); video->SetScreenClip( NULL ); //removed this? video->DrawRect( screen, ColorBlack ); if (core->WindowFrames[0]) video->BlitSprite( core->WindowFrames[0], 0, 0, true ); if (core->WindowFrames[1]) video->BlitSprite( core->WindowFrames[1], core->Width - core->WindowFrames[1]->Width, 0, true ); if (core->WindowFrames[2]) video->BlitSprite( core->WindowFrames[2], (core->Width - core->WindowFrames[2]->Width) / 2, 0, true ); if (core->WindowFrames[3]) video->BlitSprite( core->WindowFrames[3], (core->Width - core->WindowFrames[3]->Width) / 2, core->Height - core->WindowFrames[3]->Height, true ); } video->SetScreenClip( &clip ); //Float || Changed bool bgRefreshed = false; if (BackGround && (Flags & (WF_FLOAT|WF_CHANGED) ) ) { DrawBackground(NULL); bgRefreshed = true; } std::vector< Control*>::iterator m; for (m = Controls.begin(); m != Controls.end(); ++m) { Control* c = *m; // FIXME: drawing BG in the same loop as controls can produce incorrect results with overlapping controls. the only case I know of this occuring it is ok due to no BG drawing // furthermore, overlapping controls are still a problem when NeedsDraw() returns false for the top control, but true for the bottom (see the level up icon on char portraits) // we will fix both issues later by refactoring with the concept of views and subviews if (BackGround && !bgRefreshed && !c->IsOpaque() && c->NeedsDraw()) { const Region& fromClip = c->ControlFrame(); DrawBackground(&fromClip); } if (Flags & (WF_FLOAT)) { // FIXME: this is a total hack. Required for anything drawing over GameControl (nothing really at all to do with floating) c->MarkDirty(); } c->Draw( XPos, YPos ); } if ( (Flags&WF_CHANGED) && (Visible == WINDOW_GRAYED) ) { Color black = { 0, 0, 0, 128 }; video->DrawRect(clip, black); } video->SetScreenClip( NULL ); Flags &= ~WF_CHANGED; }
/** Draws the Control on the Output Display */ void TextEdit::DrawInternal(Region& rgn) { ieWord yOff = FontPosY; ieWord xOff = FontPosX; Video* video = core->GetVideoDriver(); if (Back) { // FIXME: temporary hack for PST map labels. // once subviews branch is merged this is not needed video->DrawRect(rgn, ColorBlack); video->BlitSprite( Back, rgn.x, rgn.y, true ); xOff += Back->XPos; yOff += Back->YPos; } else if (Text != L"") { // FIXME: temporary hack for PST map labels. // once subviews branch is merged this is not needed video->DrawRect(rgn, ColorBlack); } if (!font) { // no font was specified; happens with cheat input edits return; } //The aligning of textedit fields is done by absolute positioning (FontPosX, FontPosY) font->Print( Region( rgn.x + xOff, rgn.y + yOff, Width, Height ), Text, palette, Alignment ); if (hasFocus) { int w = font->StringSize(Text.substr(0, CurPos)).w; ieWord vcenter = (rgn.h / 2) + (Cursor->Height / 2); if (w > rgn.w) { int rows = (w / rgn.w); vcenter += rows * font->LineHeight; w = w - (rgn.w * rows); } video->BlitSprite(Cursor, w + rgn.x + xOff, yOff + vcenter + rgn.y, true); } }
/** This function Draws the Window on the Output Screen */ void Window::DrawWindow() { Video* video = core->GetVideoDriver(); Region clip( XPos, YPos, Width, Height ); //Frame && Changed if ( (Flags & (WF_FRAME|WF_CHANGED) )== (WF_FRAME|WF_CHANGED) ) { Region screen( 0, 0, core->Width, core->Height ); video->SetClipRect( NULL ); //removed this? Color black = { 0, 0, 0, 255 }; video->DrawRect( screen, black ); if (core->WindowFrames[0]) video->BlitSprite( core->WindowFrames[0], 0, 0, true ); if (core->WindowFrames[1]) video->BlitSprite( core->WindowFrames[1], core->Width - core->WindowFrames[1]->Width, 0, true ); if (core->WindowFrames[2]) video->BlitSprite( core->WindowFrames[2], (core->Width - core->WindowFrames[2]->Width) / 2, 0, true ); if (core->WindowFrames[3]) video->BlitSprite( core->WindowFrames[3], (core->Width - core->WindowFrames[3]->Width) / 2, core->Height - core->WindowFrames[3]->Height, true ); } else if (clip_regions.size()) { // clip drawing (we only do Background right now) for InvalidateForControl for (unsigned int i = 0; i < clip_regions.size(); i++) { Region to_clip = clip_regions[i]; to_clip.x += XPos; to_clip.y += YPos; video->SetClipRect(&to_clip); if (BackGround) { video->BlitSprite( BackGround, XPos, YPos, true ); } } } clip_regions.clear(); video->SetClipRect( &clip ); //Float || Changed if (BackGround && (Flags & (WF_FLOAT|WF_CHANGED) ) ) { video->BlitSprite( BackGround, XPos, YPos, true ); } std::vector< Control*>::iterator m; for (m = Controls.begin(); m != Controls.end(); ++m) { ( *m )->Draw( XPos, YPos ); } if ( (Flags&WF_CHANGED) && (Visible == WINDOW_GRAYED) ) { Color black = { 0, 0, 0, 128 }; video->DrawRect(clip, black); } video->SetClipRect( NULL ); Flags &= ~WF_CHANGED; }
/** Draws the Control on the Output Display */ void Button::DrawInternal(Region& rgn) { Video * video = core->GetVideoDriver(); // Button image if (!( Flags & IE_GUI_BUTTON_NO_IMAGE )) { Sprite2D* Image = NULL; switch (State) { case IE_GUI_BUTTON_UNPRESSED: case IE_GUI_BUTTON_LOCKED: case IE_GUI_BUTTON_LOCKED_PRESSED: Image = buttonImages[BUTTON_IMAGE_UNPRESSED]; break; case IE_GUI_BUTTON_FAKEPRESSED: case IE_GUI_BUTTON_PRESSED: Image = buttonImages[BUTTON_IMAGE_PRESSED]; break; case IE_GUI_BUTTON_SELECTED: Image = buttonImages[BUTTON_IMAGE_SELECTED]; break; case IE_GUI_BUTTON_DISABLED: case IE_GUI_BUTTON_FAKEDISABLED: Image = buttonImages[BUTTON_IMAGE_DISABLED]; break; } if (!Image) { Image = buttonImages[BUTTON_IMAGE_UNPRESSED]; } if (Image) { // FIXME: maybe it's useless... int xOffs = ( Width / 2 ) - ( Image->Width / 2 ); int yOffs = ( Height / 2 ) - ( Image->Height / 2 ); video->BlitSprite( Image, rgn.x + xOffs, rgn.y + yOffs, true ); } } if (State == IE_GUI_BUTTON_PRESSED) { //shift the writing/border a bit rgn.x += PushOffset.x; rgn.y += PushOffset.y; } // Button picture if (AnimPicture) { int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 ); int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 ); Region r( rgn.x + xOffs, rgn.y + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height ); if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) { video->BlitSprite( AnimPicture, rgn.x + xOffs + AnimPicture->XPos, rgn.y + yOffs + AnimPicture->YPos, true, &r ); } else { video->BlitSprite( AnimPicture, rgn.x + xOffs, rgn.y + yOffs, true, &r ); } } // Button picture int picXPos = 0, picYPos = 0; if (Picture && (Flags & IE_GUI_BUTTON_PICTURE) ) { // Picture is drawn centered picXPos = ( rgn.w / 2 ) - ( Picture->Width / 2 ) + rgn.x; picYPos = ( rgn.h / 2 ) - ( Picture->Height / 2 ) + rgn.y; if (Flags & IE_GUI_BUTTON_HORIZONTAL) { picXPos += Picture->XPos; picYPos += Picture->YPos; // Clipping: 0 = overlay over full button, 1 = no overlay int overlayHeight = Picture->Height * (1.0 - Clipping); if (overlayHeight < 0) overlayHeight = 0; if (overlayHeight >= Picture->Height) overlayHeight = Picture->Height; int buttonHeight = Picture->Height - overlayHeight; Region rb = Region(picXPos, picYPos, Picture->Width, buttonHeight); Region ro = Region(picXPos, picYPos + buttonHeight, Picture->Width, overlayHeight); video->BlitSprite( Picture, picXPos, picYPos, true, &rb ); // TODO: Add an option to add BLIT_GREY to the flags video->BlitGameSprite( Picture, picXPos, picYPos, BLIT_TINTED, SourceRGB, 0, 0, &ro, true); // do NOT uncomment this, you can't change Changed or invalidate things from // the middle of Window::DrawWindow() -- it needs moving to somewhere else //CloseUpColor(); } else { Region r( picXPos, picYPos, (int)(Picture->Width * Clipping), Picture->Height ); video->BlitSprite( Picture, picXPos + Picture->XPos, picYPos + Picture->YPos, true, &r ); } } // Composite pictures (paperdolls/description icons) if (!PictureList.empty() && (Flags & IE_GUI_BUTTON_PICTURE) ) { std::list<Sprite2D*>::iterator iter = PictureList.begin(); int xOffs = 0, yOffs = 0; if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) { // Center the hotspots of all pictures xOffs = Width/2; yOffs = Height/2; } else if (Flags & IE_GUI_BUTTON_BG1_PAPERDOLL) { // Display as-is xOffs = 0; yOffs = 0; } else { // Center the first picture, and align the rest to that xOffs = Width/2 - (*iter)->Width/2 + (*iter)->XPos; yOffs = Height/2 - (*iter)->Height/2 + (*iter)->YPos; } for (; iter != PictureList.end(); ++iter) { video->BlitSprite( *iter, rgn.x + xOffs, rgn.y + yOffs, true ); } } // Button label if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) { Palette* ppoi = normal_palette; int align = 0; if (State == IE_GUI_BUTTON_DISABLED) ppoi = disabled_palette; // FIXME: hopefully there's no button which sinks when selected // AND has text label //else if (State == IE_GUI_BUTTON_PRESSED || State == IE_GUI_BUTTON_SELECTED) { if (Flags & IE_GUI_BUTTON_ALIGN_LEFT) align |= IE_FONT_ALIGN_LEFT; else if (Flags & IE_GUI_BUTTON_ALIGN_RIGHT) align |= IE_FONT_ALIGN_RIGHT; else align |= IE_FONT_ALIGN_CENTER; if (Flags & IE_GUI_BUTTON_ALIGN_TOP) align |= IE_FONT_ALIGN_TOP; else if (Flags & IE_GUI_BUTTON_ALIGN_BOTTOM) align |= IE_FONT_ALIGN_BOTTOM; else align |= IE_FONT_ALIGN_MIDDLE; if (! (Flags & IE_GUI_BUTTON_MULTILINE)) { align |= IE_FONT_SINGLE_LINE; } Region r; if (Picture && (Flags & IE_GUI_BUTTON_PORTRAIT) == IE_GUI_BUTTON_PORTRAIT) { // constrain the label (status icons) to the picture bounds // FIXME: we are subtracting IE_FONT_PADDING because Font indents 5px, but we dont want that here r = Region(picXPos - IE_FONT_PADDING, picYPos + IE_FONT_PADDING, Picture->Width + IE_FONT_PADDING, Picture->Height); } else { r = Region( rgn.x, rgn.y, rgn.w - 2, rgn.h - 2); } font->Print( r, ( unsigned char * ) Text, ppoi, (ieByte) align, true ); } if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) { for (int i = 0; i < MAX_NUM_BORDERS; i++) { ButtonBorder *fr = &borders[i]; if (! fr->enabled) continue; Region r = Region( rgn.x + fr->dx1, rgn.y + fr->dy1, rgn.w - (fr->dx1 + fr->dx2 + 1), rgn.h - (fr->dy1 + fr->dy2 + 1) ); video->DrawRect( r, fr->color, fr->filled ); } } }
/** Draws the Control on the Output Display */ void MapControl::Draw(unsigned short XWin, unsigned short YWin) { if (!Width || !Height) { return; } if (Owner->Visible!=WINDOW_VISIBLE) { return; } if (Changed) { Realize(); Changed = false; } // we're going to paint over labels/etc, so they need to repaint! bool seen_this = false; unsigned int i; for (i = 0; i < Owner->GetControlCount(); i++) { Control *ctrl = Owner->GetControl(i); if (!ctrl) continue; // we could try working out which controls overlap, // but the later controls are cheap to paint.. if (ctrl == this) { seen_this = true; continue; } if (!seen_this) continue; ctrl->Changed = true; } Video* video = core->GetVideoDriver(); Region r( XWin + XPos, YWin + YPos, Width, Height ); if (MapMOS) { video->BlitSprite( MapMOS, MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r ); } if (core->FogOfWar&FOG_DRAWFOG) DrawFog(XWin, YWin); Region vp = video->GetViewport(); vp.x = GAME_TO_SCREENX(vp.x); vp.y = GAME_TO_SCREENY(vp.y); vp.w = ViewWidth; vp.h = ViewHeight; if ((vp.x + vp.w) >= MAP_TO_SCREENX( Width )) vp.w = MAP_TO_SCREENX( Width ) - vp.x; if ((vp.y + vp.h) >= MAP_TO_SCREENY( Height )) vp.h = MAP_TO_SCREENY( Height ) - vp.y; video->DrawRect( vp, colors[green], false, false ); // Draw PCs' ellipses Game *game = core->GetGame(); i = game->GetPartySize(true); while (i--) { Actor* actor = game->GetPC( i, true ); if (MyMap->HasActor(actor) ) { video->DrawEllipse( (short) GAME_TO_SCREENX(actor->Pos.x), (short) GAME_TO_SCREENY(actor->Pos.y), 3, 2, actor->Selected ? colors[green] : colors[darkgreen], false ); } } // Draw Map notes, could be turned off in bg2 // we use the common control value to handle it, because then we // don't need another interface if (Value!=MAP_NO_NOTES) { i = MyMap -> GetMapNoteCount(); while (i--) { MapNote * mn = MyMap -> GetMapNote(i); Sprite2D *anim = Flag[mn->color&7]; Point pos = mn->Pos; if (convertToGame) { vp.x = GAME_TO_SCREENX(mn->Pos.x); vp.y = GAME_TO_SCREENY(mn->Pos.y); } else { //pst style vp.x = MAP_TO_SCREENX(mn->Pos.x); vp.y = MAP_TO_SCREENY(mn->Pos.y); pos.x = pos.x * MAP_MULT / MAP_DIV; pos.y = pos.y * MAP_MULT / MAP_DIV; } //Skip unexplored map notes bool visible = MyMap->IsVisible( pos, true ); if (!visible) continue; if (anim) { video->BlitSprite( anim, vp.x - anim->Width/2, vp.y - anim->Height/2, true, &r ); } else { video->DrawEllipse( (short) vp.x, (short) vp.y, 6, 5, colors[mn->color&7], false ); } } } }
/** Draws the Control on the Output Display */ void Button::Draw(unsigned short x, unsigned short y) { if (!Changed && !(Owner->Flags&WF_FLOAT) ) { return; } Changed = false; if (XPos == 65535 || Width == 0) { return; } Video * video = core->GetVideoDriver(); // Button image if (!( Flags & IE_GUI_BUTTON_NO_IMAGE )) { Sprite2D* Image = NULL; switch (State) { case IE_GUI_BUTTON_UNPRESSED: case IE_GUI_BUTTON_LOCKED: case IE_GUI_BUTTON_LOCKED_PRESSED: Image = Unpressed; break; case IE_GUI_BUTTON_SECOND: case IE_GUI_BUTTON_PRESSED: Image = Pressed; if (! Image) Image = Unpressed; break; case IE_GUI_BUTTON_SELECTED: Image = Selected; if (! Image) Image = Unpressed; break; case IE_GUI_BUTTON_DISABLED: case IE_GUI_BUTTON_THIRD: Image = Disabled; if (! Image) Image = Unpressed; break; } if (Image) { // FIXME: maybe it's useless... int xOffs = ( Width / 2 ) - ( Image->Width / 2 ); int yOffs = ( Height / 2 ) - ( Image->Height / 2 ); video->BlitSprite( Image, x + XPos + xOffs, y + YPos + yOffs, true ); } } if (State == IE_GUI_BUTTON_PRESSED) { //shift the writing/border a bit x+= 2; y+= 2; } // Button picture if (Picture && (Flags & IE_GUI_BUTTON_PICTURE) ) { // Picture is drawn centered int xOffs = ( Width / 2 ) - ( Picture->Width / 2 ); int yOffs = ( Height / 2 ) - ( Picture->Height / 2 ); if (Flags & IE_GUI_BUTTON_HORIZONTAL) { xOffs += x + XPos + Picture->XPos; yOffs += y + YPos + Picture->YPos; video->BlitSprite( Picture, xOffs, yOffs, true ); Region r = Region( xOffs, yOffs + (int) (Picture->Height * Clipping), Picture->Width, (int) (Picture->Height*(1.0 - Clipping)) ); video->DrawRect( r, SourceRGB, true ); // do NOT uncomment this, you can't change Changed or invalidate things from // the middle of Window::DrawWindow() -- it needs moving to somewhere else //CloseUpColor(); } else { Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(Picture->Width * Clipping), Picture->Height ); video->BlitSprite( Picture, x + XPos + xOffs + Picture->XPos, y + YPos + yOffs + Picture->YPos, true, &r ); } } // Composite pictures (paperdolls/description icons) if (!PictureList.empty() && (Flags & IE_GUI_BUTTON_PICTURE) ) { std::list<Sprite2D*>::iterator iter = PictureList.begin(); int xOffs = 0, yOffs = 0; if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) { // Center the hotspots of all pictures xOffs = Width/2; yOffs = Height/2; } else if (Flags & IE_GUI_BUTTON_BG1_PAPERDOLL) { // Display as-is xOffs = 0; yOffs = 0; } else { // Center the first picture, and align the rest to that xOffs = Width/2 - (*iter)->Width/2 + (*iter)->XPos; yOffs = Height/2 - (*iter)->Height/2 + (*iter)->YPos; } for (; iter != PictureList.end(); ++iter) { video->BlitSprite( *iter, x + XPos + xOffs, y + YPos + yOffs, true ); } } // Button picture if (AnimPicture) { int xOffs = ( Width / 2 ) - ( AnimPicture->Width / 2 ); int yOffs = ( Height / 2 ) - ( AnimPicture->Height / 2 ); Region r( x + XPos + xOffs, y + YPos + yOffs, (int)(AnimPicture->Width * Clipping), AnimPicture->Height ); if (Flags & IE_GUI_BUTTON_CENTER_PICTURES) { video->BlitSprite( AnimPicture, x + XPos + xOffs + AnimPicture->XPos, y + YPos + yOffs + AnimPicture->YPos, true, &r ); } else { video->BlitSprite( AnimPicture, x + XPos + xOffs, y + YPos + yOffs, true, &r ); } } // Button label if (hasText && ! ( Flags & IE_GUI_BUTTON_NO_TEXT )) { Palette* ppoi = normal_palette; int align = 0; if (State == IE_GUI_BUTTON_DISABLED) ppoi = disabled_palette; // FIXME: hopefully there's no button which sinks when selected // AND has text label //else if (State == IE_GUI_BUTTON_PRESSED || State == IE_GUI_BUTTON_SELECTED) { if (Flags & IE_GUI_BUTTON_ALIGN_LEFT) align |= IE_FONT_ALIGN_LEFT; else if (Flags & IE_GUI_BUTTON_ALIGN_RIGHT) align |= IE_FONT_ALIGN_RIGHT; else align |= IE_FONT_ALIGN_CENTER; if (Flags & IE_GUI_BUTTON_ALIGN_TOP) align |= IE_FONT_ALIGN_TOP; else if (Flags & IE_GUI_BUTTON_ALIGN_BOTTOM) align |= IE_FONT_ALIGN_BOTTOM; else align |= IE_FONT_ALIGN_MIDDLE; if (! (Flags & IE_GUI_BUTTON_MULTILINE)) { align |= IE_FONT_SINGLE_LINE; } font->Print( Region( x + XPos, y + YPos, Width - 2, Height - 2), ( unsigned char * ) Text, ppoi, (ieByte) align, true ); } if (! (Flags&IE_GUI_BUTTON_NO_IMAGE)) { for (int i = 0; i < MAX_NUM_BORDERS; i++) { ButtonBorder *fr = &borders[i]; if (! fr->enabled) continue; Region r = Region( x + XPos + fr->dx1, y + YPos + fr->dy1, Width - (fr->dx1 + fr->dx2 + 1), Height - (fr->dy1 + fr->dy2 + 1) ); video->DrawRect( r, fr->color, fr->filled ); } } }
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, Palette* hicolor, unsigned char Alignment, bool anchor, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; if (initials) { capital=1; enablecap=true; } (void)enablecap; //HACK: shut up unused-but-set warnings, until the var is reused unsigned int psx = PARAGRAPH_START_X; Palette* pal = hicolor; if (!pal) { pal = palette; } if (initials==this) { initials = NULL; } sprBuffer->SetPalette( pal ); size_t len = strlen( ( char* ) string ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) { // ignore trailing newlines tmp[len - 1] = 0; len--; } SetupString( tmp, rgn.w, NoColor, initials, capital ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { if (tmp[i] == 0) continue; int height = yPos[( unsigned char ) tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; Video* video = core->GetVideoDriver(); if (Alignment & IE_FONT_ALIGN_CENTER) { int w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { int w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ); } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 1; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ); } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } for (size_t i = 0; i < len; i++) { if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (int k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char) g,(unsigned char) b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { sprBuffer->SetPalette( pal ); continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = PARAGRAPH_START_X; continue; } continue; } if (tmp[i] == 0) { y += ystep; x = psx; int w = CalcStringWidth( &tmp[i + 1], NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } unsigned char currChar = ( unsigned char ) tmp[i] - 1; if (initials && capital) { x = initials->PrintInitial( x, y, rgn, currChar ); enablecap=false; continue; } video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], anchor, &cliprgn ); if (cursor && ( curpos == i )) video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); x += size[currChar].w; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); } free( tmp ); }
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, Palette* hicolor, unsigned char Alignment, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; int initials_rows = 0; int last_initial_row = 0; int initials_x = 0; int initials_row = 0; unsigned char currCap = 0; size_t len = strlen( ( char* ) string ); int num_empty_rows = 0; if (initials) { capital=1; enablecap=true; initials_rows = ((initials->maxHeight - 1) / maxHeight) - (startrow - 1); currCap = string[0] - 1; if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap while(isspace(currCap) && num_empty_rows < (int)len) { //we cant cap whitespace so keep looking currCap = string[++num_empty_rows] - 1; // WARNING: this assumes all preceeding whitespace is an empty line } last_initial_row = (startrow - 1); initials_rows--; } } unsigned int psx = PARAGRAPH_START_X; Palette *pal = hicolor; if (!pal) { pal = palette; } if (initials==this) { enablecap=false; } sprBuffer->SetPalette( pal ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); SetupString( tmp, rgn.w, NoColor, initials, enablecap ); if (startrow) enablecap=false; int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { int height = yPos[( unsigned char ) tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; int w = CalcStringWidth( tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 1; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ); } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } Video* video = core->GetVideoDriver(); int row = 0; for (size_t i = 0; i < len; i++) { if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (int k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital && (row>=startrow) ) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { sprBuffer->SetPalette( pal ); continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = PARAGRAPH_START_X; } continue; } if (row < startrow) { if (tmp[i] == 0) { row++; } continue; } if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; int w = CalcStringWidth( &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; w += initials_x; } if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } unsigned char currChar = ( unsigned char ) tmp[i] - 1; if (initials && capital && enablecap) { currCap = currChar; x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; //how many more lines to be indented (one was already indented) initials_rows = (initials->maxHeight-1)/maxHeight; initials_row = row; last_initial_row = initials_row; enablecap = false; continue; } else if(initials && currCap && row > last_initial_row && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)) { // means this row doesnt have a cap, but a preceeding one did and its overlapping this row int initY = y; if (!num_empty_rows) {// num_empty_rows is for scrolling text areas initY = (y - (maxHeight * (row - initials_row))); } x = initials->PrintInitial( x, initY, rgn, currCap ); initials_x = x; x += psx; last_initial_row++; } video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); if (cursor && ( i == curpos )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } x += size[currChar].w; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } free( tmp ); }
void TextArea::Draw(unsigned short x, unsigned short y) { /** Don't come back recursively */ if (InternalFlags&TA_BITEMYTAIL) { return; } int tx=x+XPos; int ty=y+YPos; Region clip( tx, ty, Width, Height ); Video *video = core->GetVideoDriver(); if (Flags&IE_GUI_TEXTAREA_SPEAKER) { if (AnimPicture) { video->BlitSprite(AnimPicture, tx,ty, true, &clip); clip.x+=AnimPicture->Width; clip.w-=AnimPicture->Width; } } //this might look better in GlobalTimer //or you might want to change the animated button to work like this if (Flags &IE_GUI_TEXTAREA_SMOOTHSCROLL) { unsigned long thisTime; GetTime( thisTime); if (thisTime>starttime) { starttime = thisTime+ticks; smooth--; while (smooth<=0) { smooth+=ftext->maxHeight; if (startrow<rows) { startrow++; } } /** Forcing redraw of whole screen before drawing text*/ Owner->Invalidate(); InternalFlags |= TA_BITEMYTAIL; Owner->DrawWindow(); InternalFlags &= ~TA_BITEMYTAIL; } } if (!Changed && !(Owner->Flags&WF_FLOAT) ) { return; } Changed = false; if (XPos == 65535) { return; } size_t linesize = lines.size(); if (linesize == 0) { return; } //smooth vertical scrolling up if (Flags & IE_GUI_TEXTAREA_SMOOTHSCROLL) { clip.y+=smooth; clip.h-=smooth; } //if textarea is 'selectable' it actually means, it is a listbox //in this case the selected value equals the line number //if it is 'not selectable' it can still have selectable lines //but then it is like the dialog window in the main game screen: //the selected value is encoded into the line if (!(Flags & IE_GUI_TEXTAREA_SELECTABLE) ) { char* Buffer = (char *) malloc( 1 ); Buffer[0] = 0; int len = 0; int lastlen = 0; for (size_t i = 0; i < linesize; i++) { if (strnicmp( "[s=", lines[i], 3 ) == 0) { int tlen; unsigned long idx, acolor, bcolor; char* rest; idx = strtoul( lines[i] + 3, &rest, 0 ); if (*rest != ',') goto notmatched; acolor = strtoul( rest + 1, &rest, 16 ); if (*rest != ',') goto notmatched; bcolor = strtoul( rest + 1, &rest, 16 ); if (*rest != ']') goto notmatched; tlen = (int)(strstr( rest + 1, "[/s]" ) - rest - 1); if (tlen < 0) goto notmatched; len += tlen + 23; Buffer = (char *) realloc( Buffer, len + 2 ); if (seltext == (int) i) { sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]", acolor, tlen, rest + 1 ); } else { sprintf( Buffer + lastlen, "[color=%6.6lX]%.*s[/color]", bcolor, tlen, rest + 1 ); } } else { notmatched: len += ( int ) strlen( lines[i] ) + 1; Buffer = (char *) realloc( Buffer, len + 2 ); memcpy( &Buffer[lastlen], lines[i], len - lastlen ); } lastlen = len; if (i != linesize - 1) { Buffer[lastlen - 1] = '\n'; Buffer[lastlen] = 0; } } video->SetClipRect( &clip ); int pos; if (startrow==CurLine) { pos = CurPos; } else { pos = -1; } ftext->PrintFromLine( startrow, clip, ( unsigned char * ) Buffer, palette, IE_FONT_ALIGN_LEFT, finit, Cursor, pos ); free( Buffer ); video->SetClipRect( NULL ); //streaming text if (linesize>50) { //the buffer is filled enough return; } if (core->GetAudioDrv()->IsSpeaking() ) { //the narrator is still talking return; } if (RunEventHandler( TextAreaOutOfText )) { return; } if (linesize==lines.size()) { ResetEventHandler( TextAreaOutOfText ); return; } AppendText("\n",-1); return; } // normal scrolling textarea int rc = 0; int sr = startrow; unsigned int i; int yl; for (i = 0; i < linesize; i++) { if (rc + lrows[i] <= sr) { rc += lrows[i]; continue; } sr -= rc; Palette* pal = NULL; if (seltext == (int) i) pal = selected; else if (Value == i) pal = lineselpal; else pal = palette; ftext->PrintFromLine( sr, clip, ( unsigned char * ) lines[i], pal, IE_FONT_ALIGN_LEFT, finit, NULL ); yl = ftext->size[1].h*(lrows[i]-sr); clip.y+=yl; clip.h-=yl; break; } for (i++; i < linesize; i++) { Palette* pal = NULL; if (seltext == (int) i) pal = selected; else if (Value == i) pal = lineselpal; else pal = palette; ftext->Print( clip, ( unsigned char * ) lines[i], pal, IE_FONT_ALIGN_LEFT, true ); yl = ftext->size[1].h*lrows[i]; clip.y+=yl; clip.h-=yl; } }
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, Palette* hicolor, unsigned char Alignment, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; if (initials) { capital=1; enablecap=true; } int initials_rows = 0; int initials_x = 0; unsigned int psx = PARAGRAPH_START_X; Palette *pal = hicolor; if (!pal) { pal = palette; } if (startrow) enablecap=false; if (initials==this) { enablecap=false; } sprBuffer->SetPalette( pal ); size_t len = strlen( ( char* ) string ); char* tmp = ( char* ) malloc( len + 1 ); memcpy( tmp, ( char * ) string, len + 1 ); SetupString( tmp, rgn.w, NoColor, initials, enablecap ); int ystep = 0; if (Alignment & IE_FONT_SINGLE_LINE) { for (size_t i = 0; i < len; i++) { int height = yPos[( unsigned char ) tmp[i] - 1]; if (ystep < height) ystep = height; } } else { ystep = size[1].h; } if (!ystep) ystep = maxHeight; int x = psx, y = ystep; int w = CalcStringWidth( tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 1; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ); } else if (Alignment & IE_FONT_ALIGN_TOP) { y += 5; } Video* video = core->GetVideoDriver(); int row = 0; for (size_t i = 0; i < len; i++) { if (( ( unsigned char ) tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (int k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital && (row>=startrow) ) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char) r,(unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); sprBuffer->SetPalette( newPal ); gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { sprBuffer->SetPalette( pal ); continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = PARAGRAPH_START_X; } continue; } if (row < startrow) { if (tmp[i] == 0) { row++; } continue; } if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; int w = CalcStringWidth( &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; w += initials_x; } if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } unsigned char currChar = ( unsigned char ) tmp[i] - 1; if (initials && capital && enablecap) { x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; //how many more lines to be indented (one was already indented) initials_rows = (initials->maxHeight-1)/maxHeight; enablecap = false; continue; } video->BlitSpriteRegion( sprBuffer, size[currChar], x + rgn.x, y + rgn.y - yPos[currChar], true, &rgn ); if (cursor && ( i == curpos )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } x += size[currChar].w; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } free( tmp ); }
void Font::PrintFromLine(int startrow, Region rgn, const unsigned char* string, Palette* hicolor, ieByte Alignment, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { bool enablecap=false; int capital = 0; int initials_rows = 0; int last_initial_row = 0; int initials_x = 0; int initials_row = 0; ieWord currCap = 0; ieWord* tmp = NULL; size_t len = GetDoubleByteString(string, tmp); ieWord num_empty_rows = 0; if (initials && initials != this) { capital=1; enablecap=true; initials_rows = 1 + ((initials->maxHeight - 1) / maxHeight); // ceiling currCap = string[0]; if ((startrow > 0 && initials_rows > 0) || (len > 0 && isspace(currCap))) { // we need to look back to get the cap while(isspace(currCap) && num_empty_rows < len){//we cant cap whiteSpace so keep looking currCap = string[++num_empty_rows]; // WARNING: this assumes all preceeding whiteSpace is an empty line } last_initial_row = startrow - 1; // always the row before current since this cannot be the first row initials_rows = initials_rows - (startrow + 1) + num_empty_rows; // startrow + 1 because start row is 0 based, but initials_rows is 1 based } } unsigned int psx = IE_FONT_PADDING; Palette *pal = hicolor; if (!pal) { pal = palette; } Holder<Palette> blitPalette = pal; SetupString( tmp, rgn.w, NoColor, initials, enablecap ); if (startrow) enablecap=false; int ystep; if (Alignment & IE_FONT_SINGLE_LINE) { ystep = CalcStringHeight(tmp, len, NoColor); if (!ystep) ystep = maxHeight; } else { ystep = maxHeight; } int x = psx, y = ystep; size_t w = CalcStringWidth( tmp, NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ) - IE_FONT_PADDING; } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 0; for (size_t i = 0; i <= len; i++) { if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) h++; } h = h * ystep; y += ( rgn.h - h ) - IE_FONT_PADDING; } else if (Alignment & IE_FONT_ALIGN_TOP) { y += IE_FONT_PADDING; } Video* video = core->GetVideoDriver(); const Sprite2D* currGlyph; ieWord currChar = '\0'; int row = 0; for (size_t i = 0; i < len; i++) { if (( tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (size_t k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); if (capital && (row>=startrow) ) { enablecap=true; } continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); blitPalette = newPal; gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { blitPalette = pal; continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = IE_FONT_PADDING; } continue; } if (row < startrow) { if (tmp[i] == 0) { row++; } continue; } if (( tmp[i] == 0 ) || ( tmp[i] == '\n' )) { y += ystep; x = psx; size_t w = CalcStringWidth( &tmp[i + 1], NoColor ); if (initials_rows > 0) { initials_rows--; x += initials_x; w += initials_x; } if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } currChar = tmp[i]; if (initials && capital && enablecap) { currCap = currChar; x = initials->PrintInitial( x, y, rgn, currChar ); initials_x = x; //how many more lines to be indented (one was already indented) initials_rows = (initials->maxHeight - 1) / maxHeight; initials_rows += num_empty_rows; initials_row = row; last_initial_row = initials_row; enablecap = false; continue; } else if (initials && currCap && row > last_initial_row && (row - num_empty_rows - initials_row) <= ((initials->maxHeight-1)/maxHeight)){ // means this row doesnt have a cap, but a preceeding one did and its overlapping this row int initY = y; if (!num_empty_rows || row > num_empty_rows) {// num_empty_rows is for scrolling text areas initY = (y - (maxHeight * (row - initials_row - num_empty_rows))); } x = initials->PrintInitial( x, initY, rgn, currCap ); initials_x = x; last_initial_row++; if (num_empty_rows && row <= num_empty_rows) continue; else x += psx; } if (i > 0) { // kerning x -= GetKerningOffset(tmp[i-1], currChar); } currGlyph = GetCharSprite(currChar); video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, true, &rgn, blitPalette.get()); if (cursor && ( i == curpos )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } x += currGlyph->Width; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, true, &rgn ); } blitPalette = NULL; free( tmp ); }
void Font::Print(Region cliprgn, Region rgn, const unsigned char* string, Palette* hicolor, ieByte Alignment, bool anchor, Font* initials, Sprite2D* cursor, unsigned int curpos, bool NoColor) const { int capital = (initials) ? 1 : 0; unsigned int psx = IE_FONT_PADDING; Palette* pal = hicolor; if (!pal) { pal = palette; } if (initials==this) { initials = NULL; } Holder<Palette> blitPalette = pal; ieWord* tmp = NULL; size_t len = GetDoubleByteString(string, tmp); while (len > 0 && (tmp[len - 1] == '\n' || tmp[len - 1] == '\r')) { // ignore trailing newlines tmp[len - 1] = 0; len--; } SetupString( tmp, rgn.w, NoColor, initials, capital ); int ystep; if (Alignment & IE_FONT_SINGLE_LINE) { ystep = CalcStringHeight(tmp, len, NoColor); if (!ystep) ystep = maxHeight; } else { ystep = maxHeight; } int x = psx, y = ystep; Video* video = core->GetVideoDriver(); if (Alignment & IE_FONT_ALIGN_CENTER) { size_t w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { size_t w = CalcStringWidth( tmp, NoColor ); x = ( rgn.w - w ) - IE_FONT_PADDING; } if (Alignment & IE_FONT_ALIGN_MIDDLE) { int h = 0; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ) / 2; } else if (Alignment & IE_FONT_ALIGN_BOTTOM) { int h = 0; for (size_t i = 0; i <= len; i++) { if (tmp[i] == 0) h++; } h = h * ystep; y += ( rgn.h - h ) - IE_FONT_PADDING; } else if (Alignment & IE_FONT_ALIGN_TOP) { y += IE_FONT_PADDING; } ieWord currChar = '\0'; const Sprite2D* currGlyph = NULL; for (size_t i = 0; i < len; i++) { if (( tmp[i] ) == '[' && !NoColor) { i++; char tag[256]; tag[0]=0; for (size_t k = 0; k < 256 && i<len; k++) { if (tmp[i] == ']') { tag[k] = 0; break; } tag[k] = tmp[i++]; } if (strnicmp( tag, "capital=",8)==0) { sscanf( tag, "capital=%d", &capital); continue; } if (strnicmp( tag, "color=", 6 ) == 0) { unsigned int r,g,b; if (sscanf( tag, "color=%02X%02X%02X", &r, &g, &b ) != 3) continue; const Color c = {(unsigned char)r, (unsigned char)g, (unsigned char)b, 0}; Palette* newPal = core->CreatePalette( c, palette->back ); blitPalette = newPal; gamedata->FreePalette( newPal ); continue; } if (stricmp( tag, "/color" ) == 0) { blitPalette = pal; continue; } if (stricmp( "p", tag ) == 0) { psx = x; continue; } if (stricmp( "/p", tag ) == 0) { psx = IE_FONT_PADDING; continue; } continue; } if (tmp[i] == 0) { y += ystep; x = psx; size_t w = CalcStringWidth( &tmp[i + 1], NoColor ); if (Alignment & IE_FONT_ALIGN_CENTER) { x = ( rgn.w - w ) / 2; } else if (Alignment & IE_FONT_ALIGN_RIGHT) { x = ( rgn.w - w ); } continue; } currChar = tmp[i]; currGlyph = GetCharSprite(currChar); if (initials && capital) { x = initials->PrintInitial( x, y, rgn, currChar ); continue; } if (i > 0) { // kerning x -= GetKerningOffset(tmp[i-1], currChar); } video->BlitSprite(currGlyph, x + rgn.x, y + rgn.y, anchor, &cliprgn, blitPalette.get()); if (cursor && ( curpos == i )) video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); x += currGlyph->Width; } if (cursor && ( curpos == len )) { video->BlitSprite( cursor, x + rgn.x, y + rgn.y, anchor, &cliprgn ); } blitPalette = NULL; free( tmp ); }
/** Draws the Control on the Output Display */ void WorldMapControl::Draw(unsigned short XWin, unsigned short YWin) { WorldMap* worldmap = core->GetWorldMap(); if (!Width || !Height) { return; } if(!Changed) return; Changed = false; Video* video = core->GetVideoDriver(); Region r( XWin+XPos, YWin+YPos, Width, Height ); Region clipbackup; video->GetClipRect(clipbackup); video->SetClipRect(&r); video->BlitSprite( worldmap->GetMapMOS(), MAP_TO_SCREENX(0), MAP_TO_SCREENY(0), true, &r ); unsigned int i; unsigned int ec = worldmap->GetEntryCount(); for(i=0;i<ec;i++) { WMPAreaEntry *m = worldmap->GetEntry(i); if (! (m->GetAreaStatus() & WMP_ENTRY_VISIBLE)) continue; int xOffs = MAP_TO_SCREENX(m->X); int yOffs = MAP_TO_SCREENY(m->Y); Sprite2D* icon = m->GetMapIcon(worldmap->bam); if( icon ) { if (m == Area) { Palette *pal = icon->GetPalette(); icon->SetPalette(pal_selected); video->BlitSprite( icon, xOffs, yOffs, true, &r ); icon->SetPalette(pal); pal->Release(); } else { video->BlitSprite( icon, xOffs, yOffs, true, &r ); } video->FreeSprite( icon ); } if (AnimPicture && !strnicmp(m->AreaResRef, currentArea, 8) ) { video->BlitSprite( AnimPicture, xOffs, yOffs, true, &r ); } } // Draw WMP entry labels if (ftext==NULL) { video->SetClipRect(&clipbackup); return; } for(i=0;i<ec;i++) { WMPAreaEntry *m = worldmap->GetEntry(i); if (! (m->GetAreaStatus() & WMP_ENTRY_VISIBLE)) continue; Sprite2D *icon=m->GetMapIcon(worldmap->bam); int h=0,w=0,xpos=0,ypos=0; if (icon) { h=icon->Height; w=icon->Width; xpos=icon->XPos; ypos=icon->YPos; video->FreeSprite( icon ); } Region r2 = Region( MAP_TO_SCREENX(m->X-xpos), MAP_TO_SCREENY(m->Y-ypos), w, h ); if (!m->GetCaption()) continue; int tw = ftext->CalcStringWidth( (unsigned char*)m->GetCaption() ) + 5; int th = ftext->maxHeight; Palette* text_pal = pal_normal; if (Area == m) { text_pal = pal_selected; } else { if (! (m->GetAreaStatus() & WMP_ENTRY_VISITED)) { text_pal = pal_notvisited; } } ftext->Print( Region( r2.x + (r2.w - tw)/2, r2.y + r2.h, tw, th ), ( const unsigned char * ) m->GetCaption(), text_pal, 0, true ); } video->SetClipRect(&clipbackup); }