[Freeciv-Dev] (PR#8210) Wish List: a sliding mapview
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://rt.freeciv.org/Ticket/Display.html?id=8210 >
Here's an update of the patch.
There _may_ still be stippling problems when drawing fogged sprites. I
think this has been fixed but it's never really been put to the test.
It also seems slower than I remembered. Maybe this is just because I'm
using the isotrident tileset on fullscreen - lots of tiles. It's a
problem because I don't think the drawing can really be made much faster.
And of course it's incomplete. The sliding time should be a client
option and/or should be dynamically generated (proportional to distance,
and clipped). And some centerings shouldn't slide at all.
jason
? diff
? freeciv-1.14.99-devel
? settler_recursion_crash
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.144
diff -u -r1.144 mapview_common.c
--- client/mapview_common.c 13 Sep 2004 23:13:11 -0000 1.144
+++ client/mapview_common.c 14 Sep 2004 08:02:33 -0000
@@ -383,11 +383,102 @@
}
/****************************************************************************
+ Move the GUI origin to the given normalized, clipped origin. This may
+ be called many times when sliding the mapview.
+****************************************************************************/
+static void base_set_mapview_origin(int gui_x0, int gui_y0)
+{
+ int map_center_x, map_center_y, old_gui_x0, old_gui_y0, dx, dy;
+ const int width = mapview_canvas.width, height = mapview_canvas.height;
+ int common_x0, common_x1, common_y0, common_y1;
+ int update_x0, update_x1, update_y0, update_y1;
+
+ /* Then update everything. This does some tricky math to avoid having
+ * to do unnecessary redraws in update_map_canvas. This makes for ugly
+ * code but speeds up the mapview by a large factor. */
+
+ /* We need to calculate the vector of movement of the mapview. So
+ * we find the GUI distance vector and then use this to calculate
+ * the original mapview origin relative to the current position. Thus
+ * if we move one tile to the left, even if this causes GUI positions
+ * to wrap the distance vector is only one tile. */
+ normalize_gui_pos(&gui_x0, &gui_y0);
+ gui_distance_vector(&dx, &dy,
+ mapview_canvas.gui_x0, mapview_canvas.gui_y0,
+ gui_x0, gui_y0);
+ old_gui_x0 = gui_x0 - dx;
+ old_gui_y0 = gui_y0 - dy;
+
+ mapview_canvas.gui_x0 = gui_x0;
+ mapview_canvas.gui_y0 = gui_y0;
+
+ /* Find the overlapping area of the new and old mapview. This is
+ * done in GUI coordinates. Note that if the GUI coordinates wrap
+ * no overlap will be found. */
+ common_x0 = MAX(old_gui_x0, gui_x0);
+ common_x1 = MIN(old_gui_x0, gui_x0) + width;
+ common_y0 = MAX(old_gui_y0, gui_y0);
+ common_y1 = MIN(old_gui_y0, gui_y0) + height;
+
+ if (common_x1 > common_x0 && common_y1 > common_y0) {
+ /* Do a partial redraw only. This means the area of overlap (a
+ * rectangle) is copied. Then the remaining areas (two rectangles)
+ * are updated through update_map_canvas. */
+ struct canvas *target = mapview_canvas.tmp_store;
+
+ if (old_gui_x0 < gui_x0) {
+ update_x0 = MAX(old_gui_x0 + width, gui_x0);
+ update_x1 = gui_x0 + width;
+ } else {
+ update_x0 = gui_x0;
+ update_x1 = MIN(old_gui_x0, gui_x0 + width);
+ }
+ if (old_gui_y0 < gui_y0) {
+ update_y0 = MAX(old_gui_y0 + height, gui_y0);
+ update_y1 = gui_y0 + height;
+ } else {
+ update_y0 = gui_y0;
+ update_y1 = MIN(old_gui_y0, gui_y0 + height);
+ }
+
+ dirty_all();
+ canvas_copy(target, mapview_canvas.store,
+ common_x0 - old_gui_x0,
+ common_y0 - old_gui_y0,
+ common_x0 - gui_x0, common_y0 - gui_y0,
+ common_x1 - common_x0, common_y1 - common_y0);
+ mapview_canvas.tmp_store = mapview_canvas.store;
+ mapview_canvas.store = target;
+
+ if (update_y1 > update_y0) {
+ update_map_canvas(0, update_y0 - gui_y0,
+ width, update_y1 - update_y0);
+ }
+ if (update_x1 > update_x0) {
+ update_map_canvas(update_x0 - gui_x0, common_y0 - gui_y0,
+ update_x1 - update_x0, common_y1 - common_y0);
+ }
+ } else {
+ update_map_canvas_visible();
+ }
+
+ get_center_tile_mapcanvas(&map_center_x, &map_center_y);
+ center_tile_overviewcanvas(map_center_x, map_center_y);
+ if (hover_state == HOVER_GOTO || hover_state == HOVER_PATROL) {
+ create_line_at_mouse_pos();
+ }
+ if (rectangle_active) {
+ update_rect_at_mouse_pos();
+ }
+}
+
+/****************************************************************************
Change the mapview origin, clip it, and update everything.
****************************************************************************/
void set_mapview_origin(int gui_x0, int gui_y0)
{
int xmin, xmax, ymin, ymax, xsize, ysize;
+ int timing_msec = 500;
/* Normalize (wrap) the mapview origin. */
normalize_gui_pos(&gui_x0, &gui_y0);
@@ -404,90 +495,32 @@
gui_y0 = CLIP(ymin, gui_y0, ymax - ysize);
}
- /* Then update everything. This does some tricky math to avoid having
- * to do unnecessary redraws in update_map_canvas. This makes for ugly
- * code but speeds up the mapview by a large factor. */
- if (mapview_canvas.gui_x0 != gui_x0 || mapview_canvas.gui_y0 != gui_y0) {
- int map_center_x, map_center_y, old_gui_x0, old_gui_y0, dx, dy;
- const int width = mapview_canvas.store_width;
- const int height = mapview_canvas.store_height;
- int common_x0, common_x1, common_y0, common_y1;
- int update_x0, update_x1, update_y0, update_y1;
-
- /* We need to calculate the vector of movement of the mapview. So
- * we find the GUI distance vector and then use this to calculate
- * the original mapview origin relative to the current position. Thus
- * if we move one tile to the left, even if this causes GUI positions
- * to wrap the distance vector is only one tile. */
- gui_distance_vector(&dx, &dy,
- mapview_canvas.gui_x0, mapview_canvas.gui_y0,
- gui_x0, gui_y0);
- old_gui_x0 = gui_x0 - dx;
- old_gui_y0 = gui_y0 - dy;
-
- mapview_canvas.gui_x0 = gui_x0;
- mapview_canvas.gui_y0 = gui_y0;
-
- /* Find the overlapping area of the new and old mapview. This is
- * done in GUI coordinates. Note that if the GUI coordinates wrap
- * no overlap will be found. */
- common_x0 = MAX(old_gui_x0, gui_x0);
- common_x1 = MIN(old_gui_x0, gui_x0) + width;
- common_y0 = MAX(old_gui_y0, gui_y0);
- common_y1 = MIN(old_gui_y0, gui_y0) + height;
-
- if (common_x1 > common_x0 && common_y1 > common_y0) {
- /* Do a partial redraw only. This means the area of overlap (a
- * rectangle) is copied. Then the remaining areas (two rectangles)
- * are updated through update_map_canvas. */
- struct canvas *target = mapview_canvas.tmp_store;
-
- if (old_gui_x0 < gui_x0) {
- update_x0 = MAX(old_gui_x0 + width, gui_x0);
- update_x1 = gui_x0 + width;
- } else {
- update_x0 = gui_x0;
- update_x1 = MIN(old_gui_x0, gui_x0 + width);
- }
- if (old_gui_y0 < gui_y0) {
- update_y0 = MAX(old_gui_y0 + height, gui_y0);
- update_y1 = gui_y0 + height;
- } else {
- update_y0 = gui_y0;
- update_y1 = MIN(old_gui_y0, gui_y0 + height);
- }
+ if (mapview_canvas.gui_x0 == gui_x0 && mapview_canvas.gui_y0 == gui_y0) {
+ return;
+ }
- dirty_all();
- canvas_copy(target, mapview_canvas.store,
- common_x0 - old_gui_x0,
- common_y0 - old_gui_y0,
- common_x0 - gui_x0, common_y0 - gui_y0,
- common_x1 - common_x0, common_y1 - common_y0);
- mapview_canvas.tmp_store = mapview_canvas.store;
- mapview_canvas.store = target;
-
- if (update_y1 > update_y0) {
- update_map_canvas(0, update_y0 - gui_y0,
- width, update_y1 - update_y0);
- }
- if (update_x1 > update_x0) {
- update_map_canvas(update_x0 - gui_x0, common_y0 - gui_y0,
- update_x1 - update_x0, common_y1 - common_y0);
- }
- } else {
- update_map_canvas_visible();
- }
+ if (timing_msec > 0) {
+ int start_x = mapview_canvas.gui_x0, start_y = mapview_canvas.gui_y0;
+ int diff_x, diff_y;
+ double timing_sec = (double)timing_msec / 1000.0, mytime;
+ static struct timer *anim_timer;
- get_center_tile_mapcanvas(&map_center_x, &map_center_y);
- center_tile_overviewcanvas(map_center_x, map_center_y);
- update_map_canvas_scrollbars();
- if (hover_state == HOVER_GOTO || hover_state == HOVER_PATROL) {
- create_line_at_mouse_pos();
- }
- }
- if (rectangle_active) {
- update_rect_at_mouse_pos();
+ gui_distance_vector(&diff_x, &diff_y, start_x, start_y, gui_x0, gui_y0);
+ anim_timer = renew_timer_start(anim_timer, TIMER_USER, TIMER_ACTIVE);
+
+ do {
+ mytime = MIN(read_timer_seconds(anim_timer), timing_sec);
+
+ base_set_mapview_origin(start_x + diff_x * (mytime / timing_sec),
+ start_y + diff_y * (mytime / timing_sec));
+ flush_dirty();
+ gui_flush();
+ } while (mytime < timing_sec);
+ } else {
+ base_set_mapview_origin(gui_x0, gui_y0);
}
+
+ update_map_canvas_scrollbars();
}
/****************************************************************************
- [Freeciv-Dev] (PR#8210) Wish List: a sliding mapview,
Jason Short <=
|
|