static void
update_rect(SDL_Rect *fill, int x, int y, int w, int h, int idx, int level)
{
    SDL_Rect r = {x, y, w, h};
    int nw = w / 2;
    int nh = h / 2;
    int area = 0;

    assert((unsigned)idx < dirty_tree_length);

    /* PRUNING: see if already dirty */
    if (dirty_tree[idx])
        return;

    /* PRUNING: check if covered area > AV_DTREE_FILL_RATIO */
    area = intersect_area(fill, &r);
    if (area == 0)
        return;
    else if (level == AV_DTREE_DEPTH
            || area > AV_DTREE_FILL_RATIO * h * w)
    {
        dirty_tree[idx] = 1;
        return;
    }

    idx *= 4;
    level += 1;

    update_rect(fill, x,      y,      nw,     nh,     idx + 1, level);
    update_rect(fill, x + nw, y,      w - nw, nh,     idx + 2, level);
    update_rect(fill, x,      y + nh, nw,     h - nh, idx + 3, level);
    update_rect(fill, x + nw, y + nh, w - nw, h - nh, idx + 4, level);
}
void textbox::draw_contents()
{
	SDL_Rect const &loc = inner_location();

	surface surf = video().getSurface();
	draw_solid_tinted_rectangle(loc.x,loc.y,loc.w,loc.h,0,0,0,
				    focus(NULL) ? alpha_focus_ : alpha_, surf);

	SDL_Rect src;

	if(text_image_ == NULL) {
		update_text_cache(true);
	}

	if(text_image_ != NULL) {
		src.y = yscroll_;
		src.w = std::min<size_t>(loc.w,text_image_->w);
		src.h = std::min<size_t>(loc.h,text_image_->h);
		src.x = text_pos_;
		SDL_Rect dest = screen_area();
		dest.x = loc.x;
		dest.y = loc.y;

		// Fills the selected area
		if(is_selection()) {
			const int start = std::min<int>(selstart_,selend_);
			const int end = std::max<int>(selstart_,selend_);
			int startx = char_x_[start];
			int starty = char_y_[start];
			const int endx = char_x_[end];
			const int endy = char_y_[end];

			while(starty <= endy) {
				const size_t right = starty == endy ? endx : text_image_->w;
				if(right <= size_t(startx)) {
					break;
				}

				SDL_Rect rect = create_rect(loc.x + startx
						, loc.y + starty - src.y
						, right - startx
						, line_height_);

				const clip_rect_setter clipper(surf, &loc);

				Uint32 color = SDL_MapRGB(surf->format, 0, 0, 160);
				fill_rect_alpha(rect, color, 140, surf);

				starty += int(line_height_);
				startx = 0;
			}
		}

		sdl_blit(text_image_, &src, surf, &dest);
	}

	draw_cursor((cursor_pos_ == 0 ? 0 : cursor_pos_ - 1), video());

	update_rect(loc);
}
int
SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, bool update)
{
  SDL_Rect dest;

  dest.x = (int)x;
  dest.y = (int)y;
  dest.w = (int)sw;
  dest.h = (int)sh;

  if(alpha != 255)
    SDL_SetAlpha(sdl_surface ,SDL_SRCALPHA,alpha);


  SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
                                  sw, sh, sdl_surface->format->BitsPerPixel,
                                  sdl_surface->format->Rmask, sdl_surface->format->Gmask,
                                  sdl_surface->format->Bmask,
                                  0);

  SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
  SDL_SoftStretch(sdl_surface_copy, NULL, sdl_surface_copy, &dest);

  int ret = SDL_BlitSurface(sdl_surface_copy,NULL,screen,&dest);
  SDL_FreeSurface(sdl_surface_copy);

  if (update == UPDATE)
    update_rect(screen, dest.x, dest.y, dest.w, dest.h);

  return ret;
}
示例#4
0
文件: halo.cpp 项目: N4tr0n/wesnoth
void halo_impl::effect::unrender()
{
	if (!surf_ || !buffer_) {
		return;
	}

	// Shrouded haloes are never rendered unless shroud has been re-placed; in
	// that case, unrendering causes the hidden terrain (and previous halo
	// frame, when dealing with animated halos) to glitch through shroud. We
	// don't need to unrender them because shroud paints over the underlying
	// area anyway.
	if (loc_.x != -1 && loc_.y != -1 && disp->shrouded(loc_)) {
		return;
	}

	surface& screen = disp->get_screen_surface();

	SDL_Rect clip_rect = disp->map_outside_area();
	const clip_rect_setter clip_setter(screen, &clip_rect);

	// Due to scrolling, the location of the rendered halo
	// might have changed; recalculate
	const int screenx = disp->get_location_x(map_location::ZERO());
	const int screeny = disp->get_location_y(map_location::ZERO());

	const int xpos = x_ + screenx - surf_->w/2;
	const int ypos = y_ + screeny - surf_->h/2;

	SDL_Rect rect = sdl::create_rect(xpos, ypos, surf_->w, surf_->h);
	sdl_blit(buffer_,nullptr,screen,&rect);
	update_rect(rect);
}
示例#5
0
void VNCCanvas::onPaint(wxPaintEvent &WXUNUSED(event))
{
  // this happens on GTK even if our size is (0,0)
  if(GetSize().GetWidth() == 0 || GetSize().GetHeight() == 0)
    return;

  wxPaintDC dc(this);

  // get the update rect list
  wxRegionIterator upd(GetUpdateRegion()); 
  while(upd)
    {
      wxRect update_rect(upd.GetRect());
     
      wxLogDebug(wxT("VNCCanvas %p: got repaint event: (%i,%i,%i,%i)"),
		 this,
		 update_rect.x,
		 update_rect.y,
		 update_rect.width,
		 update_rect.height);
      
    
      const wxBitmap& region = conn->getFrameBufferRegion(update_rect);
      if(region.IsOk())
	dc.DrawBitmap(region, update_rect.x, update_rect.y);
	
      ++upd;
    }
}
示例#6
0
bool part_ui::render_floating_images()
{
	events::raise_draw_event();
	update_whole_screen();

	skip_ = false;
	last_key_ = true;

	size_t fi_n = 0;
	foreach(floating_image::render_input& ri, imgs_) {
		const floating_image& fi = p_.get_floating_images()[fi_n];

		if(!ri.image.null()) {
			sdl_blit(ri.image, NULL, video_.getSurface(), &ri.rect);
			update_rect(ri.rect);
		}

		if (!skip_)
		{
			int delay = fi.display_delay(), delay_step = 20;
			for (int i = 0; i != (delay + delay_step - 1) / delay_step; ++i)
			{
				if (handle_interface()) return false;
				if (skip_) break;
				disp_.delay(std::min<int>(delay_step, delay - i * delay_step));
			}
		}

		++fi_n;
	}

	return true;
}
示例#7
0
void help_text_area::draw_contents()
{
	SDL_Rect const &loc = inner_location();
	bg_restore();
	surface screen = video().getSurface();
	clip_rect_setter clip_rect_set(screen, &loc);
	for(std::list<item>::const_iterator it = items_.begin(), end = items_.end(); it != end; ++it) {
		SDL_Rect dst = it->rect;
		dst.y -= get_position();
		if (dst.y < static_cast<int>(loc.h) && dst.y + it->rect.h > 0) {
			dst.x += loc.x;
			dst.y += loc.y;
			if (it->box) {
				for (int i = 0; i < box_width; ++i) {
					sdl::draw_rectangle(dst.x, dst.y, it->rect.w - i * 2, it->rect.h - i * 2,
					                    0, screen);
					++dst.x;
					++dst.y;
				}
			}
			sdl_blit(it->surf, NULL, screen, &dst);
		}
	}
	update_rect(loc);
}
示例#8
0
/**
 *  Fade-in the wesnoth-logo.
 *
 *  Animation-effect: scroll-in from right. \n
 *  Used only once, after the game is started.
 *
 *  @param	screen	surface to operate on
 *  @param	xpos	x-position of logo
 *  @param	ypos	y-position of logo
 *
 *  @return		Result of running the routine
 *  @retval true	operation finished (successful or not)
 *  @retval false	operation failed (because modeChanged), need to retry
 */
