Index: video/sdl_v.c =================================================================== --- video/sdl_v.c (revision 3597) +++ video/sdl_v.c (working copy) @@ -85,7 +85,8 @@ {1400, 1050}, {1600, 1200}, {1680, 1050}, - {1920, 1200} + {1920, 1200}, + {2560, 1024} }; static void GetVideoModes(void) 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}) @@ -1012,6 +1015,18 @@ STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT :{LTBLUE}Disable aircraft for computer: {ORANGE}{STRING1} STR_CONFIG_PATCHES_AI_BUILDS_SHIPS :{LTBLUE}Disable ships for computer: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_SM_ACTIVE_ZOOM :{LTBLUE}Zoom in Minimap +STR_CONFIG_PATCHES_SM_ACTIVE_ZOOM_SMOOTH :{LTBLUE}Smooth Zoom +STR_CONFIG_PATCHES_SM_NEW_LEGEND :{LTBLUE}Use new Legend +STR_CONFIG_PATCHES_SM_DISPLAY_INDUSTRY_SIGNS :{LTBLUE}Display Industry Signs +STR_CONFIG_PATCHES_SM_INDUSTRY_SIGNS_RANGE :{LTBLUE}Display Range of Industry Signs: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_SM_ADDITIONAL_TOWNINFO :{LTBLUE}Display additional Towninfo +STR_CONFIG_PATCHES_SM_ADDITIONAL_TOWNINFO_RANGE :{LTBLUE}Display Range of additional Towninfo: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_TRAINS :{LTBLUE}Display Range for Trains: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_ROAD :{LTBLUE}Display Range for Road Vehicles: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_SHIP :{LTBLUE}Display Range for Ships: {ORANGE}{STRING1} +STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_AIR :{LTBLUE}Display Range for Aircrafts: {ORANGE}{STRING1} + STR_CONFIG_PATCHES_AINEW_ACTIVE :{LTBLUE}Enable new AI (alpha): {ORANGE}{STRING1} STR_CONFIG_PATCHES_AI_IN_MULTIPLAYER :{LTBLUE}Allow AIs in multiplayer (experimental): {ORANGE}{STRING1} @@ -1045,6 +1060,7 @@ STR_CONFIG_PATCHES_STATIONS :{BLACK}Stations STR_CONFIG_PATCHES_ECONOMY :{BLACK}Economy STR_CONFIG_PATCHES_AI :{BLACK}Competitors +STR_CONFIG_PATCHES_SM :{BLACK}SmallMap STR_CONFIG_PATCHES_DISABLED :disabled STR_CONFIG_PATCHES_INT32 :{NUM} @@ -1565,6 +1581,7 @@ STR_TOWN_BRIBE_THE_LOCAL_AUTHORITY_DESC :{WHITE}{STRING}{}{YELLOW} Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{} Cost: {CURRENCY} STR_2055_TRAFFIC_CHAOS_IN_ROAD_REBUILDING :{BIGFONT}{BLACK}Traffic chaos in {TOWN}!{}{}Road rebuilding programme funded by {COMPANY} brings 6 months of misery to motorists! STR_2056 :{TINYFONT}{WHITE}{TOWN} +STR_2006_POPULATION_MINIMAP :{TINYFONT}{WHITE}Population: {COMMA} Houses: {COMMA} STR_2057 :{ORANGE}{TOWN}{BLACK} ({COMMA}) STR_2058_UNDER_CONSTRUCTION :{STRING} (under construction) STR_2059_IGLOO :Igloo @@ -1749,15 +1766,21 @@ STR_4824_BUBBLE_GENERATOR :Bubble Generator STR_4825_TOFFEE_QUARRY :Toffee Quarry STR_4826_SUGAR_MINE :Sugar Mine +STR_4829_SMALLMAP_ZOOM :{TINYFONT}{WHITE}zoom: {COMMA}% ({COMMA}) ############ range for requires starts STR_4827_REQUIRES :{BLACK}Requires: {YELLOW}{STRING} STR_4828_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}, {STRING} STR_4829_REQUIRES :{BLACK}Requires: {YELLOW}{STRING}, {STRING}, {STRING} +STR_4827_REQUIRES_SMALLMAP :{TINYFONT}{BLACK}-{STRING} +STR_4828_REQUIRES_SMALLMAP :{TINYFONT}{BLACK}-{STRING}, {STRING} +STR_4829_REQUIRES_SMALLMAP :{TINYFONT}{BLACK}-{STRING}, {STRING}, {STRING} ############ range for requires ends STR_482A_PRODUCTION_LAST_MONTH :{BLACK}Production last month: +STR_482A_PRODUCTION_LAST_MONTH_SMALLMAP :{BLACK}{WHITE}+ STR_482B_TRANSPORTED :{YELLOW}{STRING1}{BLACK} ({COMMA}% transported) +STR_482B_TRANSPORTED_SMALLMAP :{TINYFONT}{BLACK}+{STRING1}({COMMA}%) STR_482C_CENTER_THE_MAIN_VIEW_ON :{BLACK}Centre the main view on industry location STR_482D_NEW_UNDER_CONSTRUCTION :{BLACK}{BIGFONT}New {STRING} under construction near {TOWN}! STR_482E_NEW_BEING_PLANTED_NEAR :{BLACK}{BIGFONT}New {STRING} being planted near {TOWN}! Index: variables.h =================================================================== --- variables.h (revision 3597) +++ variables.h (working copy) @@ -177,6 +177,19 @@ bool ainew_active; // Is the new AI active? bool ai_in_multiplayer; // Do we allow AIs in multiplayer + /* new smallmap GUI */ + bool sm_zoom_active; /* activate zoom? */ + bool sm_zoom_smooth; /* */ + bool sm_usenew_legend; /* */ + bool sm_display_industry_signs; /* */ + uint32 sm_display_industry_signsrange; /* */ + bool sm_enable_additional_towninfo; /* */ + uint32 sm_display_towninforange; /* */ + uint32 sm_display_train; /* to which zoom level display trains? */ + uint32 sm_display_road; + uint32 sm_display_ship; + uint32 sm_display_aircraft; + /* * New Path Finding */ Index: smallmap_gui.c =================================================================== --- smallmap_gui.c (revision 3597) +++ smallmap_gui.c (working copy) @@ -16,9 +16,11 @@ #include "viewport.h" #include "player.h" #include "vehicle.h" +#include "industry.h" #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,16 +34,20 @@ { 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_PUSHIMGBTN, 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_PUSHIMGBTN, RESIZE_LRTB, 13, 336, 357, 258, 279, 0x2DF, STR_ZOOM_IN_SMALLMAP}, +{WWT_PUSHIMGBTN, 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}, }; + static int _smallmap_type; static bool _smallmap_show_towns = true; +void SmallMapRecentre(void); #define MK(a,b) a, b #define MKEND() 0xFFFF @@ -324,16 +330,16 @@ * @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); + 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); @@ -586,7 +592,9 @@ Pixel *ptr; int tile_x; int tile_y; + int tempcounter; ViewPort *vp; + double smallmap_zoom=WP(w,smallmap_d).zoom_ist; old_dpi = _cur_dpi; _cur_dpi = dpi; @@ -663,7 +671,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: @@ -680,6 +688,67 @@ x += 2; } + /* draw industries? */ + if (type == 2 && (smallmap_zoom<((double)_patches.sm_display_industry_signsrange/10) && ( _patches.sm_display_industry_signs))) { + Industry *i; + FOR_ALL_INDUSTRIES(i) { + if (i->xy != 0) { + // Remap the town coordinate + Point pt = RemapCoords( + (int)((TileX(i->xy) / smallmap_zoom) * 16 - WP(w, smallmap_d).scroll_x) / 16, + (int)((TileY(i->xy) / smallmap_zoom) * 16 - WP(w, smallmap_d).scroll_y) / 16, + 0); + x = pt.x - WP(w,smallmap_d).subscroll + 3; + y = pt.y; + + + int c1 = _industry_smallmap_colors[_m[i->xy].m5]; + /* draw the background for the text */ + tempcounter=0; + if (i->accepts_cargo[0] != CT_INVALID) tempcounter+=6; + if (i->accepts_cargo[1] != CT_INVALID) tempcounter+=6; + if (i->accepts_cargo[2] != CT_INVALID) tempcounter+=6; + if (i->produced_cargo[0] != CT_INVALID) tempcounter+=6; + if (i->produced_cargo[1] != CT_INVALID) tempcounter+=6; + + GfxFillRect(x-3, y-3, x+121, y+tempcounter+4, 13); + GfxFillRect(x-2, y-2, x+120, y+tempcounter+3, c1); + + tempcounter = 0; + if (i->accepts_cargo[0] != CT_INVALID) { + StringID str; + + SetDParam(0, _cargoc.names_s[i->accepts_cargo[0]]); + str = STR_4827_REQUIRES_SMALLMAP; + if (i->accepts_cargo[1] != CT_INVALID) { + SetDParam(1, _cargoc.names_s[i->accepts_cargo[1]]); + str = STR_4828_REQUIRES_SMALLMAP; + if (i->accepts_cargo[2] != CT_INVALID) { + SetDParam(2, _cargoc.names_s[i->accepts_cargo[2]]); + str = STR_4829_REQUIRES_SMALLMAP; + } + } + DrawString(x, y, str, 12); + tempcounter = 6; + } + + if (i->produced_cargo[0] != CT_INVALID) { + SetDParam(0, _cargoc.names_long[i->produced_cargo[0]]); + SetDParam(1, i->total_production[0]); + + SetDParam(2, i->pct_transported[0] * 100 >> 8); + DrawString(x, y + tempcounter, STR_482B_TRANSPORTED_SMALLMAP, 12); + + if (i->produced_cargo[1] != CT_INVALID) { + SetDParam(0, _cargoc.names_long[i->produced_cargo[1]]); + SetDParam(1, i->total_production[1]); + SetDParam(2, i->pct_transported[1] * 100 >> 8); + DrawString(x , y+tempcounter+6, STR_482B_TRANSPORTED_SMALLMAP, 12); + } + } + } + } + } /* draw vehicles? */ if (type == 0 || type == 1) { Vehicle *v; @@ -691,40 +760,55 @@ (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0) { // Remap into flat coordinates. Point pt = RemapCoords( - (v->x_pos - WP(w,smallmap_d).scroll_x) / 16, - (v->y_pos - WP(w,smallmap_d).scroll_y) / 16, + ((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; + /* if ((smallmap_zoom<0.125 && (v->type==VEH_Train || v->type==VEH_Road || v->type==VEH_Ship)) || (v->type==VEH_Aircraft && (smallmap_zoom<1))) */ - // Check if y is out of bounds? - y -= dpi->top; - if (!IS_INT_INSIDE(y, 0, dpi->height)) continue; - - // Default is to draw both pixels. - skip = false; - - // Offset X coordinate - x -= WP(w,smallmap_d).subscroll + 3 + dpi->left; - - if (x < 0) { - // if x+1 is 0, that means we're on the very left edge, - // and should thus only draw a single pixel - if (++x != 0) continue; - skip = true; - } else if (x >= dpi->width - 1) { - // Check if we're at the very right edge, and if so draw only a single pixel - if (x != dpi->width - 1) continue; - skip = true; + if ( (smallmap_zoom<((double)_patches.sm_display_train/10) && (v->type==VEH_Train)) || + (smallmap_zoom<((double)_patches.sm_display_road/10) && (v->type==VEH_Road)) || + (smallmap_zoom<((double)_patches.sm_display_ship/10) && (v->type==VEH_Ship)) || + (smallmap_zoom<((double)_patches.sm_display_aircraft/10) && (v->type==VEH_Aircraft)) + ) { + /* draw the vehicle if near enough*/ + int image = v->cur_image; + uint32 ormod = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(v->owner)); + if (v->vehstatus & VS_CRASHED) + ormod = PALETTE_CRASH; + DrawSprite(image | ormod, x, y); + } else { + /* far away, just draw that ugly pixel */ + // Check if y is out of bounds? + y -= dpi->top; + if (!IS_INT_INSIDE(y, 0, dpi->height)) continue; + + // Default is to draw both pixels. + skip = false; + + // Offset X coordinate + x -= WP(w,smallmap_d).subscroll + 3 + dpi->left; + + if (x < 0) { + // if x+1 is 0, that means we're on the very left edge, + // and should thus only draw a single pixel + if (++x != 0) continue; + skip = true; + } else if (x >= dpi->width - 1) { + // Check if we're at the very right edge, and if so draw only a single pixel + if (x != dpi->width - 1) continue; + skip = true; + } + + // Calculate pointer to pixel and the color + ptr = dpi->dst_ptr + y * dpi->pitch + x; + color = (type == 1) ? _vehicle_type_colors[v->type-0x10] : 0xF; + + // And draw either one or two pixels depending on clipping + ptr[0] = color; + if (!skip) ptr[1] = color; } - - // Calculate pointer to pixel and the color - ptr = dpi->dst_ptr + y * dpi->pitch + x; - color = (type == 1) ? _vehicle_type_colors[v->type-0x10] : 0xF; - - // And draw either one or two pixels depending on clipping - ptr[0] = color; - if (!skip) ptr[1] = color; } } } @@ -736,9 +820,9 @@ if (t->xy != 0) { // Remap the town coordinate 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); + (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; @@ -747,9 +831,18 @@ x < dpi->left + dpi->width && y + 6 > dpi->top && y < dpi->top + dpi->height) { - // And draw it. - SetDParam(0, t->index); - DrawString(x, y, STR_2056, 12); + + /* draw the town name if in valid range*/ + if (smallmap_zoom<10){ + SetDParam(0, t->index); + DrawString(x, y, STR_2056, 12); + } + if ( (smallmap_zoom<((double)_patches.sm_display_towninforange/10) && ( _patches.sm_enable_additional_towninfo))) { + /* draw some additional info if in valid range*/ + SetDParam(0, t->population); + SetDParam(1, t->num_houses); + DrawString(x, y+8, STR_2006_POPULATION_MINIMAP, 0); + } } } } @@ -763,11 +856,11 @@ vp = FindWindowById(WC_MAIN_WINDOW,0)->viewport; pt = RemapCoords(WP(w, smallmap_d).scroll_x, WP(w, smallmap_d).scroll_y, 0); + 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 = vp->virtual_left - pt.x; - y = vp->virtual_top - pt.y; - x2 = (x + vp->virtual_width) / 16; - y2 = (y + vp->virtual_height) / 16; x /= 16; y /= 16; @@ -780,11 +873,113 @@ DrawHorizMapIndicator(x, y, x2, y); DrawHorizMapIndicator(x, y2, x2, y2); } + _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_ist; + 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; + DEBUG(misc,10)("Recenter Location: x: %i, y: %i, scroll_x: %i, scroll_y: %i, subscroll: %i",x,y,WP(w,smallmap_d).scroll_x,WP(w,smallmap_d).scroll_y,WP(w,smallmap_d).subscroll); + + if (_patches.sm_zoom_active){ + /* 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_ist; + + 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; + DEBUG(misc,10)("Scroll: x: %i, y: %i, scroll_x: %i, scroll_y: %i, subscroll: %i",x,y,WP(w,smallmap_d).scroll_x,WP(w,smallmap_d).scroll_y,WP(w,smallmap_d).subscroll); +} + static void SmallMapWindowProc(Window *w, WindowEvent *e) { + /* zoom smoothly :) */ + if (WP(w,smallmap_d).zoom_ist != WP(w,smallmap_d).zoom_soll){ + if (_patches.sm_zoom_smooth){ + double diff=WP(w,smallmap_d).zoom_soll-WP(w,smallmap_d).zoom_ist; + double diff_abs=(diff<0)?diff*-1:diff; + DEBUG(misc,10)("diff: %f, diff_abs: %f",(float)diff,(float)diff_abs); + if (diff_abs < 0.01){ + WP(w,smallmap_d).zoom_ist=WP(w,smallmap_d).zoom_soll; + SmallMapRecentre(); + DEBUG(misc,10)("ZOOMING smoothly FINISHED ist: %f, soll: %f",(float)WP(w,smallmap_d).zoom_ist,(float)WP(w,smallmap_d).zoom_soll); + } else { + WP(w,smallmap_d).zoom_ist+=diff/10; + SmallMapRecentre(); + DEBUG(misc,10)("ZOOMING smoothly ist: %f, soll: %f, diff: %f",(float)WP(w,smallmap_d).zoom_ist,(float)WP(w,smallmap_d).zoom_soll,(float)diff); + } + }else{ + WP(w,smallmap_d).zoom_ist=WP(w,smallmap_d).zoom_soll; + SmallMapRecentre(); + DEBUG(misc,10)("ZOOMING unsmoothly: %f",(float)WP(w,smallmap_d).zoom_ist); + } + } + double smallmap_zoom=WP(w,smallmap_d).zoom_ist; + switch (e->event) { case WE_PAINT: { const uint16 *tbl; @@ -820,6 +1015,29 @@ return; DrawSmallMap(&new_dpi, w, _smallmap_type, _smallmap_show_towns); + + if (_patches.sm_zoom_active){ + CLRBIT(w->disabled_state, 13); + CLRBIT(w->disabled_state, 14); + + /* draw the zoom level */ + int displayedzoomlevel=0; + if (smallmap_zoom<=1) + displayedzoomlevel=100+(1-smallmap_zoom)*100; + else if (smallmap_zoom==1) + displayedzoomlevel=100; + else if (smallmap_zoom>1) + displayedzoomlevel=100-(smallmap_zoom)*2; + + SetDParam(0, (int)displayedzoomlevel); + SetDParam(1, (int)(smallmap_zoom*10)); + DrawString(4, w->height - 64 - 2, STR_4829_SMALLMAP_ZOOM, 12); + } else { + WP(w,smallmap_d).zoom_soll=1; + SETBIT(w->disabled_state, 13); + SETBIT(w->disabled_state, 14); + } + } break; case WE_CLICK: @@ -833,8 +1051,9 @@ 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); - 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 +1070,44 @@ 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 (_patches.sm_zoom_active){ + DEBUG(misc,10)("1ZOOMING ist: %f, soll: %f",(float)WP(w,smallmap_d).zoom_ist,(float)WP(w,smallmap_d).zoom_soll); + if (smallmap_zoom > 0.04){ // can zoom in up to 5 times + WP(w,smallmap_d).zoom_soll=WP(w,smallmap_d).zoom_ist / 2; + } + DEBUG(misc,10)("2ZOOMING ist: %f, soll: %f",(float)WP(w,smallmap_d).zoom_ist,(float)WP(w,smallmap_d).zoom_soll); + SmallMapRecentre(); + SetWindowDirty(w); + SndPlayFx(SND_15_BEEP); + } + break; + + case 14: /* zoom out */ + if (_patches.sm_zoom_active){ + DEBUG(misc,10)("zoom-level: %f",(float)smallmap_zoom); + if (smallmap_zoom < 32){ + WP(w,smallmap_d).zoom_soll=WP(w,smallmap_d).zoom_ist * 2; + } + SmallMapRecentre(); + SetWindowDirty(w); + SndPlayFx(SND_15_BEEP); + } + break; + } break; case WE_RCLICK: @@ -873,6 +1123,41 @@ /* update the window every now and then */ if ((++w->vscroll.pos & 0x1F) == 0) SetWindowDirty(w); break; + + case WE_SCROLL: + /* 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_MOUSEWHEEL: + if (_patches.sm_zoom_active){ + /* DEBUG(misc,10)("GOT WHEEL-EVENT: %i",e->wheel.wheel); */ + if ((e->wheel.wheel<0) && (smallmap_zoom > 0.04)){ /* can zoom in up to 5 times */ + WP(w,smallmap_d).zoom_soll=WP(w,smallmap_d).zoom_ist / (2*(-e->wheel.wheel)); + } else if ((e->wheel.wheel>0) && (smallmap_zoom < 32)) { + WP(w,smallmap_d).zoom_soll=WP(w,smallmap_d).zoom_ist * (2*(e->wheel.wheel)); + } else { + return; + } + DEBUG(misc,10)("zoom-level: %f",(float)smallmap_zoom); + SmallMapRecentre(); + 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; } } @@ -895,11 +1180,13 @@ w->click_state = ((1<<5) << _smallmap_type) | (_smallmap_show_towns << 12); w->resize.width = 350; w->resize.height = 250; - + WP(w,smallmap_d).zoom_ist = 1; + WP(w,smallmap_d).zoom_soll = 1; + double smallmap_zoom = WP(w,smallmap_d).zoom_ist; vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; - 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: settings.c =================================================================== --- settings.c (revision 3597) +++ settings.c (working copy) @@ -906,6 +906,20 @@ {"population_in_label", SDT_BOOL, (void*)true, &_patches.population_in_label, NULL}, {"link_terraform_toolbar", SDT_BOOL, (void*)false, &_patches.link_terraform_toolbar, NULL}, + + {"sm_zoom_active", SDT_BOOL, (void*)false, &_patches.sm_zoom_active, NULL}, + {"sm_zoom_smooth", SDT_BOOL, (void*)false, &_patches.sm_zoom_smooth, NULL}, + {"sm_usenew_legend", SDT_BOOL, (void*)false, &_patches.sm_usenew_legend, NULL}, + {"sm_display_industry_signs", SDT_BOOL, (void*)false, &_patches.sm_display_industry_signs, NULL}, + {"sm_enable_additional_towninfo", SDT_BOOL, (void*)false, &_patches.sm_enable_additional_towninfo, NULL}, + {"sm_display_industry_signsrange", SDT_INT32, (void*)0, &_patches.sm_display_industry_signsrange, NULL}, + {"sm_display_towninforange", SDT_INT32, (void*)0, &_patches.sm_display_towninforange, NULL}, + {"sm_display_train", SDT_INT32, (void*)0, &_patches.sm_display_train, NULL}, + {"sm_display_road", SDT_INT32, (void*)0, &_patches.sm_display_road, NULL}, + {"sm_display_ship", SDT_INT32, (void*)0, &_patches.sm_display_ship, NULL}, + {"sm_display_aircraft", SDT_INT32, (void*)0, &_patches.sm_display_aircraft, NULL}, + + {NULL, 0, NULL, NULL, NULL} }; Index: industry_gui.c =================================================================== --- industry_gui.c (revision 3597) +++ industry_gui.c (working copy) @@ -420,7 +420,7 @@ { WWT_6, RESIZE_NONE, 9, 2, 257, 16, 103, 0x0, STR_NULL}, { WWT_IMGBTN, RESIZE_NONE, 9, 0, 259, 106, 147, 0x0, STR_NULL}, { WWT_PUSHTXTBTN, RESIZE_NONE, 9, 0, 129, 148, 159, STR_00E4_LOCATION, STR_482C_CENTER_THE_MAIN_VIEW_ON}, -{ WWT_IMGBTN, RESIZE_NONE, 9, 130, 259, 148, 159, 0x0, STR_NULL}, +{ WWT_PUSHTXTBTN, RESIZE_NONE, 9, 130, 259, 148, 159, STR_00E4_LOCATION, STR_482C_CENTER_THE_MAIN_VIEW_ON}, { WIDGETS_END}, }; Index: settings_gui.c =================================================================== --- settings_gui.c (revision 3597) +++ settings_gui.c (working copy) @@ -770,8 +770,25 @@ {PE_BOOL, 0, STR_CONFIG_PATCHES_AI_BUILDS_ROADVEH,"ai_disable_veh_roadveh",&_patches.ai_disable_veh_roadveh, 0, 0, 0, NULL}, {PE_BOOL, 0, STR_CONFIG_PATCHES_AI_BUILDS_AIRCRAFT,"ai_disable_veh_aircraft",&_patches.ai_disable_veh_aircraft,0, 0, 0, NULL}, {PE_BOOL, 0, STR_CONFIG_PATCHES_AI_BUILDS_SHIPS,"ai_disable_veh_ship",&_patches.ai_disable_veh_ship, 0, 0, 0, NULL}, + {PE_BOOL, 0, STR_CONFIG_PATCHES_AI_BUILDS_SHIPS,"ai_disable_veh_ship",&_patches.ai_disable_veh_ship, 0, 0, 0, NULL}, }; +static const PatchEntry _patches_sm[] = { + {PE_BOOL, 0, STR_CONFIG_PATCHES_SM_ACTIVE_ZOOM, "sm_zoom_active", &_patches.sm_zoom_active, 0, 1, 1, NULL}, + {PE_BOOL, 0, STR_CONFIG_PATCHES_SM_ACTIVE_ZOOM_SMOOTH, "sm_zoom_smooth", &_patches.sm_zoom_smooth, 0, 1, 1, NULL}, + {PE_BOOL, 0, STR_CONFIG_PATCHES_SM_NEW_LEGEND, "sm_usenew_legend", &_patches.sm_usenew_legend, 0, 1, 1, NULL}, + + {PE_BOOL, 0, STR_CONFIG_PATCHES_SM_DISPLAY_INDUSTRY_SIGNS, "sm_display_industry_signs", &_patches.sm_display_industry_signs, 0, 0, 0, NULL}, + {PE_INT32, 0, STR_CONFIG_PATCHES_SM_INDUSTRY_SIGNS_RANGE,"sm_display_industry_signsrange",&_patches.sm_display_industry_signsrange, 0, 330, 1, NULL}, + {PE_BOOL, 0, STR_CONFIG_PATCHES_SM_ADDITIONAL_TOWNINFO,"sm_enable_additional_towninfo",&_patches.sm_enable_additional_towninfo, 0, 0, 0, NULL}, + {PE_INT32, 0, STR_CONFIG_PATCHES_SM_ADDITIONAL_TOWNINFO_RANGE,"sm_display_towninforange",&_patches.sm_display_towninforange, 0, 330, 1, NULL}, + + {PE_INT32, 0, STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_TRAINS,"sm_display_train",&_patches.sm_display_train, 0, 330, 1, NULL}, + {PE_INT32, 0, STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_ROAD,"sm_display_road",&_patches.sm_display_road, 0, 330, 1, NULL}, + {PE_INT32, 0, STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_SHIP,"sm_display_ship",&_patches.sm_display_ship, 0, 330, 1, NULL}, + {PE_INT32, 0, STR_CONFIG_PATCHES_SM_DISPLAY_RANGE_AIR,"sm_display_aircraft",&_patches.sm_display_aircraft, 0, 330, 1, NULL}, +}; + typedef struct PatchPage { const PatchEntry *entries; uint num; @@ -784,6 +801,7 @@ {_patches_stations, lengthof(_patches_stations) }, {_patches_economy, lengthof(_patches_economy) }, {_patches_ai, lengthof(_patches_ai) }, + {_patches_sm, lengthof(_patches_sm) }, }; @@ -990,7 +1008,7 @@ break; } - case 4: case 5: case 6: case 7: case 8: case 9: + case 4: case 5: case 6: case 7: case 8: case 9: case 10: WP(w,def_d).data_1 = e->click.widget - 4; DeleteWindowById(WC_QUERY_STRING, 0); SetWindowDirty(w); @@ -1145,6 +1163,7 @@ { WWT_TEXTBTN, RESIZE_NONE, 3, 271, 357, 16, 27, STR_CONFIG_PATCHES_STATIONS, STR_NULL}, { WWT_TEXTBTN, RESIZE_NONE, 3, 10, 96, 28, 39, STR_CONFIG_PATCHES_ECONOMY, STR_NULL}, { WWT_TEXTBTN, RESIZE_NONE, 3, 97, 183, 28, 39, STR_CONFIG_PATCHES_AI, STR_NULL}, +{ WWT_TEXTBTN, RESIZE_NONE, 3, 184, 270, 28, 39, STR_CONFIG_PATCHES_SM, STR_NULL}, { WIDGETS_END}, }; Index: window.c =================================================================== --- window.c (revision 3597) +++ window.c (working copy) @@ -119,9 +119,15 @@ { const Widget *wi1, *wi2; Scrollbar *sb; - + if (widget < 0) return; + /* send WE_MOUSEWHEEL event to window */ + WindowEvent e; + e.event = WE_MOUSEWHEEL; + e.wheel.wheel=wheel; + w->wndproc(w, &e); + wi1 = &w->widget[widget]; wi2 = &w->widget[widget + 1]; @@ -1177,66 +1183,14 @@ WP(w,vp_d).scrollpos_y += dy << vp->zoom; } 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 = 0; _cursor.delta.y = 0; return false; @@ -1440,6 +1394,7 @@ } else { if (mousewheel) DispatchMouseWheelEvent(w, GetWidgetFromPos(w, x - w->left, y - w->top), mousewheel); + switch (click) { case 1: DispatchLeftClickEvent(w, x - w->left, y - w->top); break; Index: window.h =================================================================== --- window.h (revision 3597) +++ window.h (working copy) @@ -134,6 +134,16 @@ uint wparam; // additional message-specific information uint lparam; // additional message-specific information } message; + + struct { + byte event; + Point delta; // cursor delta information + } scroll; + + struct { + byte event; + int wheel; // scrollwheel change + } wheel; }; enum WindowKeyCodes { @@ -376,8 +386,10 @@ int32 scroll_x; int32 scroll_y; int32 subscroll; + double zoom_ist; + double zoom_soll; } smallmap_d; -assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(traindetails_d)); +assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(smallmap_d)); typedef struct { uint32 face; @@ -497,7 +509,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 };