[Freeciv-Dev] (PR#8210) WISHLIST: 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 is version 3. It is substantially faster - possibly even usably fast.
It is still rather crude, but I believe the potential is very high.
jason
? convert.sh
? diff
? flags
? data/flags
Index: client/mapview_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapview_common.c,v
retrieving revision 1.120
diff -u -r1.120 mapview_common.c
--- client/mapview_common.c 22 May 2004 18:12:21 -0000 1.120
+++ client/mapview_common.c 23 May 2004 05:46:45 -0000
@@ -317,11 +317,123 @@
}
/****************************************************************************
+ Find the vector with minimum "real" distance between two GUI positions.
+
+ See also map_distance_vector().
+****************************************************************************/
+static void gui_distance_vector(int *gui_dx, int *gui_dy,
+ int gui_x0, int gui_y0,
+ int gui_x1, int gui_y1)
+{
+ int map_x0, map_y0, map_x1, map_y1;
+ int gui_x0_base, gui_y0_base, gui_x1_base, gui_y1_base;
+ int gui_x0_diff, gui_y0_diff, gui_x1_diff, gui_y1_diff;
+ int map_dx, map_dy;
+
+ /* Make sure positions are canonical. Yes, this is the only way. */
+ normalize_gui_pos(&gui_x0, &gui_y0);
+ normalize_gui_pos(&gui_x1, &gui_y1);
+
+ gui_to_map_pos(&map_x0, &map_y0, gui_x0, gui_y0);
+ gui_to_map_pos(&map_x1, &map_y1, gui_x1, gui_y1);
+
+ map_to_gui_pos(&gui_x0_base, &gui_y0_base, map_x0, map_y0);
+ map_to_gui_pos(&gui_x1_base, &gui_y1_base, map_x1, map_y1);
+
+ gui_x0_diff = gui_x0 - gui_x0_base;
+ gui_y0_diff = gui_y0 - gui_y0_base;
+ gui_x1_diff = gui_x1 - gui_x1_base;
+ gui_y1_diff = gui_y1 - gui_y1_base;
+
+ map_distance_vector(&map_dx, &map_dy, map_x0, map_y0, map_x1, map_y1);
+ map_to_gui_pos(gui_dx, gui_dy, map_dx, map_dy);
+
+ *gui_dx += gui_x1_diff - gui_x0_diff;
+ *gui_dy += gui_y1_diff - gui_y1_diff;
+}
+
+static void base_set_mapview_origin(int gui_x0, int gui_y0)
+{
+ int map_center_x, map_center_y;
+ int old_gui_x0 = mapview_canvas.gui_x0;
+ int old_gui_y0 = mapview_canvas.gui_y0;
+ 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;
+
+ normalize_gui_pos(&gui_x0, &gui_y0);
+ 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 start_x = mapview_canvas.gui_x0, start_y = mapview_canvas.gui_y0;
+ int diff_x, diff_y;
+ int timing_msec = 500;
/* Normalize (wrap) the mapview origin. */
normalize_gui_pos(&gui_x0, &gui_y0);
@@ -338,78 +450,31 @@
gui_y0 = CLIP(ymin, gui_y0, ymax - ysize);
}
+ if (mapview_canvas.gui_x0 == gui_x0 && mapview_canvas.gui_y0 == gui_y0) {
+ return;
+ }
+
/* Then update everything. */
- if (mapview_canvas.gui_x0 != gui_x0 || mapview_canvas.gui_y0 != gui_y0) {
- int map_center_x, map_center_y;
- int old_gui_x0 = mapview_canvas.gui_x0;
- int old_gui_y0 = mapview_canvas.gui_y0;
- 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;
-
- 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 (timing_msec > 0) {
+ double timing_sec = (double)timing_msec / 1000.0, mytime;
+ static struct timer *anim_timer;
- 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();
- }
+ 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);
- 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();
+ 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();
}
/****************************************************************************
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#8210) WISHLIST: a sliding mapview,
Jason Short <=
|
|