static bool fade_logo(game_display& screen, int xpos, int ypos)
{
	const surface logo(image::get_image(game_config::game_logo));
	if(logo == NULL) {
		ERR_DP << "Could not find game logo\n";
		return true;
	}

	surface const fb = screen.video().getSurface();

	if(fb == NULL || xpos < 0 || ypos < 0 || xpos + logo->w > fb->w || ypos + logo->h > fb->h) {
		return true;
	}

	// Only once, when the game is first started, the logo fades in unless
	// it was disabled in adv. preferences
	static bool faded_in = !preferences::startup_effect();
//	static bool faded_in = true;	// for faster startup: mark logo as 'has already faded in'

	CKey key;
	bool last_button = key[SDLK_ESCAPE] || key[SDLK_SPACE];

	LOG_DP << "fading logo in....\n";
	LOG_DP << "logo size: " << logo->w << "," << logo->h << "\n";

	for(int x = 0; x != logo->w; ++x) {
		SDL_Rect srcrect = {x,0,1,logo->h};
		SDL_Rect dstrect = {xpos+x,ypos,1,logo->h};
		SDL_BlitSurface(logo,&srcrect,fb,&dstrect);

		update_rect(dstrect);

		if(!faded_in && (x%5) == 0) {

			const bool new_button = key[SDLK_ESCAPE] || key[SDLK_SPACE] ||
									key[SDLK_RETURN] || key[SDLK_KP_ENTER] ;
			if(new_button && !last_button) {
				faded_in = true;
			}

			last_button = new_button;

			screen.update_display();
			screen.delay(10);

			events::pump();
			if(screen.video().modeChanged()) {
				faded_in = true;
				return false;
			}
		}

	}

	LOG_DP << "logo faded in\n";

	faded_in = true;
	return true;
}
示例#9
0
void menu::draw()
{
	if(hidden()) {
		return;
	}

	if(!dirty()) {

		for(std::set<int>::const_iterator i = invalid_.begin(); i != invalid_.end(); ++i) {
			if(*i == -1) {
				SDL_Rect heading_rect = inner_location();
				heading_rect.h = heading_height();
				bg_restore(heading_rect);
				style_->draw_row(*this,0,heading_rect,HEADING_ROW);
				update_rect(heading_rect);
			} else if(*i >= 0 && *i < int(item_pos_.size())) {
				const unsigned int pos = item_pos_[*i];
				const SDL_Rect& rect = get_item_rect(*i);
				bg_restore(rect);
				style_->draw_row(*this,pos,rect,
					(!out_ && pos == selected_) ? SELECTED_ROW : NORMAL_ROW);
				update_rect(rect);
			}
		}

		invalid_.clear();
		return;
	}

	invalid_.clear();

	bg_restore();

	util::scoped_ptr<clip_rect_setter> clipper(NULL);
	if(clip_rect())
		clipper.assign(new clip_rect_setter(video().getSurface(), *clip_rect()));

	draw_contents();

	update_rect(location());
	set_dirty(false);
}
示例#10
0
void button::draw_contents()
{
	surface image = image_;
	const int image_w = image_->w;

	int offset = 0;
	switch(state_) {
	case ACTIVE:
		image = activeImage_;
		break;
	case PRESSED:
		image = pressedImage_;
		if (type_ == TYPE_PRESS)
			offset = 1;
		break;
	case PRESSED_ACTIVE:
		image = pressedActiveImage_;
		break;
	default:
		break;
	}

	SDL_Rect const &loc = location();
	SDL_Rect clipArea = loc;
	const int texty = loc.y + loc.h / 2 - textRect_.h / 2 + offset;
	int textx;

	if (type_ != TYPE_CHECK)
		textx = loc.x + image->w / 2 - textRect_.w / 2 + offset;
	else {
		clipArea.w += image_w + checkbox_horizontal_padding;
		textx = loc.x + image_w + checkbox_horizontal_padding / 2;
	}

	SDL_Color button_color = font::BUTTON_COLOR;

	if (!enabled()) {
		static const Uint32 disabled_btn_color = 0xAAAAAA;
		static const double disabled_btn_adjust = 0.18;
		image = blend_surface(greyscale_image(image), disabled_btn_adjust, disabled_btn_color);
		button_color = font::GRAY_COLOR;
	}

	video().blit_surface(loc.x, loc.y, image);
	if (type_ != TYPE_IMAGE){
		clipArea.x += offset;
		clipArea.y += offset;
		clipArea.w -= 2*offset;
		clipArea.h -= 2*offset;
		font::draw_text(&video(), clipArea, font_size, button_color, label_, textx, texty);
	}

	update_rect(loc);
}
示例#11
0
void the_end(display &disp, std::string text, unsigned int duration)
{
	//
	// Some sane defaults.
	//
	if(text.empty())
		text = _("The End");
	if(!duration)
		duration = 3500;

	SDL_Rect area = screen_area();
	CVideo &video = disp.video();
	sdl_fill_rect(video.getSurface(),&area,0);

	update_whole_screen();
	disp.flip();

	const size_t font_size = font::SIZE_XLARGE;

	area = font::text_area(text,font_size);
	area.x = screen_area().w/2 - area.w/2;
	area.y = screen_area().h/2 - area.h/2;

	for(size_t n = 0; n < 255; n += 5) {
		if(n)
			sdl_fill_rect(video.getSurface(),&area,0);

		const SDL_Color col = create_color(n, n, n, n);
		font::draw_text(&video,area,font_size,col,text,area.x,area.y);
		update_rect(area);

		events::pump();
		events::raise_process_event();
		events::raise_draw_event();
		disp.flip();
		disp.delay(10);
	}

	//
	// Delay after the end of fading.
	// Rounded to multiples of 10.
	//
	unsigned int count = duration/10;
	while(count) {
		events::pump();
		events::raise_process_event();
		events::raise_draw_event();
		disp.flip();
		disp.delay(10);
		--count;
	}
}
int
SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, bool update)
{
  SDL_Rect src, dest;

  src.x = (int)sx;
  src.y = (int)sy;
  src.w = (int)w;
  src.h = (int)h;

  dest.x = (int)x;
  dest.y = (int)y;
  dest.w = (int)w;
  dest.h = (int)h;

  if(alpha != 255)
    {
    /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
      to temp sur, blit the temp into the screen */
    /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
      already have an alpha mask yet... */

    SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
                                    sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
                                    sdl_surface->format->Rmask, sdl_surface->format->Gmask,
                                    sdl_surface->format->Bmask,
                                    0);
    int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
    SDL_FillRect(sdl_surface_copy, NULL, colorkey);
    SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);


    SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
    SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);

    int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);

    if (update == UPDATE)
      SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);

    SDL_FreeSurface (sdl_surface_copy);
    return ret;
    }

  int ret = SDL_BlitSurface(sdl_surface, &src, screen, &dest);

  if (update == UPDATE)
    update_rect(screen, dest.x, dest.y, dest.w, dest.h);

  return ret;
}
示例#13
0
void widget::draw()
{
	if (hidden() || !dirty())
		return;

	bg_restore();

	clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);

	draw_contents();

	update_rect(rect_);
	set_dirty(false);
}
示例#14
0
void undraw(surface screen)
{
	if(use_colour_cursors() == false) {
		return;
	}

	if(cursor_buf == NULL) {
		return;
	}

	SDL_Rect area = {cursor_x - shift_x[current_cursor], cursor_y - shift_y[current_cursor],cursor_buf->w,cursor_buf->h};
	SDL_BlitSurface(cursor_buf,NULL,screen,&area);
	update_rect(area);
}
示例#15
0
void widget::bg_restore() const
{
	clip_rect_setter clipper(video().getSurface(), &clip_rect_, clip_);

	if (needs_restore_) {
		for(std::vector< surface_restorer >::const_iterator i = restorer_.begin(),
		    i_end = restorer_.end(); i != i_end; ++i)
			i->restore();
		needs_restore_ = false;
	} else {
		//this function should be able to be relied upon to update the rectangle,
		//so do that even if we don't restore
		update_rect(rect_);
	}
}
示例#16
0
void widget::draw()
{
	if (hidden() || !dirty())
		return;

	bg_restore();

	util::scoped_ptr<clip_rect_setter> clipper(NULL);
	if (clip_)
		clipper.assign(new clip_rect_setter(video().getSurface(), clip_rect_));

	draw_contents();

	update_rect(rect_);
	set_dirty(false);
}
示例#17
0
void create::draw_level_image()
{
    boost::scoped_ptr<surface> image(
        engine_.current_level().create_image_surface(image_rect_));

    if (image.get() != NULL) {
        SDL_Color back_color = {0,0,0,255};
        draw_centered_on_background(*image, image_rect_, back_color,
                                    video().getSurface());
    } else {
        surface display(disp_.get_screen_surface());
        sdl_fill_rect(display, &image_rect_,
                      SDL_MapRGB(display->format, 0, 0, 0));
        update_rect(image_rect_);

    }
}
示例#18
0
	BOOST_FOREACH(mouse_action_map::value_type a, mouse_actions_) {
		if (a.second->toolbar_button() != NULL) {
			SDL_Rect r = a.second->toolbar_button()->location(gui_.screen_area());
			SDL_Rect outline = create_rect(r.x - 2, r.y - 2, r.h + 4, r.w + 4);
			//TODO comment or remove
			//outline = intersect_rects(r, gui().screen_area());
			surface screen = gui_.video().getSurface();
			Uint32 color;
			if (a.second == mouse_action_) {
				color = SDL_MapRGB(screen->format, 0xFF, 0x00, 0x00);
			} else {
				color = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
			}
			draw_rectangle(outline.x, outline.y, outline.w, outline.h, color, screen);
			update_rect(outline);
		}
	}
示例#19
0
void VNCCanvas::onUpdateTimer(wxTimerEvent& event)
{
#ifdef __WXDEBUG__
  wxLongLong t0 = wxGetLocalTimeMillis();
  size_t nr_rects = 0;
  size_t nr_bytes = 0;
#endif
  
  wxClientDC dc(this);
  
  // get the update rect list
  wxRegionIterator upd(updated_area); 
  while(upd)
    {
      wxRect update_rect(upd.GetRect());
     
      wxLogDebug(wxT("VNCCanvas %p: drawing updated rect: (%i,%i,%i,%i)"),
		 this,
		 update_rect.x,
		 update_rect.y,
		 update_rect.width,
		 update_rect.height);
#ifdef __WXDEBUG__      
      ++nr_rects;
      nr_bytes += update_rect.width * update_rect.height;
#endif

      const wxBitmap& region = conn->getFrameBufferRegion(update_rect);
      if(region.IsOk())
	dc.DrawBitmap(region, update_rect.x, update_rect.y);
	
      ++upd;
    }

  updated_area.Clear();


#ifdef __WXDEBUG__
  wxLongLong t1 = wxGetLocalTimeMillis();
  wxLogDebug(wxT("VNCCanvas %p: updating %zu rects (%zu bytes) took %lld ms"),
	     this,
	     nr_rects,
	     nr_bytes,
	     (t1-t0).GetValue());
#endif
}
示例#20
0
void dialog_frame::draw_border()
{
	if(have_border_ == false) {
		return;
	}

	surface top_image(scale_surface(top_, dim_.interior.w, top_->h));

	if(top_image != NULL) {
		video_.blit_surface(dim_.interior.x, dim_.exterior.y, top_image);
	}

	surface bot_image(scale_surface(bot_, dim_.interior.w, bot_->h));

	if(bot_image != NULL) {
		video_.blit_surface(dim_.interior.x, dim_.interior.y + dim_.interior.h, bot_image);
	}

	surface left_image(scale_surface(left_, left_->w, dim_.interior.h));

	if(left_image != NULL) {
		video_.blit_surface(dim_.exterior.x, dim_.interior.y, left_image);
	}

	surface right_image(scale_surface(right_, right_->w, dim_.interior.h));

	if(right_image != NULL) {
		video_.blit_surface(dim_.interior.x + dim_.interior.w, dim_.interior.y, right_image);
	}

	update_rect(dim_.exterior);

	if(top_left_ == NULL || bot_left_ == NULL || top_right_ == NULL || bot_right_ == NULL) {
		return;
	}

	video_.blit_surface(dim_.interior.x - left_->w, dim_.interior.y - top_->h, top_left_);
	video_.blit_surface(dim_.interior.x - left_->w, dim_.interior.y + dim_.interior.h + bot_->h - bot_left_->h, bot_left_);
	video_.blit_surface(dim_.interior.x + dim_.interior.w + right_->w - top_right_->w, dim_.interior.y - top_->h, top_right_);
	video_.blit_surface(dim_.interior.x + dim_.interior.w + right_->w - bot_right_->w, dim_.interior.y + dim_.interior.h + bot_->h - bot_right_->h, bot_right_);
}
示例#21
0
void pdf_set_text_annot_position(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point pt)
{
	fz_matrix ctm;
	fz_rect rect;
	int flags;

	fz_invert_matrix(&ctm, &annot->page->ctm);
	rect.x0 = pt.x;
	rect.x1 = pt.x + TEXT_ANNOT_SIZE;
	rect.y0 = pt.y;
	rect.y1 = pt.y + TEXT_ANNOT_SIZE;
	fz_transform_rect(&rect, &ctm);

	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));

	flags = pdf_to_int(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_F));
	flags |= (F_NoZoom|F_NoRotate);
	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_F, pdf_new_int(ctx, doc, flags));

	update_rect(ctx, annot);
}
LEVEL_RESULT playsingle_controller::play_scenario(
	const config::const_child_itors &story,
	bool skip_replay)
{
	LOG_NG << "in playsingle_controller::play_scenario()...\n";

	// Start music.
	foreach (const config &m, level_.child_range("music")) {
		sound::play_music_config(m);
	}
	sound::commit_music_changes();

	if(!skip_replay) {
		show_story(*gui_, level_["name"], story);
	}
	gui_->labels().read(level_);

	// Read sound sources
	assert(soundsources_manager_ != NULL);
	foreach (const config &s, level_.child_range("sound_source")) {
		soundsource::sourcespec spec(s);
		soundsources_manager_->add(spec);
	}

	set_victory_when_enemies_defeated(level_["victory_when_enemies_defeated"].to_bool(true));
	end_level_data &end_level = get_end_level_data();
	end_level.carryover_percentage = level_["carryover_percentage"].to_int(game_config::gold_carryover_percentage);
	end_level.carryover_add = level_["carryover_add"].to_bool();

	bool past_prestart = false;

	LOG_NG << "entering try... " << (SDL_GetTicks() - ticks_) << "\n";
	try {

		fire_prestart(!loading_game_);
		init_gui();

		past_prestart = true;

		LOG_NG << "first_time..." << (recorder.is_skipping() ? "skipping" : "no skip") << "\n";

		events::raise_draw_event();
		fire_start(!loading_game_);
		gui_->recalculate_minimap();

		replaying_ = (recorder.at_end() == false);

		LOG_NG << "starting main loop\n" << (SDL_GetTicks() - ticks_) << "\n";

		// Initialize countdown clock.
		std::vector<team>::iterator t;
		for(t = teams_.begin(); t != teams_.end(); ++t) {
			if (gamestate_.mp_settings().mp_countdown && !loading_game_ ){
				t->set_countdown_time(1000 * gamestate_.mp_settings().mp_countdown_init_time);
			}
		}

		// if we loaded a save file in linger mode, skip to it.
		if (linger_) {
			//determine the bonus gold handling for this scenario
			end_level.read(level_.child_or_empty("endlevel"));
			end_level.carryover_report = false;
			end_level.disabled = true;
			throw end_level_exception(SKIP_TO_LINGER);
		}

		// Avoid autosaving after loading, but still
		// allow the first turn to have an autosave.
		bool save = !loading_game_;
		ai_testing::log_game_start();
		for(; ; first_player_ = 1) {
			play_turn(save);
			save = true;
		} //end for loop

#ifdef _MSC_VER
//MSVC claims that const game::load_game_exception& lge would be unreferenced...
#pragma warning (push)
#pragma warning (disable : 4101)
#endif
	} catch(const game::load_game_exception& lge) {
		// Loading a new game is effectively a quit.
		//
		if (lge.game != "") {
			gamestate_ = game_state();
		}
		throw;
	} catch (end_level_exception &end_level_exn) {
		if(!past_prestart) {
			draw_solid_tinted_rectangle(
				0, 0, gui_->video().getx(), gui_->video().gety(), 0, 0, 0, 1.0,
				gui_->video().getSurface()
			);
			update_rect(0, 0, gui_->video().getx(), gui_->video().gety());
		}

		ai_testing::log_game_end();
		LEVEL_RESULT end_level_result = end_level_exn.result;
		if (!end_level.custom_endlevel_music.empty()) {
			if (end_level_result == DEFEAT) {
				set_defeat_music_list(end_level.custom_endlevel_music);
			} else {
				set_victory_music_list(end_level.custom_endlevel_music);
			}
		}

		if (teams_.empty())
		{
			//store persistent teams
			gamestate_.snapshot = config();
			store_recalls();

			return VICTORY; // this is probably only a story scenario, i.e. has its endlevel in the prestart event
		}
		const bool obs = is_observer();
		if (game_config::exit_at_end) {
			exit(0);
		}
		if (end_level_result == DEFEAT || end_level_result == VICTORY)
		{
			gamestate_.classification().completion = (end_level_exn.result == VICTORY) ? "victory" : "defeat";
			// If we're a player, and the result is victory/defeat, then send
			// a message to notify the server of the reason for the game ending.
			if (!obs) {
				config cfg;
				config& info = cfg.add_child("info");
				info["type"] = "termination";
				info["condition"] = "game over";
				info["result"] = gamestate_.classification().completion;
				network::send_data(cfg, 0);
			} else {
				gui2::show_transient_message(gui_->video(),_("Game Over"),
									_("The game is over."));
				return OBSERVER_END;
			}
		}

		if (end_level_result == QUIT) {
			return QUIT;
		}
		else if (end_level_result == DEFEAT)
		{
			gamestate_.classification().completion = "defeat";
			game_events::fire("defeat");

			if (!obs) {
				const std::string& defeat_music = select_defeat_music();
				if(defeat_music.empty() != true)
					sound::play_music_once(defeat_music);

				return DEFEAT;
			} else {
				return QUIT;
			}
		}
		else if (end_level_result == VICTORY)
		{
			gamestate_.classification().completion =
				!end_level.linger_mode ? "running" : "victory";
			game_events::fire("victory");

			//
			// Play victory music once all victory events
			// are finished, if we aren't observers.
			//
			// Some scenario authors may use 'continue'
			// result for something that is not story-wise
			// a victory, so let them use [music] tags
			// instead should they want special music.
			//
			if (!obs && end_level.linger_mode) {
				const std::string& victory_music = select_victory_music();
				if(victory_music.empty() != true)
					sound::play_music_once(victory_music);
			}

			// Add all the units that survived the scenario.
			LOG_NG << "Add units that survived the scenario to the recall list.\n";
			for(unit_map::iterator un = units_.begin(); un != units_.end(); ++un) {

				if (teams_[un->side() - 1].persistent()) {
					LOG_NG << "Added unit " << un->id() << ", " << un->name() << "\n";
					un->new_turn();
					un->new_scenario();
					teams_[un->side() - 1].recall_list().push_back(*un);
				}
			}
			//store all units that survived (recall list for the next scenario) in snapshot
			gamestate_.snapshot = config();
			store_recalls();
			//store gold and report victory
			store_gold(obs);
			return VICTORY;
		}
		else if (end_level_result == SKIP_TO_LINGER)
		{
			LOG_NG << "resuming from loaded linger state...\n";
			//as carryover information is stored in the snapshot, we have to re-store it after loading a linger state
			gamestate_.snapshot = config();
			store_recalls();
			store_gold();
			return VICTORY;
		}
	} // end catch
	catch(network::error& e) {
		bool disconnect = false;
		if(e.socket) {
			e.disconnect();
			disconnect = true;
		}

		savegame::game_savegame save(gamestate_, *gui_, to_config(), preferences::compress_saves());
		save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO);
		if(disconnect) {
			throw network::error();
		} else {
			return QUIT;
		}
	}

	return QUIT;
}
示例#23
0
文件: pgrid.cpp 项目: jkroll20/pgrid
void t_pgrid::run()
{
    bool quit= false;
    
    setvbuf(stdout, 0, _IONBF, 0);
    
    SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
    SDL_WM_SetCaption("pgrid", "pgrid");
    
    lastmillis= curmillis= SDL_GetTicks();
    SDL_ShowCursor(0);
    SDL_EnableUNICODE(true);
    
    gui= new flux_gui();
    
    bool guimouse= false;
    
    while(!quit)
    {
	lastframephystime= physicstime;
	lastmillis= curmillis;
	curmillis= SDL_GetTicks();
	
	SDL_Event event;
	while(SDL_PollEvent(&event))
	{
	    switch(event.type)
	    {
		case SDL_KEYDOWN:
		case SDL_KEYUP:
		{
		    if(event.key.keysym.sym==SDLK_ESCAPE) quit= true;
		    
		    if(wnd_getkbdfocus()!=NOWND)
		    {
			flux_keyboard_event(event.type==SDL_KEYDOWN, event.key.keysym.sym, event.key.keysym.unicode&0x7F);
		    }
		    else
		    {
			current_workspace()->keyboard_event(event.key);
			editor->keyboard_event(event.key);
			for(t_dyninputhandler_list::iterator i= dyninputhandlers.begin(); i!=dyninputhandlers.end(); i++)
			    (*i)->keyboard_event(event.key);
		    }
		    
		    keystate[event.key.keysym.sym]= (event.key.state==SDL_PRESSED? 1: 0);
		    break;
		}
		
		case SDL_MOUSEMOTION:
		    flux_mouse_move_event(event.motion.xrel, event.motion.yrel);
		    
		    if( find_prim_pos(event.motion.x, event.motion.y, true) || 
			find_mouse_handler(event.motion.x, event.motion.y) )
			guimouse= true;
		    else
		    {
			guimouse= false;
			mouse.x= event.motion.x;
			mouse.y= event.motion.y;
			mouse.buttons= event.motion.state;
			current_workspace()->mouse_motion_event(event.motion);
			editor->mouse_motion_event(event.motion);
			for(t_dyninputhandler_list::iterator i= dyninputhandlers.begin(); i!=dyninputhandlers.end(); i++)
			    (*i)->mouse_motion_event(event.motion);
		    }
		    break;
		
		case SDL_MOUSEBUTTONUP:
		case SDL_MOUSEBUTTONDOWN:
		{
		    int b= event.button.button;
		    int fluxbutton= (b==SDL_BUTTON_RIGHT? 2: b==SDL_BUTTON_MIDDLE? 3: b)-1;
		    flux_mouse_button_event(fluxbutton, event.type==SDL_MOUSEBUTTONDOWN);
		    
		    if( find_prim_pos(event.button.x, event.button.y, true) || 
			find_mouse_handler(event.button.x, event.button.y) )
		    {
		    	guimouse= true;
		    }
		    else
		    {
			guimouse= false;
			wnd_setkbdfocus(NOWND);
			if(event.type==SDL_MOUSEBUTTONUP)
			    mouse.buttons&= ~(SDL_BUTTON(event.button.button));
			else
			    mouse.buttons|= SDL_BUTTON(event.button.button);
			mouse.x= event.button.x;
			mouse.y= event.button.y;
			current_workspace()->mouse_button_event(event.button);
			editor->mouse_button_event(event.button);
			for(t_dyninputhandler_list::iterator i= dyninputhandlers.begin(); i!=dyninputhandlers.end(); i++)
			    (*i)->mouse_button_event(event.button);
		    }
		    break;
		}

		case SDL_QUIT:
		    quit= true;
		    break;
		
		case SDL_VIDEORESIZE:
		{
		    SDL_Surface *surf= SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_OPENGL|SDL_RESIZABLE);
		    if(!surf) break;
		    screen.sdl_surface= surf;
		    screen.gl_init(event.resize.w, event.resize.h);
		    current_workspace()->centerimage();
		    break;
		}
		
		case SDL_ACTIVEEVENT:
		{
		    if(event.active.state&SDL_APPINPUTFOCUS)
		    {
			hasinputfocus= event.active.gain;
			SDL_ShowCursor(!hasinputfocus);
		    }
		    if(event.active.state&SDL_APPMOUSEFOCUS)
		    	hasmousefocus= event.active.gain;
		    break;
		}
		
		case SDL_VIDEOEXPOSE:
		{
		    if(!hasinputfocus)
		    {
    			glClear(GL_DEPTH_BUFFER_BIT);
			current_workspace()->render();
			SDL_GL_SwapBuffers();
			checkglerror();
		    }
		    break;
		}
	    }
	}
	
	int x, y;
	SDL_GetMouseState(&x, &y);
	mousepos.x= x; mousepos.y= y;

	SDL_GetRelativeMouseState(&x, &y);
	mousevel.x= x; mousevel.y= y;
	mousevel.mul( 1000.0/(curmillis-lastmillis) );
	
	current_workspace()->image->frame_tick((curmillis-lastmillis)*0.001);
	runphysics();
	

    	if(hasinputfocus)
	{
	    glClear(GL_DEPTH_BUFFER_BIT);
	    //~ screen.setperspective();
	    current_workspace()->render();
	    if(hasmousefocus && !guimouse) editor->render();

#if 1
	    next_event();
	    //~ aq_exec();
	    run_timers();
	    
	    glMatrixMode(GL_MODELVIEW);
	    glPushMatrix();
	    glLoadIdentity();
	    
	    glMatrixMode(GL_PROJECTION);
	    glPushMatrix();
	    glLoadIdentity();
	    glOrtho(0, screen.width,screen.height, 0, -1000, 1000);

	    glDisable(GL_DEPTH_TEST);
	    glEnable(GL_BLEND);
	    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	    //~ glEnable(GL_POINT_SMOOTH);
	    //~ glPointSize(1.0);
	    
	    //~ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	    //~ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	    glColor3f(1,1,1);
	    glDisable(GL_TEXTURE_2D);
	    
	    redraw_rect(&viewport);
	    //~ cliptext(0,0,0,0);
	    update_rect(&viewport);

	    glEnable(GL_DEPTH_TEST);
	    glDisable(GL_BLEND);
	    
	    glMatrixMode(GL_PROJECTION);
	    glPopMatrix();
	    glMatrixMode(GL_MODELVIEW);
	    glPopMatrix();
#endif
	    
	    gui->tick( (curmillis-lastmillis)*0.001 );
	    
	    if(guimouse) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glDisable(GL_DEPTH_TEST); redraw_cursor(); }
	    
	    SDL_GL_SwapBuffers();
	    checkglerror();
	}
	
	
	int delay= 10 - (curmillis-lastmillis);
	if(!hasinputfocus) SDL_Delay(100);
	if(delay>0) SDL_Delay(delay);
    }
    
    SDL_WM_GrabInput(SDL_GRAB_OFF);
    
    delete gui;
    gui= 0;
}
示例#24
0
void draw(surface screen)
{
	if(use_color_cursors() == false) {
		return;
	}

	if(current_cursor == NUM_CURSORS) {
		current_cursor = NORMAL;
	}

	if(have_focus == false) {
		cursor_buf = NULL;
		return;
	}

	if (!color_ready) {
		// Display start to draw cursor
		// so it can now display color cursor
		color_ready = true;
		// Reset the cursor to be sure that we hide the b&w
		set();
	}

	/** @todo FIXME: don't parse the file path every time */
	const surface surf(image::get_image("cursors/" + color_images[current_cursor]));
	if(surf == NULL) {
		// Fall back to b&w cursors
		std::cerr << "could not load color cursors. Falling back to hardware cursors\n";
		preferences::set_color_cursors(false);
		return;
	}

	if(cursor_buf != NULL && (cursor_buf->w != surf->w || cursor_buf->h != surf->h)) {
		cursor_buf = NULL;
	}

	if(cursor_buf == NULL) {
		cursor_buf = create_compatible_surface(surf);
		if(cursor_buf == NULL) {
			std::cerr << "Could not allocate surface for mouse cursor\n";
			return;
		}
	}

	int new_cursor_x, new_cursor_y;
	SDL_GetMouseState(&new_cursor_x,&new_cursor_y);
	const bool must_update = new_cursor_x != cursor_x || new_cursor_y != cursor_y;
	cursor_x = new_cursor_x;
	cursor_y = new_cursor_y;

	// Save the screen area where the cursor is being drawn onto the back buffer
	SDL_Rect area = create_rect(cursor_x - shift_x[current_cursor]
			, cursor_y - shift_y[current_cursor]
			, surf->w
			, surf->h);
	sdl_blit(screen,&area,cursor_buf,NULL);

	// Blit the surface
	sdl_blit(surf,NULL,screen,&area);

	if(must_update) {
		update_rect(area);
	}
}
示例#25
0
void loadscreen::draw_screen(const std::string &text)
{
	// Set progress bar parameters:
	//
	// RGB-values for finished piece.
	int fcr =  21, fcg =  53, fcb =  80;
	// Groove.
	int lcr =  21, lcg =  22, lcb =  24;
	// Border color.
	int bcr = 188, bcg = 176, bcb = 136;
	// Border width.
	int bw = 1;
	// Border inner spacing width.
	int bispw = 1;
	bw = 2*(bw+bispw) > screen_.getx() ? 0: 2*(bw+bispw) > screen_.gety() ? 0: bw;
	// Available width.
	int scrx = screen_.getx() - 2*(bw+bispw);
	// Available height.
	int scry = screen_.gety() - 2*(bw+bispw);
	// Used width.
	int pbw = scrx/2;
	// Used height.
	int pbh = scry/16;
	// Height of the lighting line.
	int	lightning_thickness = 2;

	surface gdis = screen_.getSurface();
	SDL_Rect area;

	// Pump events and make sure to redraw the logo if there's a chance that it's been obscured
	SDL_Event ev;
	while(SDL_PollEvent(&ev)) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
		if(ev.type == SDL_WINDOWEVENT
				&& (ev.window.event == SDL_WINDOWEVENT_RESIZED
					|| ev.window.event == SDL_WINDOWEVENT_EXPOSED))
#else
		if(ev.type == SDL_VIDEORESIZE || ev.type == SDL_VIDEOEXPOSE)
#endif
		{
			logo_drawn_ = false;
		}
	}

	// Draw logo if it was successfully loaded.
