Author: alink
Date: Tue Mar 25 05:56:30 2008
New Revision: 25096
URL: http://svn.gna.org/viewcvs/wesnoth?rev=25096&view=rev
Log:
Map screenshot feature for editor and game (with units):
The render engine is rerouted, so most objects are on it. So keep the UI parts
that you can hide by moving your mouse (footsteps, highlighted hex etc...),
may be useful. But don't write map labels (not hideable).
Need a warning because filesize can be really huge (bmp). Dezoom helps that.
PS: a nice useful bug show the minimap rectangle change to include all the map
during the screenshot
Modified:
trunk/src/display.cpp
trunk/src/display.hpp
trunk/src/editor/editor.cpp
trunk/src/editor/editor_display.cpp
trunk/src/filesystem.cpp
trunk/src/filesystem.hpp
trunk/src/game_display.cpp
trunk/src/halo.cpp
trunk/src/hotkeys.cpp
trunk/src/hotkeys.hpp
trunk/src/play_controller.cpp
Modified: trunk/src/display.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/display.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/display.cpp (original)
+++ trunk/src/display.cpp Tue Mar 25 05:56:30 2008
@@ -110,9 +110,11 @@
#else
drawing_buffer_(),
#endif
+ map_screenshot_(false),
fps_handle_(0),
idle_anim_(preferences::idle_anim()),
- idle_anim_rate_(1.0)
+ idle_anim_rate_(1.0),
+ map_screenshot_surf_(NULL)
{
if(non_interactive()) {
screen_.lock_updates(true);
@@ -129,10 +131,9 @@
{
}
-const SDL_Rect& display::map_area() const
-{
- static SDL_Rect res = {0, 0, 0, 0};
- res = map_outside_area();
+const SDL_Rect& display::max_map_area() const
+{
+ static SDL_Rect max_area = {0, 0, 0, 0};
// hex_size() is always a multiple of 4
// and hex_width() a multiple of 3,
@@ -141,19 +142,35 @@
// To display a hex fully on screen,
// a little bit extra space is needed.
// Also added the border two times.
- const int width = static_cast<int>((map_.w() + 2 *
theme_.border().size + 1.0/3.0) * hex_width());
- const int height = static_cast<int>((map_.h() + 2 *
theme_.border().size + 0.5) * hex_size());
-
- if(width < res.w) {
+ max_area.w = static_cast<int>((map_.w() + 2 * theme_.border().size +
1.0/3.0) * hex_width());
+ max_area.h = static_cast<int>((map_.h() + 2 * theme_.border().size +
0.5) * hex_size());
+
+ return max_area;
+}
+
+const SDL_Rect& display::map_area() const
+{
+ static SDL_Rect max_area;
+ max_area = max_map_area();
+
+ // if it's for map_screenshot, maximize and don't recenter
+ if (map_screenshot_) {
+ return max_area;
+ }
+
+ static SDL_Rect res;
+ res = map_outside_area();
+
+ if(max_area.w < res.w) {
// map is smaller, center
- res.x += (res.w - width)/2;
- res.w = width;
- }
-
- if(height < res.h) {
+ res.x += (res.w - max_area.w)/2;
+ res.w = max_area.w;
+ }
+
+ if(max_area.h < res.h) {
// map is smaller, center
- res.y += (res.h - height)/2;
- res.h = height;
+ res.y += (res.h - max_area.h)/2;
+ res.h = max_area.h;
}
return res;
@@ -400,25 +417,53 @@
void display::screenshot()
{
- std::string datadir = get_screenshot_dir();
- static unsigned int counter = 0;
- std::string name;
-
- do {
- std::stringstream filename;
-
- filename << datadir << "/" << _("Screenshot") << "_";
- filename.width(5);
- filename.fill('0');
- filename.setf(std::ios_base::right);
- filename << counter << ".bmp";
-
- counter++;
- name = filename.str();
-
- } while(file_exists(name));
-
- SDL_SaveBMP(screen_.getSurface().get(), name.c_str());
+ static int screenshot_counter = 0;
+ std::string filename = get_screenshot_dir() + "/" + _("Screenshot") +
"_";
+ filename = get_next_filename(filename, ".bmp", screenshot_counter);
+
+ SDL_SaveBMP(screen_.getSurface(), filename.c_str());
+}
+
+void display::map_screenshot()
+{
+ static int map_screenshot_counter = 0;
+ std::string filename = get_screenshot_dir() + "/" + _("Map_Screenshot")
+ "_";
+ filename = get_next_filename(filename, ".bmp", map_screenshot_counter);
+
+ SDL_Rect area = max_map_area();
+ map_screenshot_surf_ = create_compatible_surface(screen_.getSurface(),
area.w, area.h);
+
+ if (map_screenshot_surf_ == NULL) {
+ std::cerr << "Can't create the screenshot surface. Maybe too
big, try dezooming.\n";
+ return;
+ }
+
+ // back up the current map view position and move to top-left
+ int old_xpos = xpos_;
+ int old_ypos = ypos_;
+ xpos_ = 0;
+ ypos_ = 0;
+
+ // we reroute render output to the screenshot surface and invalidate all
+ map_screenshot_= true ;
+ invalidateAll_ = true;
+
+ DBG_DP << "draw() with map_screenshot\n";
+ draw(true,true);
+
+ // save the screenshot surface
+ SDL_SaveBMP(map_screenshot_surf_, filename.c_str());
+ //NOTE: need to be sure that we free this huge surface (enough?)
+ map_screenshot_surf_ = NULL;
+
+ // restore normal rendering
+ map_screenshot_= false;
+ xpos_ = old_xpos;
+ ypos_ = old_ypos;
+ // some drawing functions are confused by the temporary change
+ // of the map_area and thus affect the UI outside of the map
+ redraw_everything();
+ draw(true, true);
}
gui::button* display::find_button(const std::string& id)
@@ -612,7 +657,7 @@
void display::drawing_buffer_commit()
{
SDL_Rect clip_rect = map_area();
- surface const dst(screen_.getSurface());
+ surface const dst(get_screen_surface());
clip_rect_setter set_clip_rect(dst, clip_rect);
// Simply go down all levels in the drawing_buffer_ and render them.
@@ -1043,9 +1088,9 @@
if(redraw_background_) {
// Full redraw of the background
const SDL_Rect clip_rect = map_outside_area();
- const surface outside_surf(screen_.getSurface());
- clip_rect_setter set_clip_rect(outside_surf, clip_rect);
- draw_background(outside_surf, clip_rect,
theme_.border().background_image);
+ const surface screen = get_screen_surface();
+ clip_rect_setter set_clip_rect(screen, clip_rect);
+ draw_background(screen, clip_rect,
theme_.border().background_image);
update_rect(clip_rect);
redraw_background_ = false;
@@ -1196,12 +1241,14 @@
* This way this code doesn't need modifications for other border sizes.
*/
+ surface screen = get_screen_surface();
+
// First handle the corners :
if(loc.x == -1 && loc.y == -1) { // top left corner
SDL_Rect rect = { xpos + zoom_/4, ypos, 3 * zoom_/4, zoom_ } ;
const surface
border(image::get_image(theme_.border().corner_image_top_left,
image::SCALED_TO_ZOOM));
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
} else if(loc.x == map_.w() && loc.y == -1) { // top right corner
SDL_Rect rect = { xpos, -1, 3 * zoom_/4, zoom_ } ;
surface border;
@@ -1216,14 +1263,14 @@
border =
image::get_image(theme_.border().corner_image_top_right_even,
image::SCALED_TO_ZOOM);
}
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
} else if(loc.x == -1 && loc.y == map_.h()) { // bottom left corner
SDL_Rect rect = { xpos + zoom_/4, ypos, 3 * zoom_/4, zoom_/2 } ;
const surface
border(image::get_image(theme_.border().corner_image_bottom_left,
image::SCALED_TO_ZOOM));
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
} else if(loc.x == map_.w() && loc.y == map_.h()) { // bottom right
corner
SDL_Rect rect = { xpos, ypos, 3 * zoom_/4, zoom_/2 } ;
@@ -1235,20 +1282,20 @@
border =
image::get_image(theme_.border().corner_image_bottom_right_odd,
image::SCALED_TO_ZOOM);
}
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
// Now handle the sides:
} else if(loc.x == -1) { // left side
SDL_Rect rect = { xpos + zoom_/4 , ypos, zoom_/2, zoom_ } ;
const surface
border(image::get_image(theme_.border().border_image_left,
image::SCALED_TO_ZOOM));
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
} else if(loc.x == map_.w()) { // right side
SDL_Rect rect = { xpos + zoom_/4 , ypos, zoom_/2, zoom_ } ;
const surface
border(image::get_image(theme_.border().border_image_right,
image::SCALED_TO_ZOOM));
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
} else if(loc.y == -1) { // top side
SDL_Rect rect = { xpos, -1, zoom_, zoom_/2 } ;
@@ -1262,7 +1309,7 @@
border =
image::get_image(theme_.border().border_image_top_odd, image::SCALED_TO_ZOOM);
}
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
} else if(loc.y == map_.h()) { // bottom side
SDL_Rect rect = { xpos, -1, zoom_, zoom_/2 } ;
@@ -1276,7 +1323,7 @@
border =
image::get_image(theme_.border().border_image_bottom_odd,
image::SCALED_TO_ZOOM);
}
- SDL_BlitSurface( border, NULL, screen_.getSurface(), &rect);
+ SDL_BlitSurface( border, NULL, screen, &rect);
}
}
Modified: trunk/src/display.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/display.hpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/display.hpp (original)
+++ trunk/src/display.hpp Tue Mar 25 05:56:30 2008
@@ -68,6 +68,9 @@
// Gets the underlying screen object.
CVideo& video() { return screen_; }
+ // return the screen surface or the surface used for map_screenshot
+ surface get_screen_surface() { return map_screenshot_ ?
map_screenshot_surf_ : screen_.getSurface();}
+
virtual bool in_game() const { return false; }
// the dimensions of the display. x and y are width/height.
@@ -84,6 +87,12 @@
{ const SDL_Rect res = {0,0,w(),h()}; return res; }
/**
+ * Returns the maximum area used for the map
+ * regardless to resolution and view size
+ */
+ const SDL_Rect& max_map_area() const;
+
+ /**
* Returns the area used for the map
*/
const SDL_Rect& map_area() const;
@@ -93,8 +102,8 @@
* from the above. This area will get the background area
* applied to it.
*/
- const SDL_Rect& map_outside_area() const
- { return theme_.main_map_location(screen_area()); }
+ const SDL_Rect& map_outside_area() const { return map_screenshot_ ?
+ max_map_area() : theme_.main_map_location(screen_area()); }
//! Check if the bbox of the hex at x,y has pixels outside the area
rectangle.
bool outside_area(const SDL_Rect& area, const int x,const int y) const;
@@ -163,6 +172,9 @@
//! Make a screenshot and save it in a default location.
void screenshot();
+
+ //! Make a map-screenshot and save it in a default location.
+ void map_screenshot();
//! Invalidates entire screen, including all tiles and sidebar.
void redraw_everything();
@@ -551,12 +563,17 @@
bool draw_init();
void draw_wrap(bool update,bool force,bool changed);
+ //! Used to indicate to drawing funtions that we are doing a map
screenshot
+ bool map_screenshot_;
+
private:
//! Handle for the label which displays frames per second.
int fps_handle_;
bool idle_anim_;
double idle_anim_rate_;
+
+ surface map_screenshot_surf_;
};
//! Simplified display class for the editor.
Modified: trunk/src/editor/editor.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor/editor.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/editor/editor.cpp (original)
+++ trunk/src/editor/editor.cpp Tue Mar 25 05:56:30 2008
@@ -899,6 +899,7 @@
case hotkey::HOTKEY_ZOOM_DEFAULT:
case hotkey::HOTKEY_FULLSCREEN:
case hotkey::HOTKEY_SCREENSHOT:
+ case hotkey::HOTKEY_MAP_SCREENSHOT:
case hotkey::HOTKEY_TOGGLE_GRID:
case hotkey::HOTKEY_MOUSE_SCROLL:
case hotkey::HOTKEY_PREFERENCES:
Modified: trunk/src/editor/editor_display.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/editor/editor_display.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/editor/editor_display.cpp (original)
+++ trunk/src/editor/editor_display.cpp Tue Mar 25 05:56:30 2008
@@ -53,8 +53,8 @@
changed = true;
SDL_Rect clip_rect = map_outside_area();
- surface const dst(screen_.getSurface());
- clip_rect_setter set_clip_rect(dst, clip_rect);
+ surface const screen(get_screen_surface());
+ clip_rect_setter set_clip_rect(screen, clip_rect);
std::set<gamemap::location>::const_iterator it;
for(it = invalidated_.begin(); it != invalidated_.end(); ++it) {
Modified: trunk/src/filesystem.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/filesystem.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/filesystem.cpp (original)
+++ trunk/src/filesystem.cpp Tue Mar 25 05:56:30 2008
@@ -276,6 +276,28 @@
return get_dir(dir_path);
}
+std::string get_next_filename(const std::string& name, const std::string&
extension, int& counter)
+{
+ std::string next_filename;
+
+ do {
+ std::stringstream filename;
+
+ filename << name;
+ filename.width(5);
+ filename.fill('0');
+ filename.setf(std::ios_base::right);
+ filename << counter << extension;
+ counter++;
+
+ next_filename = filename.str();
+
+ } while(file_exists(next_filename));
+
+ return next_filename;
+}
+
+
std::string get_upload_dir()
{
const std::string dir_path = get_user_data_dir() + "/upload";
Modified: trunk/src/filesystem.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/filesystem.hpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/filesystem.hpp (original)
+++ trunk/src/filesystem.hpp Tue Mar 25 05:56:30 2008
@@ -60,6 +60,10 @@
std::string get_cache_dir();
std::string get_intl_dir();
std::string get_screenshot_dir();
+
+//! Get the next free filename using "name + number (5 digits) + extension"
+//! counter is used to hint the search and track the final number used
+std::string get_next_filename(const std::string& name, const std::string&
extension, int& counter);
std::string get_upload_dir();
std::string get_user_data_dir();
Modified: trunk/src/game_display.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/game_display.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/game_display.cpp (original)
+++ trunk/src/game_display.cpp Tue Mar 25 05:56:30 2008
@@ -308,8 +308,8 @@
map_.get_terrain_info(t_translation::FOGGED).minimap_image() + ".png";
SDL_Rect clip_rect = map_area();
- surface const dst(screen_.getSurface());
- clip_rect_setter set_clip_rect(dst, clip_rect);
+ surface screen = get_screen_surface();
+ clip_rect_setter set_clip_rect(screen, clip_rect);
std::set<gamemap::location>::const_iterator it;
for(it = invalidated_.begin(); it != invalidated_.end(); ++it) {
Modified: trunk/src/halo.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/halo.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/halo.cpp (original)
+++ trunk/src/halo.cpp Tue Mar 25 05:56:30 2008
@@ -185,7 +185,7 @@
return false;
}
- surface const screen = disp->video().getSurface();
+ surface const screen = disp->get_screen_surface();
const clip_rect_setter clip_setter(screen,clip_rect);
if(buffer_ == NULL || buffer_->w != rect.w || buffer_->h != rect.h) {
@@ -209,7 +209,7 @@
return;
}
- surface const screen = disp->video().getSurface();
+ surface const screen = disp->get_screen_surface();
SDL_Rect clip_rect = disp->map_outside_area();
const clip_rect_setter clip_setter(screen,clip_rect);
Modified: trunk/src/hotkeys.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/hotkeys.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/hotkeys.cpp (original)
+++ trunk/src/hotkeys.cpp Tue Mar 25 05:56:30 2008
@@ -63,6 +63,7 @@
{ hotkey::HOTKEY_ZOOM_DEFAULT, "zoomdefault", N_("Default Zoom"), false
},
{ hotkey::HOTKEY_FULLSCREEN, "fullscreen", N_("Toggle Full Screen"),
false },
{ hotkey::HOTKEY_SCREENSHOT, "screenshot", N_("Screenshot"), false },
+ { hotkey::HOTKEY_MAP_SCREENSHOT, "mapscreenshot", N_("Map Screenshot"),
false },
{ hotkey::HOTKEY_ACCELERATED, "accelerated", N_("Accelerated"), false },
{ hotkey::HOTKEY_UNIT_DESCRIPTION, "describeunit", N_("Unit
Description"), false },
{ hotkey::HOTKEY_RENAME_UNIT, "renameunit", N_("Rename Unit"), false },
@@ -807,6 +808,9 @@
case HOTKEY_SCREENSHOT:
disp.screenshot();
break;
+ case HOTKEY_MAP_SCREENSHOT:
+ disp.map_screenshot();
+ break;
case HOTKEY_ACCELERATED:
preferences::set_turbo(!preferences::turbo());
break;
Modified: trunk/src/hotkeys.hpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/hotkeys.hpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/hotkeys.hpp (original)
+++ trunk/src/hotkeys.hpp Tue Mar 25 05:56:30 2008
@@ -33,7 +33,7 @@
HOTKEY_END_UNIT_TURN, HOTKEY_LEADER,
HOTKEY_UNDO, HOTKEY_REDO,
HOTKEY_ZOOM_IN, HOTKEY_ZOOM_OUT, HOTKEY_ZOOM_DEFAULT,
- HOTKEY_FULLSCREEN, HOTKEY_SCREENSHOT, HOTKEY_ACCELERATED,
+ HOTKEY_FULLSCREEN, HOTKEY_SCREENSHOT, HOTKEY_MAP_SCREENSHOT,
HOTKEY_ACCELERATED,
HOTKEY_UNIT_DESCRIPTION, HOTKEY_RENAME_UNIT,
HOTKEY_SAVE_GAME, HOTKEY_SAVE_REPLAY, HOTKEY_SAVE_MAP, HOTKEY_LOAD_GAME,
HOTKEY_RECRUIT, HOTKEY_REPEAT_RECRUIT, HOTKEY_RECALL, HOTKEY_ENDTURN,
Modified: trunk/src/play_controller.cpp
URL:
http://svn.gna.org/viewcvs/wesnoth/trunk/src/play_controller.cpp?rev=25096&r1=25095&r2=25096&view=diff
==============================================================================
--- trunk/src/play_controller.cpp (original)
+++ trunk/src/play_controller.cpp Tue Mar 25 05:56:30 2008
@@ -513,6 +513,7 @@
case hotkey::HOTKEY_ZOOM_DEFAULT:
case hotkey::HOTKEY_FULLSCREEN:
case hotkey::HOTKEY_SCREENSHOT:
+ case hotkey::HOTKEY_MAP_SCREENSHOT:
case hotkey::HOTKEY_ACCELERATED:
case hotkey::HOTKEY_SAVE_MAP:
case hotkey::HOTKEY_TOGGLE_GRID:
_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits