Index: lang/english.txt =================================================================== --- lang/english.txt (revision 3597) +++ lang/english.txt (working copy) @@ -410,6 +410,9 @@ STR_0196_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Show land owners on map STR_0197_TOGGLE_TOWN_NAMES_ON_OFF :{BLACK}Toggle town names on/off on map STR_0198_PROFIT_THIS_YEAR_LAST_YEAR :{TINYFONT}{BLACK}Profit this year: {CURRENCY} (last year: {CURRENCY}) +STR_RECENTRE_SMALLMAP :{BLACK}Recenter the view +STR_ZOOM_IN_SMALLMAP :{BLACK}zoom in +STR_ZOOM_OUT_SMALLMAP :{BLACK}zoom out ############ range for service numbers starts STR_AGE :{COMMA} year{P "" s} ({COMMA}) Index: smallmap_gui.c =================================================================== --- smallmap_gui.c (revision 3597) +++ smallmap_gui.c (working copy) @@ -19,6 +19,7 @@ #include "town.h" #include "sound.h" #include "variables.h" +#include "debug.h" static const Widget _smallmap_widgets[] = { { WWT_CLOSEBOX, RESIZE_NONE, 13, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, @@ -32,9 +33,12 @@ { WWT_IMGBTN, RESIZE_LRTB, 13, 380, 401, 280, 301, SPR_IMG_SHOW_ROUTES, STR_0194_SHOW_TRANSPORT_ROUTES_ON}, { WWT_IMGBTN, RESIZE_LRTB, 13, 402, 423, 280, 301, SPR_IMG_PLANTTREES, STR_0195_SHOW_VEGETATION_ON_MAP}, { WWT_IMGBTN, RESIZE_LRTB, 13, 424, 445, 280, 301, SPR_IMG_COMPANY_GENERAL, STR_0196_SHOW_LAND_OWNERS_ON_MAP}, -{ WWT_IMGBTN, RESIZE_LRTB, 13, 358, 379, 258, 279, 0x0, STR_NULL}, + +{ WWT_PANEL, RESIZE_LRTB, 13, 358, 379, 258, 279, 683, STR_RECENTRE_SMALLMAP}, { WWT_IMGBTN, RESIZE_LRTB, 13, 358, 379, 280, 301, SPR_IMG_TOWN, STR_0197_TOGGLE_TOWN_NAMES_ON_OFF}, -{ WWT_IMGBTN, RESIZE_RTB, 13, 0, 357, 258, 301, 0x0, STR_NULL}, +{ WWT_PANEL, RESIZE_LRTB, 13, 336, 357, 258, 279, 0x2DF, STR_ZOOM_IN_SMALLMAP}, +{ WWT_PANEL, RESIZE_LRTB, 13, 336, 357, 280, 301, 0x2E0, STR_ZOOM_OUT_SMALLMAP}, +{ WWT_IMGBTN, RESIZE_RTB, 13, 0, 335, 258, 301, 0x0, STR_NULL}, { WWT_PANEL, RESIZE_RTB, 13, 0, 433, 302, 313, 0x0, STR_NULL}, { WWT_RESIZEBOX, RESIZE_LRTB, 13, 434, 445, 302, 313, 0x0, STR_RESIZE_BUTTON}, { WIDGETS_END}, @@ -42,6 +46,7 @@ static int _smallmap_type; static bool _smallmap_show_towns = true; +void SmallMapRecentre(void); #define MK(a,b) a, b #define MKEND() 0xFFFF @@ -324,17 +329,18 @@ * @param proc Pointer to the colour function * @see GetSmallMapPixels(TileIndex) */ -static void DrawSmallMapStuff(Pixel *dst, uint xc, uint yc, int pitch, int reps, uint32 mask, GetSmallMapPixels *proc) +static void DrawSmallMapStuff(Pixel *dst, uint xc, uint yc, int pitch, int reps, uint32 mask, GetSmallMapPixels *proc,double smallmap_zoom) { Pixel *dst_ptr_end = _screen.dst_ptr + _screen.width * _screen.height - _screen.width; - do { // check if the tile (xc,yc) is within the map range - if (xc < MapMaxX() && yc < MapMaxY()) { + if (xc * smallmap_zoom < MapMaxX() && yc * smallmap_zoom < MapMaxY()) { // check if the dst pointer points to a pixel inside the screen buffer if (dst > _screen.dst_ptr && dst < dst_ptr_end) - WRITE_PIXELS_OR(dst, proc(TileXY(xc, yc)) & mask); - } + //old pixel writing func + //WRITE_PIXELS_OR(dst, proc(TileXY(xc, yc)) & mask); + WRITE_PIXELS_OR(dst, proc(TileXY(xc * smallmap_zoom, yc * smallmap_zoom)) & mask); + } // switch to next tile in the column } while (xc++, yc++, dst += pitch, --reps != 0); } @@ -587,7 +593,9 @@ int tile_x; int tile_y; ViewPort *vp; + double smallmap_zoom=WP(w,smallmap_d).zoom; + old_dpi = _cur_dpi; _cur_dpi = dpi; @@ -640,10 +648,12 @@ y = 0; for (;;) { - uint32 mask = 0xFFFFFFFF; + uint32 mask; int reps; int t; + mask = 0xFFFFFFFF; + /* distance from left edge */ if (x < 0) { if (x < -3) goto skip_column; @@ -663,7 +673,7 @@ reps = (dpi->height - y + 1) / 2; if (reps > 0) { // assert(ptr >= dpi->dst_ptr); - DrawSmallMapStuff(ptr, tile_x, tile_y, dpi->pitch*2, reps, mask, _smallmap_draw_procs[type]); + DrawSmallMapStuff(ptr, tile_x, tile_y, dpi->pitch*2, reps, mask, _smallmap_draw_procs[type],smallmap_zoom); } skip_column: @@ -690,11 +700,19 @@ if (v->type != 0 && v->type != VEH_Special && (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0) { // Remap into flat coordinates. - Point pt = RemapCoords( + + /* old + Point pt = RemapCoords( (v->x_pos - WP(w,smallmap_d).scroll_x) / 16, (v->y_pos - WP(w,smallmap_d).scroll_y) / 16, 0); - x = pt.x; + */ + Point pt = RemapCoords( + ((v->x_pos / smallmap_zoom) - WP(w,smallmap_d).scroll_x) / 16, + ((v->y_pos / smallmap_zoom) - WP(w,smallmap_d).scroll_y) / 16, + 0); + + x = pt.x; y = pt.y; // Check if y is out of bounds? @@ -735,10 +753,18 @@ FOR_ALL_TOWNS(t) { if (t->xy != 0) { // Remap the town coordinate - Point pt = RemapCoords( + + /* old + Point pt = RemapCoords( (int)(TileX(t->xy) * 16 - WP(w, smallmap_d).scroll_x) / 16, (int)(TileY(t->xy) * 16 - WP(w, smallmap_d).scroll_y) / 16, 0); + */ + Point pt = RemapCoords( + (int)((TileX(t->xy) / smallmap_zoom) * 16 - WP(w, smallmap_d).scroll_x) / 16, + (int)((TileY(t->xy) / smallmap_zoom) * 16 - WP(w, smallmap_d).scroll_y) / 16, + 0); + x = pt.x - WP(w,smallmap_d).subscroll + 3 - (t->sign.width_2 >> 1); y = pt.y; @@ -763,11 +789,19 @@ vp = FindWindowById(WC_MAIN_WINDOW,0)->viewport; pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w, smallmap_d).scroll_y, 0); - + + /* old x = vp->virtual_left - pt.x; y = vp->virtual_top - pt.y; x2 = (x + vp->virtual_width) / 16; y2 = (y + vp->virtual_height) / 16; + */ + + x = (vp->virtual_left / smallmap_zoom) - pt.x; + y = (vp->virtual_top / smallmap_zoom) - pt.y; + x2 = (x + (vp->virtual_width / smallmap_zoom)) / 16; + y2 = (y + (vp->virtual_height / smallmap_zoom)) / 16; + x /= 16; y /= 16; @@ -783,8 +817,95 @@ _cur_dpi = old_dpi; } + + + +void SmallMapRecentre(void) +{ + int x,y; + Window *w; + ViewPort *vp; + + /* recentre the map */ + w = FindWindowById(WC_SMALLMAP, 0); + double smallmap_zoom=WP(w,smallmap_d).zoom; + vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + + x = ((((vp->virtual_width / smallmap_zoom) - (220*32)) / 2) + (vp->virtual_left / smallmap_zoom)) / 4; + y = (((((vp->virtual_height / smallmap_zoom) - (120*32)) / 2) + (vp->virtual_top / smallmap_zoom)) / 2) - 32; + + + WP(w,smallmap_d).scroll_x = (y-x) & ~0xF; + WP(w,smallmap_d).scroll_y = (x+y) & ~0xF; + WP(w,smallmap_d).subscroll = 0; + + /* handle disabled states of buttons */ + CLRBIT(w->disabled_state, 13); + CLRBIT(w->disabled_state, 14); + + if (smallmap_zoom <= 0) { + SETBIT(w->disabled_state, 13); + }if (smallmap_zoom >= 32) { + SETBIT(w->disabled_state, 14); + } +} + +void ScrollSmallmap(int mx, int my) +{ + int hx, hy; + int hvx, hvy; + int x, y, sub; + + + Window *w = FindWindowById(WC_SMALLMAP, 0); + double smallmap_zoom=WP(w,smallmap_d).zoom; + + x = WP(w,smallmap_d).scroll_x; + y = WP(w,smallmap_d).scroll_y; + + sub = WP(w,smallmap_d).subscroll + mx; + + x -= (sub >> 2) << 4; + y += (sub >> 2) << 4; + sub &= 3; + + x += (my >> 1) << 4; + y += (my >> 1) << 4; + + if (my & 1) { + x += 16; + sub += 2; + if (sub > 3) { + sub -= 4; + x -= 16; + y += 16; + } + } + + hx = (w->widget[4].right - w->widget[4].left) / 2; + hy = (w->widget[4].bottom - w->widget[4].top ) / 2; + hvx = hx * -4 + hy * 8; + hvy = hx * 4 + hy * 8; + if (x < -hvx) { x = -hvx; sub = 0; } + if (x > (int)((MapMaxX() * 16) / smallmap_zoom) - hvx) { x = ((MapMaxX() * 16) / smallmap_zoom) - hvx; sub = 0; } + if (y < -hvy) { y = -hvy; sub = 0; } + if (y > (int)((MapMaxY() * 16) / smallmap_zoom) - hvy) { y = ((MapMaxY() * 16) / smallmap_zoom) - hvy; sub = 0; } + + WP(w,smallmap_d).scroll_x = x; + WP(w,smallmap_d).scroll_y = y; + WP(w,smallmap_d).subscroll = sub; +} + + + + + + + static void SmallMapWindowProc(Window *w, WindowEvent *e) { + double smallmap_zoom=WP(w,smallmap_d).zoom; + switch (e->event) { case WE_PAINT: { const uint16 *tbl; @@ -833,8 +954,13 @@ w2 = FindWindowById(WC_MAIN_WINDOW, 0); pt = RemapCoords(WP(w,smallmap_d).scroll_x, WP(w,smallmap_d).scroll_y, 0); - WP(w2,vp_d).scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1); + /* old + WP(w2,vp_d).scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1); WP(w2,vp_d).scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1); + */ + WP(w2,vp_d).scrollpos_x = (pt.x * smallmap_zoom) + (((_cursor.pos.x - w->left + 2) << 4) * smallmap_zoom) - (w2->viewport->virtual_width >> 1); + WP(w2,vp_d).scrollpos_y = (pt.y * smallmap_zoom) + (((_cursor.pos.y - w->top - 16) << 4) * smallmap_zoom) - (w2->viewport->virtual_height >> 1); + } break; case 5: /* Show land contours */ @@ -851,13 +977,36 @@ SndPlayFx(SND_15_BEEP); break; + case 11: /* centre location */ + SmallMapRecentre(); + SetWindowDirty(w); + SndPlayFx(SND_15_BEEP); + break; + case 12: /* toggle town names */ w->click_state ^= (1 << 12); _smallmap_show_towns = (w->click_state >> 12) & 1; SetWindowDirty(w); SndPlayFx(SND_15_BEEP); break; - } + + case 13: /* zoom in */ + if (smallmap_zoom > 0.04) // can zoom in up to 5 times + WP(w,smallmap_d).zoom /= 2; + + SmallMapRecentre(); + SetWindowDirty(w); + SndPlayFx(SND_15_BEEP); + break; + case 14: /* zoom out */ + if (smallmap_zoom < 32) + WP(w,smallmap_d).zoom *= 2; + + SmallMapRecentre(); + SetWindowDirty(w); + SndPlayFx(SND_15_BEEP); + break; + } break; case WE_RCLICK: @@ -873,9 +1022,27 @@ /* update the window every now and then */ if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w); break; + case WE_SCROLL: + //got a scroll-event, interpret it! + DEBUG(misc,1)("GOT SCROLL-EVENT: %i,%i",e->scroll.delta.x,e->scroll.delta.y); + _cursor.fix_at = true; + ScrollSmallmap(e->scroll.delta.x,e->scroll.delta.y); + SetWindowDirty(w); + break; + case WE_TICK: + SetWindowDirty(w); + break; + case WE_MOUSEOVER: + //do nothing + break; + default: + DEBUG(misc,10)("got unhandled event :%i",e->event); + break; } } + + static const WindowDesc _smallmap_desc = { -1,-1, 446, 314, WC_SMALLMAP,0, @@ -889,17 +1056,25 @@ Window *w; ViewPort *vp; int x,y; + w = AllocateWindowDescFront(&_smallmap_desc, 0); if (w != NULL) { w->click_state = ((1<<5) << _smallmap_type) | (_smallmap_show_towns << 12); w->resize.width = 350; w->resize.height = 250; + WP(w,smallmap_d).zoom=1; + double smallmap_zoom=WP(w,smallmap_d).zoom; vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; - x = ((vp->virtual_width - 220 * 32) / 2 + vp->virtual_left) / 4; + /* old + x = ((vp->virtual_width - 220 * 32) / 2 + vp->virtual_left) / 4; y = ((vp->virtual_height - 120 * 32) / 2 + vp->virtual_top ) / 2 - 32; + */ + x = ((((vp->virtual_width / smallmap_zoom) - (220*32)) / 2) + vp->virtual_left) / (4 * smallmap_zoom); + y = (((((vp->virtual_height / smallmap_zoom) - (120*32)) / 2) + vp->virtual_top) / (2 * smallmap_zoom)) - 32; + WP(w,smallmap_d).scroll_x = (y - x) & ~0xF; WP(w,smallmap_d).scroll_y = (x + y) & ~0xF; WP(w,smallmap_d).subscroll = 0; Index: window.c =================================================================== --- window.c (revision 3597) +++ window.c (working copy) @@ -1144,8 +1144,7 @@ static bool HandleViewportScroll(void) { Window *w; - int dx; - int dy; + int dx,dy; if (!_scrolling_viewport) return true; @@ -1169,77 +1168,27 @@ if (w->window_class != WC_SMALLMAP) { ViewPort* vp = IsPtInWindowViewport(w, _cursor.pos.x, _cursor.pos.y); - if (vp == NULL) goto stop_capt; WP(w,vp_d).scrollpos_x += dx << vp->zoom; WP(w,vp_d).scrollpos_y += dy << vp->zoom; + _cursor.delta.x = _cursor.delta.y = 0; + return false; } else { - int x; - int y; - int sub; - int hx; - int hy; - int hvx; - int hvy; - - _cursor.fix_at = true; - - x = WP(w,smallmap_d).scroll_x; - y = WP(w,smallmap_d).scroll_y; - - sub = WP(w,smallmap_d).subscroll + dx; - - x -= (sub >> 2) << 4; - y += (sub >> 2) << 4; - sub &= 3; - - x += (dy >> 1) << 4; - y += (dy >> 1) << 4; - - if (dy & 1) { - x += 16; - sub += 2; - if (sub > 3) { - sub -= 4; - x -= 16; - y += 16; - } - } - - hx = (w->widget[4].right - w->widget[4].left) / 2; - hy = (w->widget[4].bottom - w->widget[4].top ) / 2; - hvx = hx * -4 + hy * 8; - hvy = hx * 4 + hy * 8; - if (x < -hvx) { - x = -hvx; - sub = 0; - } - if (x > (int)MapMaxX() * 16 - hvx) { - x = MapMaxX() * 16 - hvx; - sub = 0; - } - if (y < -hvy) { - y = -hvy; - sub = 0; - } - if (y > (int)MapMaxY() * 16 - hvy) { - y = MapMaxY() * 16 - hvy; - sub = 0; - } - - WP(w,smallmap_d).scroll_x = x; - WP(w,smallmap_d).scroll_y = y; - WP(w,smallmap_d).subscroll = sub; - - SetWindowDirty(w); + //create a scroll-event and send it to the client + WindowEvent we; + we.event = WE_SCROLL; + we.scroll.delta.x = _cursor.delta.x; + we.scroll.delta.y = _cursor.delta.y; + //DEBUG(misc,3)("GOT SCROLL EVENT, passing to client!,%i,%i,%i",e.event,e.scroll.deltax,e.scroll.deltay); + w->wndproc(w, &we); + _cursor.delta.x = _cursor.delta.y = 0; + //the client refreshes! + //SetWindowDirty(w); + return true; } - - _cursor.delta.x = 0; - _cursor.delta.y = 0; - return false; } static Window *MaybeBringWindowToFront(Window *w) @@ -1664,8 +1613,8 @@ IConsoleResize(); - switch (w->window_class) { - case WC_MAIN_TOOLBAR: + switch (w->window_class) { + case WC_MAIN_TOOLBAR: top = w->top; left = PositionMainToolbar(w); // changes toolbar orientation break; @@ -1700,6 +1649,7 @@ break; } + if (w->viewport != NULL) { w->viewport->left += left - w->left; w->viewport->top += top - w->top; Index: window.h =================================================================== --- window.h (revision 3597) +++ window.h (working copy) @@ -134,6 +134,11 @@ uint wparam; // additional message-specific information uint lparam; // additional message-specific information } message; + + struct { + byte event; + Point delta; + } scroll; }; enum WindowKeyCodes { @@ -376,8 +381,9 @@ int32 scroll_x; int32 scroll_y; int32 subscroll; + double zoom; } smallmap_d; -assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(traindetails_d)); +assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d)); typedef struct { uint32 face; @@ -497,7 +503,9 @@ WE_MOUSEOVER = 20, WE_ON_EDIT_TEXT_CANCEL = 21, WE_RESIZE = 22, - WE_MESSAGE = 23 + WE_MESSAGE = 23, + WE_SCROLL=24, + WE_MOUSEWHEEL=25 };