#if SDL_VERSION_ATLEAST(2,0,0)
	static int angle = 0;
	if (!logo_texture_.null() /*&& !logo_drawn_*/) {
		int x = (screen_.getx () - logo_texture_.width()) / 2;
		int y = ((scry - logo_texture_.height()) / 2) - pbh;

		// Check if we have enough pixels to display it.
		if (x > 0 && y > 0) {
			pby_offset_ = (pbh + logo_texture_.height())/2;
			CVideo::get_window()->draw(logo_texture_, x, y);
		} else {
			if (!screen_.faked()) {  // Avoid error if --nogui is used.
				ERR_DP << "loadscreen: Logo image is too big." << std::endl;
			}
		}
		logo_drawn_ = true;
		logo_texture_.set_rotation(angle+=3);
	}
#else
	if (logo_surface_ && !logo_drawn_) {
		area.x = (screen_.getx () - logo_surface_->w) / 2;
		area.y = ((scry - logo_surface_->h) / 2) - pbh;
		area.w = logo_surface_->w;
		area.h = logo_surface_->h;
		// Check if we have enough pixels to display it.
		if (area.x > 0 && area.y > 0) {
			pby_offset_ = (pbh + area.h)/2;
			sdl_blit(logo_surface_, 0, gdis, &area);
		} else {
			if (!screen_.faked()) {  // Avoid error if --nogui is used.
				ERR_DP << "loadscreen: Logo image is too big." << std::endl;
			}
		}
		logo_drawn_ = true;
		update_rect(area.x, area.y, area.w, area.h);
	}
