void OsuCircle::drawApproachCircle(Graphics *g, OsuSkin *skin, Vector2 pos, Color comboColor, float hitcircleDiameter, float approachScale, float alpha, bool modHD, bool overrideHDApproachCircle) { if ((!modHD || overrideHDApproachCircle) && osu_draw_approach_circles.getBool() && !OsuGameRules::osu_mod_mafham.getBool()) { g->setColor(comboColor); if (osu_circle_rainbow.getBool()) { float frequency = 0.3f; float time = engine->getTime()*20; char red1 = std::sin(frequency*time + 0 + rainbowNumber*rainbowColorCounter) * 127 + 128; char green1 = std::sin(frequency*time + 2 + rainbowNumber*rainbowColorCounter) * 127 + 128; char blue1 = std::sin(frequency*time + 4 + rainbowNumber*rainbowColorCounter) * 127 + 128; g->setColor(COLOR(255, red1, green1, blue1)); } g->setAlpha(alpha*osu_approach_circle_alpha_multiplier.getFloat()); if (approachScale > 1.0f) { const float approachCircleImageScale = hitcircleDiameter / (128.0f * (skin->isApproachCircle2x() ? 2.0f : 1.0f)); g->pushTransform(); g->scale(approachCircleImageScale*approachScale, approachCircleImageScale*approachScale); g->translate(pos.x, pos.y); g->drawImage(skin->getApproachCircle()); g->popTransform(); } } }
void OsuCircle::drawSliderEndCircle(Graphics *g, OsuSkin *skin, Vector2 pos, float hitcircleDiameter, float numberScale, float overlapScale, int number, int colorCounter, int colorOffset, float approachScale, float alpha, float numberAlpha, bool drawNumber, bool overrideHDApproachCircle) { if (alpha <= 0.0f || !osu_slider_draw_endcircle.getBool() || !osu_draw_circles.getBool()) return; // if no sliderendcircle image is preset, fallback to default circle if (skin->getSliderEndCircle() == skin->getMissingTexture()) { drawCircle(g, skin, pos, hitcircleDiameter, numberScale, overlapScale, number, colorCounter, colorOffset, approachScale, alpha, numberAlpha, drawNumber, overrideHDApproachCircle); return; } rainbowNumber = number; rainbowColorCounter = colorCounter; const Color comboColor = skin->getComboColorForCounter(colorCounter, colorOffset); // circle const float circleImageScale = hitcircleDiameter / (128.0f * (skin->isSliderEndCircle2x() ? 2.0f : 1.0f)); drawHitCircle(g, skin->getSliderEndCircle(), pos, comboColor, circleImageScale, alpha); // overlay if (skin->getSliderEndCircleOverlay() != skin->getMissingTexture()) { const float circleOverlayImageScale = hitcircleDiameter / skin->getSliderEndCircleOverlay2()->getSizeBaseRaw().x; drawHitCircleOverlay(g, skin->getSliderEndCircleOverlay2(), pos, circleOverlayImageScale, alpha); } }
void OsuCircle::drawCircle(Graphics *g, OsuSkin *skin, Vector2 pos, float hitcircleDiameter, float numberScale, float overlapScale, int number, int colorCounter, int colorOffset, float approachScale, float alpha, float numberAlpha, bool drawNumber, bool overrideHDApproachCircle) { if (alpha <= 0.0f || !osu_draw_circles.getBool()) return; rainbowNumber = number; rainbowColorCounter = colorCounter; Color comboColor = skin->getComboColorForCounter(colorCounter, colorOffset); comboColor = COLOR(255, (int)(COLOR_GET_Ri(comboColor)*osu_circle_color_saturation.getFloat()), (int)(COLOR_GET_Gi(comboColor)*osu_circle_color_saturation.getFloat()), (int)(COLOR_GET_Bi(comboColor)*osu_circle_color_saturation.getFloat())); // approach circle ///drawApproachCircle(g, skin, pos, comboColor, hitcircleDiameter, approachScale, alpha, modHD, overrideHDApproachCircle); // they are now drawn separately in draw2() // circle const float circleImageScale = hitcircleDiameter / (128.0f * (skin->isHitCircle2x() ? 2.0f : 1.0f)); comboColor = skin->getComboColorForCounter(colorCounter, colorOffset); drawHitCircle(g, skin->getHitCircle(), pos, comboColor, circleImageScale, alpha); // overlay const float circleOverlayImageScale = hitcircleDiameter / skin->getHitCircleOverlay2()->getSizeBaseRaw().x; if (!skin->getHitCircleOverlayAboveNumber()) drawHitCircleOverlay(g, skin->getHitCircleOverlay2(), pos, circleOverlayImageScale, alpha); // number if (drawNumber) drawHitCircleNumber(g, skin, numberScale, overlapScale, pos, number, numberAlpha); // overlay if (skin->getHitCircleOverlayAboveNumber()) drawHitCircleOverlay(g, skin->getHitCircleOverlay2(), pos, circleOverlayImageScale, alpha); }
void CBaseUIBoxShadow::draw(Graphics *g) { if (m_bNeedsRedraw) { render(g); m_bNeedsRedraw = false; } if (debug_box_shadows.getBool()) { g->setColor(0xff00ff00); g->drawRect(m_vPos.x-m_fRadius,m_vPos.y-m_fRadius, m_blur->getSize().x, m_blur->getSize().y); } if (!m_bVisible) return; /* // HACKHACK: switching blend funcs if (m_bColoredContent) glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); */ g->setColor(m_color); m_blur->draw(g, m_vPos.x-m_fRadius, m_vPos.y-m_fRadius); /* if (m_bColoredContent) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); */ }
void OsuPauseMenu::draw(Graphics *g) { if (!m_bVisible) return; if (osu_pause_dim_background.getBool()) { g->setColor(COLOR(150, 20, 20, 20)); g->fillRect(0, 0, Osu::getScreenWidth(), Osu::getScreenHeight()); } /* g->setColor(0xffff0000); g->drawLine(0, Osu::getScreenHeight()/3.0f, Osu::getScreenWidth(), Osu::getScreenHeight()/3.0f); g->drawLine(0, (Osu::getScreenHeight()/3.0f)*2, Osu::getScreenWidth(), (Osu::getScreenHeight()/3.0f)*2); g->drawLine(0, (Osu::getScreenHeight()/3.0f)*3, Osu::getScreenWidth(), (Osu::getScreenHeight()/3.0f)*3); */ m_container->draw(g); if (m_selectedButton != NULL) { const Color arrowColor = COLOR(255, 0, 114, 255); float animation = fmod((float)(engine->getTime()-m_fWarningArrowsAnimStartTime)*3.2f, 2.0f); if (animation > 1.0f) animation = 2.0f - animation; animation = -animation*(animation-2); // quad out float offset = m_osu->getUIScale(20.0f + 45.0f*animation); g->setColor(arrowColor); g->setAlpha(m_fWarningArrowsAnimAlpha); m_osu->getHUD()->drawWarningArrow(g, Vector2(m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) + Vector2(0, m_selectedButton->getSize().y/2) - Vector2(offset, 0), false, false); m_osu->getHUD()->drawWarningArrow(g, Vector2(Osu::getScreenWidth() - m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) + Vector2(0, m_selectedButton->getSize().y/2) + Vector2(offset, 0), true, false); } }
void OsuPauseMenu::draw(Graphics *g) { if (!m_bVisible) return; if (osu_pause_dim_background.getBool()) { g->setColor(COLOR(150, 20, 20, 20)); g->fillRect(0, 0, m_osu->getScreenWidth(), m_osu->getScreenHeight()); } // draw overlay if (m_osu->getSkin()->getPauseOverlay() != m_osu->getSkin()->getMissingTexture()) { const float scale = Osu::getImageScaleToFillResolution(m_osu->getSkin()->getPauseOverlay(), m_osu->getScreenSize()); const Vector2 centerTrans = (m_osu->getScreenSize()/2); g->setColor(COLOR(255, 255, 255, 255)); g->pushTransform(); { g->scale(scale, scale); g->translate((int)centerTrans.x, (int)centerTrans.y); g->drawImage(m_osu->getSkin()->getPauseOverlay()); } g->popTransform(); } /* g->setColor(0xffff0000); g->drawLine(0, m_osu->getScreenHeight()/3.0f, m_osu->getScreenWidth(), m_osu->getScreenHeight()/3.0f); g->drawLine(0, (m_osu->getScreenHeight()/3.0f)*2, m_osu->getScreenWidth(), (m_osu->getScreenHeight()/3.0f)*2); g->drawLine(0, (m_osu->getScreenHeight()/3.0f)*3, m_osu->getScreenWidth(), (m_osu->getScreenHeight()/3.0f)*3); */ m_container->draw(g); if (m_selectedButton != NULL) { const Color arrowColor = COLOR(255, 0, 114, 255); float animation = fmod((float)(engine->getTime()-m_fWarningArrowsAnimStartTime)*3.2f, 2.0f); if (animation > 1.0f) animation = 2.0f - animation; animation = -animation*(animation-2); // quad out const float offset = m_osu->getUIScale(m_osu, 20.0f + 45.0f*animation); g->setColor(arrowColor); g->setAlpha(m_fWarningArrowsAnimAlpha); m_osu->getHUD()->drawWarningArrow(g, Vector2(m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) + Vector2(0, m_selectedButton->getSize().y/2) - Vector2(offset, 0), false, false); m_osu->getHUD()->drawWarningArrow(g, Vector2(m_osu->getScreenWidth() - m_fWarningArrowsAnimX, m_fWarningArrowsAnimY) + Vector2(0, m_selectedButton->getSize().y/2) + Vector2(offset, 0), true, false); } }
void OsuCircle::draw2(Graphics *g) { if (m_bFinished || (!m_bVisible && !m_bWaiting)) // special case needed for when we are past this objects time, but still within not-miss range, because we still need to draw the object return; // draw approach circle const bool hd = m_beatmap->getOsu()->getModHD(); // HACKHACK: don't fucking change this piece of code here, it fixes a heisenbug (https://github.com/McKay42/McOsu/issues/165) if (osu_bug_flicker_log.getBool()) { const float approachCircleImageScale = m_beatmap->getHitcircleDiameter() / (128.0f * (m_beatmap->getSkin()->isApproachCircle2x() ? 2.0f : 1.0f)); debugLog("m_iTime = %ld, aScale = %f, iScale = %f\n", m_iTime, m_fApproachScale, approachCircleImageScale); } drawApproachCircle(g, m_beatmap, m_vRawPos, m_iComboNumber, m_iColorCounter, m_iColorOffset, m_bWaiting && !hd ? 1.0f : m_fApproachScale, m_bWaiting && !hd ? 1.0f : m_fAlphaForApproachCircle, m_bOverrideHDApproachCircle); }
void OsuCircle::drawSliderStartCircle(Graphics *g, OsuSkin *skin, Vector2 pos, float hitcircleDiameter, float numberScale, float hitcircleOverlapScale, int number, int colorCounter, int colorOffset, float approachScale, float alpha, float numberAlpha, bool drawNumber, bool overrideHDApproachCircle) { if (alpha <= 0.0f || !osu_draw_circles.getBool()) return; // if no sliderstartcircle image is preset, fallback to default circle if (skin->getSliderStartCircle() == skin->getMissingTexture()) { drawCircle(g, skin, pos, hitcircleDiameter, numberScale, hitcircleOverlapScale, number, colorCounter, colorOffset, approachScale, alpha, numberAlpha, drawNumber, overrideHDApproachCircle); // normal return; } rainbowNumber = number; rainbowColorCounter = colorCounter; const Color comboColor = skin->getComboColorForCounter(colorCounter, colorOffset); // approach circle ///drawApproachCircle(g, skin, pos, comboColor, beatmap->getHitcircleDiameter(), approachScale, alpha, beatmap->getOsu()->getModHD(), overrideHDApproachCircle); // they are now drawn separately in draw2() // circle const float circleImageScale = hitcircleDiameter / (128.0f * (skin->isSliderStartCircle2x() ? 2.0f : 1.0f)); drawHitCircle(g, skin->getSliderStartCircle(), pos, comboColor, circleImageScale, alpha); // overlay const float circleOverlayImageScale = hitcircleDiameter / skin->getSliderStartCircleOverlay2()->getSizeBaseRaw().x; if (skin->getSliderStartCircleOverlay() != skin->getMissingTexture()) { if (!skin->getHitCircleOverlayAboveNumber()) drawHitCircleOverlay(g, skin->getSliderStartCircleOverlay2(), pos, circleOverlayImageScale, alpha); } // number if (drawNumber) drawHitCircleNumber(g, skin, numberScale, hitcircleOverlapScale, pos, number, numberAlpha); // overlay if (skin->getSliderStartCircleOverlay() != skin->getMissingTexture()) { if (skin->getHitCircleOverlayAboveNumber()) drawHitCircleOverlay(g, skin->getSliderStartCircleOverlay2(), pos, circleOverlayImageScale, alpha); } }
void OsuCircle::drawHitCircle(Graphics *g, Image *hitCircleImage, Vector2 pos, Color comboColor, float circleImageScale, float alpha) { g->setColor(comboColor); if (osu_circle_rainbow.getBool()) { float frequency = 0.3f; float time = engine->getTime()*20; char red1 = std::sin(frequency*time + 0 + rainbowNumber*rainbowNumber*rainbowColorCounter) * 127 + 128; char green1 = std::sin(frequency*time + 2 + rainbowNumber*rainbowNumber*rainbowColorCounter) * 127 + 128; char blue1 = std::sin(frequency*time + 4 + rainbowNumber*rainbowNumber*rainbowColorCounter) * 127 + 128; g->setColor(COLOR(255, red1, green1, blue1)); } g->setAlpha(alpha); g->pushTransform(); g->scale(circleImageScale, circleImageScale); g->translate(pos.x, pos.y); g->drawImage(hitCircleImage); g->popTransform(); }
void OsuCircle::drawHitCircleNumber(Graphics *g, OsuSkin *skin, float numberScale, float overlapScale, Vector2 pos, int number, float numberAlpha) { if (!osu_draw_numbers.getBool()) return; class DigitWidth { public: static float getWidth(OsuSkin *skin, int digit) { switch (digit) { case 0: return skin->getDefault0()->getWidth(); case 1: return skin->getDefault1()->getWidth(); case 2: return skin->getDefault2()->getWidth(); case 3: return skin->getDefault3()->getWidth(); case 4: return skin->getDefault4()->getWidth(); case 5: return skin->getDefault5()->getWidth(); case 6: return skin->getDefault6()->getWidth(); case 7: return skin->getDefault7()->getWidth(); case 8: return skin->getDefault8()->getWidth(); case 9: return skin->getDefault9()->getWidth(); } return skin->getDefault0()->getWidth(); } }; // generate digits std::vector<int> digits; while (number >= 10) { digits.push_back(number % 10); number = number / 10; } digits.push_back(number); int digitOffsetMultiplier = digits.size()-1; // set color g->setColor(0xffffffff); if (osu_circle_number_rainbow.getBool()) { float frequency = 0.3f; float time = engine->getTime()*20; char red1 = std::sin(frequency*time + 0 + rainbowNumber*rainbowNumber*rainbowNumber*rainbowColorCounter) * 127 + 128; char green1 = std::sin(frequency*time + 2 + rainbowNumber*rainbowNumber*rainbowNumber*rainbowColorCounter) * 127 + 128; char blue1 = std::sin(frequency*time + 4 + rainbowNumber*rainbowNumber*rainbowNumber*rainbowColorCounter) * 127 + 128; g->setColor(COLOR(255, red1, green1, blue1)); } g->setAlpha(numberAlpha); // draw digits, start at correct offset g->pushTransform(); g->scale(numberScale, numberScale); g->translate(pos.x, pos.y); g->translate(-DigitWidth::getWidth(skin, (digits.size() > 0 ? digits[digits.size()-1] : 0))*digitOffsetMultiplier*numberScale*0.5f + skin->getHitCircleOverlap()*digitOffsetMultiplier*overlapScale*0.5f, 0); for (int i=digits.size()-1; i>=0; i--) { switch (digits[i]) { case 0: g->drawImage(skin->getDefault0()); break; case 1: g->drawImage(skin->getDefault1()); break; case 2: g->drawImage(skin->getDefault2()); break; case 3: g->drawImage(skin->getDefault3()); break; case 4: g->drawImage(skin->getDefault4()); break; case 5: g->drawImage(skin->getDefault5()); break; case 6: g->drawImage(skin->getDefault6()); break; case 7: g->drawImage(skin->getDefault7()); break; case 8: g->drawImage(skin->getDefault8()); break; case 9: g->drawImage(skin->getDefault9()); break; } g->translate(DigitWidth::getWidth(skin, digits[i])*numberScale - skin->getHitCircleOverlap()*overlapScale, 0); } g->popTransform(); }