Beispiel #1
0
void
BadGuy::draw(DrawingContext& context)
{
  if (!m_sprite.get()) return;

  if (m_state == STATE_INIT || m_state == STATE_INACTIVE)
  {
    if (Editor::is_active()) {
      m_sprite->draw(context.color(), get_pos(), m_layer);
    }
  }
  else
  {
    if (m_state == STATE_FALLING) {
      context.push_transform();
      context.set_flip(context.get_flip() ^ VERTICAL_FLIP);
      m_sprite->draw(context.color(), get_pos(), m_layer);
      context.pop_transform();
    } else {
      m_sprite->draw(context.color(), get_pos(), m_layer);
    }

    if (m_glowing) {
      m_lightsprite->draw(context.light(), m_col.m_bbox.get_middle(), 0);
    }
  }
}
Beispiel #2
0
void
TextObject::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(Vector(0, 0));
  if(fading > 0) {
    context.set_alpha((fadetime-fading) / fadetime);
  } else if(fading < 0) {
    context.set_alpha(-fading / fadetime);
  } else if(!visible) {
    context.pop_transform();
    return;
  }

  float width  = 500;
  float height = 70;
  Vector spos = pos + get_anchor_pos(Rectf(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
                                     width, height, anchor);

  context.draw_filled_rect(spos, Vector(width, height),
                           Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);
  if (centered) {
    context.draw_center_text(font, text, spos, LAYER_GUI-40, TextObject::default_color);
  } else {
    context.draw_text(font, text, spos + Vector(10, 10), ALIGN_LEFT, LAYER_GUI-40, TextObject::default_color);
  }

  context.pop_transform();
}
Beispiel #3
0
void
Sector::draw(DrawingContext& context)
{
  context.set_ambient_color( ambient_light );
  context.push_transform();
  context.set_translation(camera->get_translation());

  for(auto i = gameobjects.begin(); i != gameobjects.end(); ++i) {
    GameObjectPtr& object = *i;
    if(!object->is_valid())
      continue;

    if (draw_solids_only)
    {
      TileMap* tm = dynamic_cast<TileMap*>(object.get());
      if (tm && !tm->is_solid())
        continue;
    }

    object->draw(context);
  }

  if(show_collrects) {
    Color color(1.0f, 0.0f, 0.0f, 0.75f);
    for(auto i = moving_objects.begin(); i != moving_objects.end(); ++i) {
      MovingObject* object = *i;
      const Rectf& rect = object->get_bbox();

      context.draw_filled_rect(rect, color, LAYER_FOREGROUND1 + 10);
    }
  }

  context.pop_transform();
}
void ParticleSystem::draw(DrawingContext& context)
{
  float scrollx = context.get_translation().x;
  float scrolly = context.get_translation().y;

  context.push_transform();
  context.set_translation(Vector(max_particle_size,max_particle_size));

  std::vector<Particle*>::iterator i;
  for(i = particles.begin(); i != particles.end(); ++i) {
    Particle* particle = *i;

    // remap x,y coordinates onto screencoordinates
    Vector pos;

    pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
    if(pos.x < 0) pos.x += virtual_width;

    pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
    if(pos.y < 0) pos.y += virtual_height;

    //if(pos.x > virtual_width) pos.x -= virtual_width;
    //if(pos.y > virtual_height) pos.y -= virtual_height;

    context.draw_surface(particle->texture, pos, particle->angle, Color(1.0f, 1.0f, 1.0f), Blend(), z_pos);
  }

  context.pop_transform();
}
Beispiel #5
0
void
LevelTime::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(Vector(0, 0));

  if ((time_left > TIME_WARNING) || (int(game_time * 2.5) % 2)) {
    std::stringstream ss;
    ss << int(time_left);
    std::string time_text = ss.str();

    if (time_surface)
    {
      float all_width = static_cast<float>(time_surface->get_width()) + Resources::normal_font->get_text_width(time_text);
      context.color().draw_surface(time_surface,
                                   Vector((static_cast<float>(context.get_width()) - all_width) / 2.0f,
                                          BORDER_Y + 1),
                                   LAYER_FOREGROUND1);
      context.color().draw_text(Resources::normal_font, time_text,
                                Vector((static_cast<float>(context.get_width()) - all_width) / 2.0f + static_cast<float>(time_surface->get_width()),
                                       BORDER_Y),
                                ALIGN_LEFT, LAYER_FOREGROUND1, LevelTime::text_color);
    }
  }

  context.pop_transform();
}
Beispiel #6
0
void ParticleSystem::draw(DrawingContext& context)
{
  if(!enabled)
    return;

  float scrollx = context.get_translation().x;
  float scrolly = context.get_translation().y;

  context.push_transform();
  context.set_translation(Vector(max_particle_size,max_particle_size));

  for(const auto& particle : particles) {
    // remap x,y coordinates onto screencoordinates
    Vector pos;

    pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
    if(pos.x < 0) pos.x += virtual_width;

    pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
    if(pos.y < 0) pos.y += virtual_height;

    //if(pos.x > virtual_width) pos.x -= virtual_width;
    //if(pos.y > virtual_height) pos.y -= virtual_height;

    context.color().draw_surface(particle->texture, pos, particle->angle, Color(1.0f, 1.0f, 1.0f), Blend(), z_pos);
  }

  context.pop_transform();
}
void
Background::draw(DrawingContext& context)
{
  if(image.get() == NULL)
    return;
    
  int w = (int) image->get_width();
  int h = (int) image->get_height();
  int sx = int(pos.x-context.get_translation().x * speed) % w - w;
  int sy = int(pos.y-context.get_translation().y * speed_y) % h - h;
  int center_image_py = int(pos.y-context.get_translation().y * speed_y);
  int bottom_image_py = int(pos.y-context.get_translation().y * speed_y) + h;
  context.push_transform();
  context.set_translation(Vector(0, 0));
  for(int x = sx; x < SCREEN_WIDTH; x += w) {
    for(int y = sy; y < SCREEN_HEIGHT; y += h) {
      if (image_top.get() != NULL && (y < center_image_py)) {
        context.draw_surface(image_top.get(), Vector(x, y), layer);
        continue;
      } 
      if (image_bottom.get() != NULL && (y >= bottom_image_py)) {
        context.draw_surface(image_bottom.get(), Vector(x, y), layer);
        continue;
      }
      context.draw_surface(image.get(), Vector(x, y), layer);
    }
  }
  context.pop_transform();
}
Beispiel #8
0
void
Gradient::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(Vector(0, 0));
  context.draw_gradient(gradient_top, gradient_bottom, layer, gradient_direction);
  context.pop_transform();
}
Beispiel #9
0
void
TileMap::draw(DrawingContext& context)
{
  // skip draw if current opacity is 0.0
  if (current_alpha == 0.0) return;

  context.push_transform();
  if(draw_target != DrawingContext::NORMAL) {
    context.push_target();
    context.set_target(draw_target);
  }

  if(drawing_effect != 0) context.set_drawing_effect(drawing_effect);

  if (editor_active) {
    if(current_alpha != 1.0) {
      context.set_alpha(current_alpha);
    }
  } else {
    context.set_alpha(current_alpha/2);
  }

  /* Force the translation to be an integer so that the tiles appear sharper.
   * For consistency (i.e., to avoid 1-pixel gaps), this needs to be done even
   * for solid tilemaps that are guaranteed to have speed 1.
   * FIXME Force integer translation for all graphics, not just tilemaps. */
  float trans_x = roundf(context.get_translation().x);
  float trans_y = roundf(context.get_translation().y);
  context.set_translation(Vector(int(trans_x * speed_x),
                                 int(trans_y * speed_y)));

  Rectf draw_rect = Rectf(context.get_translation(),
        context.get_translation() + Vector(SCREEN_WIDTH, SCREEN_HEIGHT));
  Rect t_draw_rect = get_tiles_overlapping(draw_rect);
  Vector start = get_tile_position(t_draw_rect.left, t_draw_rect.top);

  Vector pos;
  int tx, ty;

  for(pos.x = start.x, tx = t_draw_rect.left; tx < t_draw_rect.right; pos.x += 32, ++tx) {
    for(pos.y = start.y, ty = t_draw_rect.top; ty < t_draw_rect.bottom; pos.y += 32, ++ty) {
      int index = ty*width + tx;
      assert (index >= 0);
      assert (index < (width * height));

      if (tiles[index] == 0) continue;
      const Tile* tile = tileset->get(tiles[index]);
      assert(tile != 0);
      tile->draw(context, pos, z_pos);
    } /* for (pos y) */
  } /* for (pos x) */

  if(draw_target != DrawingContext::NORMAL) {
    context.pop_target();
  }
  context.pop_transform();
}
void
SpecialRiser::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(
      context.get_translation() + Vector(0, -32 + offset));
  child->draw(context);
  context.pop_transform();
}
Beispiel #11
0
void
Climbable::draw(DrawingContext& context)
{
  if (climbed_by && !message.empty()) {
    context.push_transform();
    context.set_translation(Vector(0, 0));
    Vector pos = Vector(0, SCREEN_HEIGHT/2 - Resources::normal_font->get_height()/2);
    context.draw_center_text(Resources::normal_font, _(message), pos, LAYER_HUD, Climbable::text_color);
    context.pop_transform();
  }
}
void ParticleSystem_Interactive::draw(DrawingContext& context)
{
  context.push_transform();

  std::vector<Particle*>::iterator i;
  for(i = particles.begin(); i != particles.end(); ++i) {
    Particle* particle = *i;
    context.draw_surface(particle->texture, particle->pos, z_pos);
  }

  context.pop_transform();
}
void
Thunderstorm::draw(DrawingContext& context)
{
  if (!flash_display_timer.started()) return;

  float alpha = 0.33f;
  context.push_transform();
  context.set_translation(Vector(0, 0));
  context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT), Color(1, 1, 1, alpha), layer);
  context.pop_transform();

}
Beispiel #14
0
void
Console::draw(DrawingContext& context)
{
  if (m_height == 0)
    return;

  int layer = LAYER_GUI + 1;

  context.push_transform();
  context.set_alpha(m_alpha);
  context.draw_surface(m_background2,
                       Vector(SCREEN_WIDTH/2 - m_background->get_width()/2 - m_background->get_width() + m_backgroundOffset,
                              m_height - m_background->get_height()),
                       layer);
  context.draw_surface(m_background2,
                       Vector(SCREEN_WIDTH/2 - m_background->get_width()/2 + m_backgroundOffset,
                              m_height - m_background->get_height()),
                       layer);
  for (int x = (SCREEN_WIDTH/2 - m_background->get_width()/2
                - (static_cast<int>(ceilf((float)SCREEN_WIDTH /
                                          (float)m_background->get_width()) - 1) * m_background->get_width()));
       x < SCREEN_WIDTH;
       x += m_background->get_width())
  {
    context.draw_surface(m_background, Vector(x, m_height - m_background->get_height()), layer);
  }
  m_backgroundOffset+=10;
  if (m_backgroundOffset > (int)m_background->get_width()) m_backgroundOffset -= (int)m_background->get_width();

  int lineNo = 0;

  if (m_focused) {
    lineNo++;
    float py = m_height-4-1 * m_font->get_height();
    context.draw_text(m_font, "> "+m_inputBuffer, Vector(4, py), ALIGN_LEFT, layer);
    if (SDL_GetTicks() % 1000 < 750) {
      int cursor_px = 2 + m_inputBufferPosition;
      context.draw_text(m_font, "_", Vector(4 + (cursor_px * m_font->get_text_width("X")), py), ALIGN_LEFT, layer);
    }
  }

  int skipLines = -m_offset;
  for (std::list<std::string>::iterator i = m_buffer.m_lines.begin(); i != m_buffer.m_lines.end(); i++)
  {
    if (skipLines-- > 0) continue;
    lineNo++;
    float py = m_height - 4 - lineNo * m_font->get_height();
    if (py < -m_font->get_height()) break;
    context.draw_text(m_font, *i, Vector(4, py), ALIGN_LEFT, layer);
  }
  context.pop_transform();
}
void ParticleSystem_Interactive::draw(DrawingContext& context)
{
  if(!enabled)
    return;

  context.push_transform();

  for(auto& particle : particles) {
    context.draw_surface(particle->texture, particle->pos, z_pos);
  }

  context.pop_transform();
}
Beispiel #16
0
void
SecretAreaTrigger::draw(DrawingContext& context)
{
  if (message_timer.started()) {
    context.push_transform();
    context.set_translation(Vector(0, 0));
    Vector pos = Vector(0, SCREEN_HEIGHT/2 - Resources::normal_font->get_height()/2);
    context.draw_center_text(Resources::normal_font, message, pos, LAYER_HUD, SecretAreaTrigger::text_color);
    context.pop_transform();
  }
  if (message_timer.check()) {
    remove_me();
  }
}
Beispiel #17
0
void
Climbable::draw(DrawingContext& context)
{
  if (climbed_by && !message.empty()) {
    context.push_transform();
    context.set_translation(Vector(0, 0));
    Vector pos = Vector(0, static_cast<float>(SCREEN_HEIGHT) / 2.0f - Resources::normal_font->get_height() / 2.0f);
    context.color().draw_center_text(Resources::normal_font, _(message), pos, LAYER_HUD, Climbable::text_color);
    context.pop_transform();
  }
  if (Editor::is_active()) {
    context.color().draw_filled_rect(bbox, Color(1.0f, 1.0f, 0.0f, 0.6f),
                             0.0f, LAYER_OBJECTS);
  }
}
Beispiel #18
0
void
Thunderstorm::draw(DrawingContext& context)
{
  if (!flash_display_timer.started()) return;

  float alpha = 0.33f;
  context.push_transform();
  context.set_translation(Vector(0, 0));
  context.color().draw_filled_rect(Vector(0, 0),
                                   Vector(static_cast<float>(context.get_width()),
                                          static_cast<float>(context.get_height())),
                                   Color(1, 1, 1, alpha), layer);
  context.pop_transform();

}
Beispiel #19
0
void
InfoBlock::draw(DrawingContext& context)
{
  Block::draw(context);

  if (shown_pct <= 0) return;

  context.push_transform();
  //context.set_translation(Vector(0, 0));
  context.set_alpha(shown_pct);

  //float x1 = SCREEN_WIDTH/2-200;
  //float y1 = SCREEN_HEIGHT/2-200;
  float border = 8;
  float width = 400; // this is the text width only
  float height = lines_height; // this is the text height only
  float x1 = (bbox.p1.x + bbox.p2.x)/2 - width/2;
  float x2 = (bbox.p1.x + bbox.p2.x)/2 + width/2;
  float y1 = original_y - height;

  if(x1 < 0) {
    x1 = 0;
    x2 = width;
  }

  if(x2 > Sector::current()->get_width()) {
    x2 = Sector::current()->get_width();
    x1 = x2 - width;
  }

  // lines_height includes one ITEMS_SPACE too much, so the bottom border is reduced by 4px
  context.draw_filled_rect(Vector(x1-border, y1-border), Vector(width+2*border, height+2*border-4), Color(0.6f, 0.7f, 0.8f, 0.5f), LAYER_GUI-50);

  float y = y1;
  for(size_t i = 0; i < lines.size(); ++i) {
    if(y >= y1 + height) {
      //log_warning << "Too many lines of text in InfoBlock" << std::endl;
      //dest_pct = 0;
      //shown_pct = 0;
      break;
    }

    lines[i]->draw(context, Rectf(x1, y, x2, y), LAYER_GUI-50+1);
    y += lines[i]->get_height();
  }

  context.pop_transform();
}
void
PlayerStatus::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(Vector(0, 0));

  char str[60];
 
  int displayCoins = std::max(player_status->coins, 0);
  sprintf(str, "%d", displayCoins);
  const char* coinstext = _("COINS");
  context.draw_text(white_text, coinstext, Vector(SCREEN_WIDTH - white_text->get_text_width(coinstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y), LEFT_ALLIGN, LAYER_FOREGROUND1);
  context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y), RIGHT_ALLIGN, LAYER_FOREGROUND1);

  context.pop_transform();
}
Beispiel #21
0
void
Yeti::draw_hit_points(DrawingContext& context)
{
  if (hud_head)
  {
    context.push_transform();
    context.set_translation(Vector(0, 0));

    for (int i = 0; i < hit_points; ++i)
    {
      context.draw_surface(hud_head, Vector(BORDER_X + (i * hud_head->get_width()), BORDER_Y + 1), LAYER_FOREGROUND1);
    }

    context.pop_transform();
  }
}
Beispiel #22
0
void
FloatingText::draw(DrawingContext& context)
{
  // make an alpha animation when disappearing
  int alpha;
  if(timer.get_timeleft() < FADING_TIME)
    alpha = int(timer.get_timeleft() * 255 / FADING_TIME);
  else
    alpha = 255;

  context.push_transform();
  context.set_alpha(alpha);

  context.draw_text(Resources::normal_font, text, position, ALIGN_LEFT, LAYER_OBJECTS+1, FloatingText::text_color);

  context.pop_transform();
}
Beispiel #23
0
void
GhostTree::draw(DrawingContext& context)
{
  BadGuy::draw(context);

  context.push_target();
  context.push_transform();
  context.set_target(DrawingContext::LIGHTMAP);
  if (mystate == STATE_SUCKING) {
    context.set_alpha(0.5 + fmodf(game_time, 0.5));
  } else {
    context.set_alpha(0.5);
  }
  glow_sprite->draw(context, get_pos(), layer);
  context.pop_transform();
  context.pop_target();
}
Beispiel #24
0
void
Gradient::draw(DrawingContext& context)
{
  if(gradient_direction != HORIZONTAL && gradient_direction != VERTICAL)
  {
      auto current_sector = Sector::current();
      auto camera_translation = current_sector->camera->get_translation();
      auto sector_width = current_sector->get_width();
      auto sector_height = current_sector->get_height();
      gradient_region = Rectf(-camera_translation.x, -camera_translation.y, sector_width, sector_height);
  }

  context.push_transform();
  context.set_translation(Vector(0, 0));
  context.draw_gradient(gradient_top, gradient_bottom, layer, gradient_direction, gradient_region);
  context.pop_transform();
}
Beispiel #25
0
void
PlayerStatus::draw(DrawingContext& context)
{
  int player_id = 0;

  if ((displayed_coins == DISPLAYED_COINS_UNSET) ||
      (std::abs(displayed_coins - coins) > 100)) {
    displayed_coins = coins;
    displayed_coins_frame = 0;
  }
  if (++displayed_coins_frame > 2) {
    displayed_coins_frame = 0;
    if (displayed_coins < coins) displayed_coins++;
    if (displayed_coins > coins) displayed_coins--;
  }
  displayed_coins = std::min(std::max(displayed_coins, 0), MAX_COINS);

  std::stringstream ss;
  ss << displayed_coins;
  std::string coins_text = ss.str();

  context.push_transform();
  context.set_translation(Vector(0, 0));

  if (coin_surface)
  {
    context.color().draw_surface(coin_surface,
                                 Vector(static_cast<float>(context.get_width()) - BORDER_X - static_cast<float>(coin_surface->get_width()) - Resources::fixed_font->get_text_width(coins_text),
                                        BORDER_Y + 1.0f + (Resources::fixed_font->get_text_height(coins_text) + 5) * static_cast<float>(player_id)),
                                   LAYER_HUD);
  }
  context.color().draw_text(Resources::fixed_font,
                            coins_text,
                            Vector(static_cast<float>(context.get_width()) - BORDER_X - Resources::fixed_font->get_text_width(coins_text),
                                   BORDER_Y + (Resources::fixed_font->get_text_height(coins_text) + 5.0f) * static_cast<float>(player_id)),
                            ALIGN_LEFT,
                            LAYER_HUD,
                            PlayerStatus::text_color);

  context.pop_transform();
}
void
FloatingImage::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(Vector(0, 0));

  if(fading > 0) {
    context.set_alpha((fadetime-fading) / fadetime);
  } else if(fading < 0) {
    context.set_alpha(-fading / fadetime);
  } else if(!visible) {
    context.pop_transform();
    return;
  }

  Vector spos = pos + get_anchor_pos(Rectf(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
                                     sprite->get_width(), sprite->get_height(), anchor);

  sprite->draw(context, spos, layer);

  context.pop_transform();
}
Beispiel #27
0
void
BouncyCoin::draw(DrawingContext& context)
{
  float time_left = timer.get_timeleft();
  bool fading = time_left < FADE_TIME;
  if(fading) {
    float alpha = time_left/FADE_TIME;
    context.push_transform();
    context.set_alpha(alpha);
  }

  int layer;
  if(emerge_distance > 0) {
    layer = LAYER_OBJECTS - 5;
  } else {
    layer = LAYER_OBJECTS + 5;
  }
  sprite->draw(context, position, layer);

  if(fading) {
    context.pop_transform();
  }
}
void
DisplayEffect::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(Vector(0, 0));

  if(black || screen_fade != NO_FADE) {
    float alpha;
    if(black) {
      alpha = 1.0f;
    } else {
      switch(screen_fade) {
        case FADE_IN:
          alpha = screen_fading / screen_fadetime;
          break;
        case FADE_OUT:
          alpha = (screen_fadetime - screen_fading) / screen_fadetime;
          break;
        default:
          alpha = 0;
          assert(false);
      }
    }
    context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
                             Color(0, 0, 0, alpha), LAYER_GUI-10);
  }

  if (borders) {
    context.draw_filled_rect(Vector(0, 0), Vector(SCREEN_WIDTH, border_size),
                             Color(0, 0, 0, 1.0f), LAYER_GUI-10);
    context.draw_filled_rect(Vector(0, SCREEN_HEIGHT - border_size), Vector(SCREEN_WIDTH, border_size),
                             Color(0, 0, 0, 1.0f), LAYER_GUI-10);
  }

  context.pop_transform();
}
void
Statistics::draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop)
{
  // skip draw if level was never played
  // TODO: do we need this?
  if (coins == nv_coins) return;

  // skip draw if stats were declared invalid
  if (!valid) return;

  // abort if we have no backdrop
  if (!backdrop) return;

  int box_w = 220+110+110;
  int box_h = 30+20+20+20;
  int box_x = (int)((SCREEN_WIDTH - box_w) / 2);
  int box_y = (int)(SCREEN_HEIGHT / 2) - box_h;

  int bd_w = (int)backdrop->get_width();
  int bd_h = (int)backdrop->get_height();
  int bd_x = (int)((SCREEN_WIDTH - bd_w) / 2);
  int bd_y = box_y + (box_h / 2) - (bd_h / 2);

  int col1_x = box_x;
  int col2_x = col1_x+200;
  int col3_x = col2_x+130;

  int row1_y = box_y;
  int row2_y = row1_y+30;
  int row3_y = row2_y+20;
  int row4_y = row3_y+20;

  context.push_transform();
  context.set_alpha(0.5);
  context.draw_surface(backdrop, Vector(bd_x, bd_y), LAYER_GUI);
  context.pop_transform();

  char buf[129];
  context.draw_text(white_text, _("You"), Vector(col2_x, row1_y), LEFT_ALLIGN, LAYER_GUI);
  context.draw_text(white_text, _("Best"), Vector(col3_x, row1_y), LEFT_ALLIGN, LAYER_GUI);

  context.draw_text(white_text, _("Coins"), Vector(col2_x-16, row2_y), RIGHT_ALLIGN, LAYER_GUI);
  snprintf(buf, sizeof(buf), "%d/%d", std::min(coins, 999), std::min(total_coins, 999));
  context.draw_text(gold_text, buf, Vector(col2_x, row2_y), LEFT_ALLIGN, LAYER_GUI);
  if (best_stats && (best_stats->coins > coins)) {
    snprintf(buf, sizeof(buf), "%d/%d", std::min(best_stats->coins, 999), std::min(best_stats->total_coins, 999));
  }
  context.draw_text(gold_text, buf, Vector(col3_x, row2_y), LEFT_ALLIGN, LAYER_GUI);

  context.draw_text(white_text, _("Secrets"), Vector(col2_x-16, row4_y), RIGHT_ALLIGN, LAYER_GUI);
  snprintf(buf, sizeof(buf), "%d/%d", secrets, total_secrets);
  context.draw_text(gold_text, buf, Vector(col2_x, row4_y), LEFT_ALLIGN, LAYER_GUI);
  if (best_stats && (best_stats->secrets > secrets)) {
    snprintf(buf, sizeof(buf), "%d/%d", best_stats->secrets, best_stats->total_secrets);
  }
  context.draw_text(gold_text, buf, Vector(col3_x, row4_y), LEFT_ALLIGN, LAYER_GUI);

  context.draw_text(white_text, _("Time"), Vector(col2_x-16, row3_y), RIGHT_ALLIGN, LAYER_GUI);
  int csecs = (int)(time * 100);
  int mins = (int)(csecs / 6000);
  int secs = (csecs % 6000) / 100;
  snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs);
  context.draw_text(gold_text, buf, Vector(col2_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
  if (best_stats && (best_stats->time < time)) {
    int csecs = (int)(best_stats->time * 100);
    int mins = (int)(csecs / 6000);
    int secs = (csecs % 6000) / 100;
    snprintf(buf, sizeof(buf), "%02d:%02d", mins,secs);
  }
  context.draw_text(gold_text, buf, Vector(col3_x, row3_y), LEFT_ALLIGN, LAYER_GUI);
}
void
Statistics::draw_worldmap_info(DrawingContext& context)
{
  // skip draw if level was never played
  if (coins == nv_coins) return;

  // skip draw if stats were declared invalid
  if (!valid) return;

  context.draw_text(white_small_text, std::string("- ") + _("Best Level Statistics") + " -", Vector((WMAP_INFO_LEFT_X + WMAP_INFO_RIGHT_X) / 2, WMAP_INFO_TOP_Y1), CENTER_ALLIGN, LAYER_GUI);

  float alpha;
  if(timer.get_timegone() < FADING_TIME)
    alpha = (timer.get_timegone() * 1.0f / FADING_TIME);
  else if(timer.get_timeleft() < FADING_TIME)
    alpha = (timer.get_timeleft() * 1.0f / FADING_TIME);
  else
    alpha = 1.0f;

  context.push_transform();
  context.set_alpha(alpha);

  char caption_buf[128];
  char stat_buf[128];
  switch (display_stat)
  {
    case 0:
      snprintf(caption_buf, sizeof(caption_buf), _("Max coins collected:"));
      snprintf(stat_buf, sizeof(stat_buf), "%d/%d", coins, total_coins);
      break;
    case 1:
      snprintf(caption_buf, sizeof(caption_buf), _("Max fragging:"));
      snprintf(stat_buf, sizeof(stat_buf), "%d/%d", badguys, total_badguys);
      break;
    case 2:
      snprintf(caption_buf, sizeof(caption_buf), _("Min time needed:"));
      {
	int csecs = (int)(time * 100);
	int mins = (int)(csecs / 6000);
	int secs = (csecs % 6000) / 100;
	snprintf(stat_buf, sizeof(stat_buf), "%02d:%02d", mins,secs);
      }
      break;
    case 3:
      snprintf(caption_buf, sizeof(caption_buf), _("Max secrets found:"));
      snprintf(stat_buf, sizeof(stat_buf), "%d/%d", secrets, total_secrets);
      break;
    default:
      log_debug << "Invalid stat requested to be drawn" << std::endl;
      break;
  }

  if (!timer.started())
  {
    timer.start(TOTAL_DISPLAY_TIME);
    display_stat++;
    if (display_stat > 3) display_stat = 0;
  }

  context.draw_text(white_small_text, caption_buf, Vector(WMAP_INFO_LEFT_X, WMAP_INFO_TOP_Y2), LEFT_ALLIGN, LAYER_GUI);
  context.draw_text(white_small_text, stat_buf, Vector(WMAP_INFO_RIGHT_X, WMAP_INFO_TOP_Y2), RIGHT_ALLIGN, LAYER_GUI);
  context.pop_transform();
}