#endif
	int pbx = (scrx - pbw)/2;					// Horizontal location.
	int pby = (scry - pbh)/2 + pby_offset_;		// Vertical location.

	// Draw top border.
	area.x = pbx; area.y = pby;
	area.w = pbw + 2*(bw+bispw); area.h = bw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw bottom border.
	area.x = pbx; area.y = pby + pbh + bw + 2*bispw;
	area.w = pbw + 2*(bw+bispw); area.h = bw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw left border.
	area.x = pbx; area.y = pby + bw;
	area.w = bw; area.h = pbh + 2*bispw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw right border.
	area.x = pbx + pbw + bw + 2*bispw; area.y = pby + bw;
	area.w = bw; area.h = pbh + 2*bispw;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
	// Draw the finished bar area.
	area.x = pbx + bw + bispw; area.y = pby + bw + bispw;
	area.w = (prcnt_ * pbw) / 100; area.h = pbh;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,fcr,fcg,fcb));

	SDL_Rect lightning = area;
	lightning.h = lightning_thickness;
	//we add 25% of white to the color of the bar to simulate a light effect
	sdl::fill_rect(gdis,&lightning,SDL_MapRGB(gdis->format,(fcr*3+255)/4,(fcg*3+255)/4,(fcb*3+255)/4));
	lightning.y = area.y+area.h-lightning.h;
	//remove 50% of color to simulate a shadow effect
	sdl::fill_rect(gdis,&lightning,SDL_MapRGB(gdis->format,fcr/2,fcg/2,fcb/2));

	// Draw the leftover bar area.
	area.x = pbx + bw + bispw + (prcnt_ * pbw) / 100; area.y = pby + bw + bispw;
	area.w = ((100 - prcnt_) * pbw) / 100; area.h = pbh;
	sdl::fill_rect(gdis,&area,SDL_MapRGB(gdis->format,lcr,lcg,lcb));

	// Clear the last text and draw new if text is provided.
	if (!text.empty())
	{
		SDL_Rect oldarea = textarea_;
		sdl::fill_rect(gdis,&textarea_,SDL_MapRGB(gdis->format,0,0,0));
		textarea_ = font::line_size(text, font::SIZE_NORMAL);
		textarea_.x = scrx/2 + bw + bispw - textarea_.w / 2;
		textarea_.y = pby + pbh + 4*(bw + bispw);
		textarea_ = font::draw_text(&screen_,textarea_,font::SIZE_NORMAL,font::NORMAL_COLOR,text,textarea_.x,textarea_.y);
		SDL_Rect refresh = sdl::union_rects(oldarea, textarea_);
		update_rect(refresh.x, refresh.y, refresh.w, refresh.h);
	}
	// Update the rectangle.
	update_rect(pbx, pby, pbw + 2*(bw + bispw), pbh + 2*(bw + bispw));
	screen_.flip();
