/*] Copyright (c) 2009-2010, Charles McGarvey [************************** **] All rights reserved. * * vi:ts=4 sw=4 tw=75 * * Distributable under the terms and conditions of the 2-clause BSD license; * see the file COPYING for a complete text of the license. * **************************************************************************/ #include #include #include #include #include "Hud.hh" ProgressBar::ProgressBar(const Mf::Texture& tilemap, Mf::Texture::TileIndex index) : mProgress(0.0), mTilemap(tilemap) { tilemap.getTileCoords(index, mTexCoords); Mf::Scalar half = (mTexCoords[2] - mTexCoords[0]) / 2.0 + mTexCoords[0]; mMidCoords[0] = half - 0.01; mMidCoords[1] = half + 0.01; } void ProgressBar::resize(const Mf::Rectangle& rect) { Mf::logInfo << "rect: " << rect.min << ", " << rect.max << std::endl; Mf::Scalar height = rect.max[1] - rect.min[1]; Mf::Scalar halfHeight = height / 2.0; mWidth = rect.max[0] - rect.min[0] - height; ASSERT(mWidth > 0); mVertices[0] = rect.min; mVertices[1] = Mf::Vector2(rect.min[0] + halfHeight, rect.min[1]); mVertices[2] = mVertices[1]; mVertices[3] = Mf::Vector2(rect.min[0] + height, rect.min[1]); mVertices[4] = Mf::Vector2(rect.min[0] + height, rect.max[1]); mVertices[5] = Mf::Vector2(rect.min[0] + halfHeight, rect.max[1]); mVertices[6] = mVertices[5]; mVertices[7] = Mf::Vector2(rect.min[0], rect.max[1]); setProgress(mProgress); } void ProgressBar::setProgress(Mf::Scalar progress) { Mf::Scalar halfHeight = (mVertices[7][1] - mVertices[0][1]) / 2.0; mVertices[2][0] = mVertices[1][0] + progress * mWidth; mVertices[3][0] = mVertices[1][0] + progress * mWidth + halfHeight; mVertices[4][0] = mVertices[1][0] + progress * mWidth + halfHeight; mVertices[5][0] = mVertices[1][0] + progress * mWidth; mProgress = progress; } void ProgressBar::draw(Mf::Scalar alpha) const { if (Mf::isEqual(mProgress, 0.0)) { // don't draw anything if the progress is 0% return; } glColor4f(1.0f, 1.0f, 1.0f, 0.85f); mTilemap.bind(); glBegin(GL_QUADS); glTexCoord(mTexCoords[0], mTexCoords[1]); glVertex(mVertices[0]); glTexCoord(mMidCoords[0], mTexCoords[3]); glVertex(mVertices[1]); glTexCoord(mMidCoords[0], mTexCoords[5]); glVertex(mVertices[6]); glTexCoord(mTexCoords[6], mTexCoords[7]); glVertex(mVertices[7]); glTexCoord(mMidCoords[0], mTexCoords[1]); glVertex(mVertices[1]); glTexCoord(mMidCoords[1], mTexCoords[3]); glVertex(mVertices[2]); glTexCoord(mMidCoords[1], mTexCoords[5]); glVertex(mVertices[5]); glTexCoord(mMidCoords[0], mTexCoords[7]); glVertex(mVertices[6]); glTexCoord(mMidCoords[1], mTexCoords[1]); glVertex(mVertices[2]); glTexCoord(mTexCoords[2], mTexCoords[3]); glVertex(mVertices[3]); glTexCoord(mTexCoords[4], mTexCoords[5]); glVertex(mVertices[4]); glTexCoord(mMidCoords[1], mTexCoords[7]); glVertex(mVertices[5]); glEnd(); } Hud::Hud(GameState& state) : mState(state), mBar1(Mf::Texture("StatusBars"), 0), mBar2(Mf::Texture("StatusBars"), 2), mFont("Font") { Mf::Video* video = Mf::Video::current(); ASSERT(video && "a current video context should be set"); resize(video->getWidth(), video->getHeight()); } void Hud::resize(int width, int height) { cml::matrix_orthographic_RH(mProjection, SCALAR(0.0), Mf::Scalar(width), SCALAR(0.0), Mf::Scalar(height), SCALAR(1.0), SCALAR(-1.0), cml::z_clip_neg_one); // position the two progress bars at the top-left of the screen mBar1.resize(Mf::Rectangle(20, height - 51, 0.7 * width, height - 3)); mBar2.resize(Mf::Rectangle(20, height - 28, 0.7 * width, height - 70)); setBar1Progress(0.05); setBar2Progress(0.0); } void Hud::update(Mf::Scalar t, Mf::Scalar dt) { mState.interp.update(t, dt); setBar1Progress(mState.interp.getState(dt)); setBar2Progress(1.0 - mState.interp.getState(dt)); } void Hud::draw(Mf::Scalar alpha) const { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrix(mProjection.data()); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); mBar1.draw(); mBar2.draw(); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } bool Hud::handleEvent(const Mf::Event& event) { switch (event.type) { case SDL_KEYUP: if (event.key.keysym.sym == SDLK_h) { // don't want the hud anymore parent().removeChild(this); Mf::logWarning("okay bye bye hud"); return true; } break; case SDL_VIDEORESIZE: resize(event.resize.w, event.resize.h); break; } return false; }