int main() { Block::loadImage("./gfx/block.png"); Block::initMap(); Event event; Game.Clear(Color(50, 50, 100)); Grid<Block> france(VectorInt(GRID_DIMS, GRID_DIMS), Block::getImageDims(), PointFloat(224, 48)); france.setCellSize(VectorFloat(BLOCK_DIMS, BLOCK_DIMS)); Block::initContainer(&france); for (int i = 0; i < france.getDimensions().x; ++i) { for (int j = 0; j < france.getDimensions().y; ++j) { PointInt temp(i, j); france.set(Block(Block::getRandomColor(7), temp), temp); } } for (int i = 0; i < france.getDimensions().x; ++i) for (int j = 0; j < france.getDimensions().y; ++j) Game.Draw(france.get(PointInt(i, j)).getSprite()); while (Game.IsOpened()) { while (Game.GetEvent(event)) { if (event.Type == sf::Event::Closed) Game.Close(); } Game.Clear(Color(50, 50, 100)); for (int i = 0; i < france.getDimensions().x; ++i) { for (int j = 0; j < france.getDimensions().y; ++j) { if (Game.GetInput().IsMouseButtonDown(sf::Mouse::Button::Left)) france.get(PointInt(i, j)).handleInput(Game.GetInput()); Game.Draw(france.get(PointInt(i, j)).getSprite()); } } Game.Display(); } //TODO: Begin the main game loop }
void Render(float x,float y,Sprite& sp,int dir,float angle=0){ if (!isFormated){ FormatSprite(sp,dir); } sp.Render(PointInt(x,y),angle); isFormated = false; }
void WindowTree::onRenderItem( RenderContext & context, const RectInt & window, PointInt & pos, Item * pItem ) { WindowStyle * pStyle = windowStyle(); ASSERT( pStyle ); Font * pFont = windowStyle()->font(); ASSERT( pFont ); // get the depth of this item int depth = itemDepth( pItem ); // determine the X position based on it's depth pos.x = window.left + (depth * m_Indent); // get the size of the label text SizeInt labelSize( pFont->size( pItem->sLabel ) ); // determine the height of this item int height = (int)(labelSize.height + TREE_ITEM_BUFFER); RectInt itemRect( window.left, pos.y, window.right, pos.y + height ); // check if this item is highlighted or not if ( m_CursorInWindow && itemRect.inRect( m_LastCursorPosition ) ) onHighlight( pItem ); PrimitiveMaterial::push( context.display(), WHITE, PrimitiveMaterial::ALPHA ); if ( pItem->dwFlags & BUTTON ) { bool expanded = (pItem->dwFlags & EXPANDED) != 0; Color backColor( expanded ? pStyle->backColor() * TREE_SHADE_COLOR : pStyle->backColor() ); Color shadeColor( expanded ? pStyle->borderColor() * TREE_LIGHT_COLOR : pStyle->borderColor() * TREE_SHADE_COLOR ); Color lightColor( expanded ? pStyle->borderColor() * TREE_SHADE_COLOR : pStyle->borderColor() * TREE_LIGHT_COLOR ); // render the button pushBackground( context, itemRect, backColor, TREE_BUTTON_STYLE, TREE_BUTTON_BORDER ); pushBorder( context, itemRect, lightColor, shadeColor, TREE_BUTTON_STYLE, TREE_BUTTON_BORDER ); // draw glow around this object if the mouse is currently over this button if ( m_pCursorOver == pItem ) pushGlow( context, itemRect, TREE_GLOW_SIZE, TREE_GLOW_INNER, TREE_GLOW_OUTER, TREE_BUTTON_STYLE, TREE_BUTTON_BORDER ); // place the label in the center of the button PointInt labelPos( itemRect.center() - PointInt( labelSize.width / 2, labelSize.height / 2 ) ); // draw the label Font::push( context.display(), pFont, labelPos, pItem->sLabel, pItem->cColor ); } else { if ( m_pSelected == pItem ) pushBackground( context, itemRect, pStyle->highColor(), 0, 0 ); if ( m_pCursorOver == pItem ) pushGlow( context, itemRect, TREE_GLOW_SIZE, TREE_GLOW_INNER, TREE_GLOW_OUTER, 0, 0 ); PointInt labelPos( pos.x, (int)(pos.y + (TREE_ITEM_BUFFER / 2)) ); // render the label text` Font::push( context.display(), pFont, labelPos, pItem->sLabel, pItem->cColor ); } // move y down pos.y += (int)(height + WINDOW_TREE_SPACING); }
ButtonUnit::ButtonUnit() { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL; m_Alpha = 0.75f; setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) ); setEnable( false ); }
ButtonBuildStructure::ButtonBuildStructure() { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL | LOCK_ICON_SIZE; m_Alpha = 0.75f; setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) ); setEnable( false ); }
ViewEngineering::ButtonGadget::ButtonGadget() { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL | LOCK_ICON_SIZE; m_Alpha = 0.75f; setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) ); setEnable( false ); }
ButtonCargo::ButtonCargo() { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL | SHOW_HOTKEY | LOCK_ICON_SIZE; m_Alpha = 0.75f; m_HotKey = 'U'; setWindow( RectInt( PointInt(0,0), CARGO_BUTTON_SIZE ) ); setEnable( false ); }
void ButtonUnit::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); if ( enabled() && m_Unit.valid() ) { GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); NounShip * pShip = pDoc->ship(); if (! pShip ) return; DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); // draw the gadget icon if ( m_Icon.valid() ) { RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 32, 16 ) ); RectFloat iconUV(0,0,1,1); Material::push( context, m_Icon ); PrimitiveWindow::push( pDisplay, iconBox, iconUV, pShip->isFriend( m_Unit ) ? GREEN : pShip->isEnemy( m_Unit ) ? RED : YELLOW ); } // draw the unit health on the button Font * pFont = windowStyle()->font(); ASSERT( pFont ); WideString sHealth; sHealth.format( STR("%d%%"), 100 - ((m_Unit->damage() * 100) / m_Unit->maxDamage()) ); SizeInt szHealth( pFont->size( sHealth ) ); PointInt ptHealth( window.right - szHealth.width, window.bottom - szHealth.height ); Font::push( context.display(), pFont, ptHealth, sHealth, WHITE ); // display damage bar if ( m_Unit->damage() > 0 ) { float damage = 1.0f - (m_Unit->damage() / m_Unit->maxDamage()); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); RectFloat barUV(0,0,1,1); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, barUV, barColor ); } // display blinking border if this unit is the current target if ( pDoc->target() == m_Unit && (pDoc->tick() % 10) < 6) renderGlow( context ); } }
ButtonGadget::ButtonGadget() : m_bCursorOver( false ) { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | EFFECT_FADEIN | SMOOTH_LL; m_Alpha = 0.75f; m_IconColor = GREEN; setWindow( RectInt( PointInt(0,0), SizeInt( 32, 24 ) ) ); setEnable( false ); }
ButtonContact::ButtonContact() : m_IsObjective( false ), m_bGroupLeader( false ), m_bGroupPending( false ) { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | SMOOTH_LL | EFFECT_FADEIN; m_Alpha = 0.75f; setWindow( RectInt( PointInt(0,0), SizeInt( BUTTON_WIDTH, BUTTON_HEIGHT ) ) ); }
ButtonContact::ButtonContact( NodeWindow * pParent, Noun * pNoun ) : m_IsObjective( false ), m_bGroupLeader( false ), m_bGroupPending( false ) { m_Flags |= NOCLIP; m_Style = HAS_BACK | EFFECT_HIGHLIGHT | SMOOTH_LL | EFFECT_FADEIN; m_Alpha = 0.75f; setWindow( RectInt( PointInt(0,0), SizeInt( BUTTON_WIDTH, BUTTON_HEIGHT ) ) ); // attach this button to the parent pParent->attachNode( this ); // set this button setButton( pNoun ); }
TEST_FIXTURE(FixtureRound, PanRoundDown) { p.Pan(SizeInt(-1, -1)); CHECK_EQUAL(PointInt(0, 0), p.TopLeft()); CHECK_EQUAL(PointInt(717, 448), p.BottomRight()); }
bool ff::Value::Convert(Type type, Value **ppValue) const { assertRetVal(ppValue, false); *ppValue = nullptr; if (type == GetType()) { *ppValue = GetAddRef(const_cast<Value *>(this)); return true; } wchar_t buf[256]; switch (GetType()) { case Type::Null: switch (type) { case Type::String: CreateString(String(L"null"), ppValue); break; } break; case Type::Bool: switch (type) { case Type::Double: CreateDouble(AsBool() ? 1.0 : 0.0, ppValue); break; case Type::Float: CreateFloat(AsBool() ? 1.0f : 0.0f, ppValue); break; case Type::Int: CreateInt(AsBool() ? 1 : 0, ppValue); break; case Type::String: CreateString(AsBool() ? String(L"true") : String(L"false"), ppValue); break; } break; case Type::Double: switch (type) { case Type::Bool: CreateBool(AsDouble() != 0, ppValue); break; case Type::Float: CreateFloat((float)AsDouble(), ppValue); break; case Type::Int: CreateInt((int)AsDouble(), ppValue); break; case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"%g", AsDouble()); CreateString(String(buf), ppValue); break; } break; case Type::Float: switch (type) { case Type::Bool: CreateBool(AsFloat() != 0, ppValue); break; case Type::Double: CreateDouble((double)AsFloat(), ppValue); break; case Type::Int: CreateInt((int)AsFloat(), ppValue); break; case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"%g", AsFloat()); CreateString(String(buf), ppValue); break; } break; case Type::Int: switch (type) { case Type::Bool: CreateBool(AsInt() != 0, ppValue); break; case Type::Double: CreateDouble((double)AsInt(), ppValue); break; case Type::Float: CreateFloat((float)AsInt(), ppValue); break; case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"%d", AsInt()); CreateString(String(buf), ppValue); break; } break; case Type::Point: switch (type) { case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"(%d,%d)", AsPoint().x, AsPoint().y); CreateString(String(buf), ppValue); break; } break; case Type::PointF: switch (type) { case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"(%g,%g)", AsPointF().x, AsPointF().y); CreateString(String(buf), ppValue); break; } break; case Type::Rect: switch (type) { case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"(%d,%d,%d,%d)", AsRect().left, AsRect().top, AsRect().right, AsRect().bottom); CreateString(String(buf), ppValue); break; } break; case Type::RectF: switch (type) { case Type::String: _snwprintf_s(buf, _countof(buf), _TRUNCATE, L"(%g,%g,%g,%g)", AsRectF().left, AsRectF().top, AsRectF().right, AsRectF().bottom); CreateString(String(buf), ppValue); break; } break; case Type::String: switch (type) { case Type::Bool: if (AsString().empty() || AsString() == L"false" || AsString() == L"no" || AsString() == L"0") { CreateBool(false, ppValue); } else if (AsString() == L"true" || AsString() == L"yes" || AsString() == L"1") { CreateBool(true, ppValue); } break; case Type::Double: { const wchar_t *start = AsString().c_str(); wchar_t *end = nullptr; double val = wcstod(start, &end); if (end > start && !*end) { CreateDouble(val, ppValue); } } break; case Type::Float: { const wchar_t *start = AsString().c_str(); wchar_t *end = nullptr; double val = wcstod(start, &end); if (end > start && !*end) { CreateFloat((float)val, ppValue); } } break; case Type::Int: { const wchar_t *start = AsString().c_str(); wchar_t *end = nullptr; long val = wcstol(start, &end, 10); if (end > start && !*end) { CreateInt((int)val, ppValue); } } break; case Type::Guid: { GUID guid; if (StringToGuid(AsString(), guid)) { CreateGuid(guid, ppValue); } } break; } break; case Type::Object: switch (type) { case Type::Bool: CreateBool(AsObject() != nullptr, ppValue); break; } break; case Type::Guid: switch (type) { case Type::String: CreateString(StringFromGuid(AsGuid()), ppValue); break; } break; case Type::Data: switch (type) { case Type::SavedData: { ff::ComPtr<ff::ISavedData> savedData; if (ff::CreateLoadedDataFromMemory(AsData(), false, &savedData)) { CreateSavedData(savedData, ppValue); } } break; } break; case Type::SavedData: switch (type) { case Type::Data: { ff::ComPtr<ff::ISavedData> savedData; if (AsSavedData()->Clone(&savedData)) { ff::ComPtr<ff::IData> data = savedData->Load(); if (data) { CreateData(data, ppValue); } } } break; } break; case Type::Dict: switch (type) { case Type::Data: case Type::SavedData: case Type::SavedDict: { ff::ComPtr<ff::IData> data; ff::ComPtr<ff::ISavedData> savedData; if (ff::SaveDict(AsDict(), true, false, &data)) { if (type == Type::Data) { CreateData(data, ppValue); } else if (ff::CreateLoadedDataFromMemory(data, true, &savedData)) { if (type == Type::SavedData) { CreateSavedData(savedData, ppValue); } else { CreateSavedDict(savedData, ppValue); } } } } break; } break; case Type::SavedDict: switch (type) { case Type::Data: { ff::ComPtr<ff::ISavedData> savedData; if (AsSavedData()->Clone(&savedData)) { ff::ComPtr<ff::IData> data = savedData->Load(); if (data) { CreateData(data, ppValue); } } } break; case Type::SavedData: CreateSavedData(AsSavedData(), ppValue); break; case Type::Dict: { ff::ComPtr<ff::ISavedData> savedData; if (AsSavedData()->Clone(&savedData)) { ff::ComPtr<ff::IData> data = savedData->Load(); ff::ComPtr<ff::IDataReader> dataReader; Dict dict; if (data && ff::CreateDataReader(data, 0, &dataReader) && ff::LoadDict(dataReader, dict)) { CreateDict(std::move(dict), ppValue); } } } break; } break; case Type::Resource: AsResource()->GetValue()->Convert(type, ppValue); break; case Type::IntVector: switch (type) { case Type::Point: if (AsIntVector().Size() == 2) { PointInt point( AsIntVector().GetAt(0), AsIntVector().GetAt(1)); CreatePoint(point, ppValue); } break; case Type::Rect: if (AsIntVector().Size() == 4) { RectInt rect( AsIntVector().GetAt(0), AsIntVector().GetAt(1), AsIntVector().GetAt(2), AsIntVector().GetAt(3)); CreateRect(rect, ppValue); } break; } break; case Type::FloatVector: switch (type) { case Type::PointF: if (AsFloatVector().Size() == 2) { PointFloat point( AsFloatVector().GetAt(0), AsFloatVector().GetAt(1)); CreatePointF(point, ppValue); } break; case Type::RectF: if (AsFloatVector().Size() == 4) { RectFloat rect( AsFloatVector().GetAt(0), AsFloatVector().GetAt(1), AsFloatVector().GetAt(2), AsFloatVector().GetAt(3)); CreateRectF(rect, ppValue); } break; } break; case Type::ValueVector: switch (type) { case Type::Point: if (AsValueVector().Size() == 2) { ValuePtr newValues[2]; const Vector<ValuePtr> &values = AsValueVector(); if (values[0]->Convert(Type::Int, &newValues[0]) && values[1]->Convert(Type::Int, &newValues[1])) { CreatePoint(PointInt(newValues[0]->AsInt(), newValues[1]->AsInt()), ppValue); } } break; case Type::PointF: if (AsValueVector().Size() == 2) { ValuePtr newValues[2]; const Vector<ValuePtr> &values = AsValueVector(); if (values[0]->Convert(Type::Float, &newValues[0]) && values[1]->Convert(Type::Float, &newValues[1])) { CreatePointF(PointFloat(newValues[0]->AsFloat(), newValues[1]->AsFloat()), ppValue); } } break; case Type::Rect: if (AsValueVector().Size() == 4) { ValuePtr newValues[4]; const Vector<ValuePtr> &values = AsValueVector(); if (values[0]->Convert(Type::Int, &newValues[0]) && values[1]->Convert(Type::Int, &newValues[1]) && values[2]->Convert(Type::Int, &newValues[2]) && values[3]->Convert(Type::Int, &newValues[3])) { CreateRect(RectInt( newValues[0]->AsInt(), newValues[1]->AsInt(), newValues[2]->AsInt(), newValues[3]->AsInt()), ppValue); } } break; case Type::RectF: if (AsValueVector().Size() == 4) { ValuePtr newValues[4]; const Vector<ValuePtr> &values = AsValueVector(); if (values[0]->Convert(Type::Float, &newValues[0]) && values[1]->Convert(Type::Float, &newValues[1]) && values[2]->Convert(Type::Float, &newValues[2]) && values[3]->Convert(Type::Float, &newValues[3])) { CreateRectF(RectFloat( newValues[0]->AsFloat(), newValues[1]->AsFloat(), newValues[2]->AsFloat(), newValues[3]->AsFloat()), ppValue); } } break; case Type::StringVector: { bool valid = true; Vector<String> newValues; const Vector<ValuePtr> &values = AsValueVector(); for (ValuePtr oldValue : values) { ValuePtr newValue; valid = oldValue->Convert(Type::String, &newValue); if (valid) { newValues.Push(newValue->AsString()); } else { break; } } if (valid) { CreateStringVector(std::move(newValues), ppValue); } } break; case Type::IntVector: { bool valid = true; Vector<int> newValues; const Vector<ValuePtr> &values = AsValueVector(); for (ValuePtr oldValue : values) { ValuePtr newValue; valid = oldValue->Convert(Type::Int, &newValue); if (valid) { newValues.Push(newValue->AsInt()); } else { break; } } if (valid) { CreateIntVector(std::move(newValues), ppValue); } } break; case Type::DoubleVector: { bool valid = true; Vector<double> newValues; const Vector<ValuePtr> &values = AsValueVector(); for (ValuePtr oldValue : values) { ValuePtr newValue; valid = oldValue->Convert(Type::Double, &newValue); if (valid) { newValues.Push(newValue->AsDouble()); } else { break; } } if (valid) { CreateDoubleVector(std::move(newValues), ppValue); } } break; case Type::FloatVector: { bool valid = true; Vector<float> newValues; const Vector<ValuePtr> &values = AsValueVector(); for (ValuePtr oldValue : values) { ValuePtr newValue; valid = oldValue->Convert(Type::Float, &newValue); if (valid) { newValues.Push(newValue->AsFloat()); } else { break; } } if (valid) { CreateFloatVector(std::move(newValues), ppValue); } } break; } break; } if (*ppValue) { return true; } return false; }
void ButtonContact::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); NounShip * pShip = pDoc->ship(); if (! pShip ) return; WindowStyle * pStyle = windowStyle(); ASSERT( pStyle ); Font * pFont = pStyle->font(); ASSERT( pFont ); // get a pointer to our gadget Noun * pContact = m_Noun; if (! pContact ) return; RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 16, 16 ) ); Color iconColor( YELLOW ); if ( pShip->isFriend( pContact ) ) iconColor = GREEN; else if ( pShip->isEnemy( pContact ) ) iconColor = RED; // draw the gadget icon Material::push( context, m_Icon ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, iconColor ); if ( WidgetCast<NounShip>( pContact ) && ((NounShip *)pContact)->canOrder( pShip ) ) { Material::push( context, WidgetCast<Material>( resource("team") ) ); iconBox += PointInt( 16, 0 ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, WHITE ); } else if ( m_IsObjective ) { Material::push( context, WidgetCast<Material>( resource("objective") ) ); iconBox += PointInt( 16, 0 ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, WHITE ); } // display status text CharString sStatus = pContact->displayName( false ); if ( m_HotKey != 0 ) sStatus = CharString().format("%c:%s", m_HotKey, sStatus ); if ( sStatus.length() > 0 ) { SizeInt stringSize( pFont->size( sStatus ) ); // make sure the text fits on the label while( stringSize.width > (BUTTON_WIDTH - 5 ) ) { // remove the right most character and check the width again sStatus.left( sStatus.length() - 1 ); stringSize = pFont->size( sStatus ); } PointInt stringPos( window.m_Right - stringSize.width, window.m_Bottom - stringSize.height ); Font::push( pDisplay, pFont, stringPos, sStatus, m_bGroupLeader ? YELLOW : (m_bGroupPending ? GREY : WHITE) ); } // display the damage bar if ( WidgetCast<NounShip>( pContact ) ) { if ( ((NounShip *)pContact)->damage() > 0 ) { float damage = ((NounShip *)pContact)->damageRatioInv(); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, barColor ); } } // render additional border if this contact is our current target if ( pDoc->rootTarget() == m_Noun && (pDoc->tick() % 10) < 6 ) renderGlow( context ); }
void ButtonGadget::onRender( RenderContext & context, const RectInt & window ) { WindowButton::onRender( context, window ); // get a pointer to our gadget NounGadget * pGadget = m_Gadget; if ( pGadget != NULL ) { DisplayDevice * pDisplay = context.display(); ASSERT( pDisplay ); GameDocument * pDoc = (GameDocument *)document(); ASSERT( pDoc ); WindowStyle * pStyle = windowStyle(); ASSERT( pStyle ); Font * pFont = pStyle->font(); ASSERT( pFont ); // display bar if gadget has delay before usabled int delay = pGadget->usableWhen(); if ( delay > 0 ) { if ( (pDoc->tick() % 10) < 6 ) // make the bar blink { RectInt bar( window.left, window.top, window.right - ((window.width() * delay) / 100), window.top + 16 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::ADDITIVE ); PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, Color(0,0,255,255) ); } } // draw the gadget icon Material * pIcon = pGadget->icon(); if ( pIcon != NULL ) { RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 32, 16 ) ); Material::push( context, pIcon ); PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, m_IconColor ); } // display any gadget status text WideString sStatus( pGadget->status() ); if ( sStatus.length() > 0 ) { SizeInt stringSize( pFont->size( sStatus ) ); Font::push( pDisplay, pFont, PointInt( window.m_Right - stringSize.width, window.top ), sStatus, YELLOW ); } // display hotkey in lower-left corner of button CharString sHotKey; if ( pGadget->hotkey() != 0 && pGadget->hotkey() != HK_SPACE ) sHotKey += keyText( Keyboard::unmap( pGadget->hotkey() ) ); if ( m_Gadget->group() != 0 ) sHotKey += CharString().format(" %c", m_Gadget->group() ); if ( WidgetCast<GadgetBeamWeapon>( pGadget ) && ((GadgetBeamWeapon *)pGadget)->pointDefense() ) sHotKey += " PD"; if ( sHotKey.length() > 0 ) { WideString sWide = sHotKey; SizeInt stringSize( pFont->size( sWide ) ); Font::push( pDisplay, pFont, PointInt( window.m_Right - stringSize.width, window.m_Bottom - stringSize.height ), sWide, YELLOW ); } // display the damage bar if ( pGadget->damage() > 0 ) { if ( (pDoc->tick() % 10) < 6 ) // make the bar blink { float damage = pGadget->damageRatioInv(); RectInt bar( window.m_Left, window.m_Bottom + 1, window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 ); Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 ); PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE ); PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, barColor ); } } // blink a white border if this is the current target if ( pDoc->target() == m_Gadget && (pDoc->tick() % 10) < 6 ) renderGlow( context ); } }