#if SDL_VERSION_ATLEAST(2,0,0)
	CVideo::get_window()->render();
#endif
}
示例#26
0
void pdf_set_free_text_details(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3])
{
	char nbuf[32];
	pdf_obj *dr;
	pdf_obj *form_fonts;
	pdf_obj *font = NULL;
	pdf_obj *ref;
	pdf_font_desc *font_desc = NULL;
	pdf_da_info da_info;
	fz_buffer *fzbuf = NULL;
	fz_matrix ctm;
	fz_point page_pos;

	fz_invert_matrix(&ctm, &annot->page->ctm);

	dr = pdf_dict_get(ctx, annot->page->me, PDF_NAME_Resources);
	if (!dr)
	{
		dr = pdf_new_dict(ctx, doc, 1);
		pdf_dict_put_drop(ctx, annot->page->me, PDF_NAME_Resources, dr);
	}

	/* Ensure the resource dictionary includes a font dict */
	form_fonts = pdf_dict_get(ctx, dr, PDF_NAME_Font);
	if (!form_fonts)
	{
		form_fonts = pdf_new_dict(ctx, doc, 1);
		pdf_dict_put_drop(ctx, dr, PDF_NAME_Font, form_fonts);
		/* form_fonts is still valid if execution continues past the above call */
	}

	fz_var(fzbuf);
	fz_var(font);
	fz_try(ctx)
	{
		unsigned char *da_str;
		int da_len;
		fz_rect bounds;

		find_free_font_name(ctx, form_fonts, nbuf, sizeof(nbuf));

		font = pdf_new_dict(ctx, doc, 5);
		ref = pdf_new_ref(ctx, doc, font);
		pdf_dict_puts_drop(ctx, form_fonts, nbuf, ref);

		pdf_dict_put_drop(ctx, font, PDF_NAME_Type, PDF_NAME_Font);
		pdf_dict_put_drop(ctx, font, PDF_NAME_Subtype, PDF_NAME_Type1);
		pdf_dict_put_drop(ctx, font, PDF_NAME_BaseFont, pdf_new_name(ctx, doc, font_name));
		pdf_dict_put_drop(ctx, font, PDF_NAME_Encoding, PDF_NAME_WinAnsiEncoding);

		memcpy(da_info.col, color, sizeof(float)*3);
		da_info.col_size = 3;
		da_info.font_name = nbuf;
		da_info.font_size = font_size;

		fzbuf = fz_new_buffer(ctx, 0);
		pdf_fzbuf_print_da(ctx, fzbuf, &da_info);

		da_len = fz_buffer_storage(ctx, fzbuf, &da_str);
		pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_DA, pdf_new_string(ctx, doc, (char *)da_str, da_len));

		/* FIXME: should convert to WinAnsiEncoding */
		pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Contents, pdf_new_string(ctx, doc, text, strlen(text)));

		font_desc = pdf_load_font(ctx, doc, NULL, font, 0);
		pdf_measure_text(ctx, font_desc, (unsigned char *)text, strlen(text), &bounds);

		page_pos = *pos;
		fz_transform_point(&page_pos, &ctm);

		bounds.x0 *= font_size;
		bounds.x1 *= font_size;
		bounds.y0 *= font_size;
		bounds.y1 *= font_size;

		bounds.x0 += page_pos.x;
		bounds.x1 += page_pos.x;
		bounds.y0 += page_pos.y;
		bounds.y1 += page_pos.y;

		pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &bounds));
		update_rect(ctx, annot);
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, font);
		fz_drop_buffer(ctx, fzbuf);
		pdf_drop_font(ctx, font_desc);
	}
	fz_catch(ctx)
	{
		fz_rethrow(ctx);
	}
}
示例#27
0
文件: halo.cpp 项目: N4tr0n/wesnoth
bool halo_impl::effect::render()
{
	if(disp == nullptr) {
		return false;
	}

	if(loc_.x != -1 && loc_.y != -1) {
		if(disp->shrouded(loc_)) {
			return false;
		} else {
			// The location of a halo is an x,y value and not a map location.
			// This means when a map is zoomed, the halo's won't move,
			// This glitch is most visible on [item] haloes.
			// This workaround always recalculates the location of the halo
			// (item haloes have a location parameter to hide them under the shroud)
			// and reapplies that location.
			// It might be optimized by storing and comparing the zoom value.
			set_location(
				disp->get_location_x(loc_) + disp->hex_size() / 2,
				disp->get_location_y(loc_) + disp->hex_size() / 2);
		}
	}

	images_.update_last_draw_time();
	surf_.assign(image::get_image(current_image(),image::SCALED_TO_ZOOM));
	if(surf_ == nullptr) {
		return false;
	}
	if(orientation_ == HREVERSE || orientation_ == HVREVERSE) {
		surf_.assign(image::reverse_image(surf_));
	}
	if(orientation_ == VREVERSE || orientation_ == HVREVERSE) {
		surf_.assign(flop_surface(surf_));
	}

	const int screenx = disp->get_location_x(map_location::ZERO());
	const int screeny = disp->get_location_y(map_location::ZERO());

	const int xpos = x_ + screenx - surf_->w/2;
	const int ypos = y_ + screeny - surf_->h/2;

	SDL_Rect rect = sdl::create_rect(xpos, ypos, surf_->w, surf_->h);
	rect_ = rect;
	SDL_Rect clip_rect = disp->map_outside_area();

	// If rendered the first time, need to determine the area affected.
	// If a halo changes size, it is not updated.
	if(location_not_known()) {
		display::rect_of_hexes hexes = disp->hexes_under_rect(rect);
		display::rect_of_hexes::iterator i = hexes.begin(), end = hexes.end();
		for (;i != end; ++i) {
			overlayed_hexes_.push_back(*i);
		}
	}

	if(sdl::rects_overlap(rect,clip_rect) == false) {
		buffer_.assign(nullptr);
		return false;
	}

	surface& screen = disp->get_screen_surface();

	const clip_rect_setter clip_setter(screen, &clip_rect);
	if(buffer_ == nullptr || buffer_->w != rect.w || buffer_->h != rect.h) {
		SDL_Rect rect = rect_;
		buffer_.assign(get_surface_portion(screen,rect));
	} else {
		SDL_Rect rect = rect_;
		sdl_copy_portion(screen,&rect,buffer_,nullptr);
	}

	sdl_blit(surf_,nullptr,screen,&rect);

	update_rect(rect_);

	return true;
}
示例#28
0
void
pdf_set_ink_annot_list(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness)
{
	fz_matrix ctm;
	pdf_obj *list = pdf_new_array(ctx, doc, ncount);
	pdf_obj *bs, *col;
	fz_rect rect;
	int i, k = 0;

	fz_invert_matrix(&ctm, &annot->page->ctm);

	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, list);

	for (i = 0; i < ncount; i++)
	{
		int j;
		pdf_obj *arc = pdf_new_array(ctx, doc, counts[i]);

		pdf_array_push_drop(ctx, list, arc);

		for (j = 0; j < counts[i]; j++)
		{
			fz_point pt = pts[k];

			fz_transform_point(&pt, &ctm);

			if (i == 0 && j == 0)
			{
				rect.x0 = rect.x1 = pt.x;
				rect.y0 = rect.y1 = pt.y;
			}
			else
			{
				fz_include_point_in_rect(&rect, &pt);
			}

			pdf_array_push_drop(ctx, arc, pdf_new_real(ctx, doc, pt.x));
			pdf_array_push_drop(ctx, arc, pdf_new_real(ctx, doc, pt.y));
			k++;
		}
	}

	/*
		Expand the rectangle by thickness all around. We cannot use
		fz_expand_rect because the rectangle might be empty in the
		single point case
	*/
	if (k > 0)
	{
		rect.x0 -= thickness;
		rect.y0 -= thickness;
		rect.x1 += thickness;
		rect.y1 += thickness;
	}

	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));
	update_rect(ctx, annot);

	bs = pdf_new_dict(ctx, doc, 1);
	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_BS, bs);
	pdf_dict_put_drop(ctx, bs, PDF_NAME_W, pdf_new_real(ctx, doc, thickness));

	col = pdf_new_array(ctx, doc, 3);
	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_C, col);
	for (i = 0; i < 3; i++)
		pdf_array_push_drop(ctx, col, pdf_new_real(ctx, doc, color[i]));
}
void progress_bar::draw_contents()
{
	surface surf = video().getSurface();
	SDL_Rect area = location();

	if(area.w >= 2 && area.h >= 2) {
		int fcr =  21, fcg =  53, fcb =  80;		// RGB-values for finished piece.
		int bcr =   0, bcg =   0, bcb =   0;		// Border color.
		int gcr = 255, gcg = 255, gcb = 255;		// Groove color.
		int	lightning_thickness = 2;
		static const SDL_Color selected_text_color = {0xCC,0xCC,0xCC,0};

		SDL_Rect inner_area = create_rect(area.x + 1
				, area.y + 1
				, area.w - 2
				, area.h - 2);

		sdl_fill_rect(surf,&area,SDL_MapRGB(surf->format,bcr,bcg,bcb));
		sdl_fill_rect(surf,&inner_area,SDL_MapRGB(surf->format,gcr,gcg,gcb));

		inner_area.w = (inner_area.w*progress_)/100;
		sdl_fill_rect(surf,&inner_area,SDL_MapRGB(surf->format,fcr,fcg,fcb));

		SDL_Rect lightning = inner_area;
		lightning.h = lightning_thickness;
		//we add 25% of white to the color of the bar to simulate a light effect
		sdl_fill_rect(surf,&lightning,SDL_MapRGB(surf->format,(fcr*3+255)/4,(fcg*3+255)/4,(fcb*3+255)/4));
		lightning.y = inner_area.y+inner_area.h-lightning.h;
		//remove 50% of color to simulate a shadow effect
		sdl_fill_rect(surf,&lightning,SDL_MapRGB(surf->format,fcr/2,fcg/2,fcb/2));

		const std::string text = text_.empty() ? str_cast(progress_) + "%" :
		                         text_ + " (" + str_cast(progress_) + "%)";
		SDL_Rect text_area = font::text_area(text,font::SIZE_NORMAL);

		text_area.x = area.x + area.w/2 - text_area.w/2;
		text_area.y = area.y + area.h/2 - text_area.h/2;

		font::draw_text(
			&video(),
			location(),
			font::SIZE_NORMAL,
			font::BLACK_COLOR,
			text,
			text_area.x,
			text_area.y
		);

		// Draw a white text section for the highlighted area
		// of the bar
		SDL_Rect selected_text_location = location();
		selected_text_location.w = inner_area.w;
		selected_text_location.h = inner_area.h;
		{
			clip_rect_setter clippy(surf, &selected_text_location);
			font::draw_text(
				&video(),
				selected_text_location,
				font::SIZE_NORMAL,
				selected_text_color,
				text,
				text_area.x,
				text_area.y
			);
		}
	}

	update_rect(location());
}
示例#30
0
LEVEL_RESULT playsingle_controller::play_scenario(const config& level)
{
	LOG_NG << "in playsingle_controller::play_scenario()...\n";

	// Start music.
	BOOST_FOREACH(const config &m, level.child_range("music")) {
		sound::play_music_config(m);
	}
	sound::commit_music_changes();

	if(!this->is_skipping_replay()) {
		show_story(gui_->video(), get_scenario_name(), level.child_range("story"));
	}
	gui_->labels().read(level);

	// Read sound sources
	assert(soundsources_manager_ != NULL);
	BOOST_FOREACH(const config &s, level.child_range("sound_source")) {
		try {
			soundsource::sourcespec spec(s);
			soundsources_manager_->add(spec);
		} catch (bad_lexical_cast &) {
			ERR_NG << "Error when parsing sound_source config: bad lexical cast." << std::endl;
			ERR_NG << "sound_source config was: " << s.debug() << std::endl;
			ERR_NG << "Skipping this sound source..." << std::endl;
		}
	}
	LOG_NG << "entering try... " << (SDL_GetTicks() - ticks()) << "\n";
	try {
		play_scenario_init();
		// clears level config;
		this->saved_game_.remove_snapshot();

		if (!is_regular_game_end() && !linger_) {
			play_scenario_main_loop();
		}
		if (game_config::exit_at_end) {
			exit(0);
		}
		const bool is_victory = get_end_level_data_const().is_victory;

		if(gamestate().gamedata_.phase() <= game_data::PRESTART) {
			sdl::draw_solid_tinted_rectangle(
				0, 0, gui_->video().getx(), gui_->video().gety(), 0, 0, 0, 1.0,
				gui_->video().getSurface()
				);
			update_rect(0, 0, gui_->video().getx(), gui_->video().gety());
		}

		ai_testing::log_game_end();

		const end_level_data& end_level = get_end_level_data_const();
		if (!end_level.transient.custom_endlevel_music.empty()) {
			if (!is_victory) {
				set_defeat_music_list(end_level.transient.custom_endlevel_music);
			} else {
				set_victory_music_list(end_level.transient.custom_endlevel_music);
			}
		}

		if (gamestate().board_.teams().empty())
		{
			//store persistent teams
			saved_game_.set_snapshot(config());

			return LEVEL_RESULT::VICTORY; // this is probably only a story scenario, i.e. has its endlevel in the prestart event
		}
		if(linger_) {
			LOG_NG << "resuming from loaded linger state...\n";
			//as carryover information is stored in the snapshot, we have to re-store it after loading a linger state
			saved_game_.set_snapshot(config());
			if(!is_observer()) {
				persist_.end_transaction();
			}
			return LEVEL_RESULT::VICTORY;
		}
		pump().fire(is_victory ? "victory" : "defeat");
		{ // Block for set_scontext_synced_base
			set_scontext_synced_base sync;
			pump().fire("scenario end");
		}
		if(end_level.proceed_to_next_level) {
			gamestate().board_.heal_all_survivors();
		}
		if(is_observer()) {
			gui2::show_transient_message(gui_->video(), _("Game Over"), _("The game is over."));
			return LEVEL_RESULT::OBSERVER_END;
		}
		// If we're a player, and the result is victory/defeat, then send
		// a message to notify the server of the reason for the game ending.
		network::send_data(config_of
			("info", config_of
				("type", "termination")
				("condition", "game over")
				("result", is_victory ? "victory" : "defeat")
			));
		// Play victory music once all victory events
		// are finished, if we aren't observers.
		//
		// Some scenario authors may use 'continue'
		// result for something that is not story-wise
		// a victory, so let them use [music] tags
		// instead should they want special music.
		const std::string& end_music = is_victory ? select_victory_music() : select_defeat_music();
		if(end_music.empty() != true) {
			sound::play_music_once(end_music);
		}
		persist_.end_transaction();
		return is_victory ? LEVEL_RESULT::VICTORY : LEVEL_RESULT::DEFEAT;
	} catch(const game::load_game_exception &) {
		// Loading a new game is effectively a quit.
		//
		if ( game::load_game_exception::game != "" ) {
			saved_game_ = saved_game();
		}
		throw;
	} catch(network::error& e) {
		bool disconnect = false;
		if(e.socket) {
			e.disconnect();
			disconnect = true;
		}

		scoped_savegame_snapshot snapshot(*this);
		savegame::ingame_savegame save(saved_game_, *gui_, preferences::save_compression_format());
		save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO);
		if(disconnect) {
			throw network::error();
		} else {
			return LEVEL_RESULT::QUIT;
		}
	}

	return LEVEL_RESULT::QUIT;
}