# HG changeset patch # User richk # Date 1213708933 0 # Node ID cd9968b6f96b9ffb021c16fbd06f5d0187abdfe0 # Parent d8811e327d12c1bc3a696191fc01094562eba851 (svn r13548) [NewGRF_ports] -Sync: with trunk r13412:13544. diff -r d8811e327d12 -r cd9968b6f96b bin/data/openttdd.grf Binary file bin/data/openttdd.grf has changed diff -r d8811e327d12 -r cd9968b6f96b bin/data/openttdw.grf Binary file bin/data/openttdw.grf has changed diff -r d8811e327d12 -r cd9968b6f96b projects/openttd_vs80.vcproj --- a/projects/openttd_vs80.vcproj Tue Jun 17 10:32:49 2008 +0000 +++ b/projects/openttd_vs80.vcproj Tue Jun 17 13:22:13 2008 +0000 @@ -1136,6 +1136,10 @@ > + + @@ -1460,6 +1464,10 @@ > + + diff -r d8811e327d12 -r cd9968b6f96b projects/openttd_vs90.vcproj --- a/projects/openttd_vs90.vcproj Tue Jun 17 10:32:49 2008 +0000 +++ b/projects/openttd_vs90.vcproj Tue Jun 17 13:22:13 2008 +0000 @@ -1121,6 +1121,10 @@ > + + @@ -1441,6 +1445,10 @@ > + + diff -r d8811e327d12 -r cd9968b6f96b source.list --- a/source.list Tue Jun 17 10:32:49 2008 +0000 +++ b/source.list Tue Jun 17 13:22:13 2008 +0000 @@ -209,6 +209,7 @@ map_type.h core/math_func.hpp md5.h +core/mem_func.hpp minilzo.h mixer.h music.h @@ -290,6 +291,7 @@ signs_type.h slope_func.h slope_type.h +core/sort_func.hpp sortlist_type.h sound_func.h sound_type.h diff -r d8811e327d12 -r cd9968b6f96b src/blitter/32bpp_optimized.cpp --- a/src/blitter/32bpp_optimized.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/blitter/32bpp_optimized.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -10,7 +10,7 @@ static FBlitter_32bppOptimized iFBlitter_32bppOptimized; -void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) +template inline void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp) { const SpriteLoader::CommonPixel *src, *src_line; uint32 *dst, *dst_line; @@ -66,6 +66,27 @@ } } +template inline void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, ZoomLevel zoom) +{ + switch (zoom) { + default: NOT_REACHED(); + case ZOOM_LVL_NORMAL: Draw(bp); return; + case ZOOM_LVL_OUT_2X: Draw(bp); return; + case ZOOM_LVL_OUT_4X: Draw(bp); return; + case ZOOM_LVL_OUT_8X: Draw(bp); return; + } +} + +void Blitter_32bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) +{ + switch (mode) { + default: NOT_REACHED(); + case BM_NORMAL: Draw (bp, zoom); return; + case BM_COLOUR_REMAP: Draw(bp, zoom); return; + case BM_TRANSPARENT: Draw (bp, zoom); return; + } +} + Sprite *Blitter_32bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator) { Sprite *dest_sprite; diff -r d8811e327d12 -r cd9968b6f96b src/blitter/32bpp_optimized.hpp --- a/src/blitter/32bpp_optimized.hpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/blitter/32bpp_optimized.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -14,6 +14,9 @@ /* virtual */ Sprite *Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator); /* virtual */ const char *GetName() { return "32bpp-optimized"; } + + template void Draw(Blitter::BlitterParams *bp); + template void Draw(Blitter::BlitterParams *bp, ZoomLevel zoom); }; class FBlitter_32bppOptimized: public BlitterFactory { diff -r d8811e327d12 -r cd9968b6f96b src/bridge_gui.cpp --- a/src/bridge_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/bridge_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -119,6 +119,7 @@ { this->bridges->SetListing(this->last_sorting); this->bridges->SetSortFuncs(this->sorter_funcs); + this->bridges->NeedResort(); this->SortBridgeList(); /* Change the data, or the caption of the gui. Set it to road or rail, accordingly */ @@ -150,7 +151,7 @@ { this->DrawWidgets(); - this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, (this->bridges->flags & VL_DESC) ? SBS_DOWN : SBS_UP); + this->DrawSortButtonState(BBSW_DROPDOWN_ORDER, this->bridges->IsDescSortOrder() ? SBS_DOWN : SBS_UP); uint y = this->widget[BBSW_BRIDGE_LIST].top + 2; diff -r d8811e327d12 -r cd9968b6f96b src/bridge_map.h --- a/src/bridge_map.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/bridge_map.h Tue Jun 17 13:22:13 2008 +0000 @@ -200,5 +200,15 @@ MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL, r); } +/** + * Make a bridge ramp for aqueducts. + * @param t the tile to make a bridge ramp + * @param o the new owner of the bridge ramp + * @param d the direction this ramp must be facing + */ +static inline void MakeAqueductBridgeRamp(TileIndex t, Owner o, DiagDirection d) +{ + MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER, 0); +} #endif /* BRIDGE_MAP_H */ diff -r d8811e327d12 -r cd9968b6f96b src/core/alloc_func.hpp --- a/src/core/alloc_func.hpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/core/alloc_func.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -90,4 +90,7 @@ return t_ptr; } +/** alloca() has to be called in the parent function, so define AllocaM() as a macro */ +#define AllocaM(T, num_elements) ((T*)alloca((num_elements) * sizeof(T))) + #endif /* ALLOC_FUNC_HPP */ diff -r d8811e327d12 -r cd9968b6f96b src/core/mem_func.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/mem_func.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -0,0 +1,97 @@ +/* $Id$ */ + +/** @file mem_func.hpp Functions related to memory operations. */ + +#ifndef MEM_FUNC_HPP +#define MEM_FUNC_HPP + +#include +#include "math_func.hpp" + +/** + * Type-safe version of memcpy(). + * + * @param destination Pointer to the destination buffer + * @param source Pointer to the source buffer + * @param num number of items to be copied. (!not number of bytes!) + */ +template +FORCEINLINE void MemCpyT(T *destination, const T *source, uint num = 1) +{ + memcpy(destination, source, num * sizeof(T)); +} + +/** + * Type-safe version of memmove(). + * + * @param destination Pointer to the destination buffer + * @param source Pointer to the source buffer + * @param num number of items to be copied. (!not number of bytes!) + */ +template +FORCEINLINE void MemMoveT(T *destination, const T *source, uint num = 1) +{ + memmove(destination, source, num * sizeof(T)); +} + +/** + * Type-safe version of memset(). + * + * @param ptr Pointer to the destination buffer + * @param value Value to be set + * @param num number of items to be set (!not number of bytes!) + */ +template +FORCEINLINE void MemSetT(T *ptr, int value, uint num = 1) +{ + memset(ptr, value, num * sizeof(T)); +} + +/** + * Type-safe version of memcmp(). + * + * @param ptr1 Pointer to the first buffer + * @param ptr2 Pointer to the second buffer + * @param num Number of items to compare. (!not number of bytes!) + * @return an int value indicating the relationship between the content of the two buffers + */ +template +FORCEINLINE int MemCmpT(const T *ptr1, const T *ptr2, uint num = 1) +{ + return memcmp(ptr1, ptr2, num * sizeof(T)); +} + +/** + * Type safe memory reverse operation. + * Reverse a block of memory in steps given by the + * type of the pointers. + * + * @param ptr1 Start-pointer to the block of memory. + * @param ptr2 End-pointer to the block of memory. + */ +template +FORCEINLINE void MemReverseT(T *ptr1, T *ptr2) +{ + assert(ptr1 != NULL && ptr2 != NULL); + assert(ptr1 < ptr2); + + do { + Swap(*ptr1, *ptr2); + } while (++ptr1 < --ptr2); +} + +/** + * Type safe memory reverse operation (overloaded) + * + * @param ptr Pointer to the block of memory. + * @param num The number of items we want to reverse. + */ +template +FORCEINLINE void MemReverseT(T *ptr, uint num) +{ + assert(ptr != NULL); + + MemReverseT(ptr, ptr + (num - 1)); +} + +#endif /* MEM_FUNC_HPP */ diff -r d8811e327d12 -r cd9968b6f96b src/core/sort_func.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/sort_func.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -0,0 +1,85 @@ +/* $Id$ */ + +/** @file sort_func.hpp Functions related to sorting operations. */ + +#ifndef SORT_FUNC_HPP +#define SORT_FUNC_HPP + +#include +#include "math_func.hpp" +#include "mem_func.hpp" + +/** + * Type safe qsort() + * + * @todo replace the normal qsort with this one + * @note Use this sort for irregular sorted data. + * + * @param base Pointer to the first element of the array to be sorted. + * @param num Number of elements in the array pointed by base. + * @param comparator Function that compares two elements. + * @param desc Sort descending. + */ +template +FORCEINLINE void QSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false) +{ + if (num < 2) return; + + qsort(base, num, sizeof(T), (int (CDECL *)(const void *, const void *))comparator); + + if (desc) MemReverseT(base, num); +} + +/** + * Type safe Gnome Sort. + * + * This is a slightly modifyied Gnome search. The basic + * Gnome search trys to sort already sorted list parts. + * The modification skips these. + * + * @note Use this sort for presorted / regular sorted data. + * + * @param base Pointer to the first element of the array to be sorted. + * @param num Number of elements in the array pointed by base. + * @param comparator Function that compares two elements. + * @param desc Sort descending. + */ +template +FORCEINLINE void GSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false) +{ + if (num < 2) return; + + assert(base != NULL); + assert(comparator != NULL); + + T *a = base; + T *b = base + 1; + uint offset = 0; + + while (num > 1) { + const int diff = comparator(a, b); + if ((!desc && diff <= 0) || (desc && diff >= 0)) { + if (offset != 0) { + /* Jump back to the last direction switch point */ + a += offset; + b += offset; + offset = 0; + continue; + } + + a++; + b++; + num--; + } else { + Swap(*a, *b); + + if (a == base) continue; + + a--; + b--; + offset++; + } + } +} + +#endif /* SORT_FUNC_HPP */ diff -r d8811e327d12 -r cd9968b6f96b src/dock_gui.cpp --- a/src/dock_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/dock_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -69,6 +69,12 @@ DoCommandP(tile, 0, 0, CcBuildDocks, CMD_BUILD_LOCK | CMD_MSG(STR_CANT_BUILD_LOCKS)); } +static void PlaceDocks_Aqueduct(TileIndex tile) +{ + VpStartPlaceSizing(tile, VPM_X_OR_Y, DDSP_BUILD_BRIDGE); +} + + /** Enum referring to the widgets of the build dock toolbar */ enum DockToolbarWidgets { DTW_BEGIN = 0, ///< Start of toolbar widgets @@ -83,6 +89,7 @@ DTW_DEPOT, ///< Build depot button DTW_STATION, ///< Build station button DTW_BUOY, ///< Build buoy button + DTW_BUILD_AQUEDUCT, ///< Build aqueduct button DTW_END, ///< End of toolbar widgets }; @@ -120,6 +127,11 @@ HandlePlacePushButton(w, DTW_BUOY, SPR_CURSOR_BOUY, VHM_RECT, PlaceDocks_Buoy); } +static void BuildDocksClick_Aqueduct(Window *w) +{ + HandlePlacePushButton(w, DTW_BUILD_AQUEDUCT, SPR_CURSOR_AQUEDUCT, VHM_RECT, PlaceDocks_Aqueduct); +} + typedef void OnButtonClick(Window *w); static OnButtonClick * const _build_docks_button_proc[] = { @@ -129,7 +141,8 @@ BuildDocksClick_Demolish, BuildDocksClick_Depot, BuildDocksClick_Dock, - BuildDocksClick_Buoy + BuildDocksClick_Buoy, + BuildDocksClick_Aqueduct }; struct BuildDocksToolbarWindow : Window { @@ -164,6 +177,8 @@ case '4': BuildDocksClick_Depot(this); break; case '5': BuildDocksClick_Dock(this); break; case '6': BuildDocksClick_Buoy(this); break; + case 'B': + case '7': BuildDocksClick_Aqueduct(this); break; default: return ES_NOT_HANDLED; } return ES_HANDLED; @@ -183,6 +198,11 @@ { if (pt.x != -1) { switch (select_proc) { + case DDSP_BUILD_BRIDGE: + ResetObjectToPlace(); + extern void CcBuildBridge(bool success, TileIndex tile, uint32 p1, uint32 p2); + DoCommandP(end_tile, start_tile, TRANSPORT_WATER << 15, CcBuildBridge, CMD_BUILD_BRIDGE | CMD_MSG(STR_CAN_T_BUILD_AQUEDUCT_HERE)); + case DDSP_DEMOLISH_AREA: GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; @@ -214,8 +234,8 @@ static const Widget _build_docks_toolb_widgets[] = { { WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, // DTW_CLOSEBOX -{ WWT_CAPTION, RESIZE_NONE, 7, 11, 123, 0, 13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS}, // DTW_CAPTION -{ WWT_STICKYBOX, RESIZE_NONE, 7, 124, 135, 0, 13, 0x0, STR_STICKY_BUTTON}, // DTW_STICKY +{ WWT_CAPTION, RESIZE_NONE, 7, 11, 145, 0, 13, STR_9801_DOCK_CONSTRUCTION, STR_018C_WINDOW_TITLE_DRAG_THIS}, // DTW_CAPTION +{ WWT_STICKYBOX, RESIZE_NONE, 7, 146, 157, 0, 13, 0x0, STR_STICKY_BUTTON}, // DTW_STICKY { WWT_IMGBTN, RESIZE_NONE, 7, 0, 21, 14, 35, SPR_IMG_BUILD_CANAL, STR_BUILD_CANALS_TIP}, // DTW_CANAL { WWT_IMGBTN, RESIZE_NONE, 7, 22, 43, 14, 35, SPR_IMG_BUILD_LOCK, STR_BUILD_LOCKS_TIP}, // DTW_LOCK @@ -225,11 +245,12 @@ { WWT_IMGBTN, RESIZE_NONE, 7, 70, 91, 14, 35, SPR_IMG_SHIP_DEPOT, STR_981E_BUILD_SHIP_DEPOT_FOR_BUILDING}, // DTW_DEPOT { WWT_IMGBTN, RESIZE_NONE, 7, 92, 113, 14, 35, SPR_IMG_SHIP_DOCK, STR_981D_BUILD_SHIP_DOCK}, // DTW_STATION { WWT_IMGBTN, RESIZE_NONE, 7, 114, 135, 14, 35, SPR_IMG_BOUY, STR_9834_POSITION_BUOY_WHICH_CAN}, // DTW_BUOY +{ WWT_IMGBTN, RESIZE_NONE, 7, 136, 157, 14, 35, SPR_IMG_AQUEDUCT, STR_BUILD_AQUEDUCT}, // DTW_BUILD_AQUEDUCT { WIDGETS_END}, }; static const WindowDesc _build_docks_toolbar_desc = { - WDP_ALIGN_TBR, 22, 136, 36, 136, 36, + WDP_ALIGN_TBR, 22, 158, 36, 158, 36, WC_BUILD_TOOLBAR, WC_NONE, WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_STICKY_BUTTON, _build_docks_toolb_widgets, diff -r d8811e327d12 -r cd9968b6f96b src/driver.cpp --- a/src/driver.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/driver.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -14,8 +14,8 @@ VideoDriver *_video_driver; char _ini_videodriver[32]; int _num_resolutions; -uint16 _resolutions[32][2]; -uint16 _cur_resolution[2]; +Dimension _resolutions[32]; +Dimension _cur_resolution; SoundDriver *_sound_driver; char _ini_sounddriver[32]; @@ -183,3 +183,18 @@ return p; } + +/** Frees memory used for this->name + */ +DriverFactoryBase::~DriverFactoryBase() { + if (this->name == NULL) return; + + /* Prefix the name with driver type to make it unique */ + char buf[32]; + strecpy(buf, GetDriverTypeName(type), lastof(buf)); + strecpy(buf + 5, this->name, lastof(buf)); + + GetDrivers().erase(buf); + if (GetDrivers().empty()) delete &GetDrivers(); + free(this->name); +} diff -r d8811e327d12 -r cd9968b6f96b src/driver.h --- a/src/driver.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/driver.h Tue Jun 17 13:22:13 2008 +0000 @@ -67,20 +67,7 @@ name(NULL) {} - /** Frees memory used for this->name - */ - virtual ~DriverFactoryBase() { - if (this->name == NULL) return; - - /* Prefix the name with driver type to make it unique */ - char buf[32]; - strecpy(buf, GetDriverTypeName(type), lastof(buf)); - strecpy(buf + 5, this->name, lastof(buf)); - - GetDrivers().erase(buf); - if (GetDrivers().empty()) delete &GetDrivers(); - free(this->name); - } + virtual ~DriverFactoryBase(); /** Shuts down all active drivers */ diff -r d8811e327d12 -r cd9968b6f96b src/gamelog.cpp --- a/src/gamelog.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/gamelog.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -754,6 +754,8 @@ la->change = ReallocT(la->change, la->changes + 1); LoggedChange *lc = &la->change[la->changes++]; + /* for SLE_STR, pointer has to be valid! so make it NULL */ + memset(lc, 0, sizeof(*lc)); lc->ct = ct; assert((uint)ct < GLCT_END); diff -r d8811e327d12 -r cd9968b6f96b src/genworld.cpp --- a/src/genworld.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/genworld.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -156,7 +156,6 @@ /* Show all vital windows again, because we have hidden them */ if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows(); _gw.active = false; - _gw.thread = NULL; _gw.proc = NULL; _gw.threaded = false; @@ -199,6 +198,7 @@ if (_gw.thread == NULL) return; _gw.quit_thread = true; _gw.thread->Join(); + delete _gw.thread; _gw.thread = NULL; _gw.threaded = false; } @@ -233,9 +233,7 @@ /* Show all vital windows again, because we have hidden them */ if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows(); - ThreadObject *thread = _gw.thread; _gw.active = false; - _gw.thread = NULL; _gw.proc = NULL; _gw.abortp = NULL; _gw.threaded = false; @@ -243,7 +241,7 @@ DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0); MarkWholeScreenDirty(); - thread->Exit(); + _gw.thread->Exit(); } /** @@ -287,6 +285,12 @@ /* Create toolbars */ SetupColorsAndInitialWindow(); + if (_gw.thread != NULL) { + _gw.thread->Join(); + delete _gw.thread; + _gw.thread = NULL; + } + if (_network_dedicated || (_gw.thread = ThreadObject::New(&_GenerateWorld, NULL)) == NULL) { DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode"); diff -r d8811e327d12 -r cd9968b6f96b src/genworld_gui.cpp --- a/src/genworld_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/genworld_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -477,7 +477,7 @@ * (use random seed) it should not be possible to be * entered into the input field; the generate seed * button can be used instead. */ - _settings_newgame.game_creation.generation_seed = minu(strtoul(this->edit_str_buf, NULL, sizeof(this->edit_str_buf) - 1), MAX_UVALUE(uint32) - 1); + _settings_newgame.game_creation.generation_seed = minu(strtoul(this->edit_str_buf, NULL, 10), MAX_UVALUE(uint32) - 1); return state; } diff -r d8811e327d12 -r cd9968b6f96b src/gfx.cpp --- a/src/gfx.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/gfx.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -18,6 +18,7 @@ #include "core/math_func.hpp" #include "settings_type.h" #include "core/alloc_func.hpp" +#include "core/sort_func.hpp" #include "landscape_type.h" #include "table/palettes.h" @@ -689,7 +690,7 @@ } } -static inline void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub) +static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub) { const DrawPixelInfo *dpi = _cur_dpi; Blitter::BlitterParams bp; @@ -715,8 +716,8 @@ bp.height = UnScaleByZoom(sprite->height - clip_top - clip_bottom, dpi->zoom); bp.top = 0; bp.left = 0; - bp.skip_left = UnScaleByZoom(clip_left, dpi->zoom); - bp.skip_top = UnScaleByZoom(clip_top, dpi->zoom); + bp.skip_left = UnScaleByZoomLower(clip_left, dpi->zoom); + bp.skip_top = UnScaleByZoomLower(clip_top, dpi->zoom); x += ScaleByZoom(bp.skip_left, dpi->zoom); y += ScaleByZoom(bp.skip_top, dpi->zoom); @@ -767,6 +768,9 @@ if (bp.width <= 0) return; } + assert(bp.skip_left + bp.width <= UnScaleByZoom(sprite->width, dpi->zoom)); + assert(bp.skip_top + bp.height <= UnScaleByZoom(sprite->height, dpi->zoom)); + BlitterFactoryBase::GetCurrentBlitter()->Draw(&bp, mode, dpi->zoom); } @@ -1309,14 +1313,14 @@ return result; } -static int CDECL compare_res(const void *pa, const void *pb) +static int CDECL compare_res(const Dimension *pa, const Dimension *pb) { - int x = ((const uint16*)pa)[0] - ((const uint16*)pb)[0]; + int x = pa->width - pb->width; if (x != 0) return x; - return ((const uint16*)pa)[1] - ((const uint16*)pb)[1]; + return pa->height - pb->height; } void SortResolutions(int count) { - qsort(_resolutions, count, sizeof(_resolutions[0]), compare_res); + QSortT(_resolutions, count, &compare_res); } diff -r d8811e327d12 -r cd9968b6f96b src/gfx_func.h --- a/src/gfx_func.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/gfx_func.h Tue Jun 17 13:22:13 2008 +0000 @@ -60,8 +60,8 @@ extern int _pal_first_dirty; extern int _pal_count_dirty; extern int _num_resolutions; -extern uint16 _resolutions[32][2]; -extern uint16 _cur_resolution[2]; +extern Dimension _resolutions[32]; +extern Dimension _cur_resolution; extern Colour _cur_palette[256]; void HandleKeypress(uint32 key); diff -r d8811e327d12 -r cd9968b6f96b src/graph_gui.cpp --- a/src/graph_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/graph_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -16,6 +16,7 @@ #include "window_func.h" #include "date_func.h" #include "gfx_func.h" +#include "sortlist_type.h" #include "table/strings.h" #include "table/sprites.h" @@ -758,34 +759,54 @@ return _performance_titles[minu(value, 1000) >> 6]; } -static int CDECL PerfHistComp(const void* elem1, const void* elem2) -{ - const Player* p1 = *(const Player* const*)elem1; - const Player* p2 = *(const Player* const*)elem2; +class CompanyLeagueWindow : public Window { +private: + GUIList players; - return p2->old_economy[1].performance_history - p1->old_economy[1].performance_history; -} + /** + * (Re)Build the company league list + */ + void BuildPlayerList() + { + if (!this->players.NeedRebuild()) return; -struct CompanyLeagueWindow : Window { + this->players.Clear(); + + const Player *p; + FOR_ALL_PLAYERS(p) { + if (p->is_active) { + *this->players.Append() = p; + } + } + + this->players.Compact(); + this->players.RebuildDone(); + } + + /** Sort the company league by performance history */ + static int CDECL PerformanceSorter(const Player* const *p1, const Player* const *p2) + { + return (*p2)->old_economy[1].performance_history - (*p1)->old_economy[1].performance_history; + } + +public: CompanyLeagueWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, window_number) { + this->players.ForceRebuild(); + this->players.NeedResort(); + this->FindWindowPlacementAndResize(desc); } virtual void OnPaint() { - const Player *plist[MAX_PLAYERS]; - const Player *p; + this->BuildPlayerList(); + this->players.Sort(&PerformanceSorter); this->DrawWidgets(); - uint pl_num = 0; - FOR_ALL_PLAYERS(p) if (p->is_active) plist[pl_num++] = p; - - qsort((void*)plist, pl_num, sizeof(*plist), PerfHistComp); - - for (uint i = 0; i != pl_num; i++) { - p = plist[i]; + for (uint i = 0; i != this->players.Length(); i++) { + const Player *p = this->players[i]; SetDParam(0, i + STR_01AC_1ST); SetDParam(1, p->index); SetDParam(2, p->index); @@ -795,6 +816,22 @@ DrawPlayerIcon(p->index, 27, 16 + i * 10); } } + + virtual void OnTick() + { + if (this->players.NeedResort()) { + this->SetDirty(); + } + } + + virtual void OnInvalidateData(int data) + { + if (data == 0) { + this->players.ForceRebuild(); + } else { + this->players.ForceResort(); + } + } }; diff -r d8811e327d12 -r cd9968b6f96b src/group_gui.cpp --- a/src/group_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/group_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -205,9 +205,9 @@ case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break; } - this->vehicles.sort_type = this->sorting->criteria; - this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE); - this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer + this->vehicles.SetListing(*this->sorting); + this->vehicles.ForceRebuild(); + this->vehicles.NeedResort(); this->groups.ForceRebuild(); this->groups.NeedResort(); @@ -260,15 +260,16 @@ ~VehicleGroupWindow() { + *this->sorting = this->vehicles.GetListing(); } virtual void OnInvalidateData(int data) { - this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT); - if (data == 0) { + this->vehicles.ForceRebuild(); this->groups.ForceRebuild(); } else { + this->vehicles.ForceResort(); this->groups.ForceResort(); } @@ -384,7 +385,7 @@ } /* Set text of sort by dropdown */ - this->widget[GRP_WIDGET_SORT_BY_DROPDOWN].data = _vehicle_sort_listing[this->vehicles.sort_type]; + this->widget[GRP_WIDGET_SORT_BY_DROPDOWN].data = _vehicle_sort_listing[this->vehicles.SortType()]; this->DrawWidgets(); @@ -434,7 +435,7 @@ DrawStringRightAligned(187, y1 + 1, STR_GROUP_TINY_NUM, (this->group_sel == g->index) ? TC_WHITE : TC_BLACK); } - this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP); + this->DrawSortButtonState(GRP_WIDGET_SORT_BY_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP); int list_width = this->widget[GRP_WIDGET_LIST_VEHICLE].right - this->widget[GRP_WIDGET_LIST_VEHICLE].left - 20; @@ -472,21 +473,18 @@ switch(widget) { case GRP_WIDGET_SORT_BY_ORDER: // Flip sorting method ascending/descending - this->vehicles.flags ^= VL_DESC; - this->vehicles.flags |= VL_RESORT; - - this->sorting->order = !!(this->vehicles.flags & VL_DESC); + this->vehicles.ToggleSortOrder(); this->SetDirty(); break; case GRP_WIDGET_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu - ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.sort_type, GRP_WIDGET_SORT_BY_DROPDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10)); + ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.SortType(), GRP_WIDGET_SORT_BY_DROPDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10)); return; case GRP_WIDGET_ALL_VEHICLES: // All vehicles button if (!IsAllGroupID(this->group_sel)) { this->group_sel = ALL_GROUP; - this->vehicles.flags |= VL_REBUILD; + this->vehicles.ForceRebuild(); this->SetDirty(); } break; @@ -494,7 +492,7 @@ case GRP_WIDGET_DEFAULT_VEHICLES: // Ungrouped vehicles button if (!IsDefaultGroupID(this->group_sel)) { this->group_sel = DEFAULT_GROUP; - this->vehicles.flags |= VL_REBUILD; + this->vehicles.ForceRebuild(); this->SetDirty(); } break; @@ -510,7 +508,7 @@ this->group_sel = this->groups[id_g]->index;; - this->vehicles.flags |= VL_REBUILD; + this->vehicles.ForceRebuild(); this->SetDirty(); break; } @@ -669,11 +667,7 @@ { switch (widget) { case GRP_WIDGET_SORT_BY_DROPDOWN: - if (this->vehicles.sort_type != index) { - this->vehicles.flags |= VL_RESORT; - this->vehicles.sort_type = index; - this->sorting->criteria = this->vehicles.sort_type; - } + this->vehicles.SetSortType(index); break; case GRP_WIDGET_MANAGE_VEHICLES_DROPDOWN: @@ -715,12 +709,7 @@ virtual void OnTick() { if (_pause_game != 0) return; - if (--this->vehicles.resort_timer == 0) { - this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; - this->vehicles.flags |= VL_RESORT; - this->SetDirty(); - } - if (this->groups.NeedResort()) { + if (this->groups.NeedResort() || this->vehicles.NeedResort()) { this->SetDirty(); } } diff -r d8811e327d12 -r cd9968b6f96b src/industry_cmd.cpp --- a/src/industry_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/industry_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -337,8 +337,7 @@ IndustryGfx gfx = GetIndustryGfx(tile); /* For NewGRF industry tiles we might not be drawing a foundation. We need to - * account for this, otherwise we might be applying a FOUNDATION_LEVELED - * on a steep slope which is not allowed. Furthermore other structures should + * account for this, as other structures should * draw the wall of the foundation in this case. */ if (gfx >= NEW_INDUSTRYTILEOFFSET) { diff -r d8811e327d12 -r cd9968b6f96b src/landscape.cpp --- a/src/landscape.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/landscape.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -79,8 +79,9 @@ if (!IsFoundation(f)) return 0; if (IsLeveledFoundation(f)) { + uint dz = TILE_HEIGHT + (IsSteepSlope(*s) ? TILE_HEIGHT : 0); *s = SLOPE_FLAT; - return TILE_HEIGHT; + return dz; } if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) { @@ -402,6 +403,9 @@ AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, 16, 16, 1, ti->z); OffsetGroundSprite(31, 9); + } else if (IsLeveledFoundation(f)) { + AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT); + OffsetGroundSprite(31, 1); } else if (f == FOUNDATION_STEEP_LOWER) { /* one corner raised */ OffsetGroundSprite(31, 1); diff -r d8811e327d12 -r cd9968b6f96b src/lang/english.txt --- a/src/lang/english.txt Tue Jun 17 10:32:49 2008 +0000 +++ b/src/lang/english.txt Tue Jun 17 13:22:13 2008 +0000 @@ -1291,6 +1291,9 @@ STR_BUILD_LOCKS_TIP :{BLACK}Build locks STR_LANDINFO_LOCK :Lock +STR_CANT_PLACE_RIVERS :{WHITE}Can't place rivers here... +STR_LANDINFO_RIVER :River + STR_BUOY_IS_IN_USE :{WHITE}...buoy is in use! STR_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING}) @@ -1943,6 +1946,7 @@ STR_3804_WATER :Water STR_3805_COAST_OR_RIVERBANK :Coast or riverbank STR_3806_SHIP_DEPOT :Ship depot +STR_AQUEDUCT :Aqueduct STR_3807_CAN_T_BUILD_ON_WATER :{WHITE}...Can't build on water STR_MUST_DEMOLISH_CANAL_FIRST :{WHITE}Must demolish canal first @@ -2662,14 +2666,17 @@ STR_8803_TRAIN_IN_THE_WAY :{WHITE}Train in the way STR_8804 :{SETX 10}{COMMA}: {STRING4} {STRING2} STR_8805 :{RIGHTARROW}{SETX 10}{COMMA}: {STRING4} {STRING2} +STR_ORDER_NON_STOP :{BLACK}Non-stop STR_ORDER_GO_TO :Go to STR_ORDER_GO_NON_STOP_TO :Go non-stop to STR_ORDER_GO_VIA :Go via STR_ORDER_GO_NON_STOP_VIA :Go non-stop via +STR_ORDER_TOGGLE_FULL_LOAD :{BLACK}Full load any cargo STR_ORDER_DROP_LOAD_IF_POSSIBLE :Load if available STR_ORDER_DROP_FULL_LOAD_ALL :Full load all cargo STR_ORDER_DROP_FULL_LOAD_ANY :Full load any cargo STR_ORDER_DROP_NO_LOADING :No loading +STR_ORDER_TOGGLE_UNLOAD :{BLACK}Unload all STR_ORDER_DROP_UNLOAD_IF_ACCEPTED :Unload if accepted STR_ORDER_DROP_UNLOAD :Unload all STR_ORDER_DROP_TRANSFER :Transfer @@ -3004,6 +3011,8 @@ STR_9833_CITIZENS_CELEBRATE_FIRST :{BLACK}{BIGFONT}Citizens celebrate . . .{}First ship arrives at {STATION}! STR_9834_POSITION_BUOY_WHICH_CAN :{BLACK}Place a buoy which can be used as a waypoint STR_9835_CAN_T_POSITION_BUOY_HERE :{WHITE}Can't place buoy here... +STR_BUILD_AQUEDUCT :{BLACK}Build aqueduct +STR_CAN_T_BUILD_AQUEDUCT_HERE :{WHITE}Can't build aqueduct here... STR_9836_RENAME :{BLACK}Rename STR_9837_RENAME_SHIP_TYPE :{BLACK}Rename ship type STR_9838_RENAME_SHIP_TYPE :{WHITE}Rename ship type diff -r d8811e327d12 -r cd9968b6f96b src/main_gui.cpp --- a/src/main_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/main_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -289,7 +289,7 @@ case '1' | WKC_ALT: // Gimme money /* Server can not cheat in advertise mode either! */ - if (!_networking || !_network_server || !_network_advertise) + if (!_networking || !_network_server || !_settings_client.network.server_advertise) DoCommandP(0, 10000000, 0, NULL, CMD_MONEY_CHEAT); break; @@ -446,8 +446,8 @@ */ void GameSizeChanged() { - _cur_resolution[0] = _screen.width; - _cur_resolution[1] = _screen.height; + _cur_resolution.width = _screen.width; + _cur_resolution.height = _screen.height; ScreenSizeChanged(); RelocateAllWindows(_screen.width, _screen.height); MarkWholeScreenDirty(); diff -r d8811e327d12 -r cd9968b6f96b src/misc/blob.hpp --- a/src/misc/blob.hpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/misc/blob.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -6,16 +6,7 @@ #define BLOB_HPP #include "../core/alloc_func.hpp" - -/** Type-safe version of memcpy(). - * @param d destination buffer - * @param s source buffer - * @param num_items number of items to be copied (!not number of bytes!) */ -template -FORCEINLINE void MemCpyT(Titem_* d, const Titem_* s, int num_items = 1) -{ - memcpy(d, s, num_items * sizeof(Titem_)); -} +#include "../core/mem_func.hpp" /** Base class for simple binary blobs. * Item is byte. diff -r d8811e327d12 -r cd9968b6f96b src/network/network.cpp --- a/src/network/network.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/network/network.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -45,7 +45,6 @@ bool _network_server; ///< network-server is active bool _network_available; ///< is network mode available? bool _network_dedicated; ///< are we a dedicated server? -bool _network_advertise; ///< is the server advertising to the master server? bool _is_network_server; ///< Does this client wants to be a network-server? NetworkServerGameInfo _network_game_info; NetworkPlayerInfo _network_player_info[MAX_PLAYERS]; @@ -1110,7 +1109,7 @@ } } - if (_network_advertise) NetworkUDPRemoveAdvertise(); + if (_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(); DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0); diff -r d8811e327d12 -r cd9968b6f96b src/network/network.h --- a/src/network/network.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/network/network.h Tue Jun 17 13:22:13 2008 +0000 @@ -16,7 +16,6 @@ extern bool _network_server; ///< network-server is active extern bool _network_available; ///< is network mode available? extern bool _network_dedicated; ///< are we a dedicated server? -extern bool _network_advertise; ///< is the server advertising to the master server? extern bool _is_network_server; ///< Does this client wants to be a network-server? #else /* ENABLE_NETWORK */ @@ -29,7 +28,6 @@ #define _network_server 0 #define _network_available 0 #define _network_dedicated 0 -#define _network_advertise 0 #define _is_network_server 0 #endif /* ENABLE_NETWORK */ diff -r d8811e327d12 -r cd9968b6f96b src/network/network_gui.cpp --- a/src/network/network_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/network/network_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -686,7 +686,7 @@ const FiosItem *item; /* draw basic widgets */ - SetDParam(1, _connection_types_dropdown[_network_advertise]); + SetDParam(1, _connection_types_dropdown[_settings_client.network.server_advertise]); SetDParam(2, _settings_client.network.max_clients); SetDParam(3, _settings_client.network.max_companies); SetDParam(4, _settings_client.network.max_spectators); @@ -748,7 +748,7 @@ } break; case NSSW_CONNTYPE_BTN: // Connection type - ShowDropDownMenu(this, _connection_types_dropdown, _network_advertise, NSSW_CONNTYPE_BTN, 0, 0); // do it for widget NSSW_CONNTYPE_BTN + ShowDropDownMenu(this, _connection_types_dropdown, _settings_client.network.server_advertise, NSSW_CONNTYPE_BTN, 0, 0); // do it for widget NSSW_CONNTYPE_BTN break; case NSSW_CLIENTS_BTND: case NSSW_CLIENTS_BTNU: // Click on up/down button for number of clients @@ -836,7 +836,7 @@ { switch (widget) { case NSSW_CONNTYPE_BTN: - _network_advertise = (index != 0); + _settings_client.network.server_advertise = (index != 0); break; case NSSW_LANGUAGE_BTN: _settings_client.network.server_lang = _language_dropdown[index] - STR_NETWORK_LANG_ANY; diff -r d8811e327d12 -r cd9968b6f96b src/network/network_udp.cpp --- a/src/network/network_udp.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/network/network_udp.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -52,7 +52,7 @@ DEBUG(net, 2, "[udp] advertising on master server successful"); /* We are advertised, but we don't want to! */ - if (!_network_advertise) NetworkUDPRemoveAdvertise(); + if (!_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(); } ///*** Communication with clients (we are server) ***/ @@ -562,7 +562,7 @@ struct sockaddr_in out_addr; /* Check if we should send an advertise */ - if (!_networking || !_network_server || !_network_udp_server || !_network_advertise) + if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise) return; /* check for socket */ diff -r d8811e327d12 -r cd9968b6f96b src/newgrf.cpp --- a/src/newgrf.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/newgrf.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1548,6 +1548,14 @@ ret = true; } break; + case 0x21: // long introduction year + housespec->min_year = grf_load_word(&buf); + break; + + case 0x22: // long maximum year + housespec->max_year = grf_load_word(&buf); + break; + default: ret = true; break; @@ -3292,9 +3300,9 @@ } } - EngineID *engines = (EngineID*)alloca(idcount * sizeof(*engines)); + EngineID *engines = AllocaM(EngineID, idcount); for (uint i = 0; i < idcount; i++) { - engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, grf_load_byte(&buf))->index; + engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, grf_load_extended(&buf))->index; if (!wagover) last_engines[i] = engines[i]; } @@ -3342,7 +3350,7 @@ static void CanalMapSpriteGroup(byte *buf, uint8 idcount) { - CanalFeature *cfs = (CanalFeature*)alloca(idcount * sizeof(*cfs)); + CanalFeature *cfs = AllocaM(CanalFeature, idcount); for (uint i = 0; i < idcount; i++) { cfs[i] = (CanalFeature)grf_load_byte(&buf); } @@ -3368,7 +3376,7 @@ static void StationMapSpriteGroup(byte *buf, uint8 idcount) { - uint8 *stations = (uint8*)alloca(idcount * sizeof(*stations)); + uint8 *stations = AllocaM(uint8, idcount); for (uint i = 0; i < idcount; i++) { stations[i] = grf_load_byte(&buf); } @@ -3415,7 +3423,7 @@ static void TownHouseMapSpriteGroup(byte *buf, uint8 idcount) { - uint8 *houses = (uint8*)alloca(idcount * sizeof(*houses)); + uint8 *houses = AllocaM(uint8, idcount); for (uint i = 0; i < idcount; i++) { houses[i] = grf_load_byte(&buf); } @@ -3441,7 +3449,7 @@ static void IndustryMapSpriteGroup(byte *buf, uint8 idcount) { - uint8 *industries = (uint8*)alloca(idcount * sizeof(*industries)); + uint8 *industries = AllocaM(uint8, idcount); for (uint i = 0; i < idcount; i++) { industries[i] = grf_load_byte(&buf); } @@ -3467,7 +3475,7 @@ static void IndustrytileMapSpriteGroup(byte *buf, uint8 idcount) { - uint8 *indtiles = (uint8*)alloca(idcount * sizeof(*indtiles)); + uint8 *indtiles = AllocaM(uint8, idcount); for (uint i = 0; i < idcount; i++) { indtiles[i] = grf_load_byte(&buf); } @@ -3493,7 +3501,7 @@ static void CargoMapSpriteGroup(byte *buf, uint8 idcount) { - CargoID *cargos = (CargoID*)alloca(idcount * sizeof(*cargos)); + CargoID *cargos = AllocaM(CargoID, idcount); for (uint i = 0; i < idcount; i++) { cargos[i] = grf_load_byte(&buf); } @@ -3678,7 +3686,14 @@ uint8 lang = grf_load_byte(&buf); uint8 num = grf_load_byte(&buf); bool generic = HasBit(lang, 7); - uint16 id = generic ? grf_load_word(&buf) : grf_load_byte(&buf); + uint16 id; + if (generic) { + id = grf_load_word(&buf); + } else if (feature <= GSF_AIRCRAFT) { + id = grf_load_extended(&buf); + } else { + id = grf_load_byte(&buf); + } ClrBit(lang, 7); @@ -3856,28 +3871,28 @@ static const Action5Type action5_types[] = { /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */ - /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" }, - /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" }, - /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" }, - /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" }, - /* 0x04 */ { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" }, - /* 0x05 */ { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" }, - /* 0x06 */ { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" }, - /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD. - /* 0x08 */ { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" }, - /* 0x09 */ { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" }, - /* 0x0A */ { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" }, - /* 0x0B */ { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" }, - /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD. - /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" }, - /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD. - /* 0x0F */ { A5BLOCK_INVALID, 0, 12, 0, "Sloped rail track" }, // Not yet used by OTTD. - /* 0x10 */ { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" }, - /* 0x11 */ { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" }, - /* 0x12 */ { A5BLOCK_INVALID, 0, 8, 0, "Aqueduct graphics" }, // Not yet used by OTTD. - /* 0x13 */ { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" }, - /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" }, - /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" }, + /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" }, + /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" }, + /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" }, + /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" }, + /* 0x04 */ { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" }, + /* 0x05 */ { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" }, + /* 0x06 */ { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" }, + /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD. + /* 0x08 */ { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" }, + /* 0x09 */ { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" }, + /* 0x0A */ { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" }, + /* 0x0B */ { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" }, + /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD. + /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" }, + /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD. + /* 0x0F */ { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" }, + /* 0x10 */ { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" }, + /* 0x11 */ { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" }, + /* 0x12 */ { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" }, + /* 0x13 */ { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" }, + /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" }, + /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" }, }; if (!check_length(len, 2, "GraphicsNew")) return; diff -r d8811e327d12 -r cd9968b6f96b src/newgrf_house.cpp --- a/src/newgrf_house.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/newgrf_house.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -254,6 +254,12 @@ /* Land info for nearby tiles. */ case 0x62: return GetNearbyTileInformation(parameter, tile); + /* Current animation frame of nearby house tiles */ + case 0x63: { + TileIndex testtile = GetNearbyTile(parameter, tile); + return IsTileType(testtile, MP_HOUSE) ? GetHouseAnimationFrame(testtile) : 0; + } + /* Read GRF parameter */ case 0x7F: return GetGRFParameter(object->u.house.house_id, parameter); } diff -r d8811e327d12 -r cd9968b6f96b src/newgrf_industries.cpp --- a/src/newgrf_industries.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/newgrf_industries.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -265,6 +265,8 @@ return industry->founder | (is_ai ? 0x10000 : 0) | (colours << 24); } + case 0x46: return industry->construction_date; // Date when built - long format - (in days) + /* Get industry ID at offset param */ case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), industry); diff -r d8811e327d12 -r cd9968b6f96b src/newgrf_spritegroup.cpp --- a/src/newgrf_spritegroup.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/newgrf_spritegroup.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -93,6 +93,8 @@ case 0x18: return object->callback_param2; case 0x1C: return object->last_value; + case 0x5F: return (object->GetRandomBits(object) << 8) | object->GetTriggers(object); + case 0x7D: return _temp_store.Get(parameter); /* Not a common variable, so evalute the feature specific variables */ diff -r d8811e327d12 -r cd9968b6f96b src/news_gui.cpp --- a/src/news_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/news_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -528,7 +528,7 @@ MoveToNextItem(); } - if ((_current_news == ni) && (FindWindowById(WC_MESSAGE_HISTORY, 0) != NULL)) { + if ((_current_news == ni) && (FindWindowById(WC_NEWS_WINDOW, 0) != NULL)) { /* about to remove the currently displayed item; also skip */ MoveToNextItem(); } diff -r d8811e327d12 -r cd9968b6f96b src/openttd.cpp --- a/src/openttd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/openttd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -286,7 +286,7 @@ * @param res variable to store the resolution in. * @param s the string to decompose. */ -static void ParseResolution(int res[2], const char *s) +static void ParseResolution(Dimension *res, const char *s) { const char *t = strchr(s, 'x'); if (t == NULL) { @@ -294,8 +294,8 @@ return; } - res[0] = max(strtoul(s, NULL, 0), 64UL); - res[1] = max(strtoul(t + 1, NULL, 0), 64UL); + res->width = max(strtoul(s, NULL, 0), 64UL); + res->height = max(strtoul(t + 1, NULL, 0), 64UL); } static void InitializeDynamicVariables() @@ -377,7 +377,7 @@ int i; const char *optformat; char musicdriver[32], sounddriver[32], videodriver[32], blitter[32]; - int resolution[2] = {0, 0}; + Dimension resolution = {0, 0}; Year startyear = INVALID_YEAR; uint generation_seed = GENERATE_NEW_SEED; bool save_config = true; @@ -442,7 +442,7 @@ debuglog_conn = mgo.opt; break; #endif /* ENABLE_NETWORK */ - case 'r': ParseResolution(resolution, mgo.opt); break; + case 'r': ParseResolution(&resolution, mgo.opt); break; case 't': startyear = atoi(mgo.opt); break; case 'd': { #if defined(WIN32) @@ -495,14 +495,14 @@ if (!StrEmpty(sounddriver)) ttd_strlcpy(_ini_sounddriver, sounddriver, sizeof(_ini_sounddriver)); if (!StrEmpty(videodriver)) ttd_strlcpy(_ini_videodriver, videodriver, sizeof(_ini_videodriver)); if (!StrEmpty(blitter)) ttd_strlcpy(_ini_blitter, blitter, sizeof(_ini_blitter)); - if (resolution[0] != 0) { _cur_resolution[0] = resolution[0]; _cur_resolution[1] = resolution[1]; } + if (resolution.width != 0) { _cur_resolution = resolution; } if (startyear != INVALID_YEAR) _settings_newgame.game_creation.starting_year = startyear; if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed; /* The width and height must be at least 1 pixel, this * way all internal drawing routines work correctly. */ - if (_cur_resolution[0] == 0) _cur_resolution[0] = 1; - if (_cur_resolution[1] == 0) _cur_resolution[1] = 1; + if (_cur_resolution.width <= 0) _cur_resolution.width = 1; + if (_cur_resolution.height <= 0) _cur_resolution.height = 1; #if defined(ENABLE_NETWORK) if (dedicated_host) snprintf(_settings_client.network.server_bind_ip, sizeof(_settings_client.network.server_bind_ip), "%s", dedicated_host); diff -r d8811e327d12 -r cd9968b6f96b src/order_gui.cpp --- a/src/order_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/order_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -43,10 +43,13 @@ ORDER_WIDGET_SCROLLBAR, ORDER_WIDGET_SKIP, ORDER_WIDGET_DELETE, + ORDER_WIDGET_NON_STOP_DROPDOWN, ORDER_WIDGET_NON_STOP, + ORDER_WIDGET_GOTO_DROPDOWN, ORDER_WIDGET_GOTO, - ORDER_WIDGET_GOTO_DROPDOWN, + ORDER_WIDGET_FULL_LOAD_DROPDOWN, ORDER_WIDGET_FULL_LOAD, + ORDER_WIDGET_UNLOAD_DROPDOWN, ORDER_WIDGET_UNLOAD, ORDER_WIDGET_REFIT, ORDER_WIDGET_SERVICE, @@ -444,13 +447,7 @@ if (order == NULL || order->GetLoadType() == load_type) return; if (load_type < 0) { - switch (order->GetLoadType()) { - case OLF_LOAD_IF_POSSIBLE: load_type = OLFB_FULL_LOAD; break; - case OLFB_FULL_LOAD: load_type = OLF_FULL_LOAD_ANY; break; - case OLF_FULL_LOAD_ANY: load_type = OLFB_NO_LOAD; break; - case OLFB_NO_LOAD: load_type = OLF_LOAD_IF_POSSIBLE; break; - default: NOT_REACHED(); - } + load_type = order->GetLoadType() == OLF_LOAD_IF_POSSIBLE ? OLF_FULL_LOAD_ANY : OLF_LOAD_IF_POSSIBLE; } DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_LOAD | (load_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER)); } @@ -507,13 +504,7 @@ if (order == NULL || order->GetUnloadType() == unload_type) return; if (unload_type < 0) { - switch (order->GetUnloadType()) { - case OUF_UNLOAD_IF_POSSIBLE: unload_type = OUFB_UNLOAD; break; - case OUFB_UNLOAD: unload_type = OUFB_TRANSFER; break; - case OUFB_TRANSFER: unload_type = OUFB_NO_UNLOAD; break; - case OUFB_NO_UNLOAD: unload_type = OUF_UNLOAD_IF_POSSIBLE; break; - default: NOT_REACHED(); - } + unload_type = order->GetUnloadType() == OUF_UNLOAD_IF_POSSIBLE ? OUFB_UNLOAD : OUF_UNLOAD_IF_POSSIBLE; } DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_UNLOAD | (unload_type << 4), NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER)); @@ -534,9 +525,10 @@ /* Keypress if negative, so 'toggle' to the next */ if (non_stop < 0) { - non_stop = (order->GetNonStopType() + 1) % ONSF_END; + non_stop = order->GetNonStopType() ^ ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS; } + w->InvalidateWidget(ORDER_WIDGET_NON_STOP); DoCommandP(w->vehicle->tile, w->vehicle->index + (sel_ord << 16), MOF_NON_STOP | non_stop << 4, NULL, CMD_MODIFY_ORDER | CMD_MSG(STR_8835_CAN_T_MODIFY_THIS_ORDER)); } @@ -631,9 +623,6 @@ if (this->vehicle->owner == _local_player) { /* Set the strings for the dropdown boxes. */ - this->widget[ORDER_WIDGET_NON_STOP].data = _order_non_stop_drowdown[order == NULL ? 0 : order->GetNonStopType()]; - this->widget[ORDER_WIDGET_FULL_LOAD].data = _order_full_load_drowdown[order == NULL ? 0 : order->GetLoadType()]; - this->widget[ORDER_WIDGET_UNLOAD].data = _order_unload_drowdown[order == NULL ? 0 : order->GetUnloadType()]; this->widget[ORDER_WIDGET_COND_VARIABLE].data = _order_conditional_variable[order == NULL ? 0 : order->GetConditionVariable()]; this->widget[ORDER_WIDGET_COND_COMPARATOR].data = _order_conditional_condition[order == NULL ? 0 : order->GetConditionComparator()]; @@ -646,8 +635,11 @@ /* non-stop only for trains */ this->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP, (this->vehicle->type != VEH_TRAIN && this->vehicle->type != VEH_ROAD) || order == NULL); + this->SetWidgetDisabledState(ORDER_WIDGET_NON_STOP_DROPDOWN, this->IsWidgetDisabled(ORDER_WIDGET_NON_STOP)); this->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load + this->SetWidgetDisabledState(ORDER_WIDGET_FULL_LOAD_DROPDOWN, this->IsWidgetDisabled(ORDER_WIDGET_FULL_LOAD)); this->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD, order == NULL || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload + this->SetWidgetDisabledState(ORDER_WIDGET_UNLOAD_DROPDOWN, this->IsWidgetDisabled(ORDER_WIDGET_UNLOAD)); /* Disable list of vehicles with the same shared orders if there is no list */ this->SetWidgetDisabledState(ORDER_WIDGET_SHARED_ORDER_LIST, !shared_orders || this->vehicle->orders == NULL); this->SetWidgetDisabledState(ORDER_WIDGET_REFIT, order == NULL); // Refit @@ -660,35 +652,53 @@ this->HideWidget(ORDER_WIDGET_COND_VALUE); } + this->ShowWidget(ORDER_WIDGET_NON_STOP_DROPDOWN); this->ShowWidget(ORDER_WIDGET_NON_STOP); + this->ShowWidget(ORDER_WIDGET_UNLOAD_DROPDOWN); this->ShowWidget(ORDER_WIDGET_UNLOAD); + this->ShowWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN); this->ShowWidget(ORDER_WIDGET_FULL_LOAD); + this->RaiseWidget(ORDER_WIDGET_NON_STOP); + this->RaiseWidget(ORDER_WIDGET_FULL_LOAD); + this->RaiseWidget(ORDER_WIDGET_UNLOAD); + if (order != NULL) { + this->SetWidgetLoweredState(ORDER_WIDGET_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); switch (order->GetType()) { case OT_GOTO_STATION: - if (!GetStation(order->GetDestination())->IsBuoy()) break; + if (!GetStation(order->GetDestination())->IsBuoy()) { + this->SetWidgetLoweredState(ORDER_WIDGET_FULL_LOAD, order->GetLoadType() == OLF_FULL_LOAD_ANY); + this->SetWidgetLoweredState(ORDER_WIDGET_UNLOAD, order->GetUnloadType() == OUFB_UNLOAD); + break; + } /* Fall-through */ case OT_GOTO_WAYPOINT: + this->DisableWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN); this->DisableWidget(ORDER_WIDGET_FULL_LOAD); + this->DisableWidget(ORDER_WIDGET_UNLOAD_DROPDOWN); this->DisableWidget(ORDER_WIDGET_UNLOAD); break; case OT_GOTO_DEPOT: - this->DisableWidget(ORDER_WIDGET_FULL_LOAD); - /* Remove unload and replace it with refit */ + this->HideWidget(ORDER_WIDGET_UNLOAD_DROPDOWN); this->HideWidget(ORDER_WIDGET_UNLOAD); + this->HideWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN); + this->HideWidget(ORDER_WIDGET_FULL_LOAD); this->ShowWidget(ORDER_WIDGET_REFIT); - this->HideWidget(ORDER_WIDGET_FULL_LOAD); this->ShowWidget(ORDER_WIDGET_SERVICE); + this->SetWidgetLoweredState(ORDER_WIDGET_SERVICE, order->GetDepotOrderType() & ODTFB_SERVICE); break; case OT_CONDITIONAL: { + this->HideWidget(ORDER_WIDGET_NON_STOP_DROPDOWN); this->HideWidget(ORDER_WIDGET_NON_STOP); this->HideWidget(ORDER_WIDGET_UNLOAD); + this->HideWidget(ORDER_WIDGET_UNLOAD_DROPDOWN); this->HideWidget(ORDER_WIDGET_FULL_LOAD); + this->HideWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN); this->ShowWidget(ORDER_WIDGET_COND_VARIABLE); this->ShowWidget(ORDER_WIDGET_COND_COMPARATOR); this->ShowWidget(ORDER_WIDGET_COND_VALUE); @@ -703,8 +713,11 @@ } break; default: // every other orders + this->DisableWidget(ORDER_WIDGET_NON_STOP_DROPDOWN); this->DisableWidget(ORDER_WIDGET_NON_STOP); + this->DisableWidget(ORDER_WIDGET_FULL_LOAD_DROPDOWN); this->DisableWidget(ORDER_WIDGET_FULL_LOAD); + this->DisableWidget(ORDER_WIDGET_UNLOAD_DROPDOWN); this->DisableWidget(ORDER_WIDGET_UNLOAD); } } @@ -790,9 +803,13 @@ OrderClick_Delete(this, 0); break; - case ORDER_WIDGET_NON_STOP: { + case ORDER_WIDGET_NON_STOP: + OrderClick_Nonstop(this, -1); + break; + + case ORDER_WIDGET_NON_STOP_DROPDOWN: { const Order *o = GetVehicleOrder(this->vehicle, this->OrderGetSel()); - ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), ORDER_WIDGET_NON_STOP, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12)); + ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), ORDER_WIDGET_NON_STOP_DROPDOWN, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12)); } break; case ORDER_WIDGET_GOTO: @@ -800,15 +817,23 @@ break; case ORDER_WIDGET_GOTO_DROPDOWN: - ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO, 0, 0, this->widget[ORDER_WIDGET_GOTO_DROPDOWN].right - this->widget[ORDER_WIDGET_GOTO].left); + ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, 0, ORDER_WIDGET_GOTO_DROPDOWN, 0, 0); break; case ORDER_WIDGET_FULL_LOAD: - ShowDropDownMenu(this, _order_full_load_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetLoadType(), ORDER_WIDGET_FULL_LOAD, 0, 2); + OrderClick_FullLoad(this, -1); + break; + + case ORDER_WIDGET_FULL_LOAD_DROPDOWN: + ShowDropDownMenu(this, _order_full_load_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetLoadType(), ORDER_WIDGET_FULL_LOAD_DROPDOWN, 0, 2); break; case ORDER_WIDGET_UNLOAD: - ShowDropDownMenu(this, _order_unload_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetUnloadType(), ORDER_WIDGET_UNLOAD, 0, 8); + OrderClick_Unload(this, -1); + break; + + case ORDER_WIDGET_UNLOAD_DROPDOWN: + ShowDropDownMenu(this, _order_unload_drowdown, GetVehicleOrder(this->vehicle, this->OrderGetSel())->GetUnloadType(), ORDER_WIDGET_UNLOAD_DROPDOWN, 0, 8); break; case ORDER_WIDGET_REFIT: @@ -871,25 +896,21 @@ virtual void OnDropdownSelect(int widget, int index) { switch (widget) { - case ORDER_WIDGET_NON_STOP: + case ORDER_WIDGET_NON_STOP_DROPDOWN: OrderClick_Nonstop(this, index); break; - case ORDER_WIDGET_FULL_LOAD: + case ORDER_WIDGET_FULL_LOAD_DROPDOWN: OrderClick_FullLoad(this, index); break; - case ORDER_WIDGET_UNLOAD: + case ORDER_WIDGET_UNLOAD_DROPDOWN: OrderClick_Unload(this, index); break; - case ORDER_WIDGET_GOTO: + case ORDER_WIDGET_GOTO_DROPDOWN: switch (index) { - case 0: - this->ToggleWidgetLoweredState(ORDER_WIDGET_GOTO); - OrderClick_Goto(this, 0); - break; - + case 0: OrderClick_Goto(this, 0); break; case 1: OrderClick_NearestDepot(this, 0); break; case 2: OrderClick_Conditional(this, 0); break; default: NOT_REACHED(); @@ -1040,11 +1061,14 @@ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 123, 88, 99, STR_8823_SKIP, STR_8853_SKIP_THE_CURRENT_ORDER}, // ORDER_WIDGET_SKIP { WWT_PUSHTXTBTN, RESIZE_TB, 14, 124, 247, 88, 99, STR_8824_DELETE, STR_8854_DELETE_THE_HIGHLIGHTED}, // ORDER_WIDGET_DELETE - { WWT_DROPDOWN, RESIZE_TB, 14, 0, 123, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_NON_STOP}, // ORDER_WIDGET_NON_STOP + { WWT_DROPDOWN, RESIZE_TB, 14, 0, 123, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_NON_STOP}, // ORDER_WIDGET_NON_STOP_DROPDOWN + { WWT_TEXTBTN, RESIZE_TB, 14, 0, 111, 76, 87, STR_ORDER_NON_STOP, STR_ORDER_TOOLTIP_NON_STOP}, // ORDER_WIDGET_NON_STOP + { WWT_DROPDOWN, RESIZE_TB, 14, 248, 371, 88, 99, STR_EMPTY, STR_ORDER_GO_TO_DROPDOWN_TOOLTIP}, // ORDER_WIDGET_GOTO_DROPDOWN { WWT_TEXTBTN, RESIZE_TB, 14, 248, 359, 88, 99, STR_8826_GO_TO, STR_8856_INSERT_A_NEW_ORDER_BEFORE}, // ORDER_WIDGET_GOTO - { WWT_DROPDOWN, RESIZE_TB, 14, 360, 371, 88, 99, STR_EMPTY, STR_ORDER_GO_TO_DROPDOWN_TOOLTIP}, // ORDER_WIDGET_GOTO_DROPDOWN - { WWT_DROPDOWN, RESIZE_TB, 14, 124, 247, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_FULL_LOAD}, // ORDER_WIDGET_FULL_LOAD - { WWT_DROPDOWN, RESIZE_TB, 14, 248, 371, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_UNLOAD}, // ORDER_WIDGET_UNLOAD + { WWT_DROPDOWN, RESIZE_TB, 14, 124, 247, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_FULL_LOAD}, // ORDER_WIDGET_FULL_LOAD_DROPDOWN + { WWT_TEXTBTN, RESIZE_TB, 14, 124, 235, 76, 87, STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD}, // ORDER_WIDGET_FULL_LOAD + { WWT_DROPDOWN, RESIZE_TB, 14, 248, 371, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_UNLOAD}, // ORDER_WIDGET_UNLOAD_DROPDOWN + { WWT_TEXTBTN, RESIZE_TB, 14, 248, 359, 76, 87, STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD}, // ORDER_WIDGET_UNLOAD { WWT_PUSHTXTBTN, RESIZE_TB, 14, 124, 247, 76, 87, STR_REFIT, STR_REFIT_TIP}, // ORDER_WIDGET_REFIT { WWT_PUSHTXTBTN, RESIZE_TB, 14, 248, 371, 76, 87, STR_SERVICE, STR_SERVICE_HINT}, // ORDER_WIDGET_SERVICE @@ -1080,11 +1104,14 @@ { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 123, 88, 99, STR_8823_SKIP, STR_8853_SKIP_THE_CURRENT_ORDER}, // ORDER_WIDGET_SKIP { WWT_PUSHTXTBTN, RESIZE_TB, 14, 124, 247, 88, 99, STR_8824_DELETE, STR_8854_DELETE_THE_HIGHLIGHTED}, // ORDER_WIDGET_DELETE + { WWT_EMPTY, RESIZE_TB, 14, 0, 0, 76, 87, 0x0, 0x0}, // ORDER_WIDGET_NON_STOP_DROPDOWN { WWT_EMPTY, RESIZE_TB, 14, 0, 0, 76, 87, 0x0, 0x0}, // ORDER_WIDGET_NON_STOP + { WWT_DROPDOWN, RESIZE_TB, 14, 248, 371, 88, 99, STR_EMPTY, STR_ORDER_GO_TO_DROPDOWN_TOOLTIP}, // ORDER_WIDGET_GOTO_DROPDOWN { WWT_TEXTBTN, RESIZE_TB, 14, 248, 359, 88, 99, STR_8826_GO_TO, STR_8856_INSERT_A_NEW_ORDER_BEFORE}, // ORDER_WIDGET_GOTO - { WWT_DROPDOWN, RESIZE_TB, 14, 360, 371, 88, 99, STR_EMPTY, STR_ORDER_GO_TO_DROPDOWN_TOOLTIP}, // ORDER_WIDGET_GOTO_DROPDOWN - { WWT_DROPDOWN, RESIZE_TB, 14, 0, 185, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_FULL_LOAD}, // ORDER_WIDGET_FULL_LOAD - { WWT_DROPDOWN, RESIZE_TB, 14, 186, 371, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_UNLOAD}, // ORDER_WIDGET_UNLOAD + { WWT_DROPDOWN, RESIZE_TB, 14, 0, 185, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_FULL_LOAD}, // ORDER_WIDGET_FULL_LOAD_DROPDOWN + { WWT_TEXTBTN, RESIZE_TB, 14, 0, 173, 76, 87, STR_ORDER_TOGGLE_FULL_LOAD, STR_ORDER_TOOLTIP_FULL_LOAD}, // ORDER_WIDGET_FULL_LOAD + { WWT_DROPDOWN, RESIZE_TB, 14, 186, 371, 76, 87, STR_NULL, STR_ORDER_TOOLTIP_UNLOAD}, // ORDER_WIDGET_UNLOAD_DROPDOWN + { WWT_TEXTBTN, RESIZE_TB, 14, 186, 359, 76, 87, STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD}, // ORDER_WIDGET_UNLOAD { WWT_PUSHTXTBTN, RESIZE_TB, 14, 0, 185, 76, 87, STR_REFIT, STR_REFIT_TIP}, // ORDER_WIDGET_REFIT { WWT_PUSHTXTBTN, RESIZE_TB, 14, 186, 371, 76, 87, STR_SERVICE, STR_SERVICE_HINT}, // ORDER_WIDGET_SERVICE @@ -1120,10 +1147,13 @@ { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_SKIP { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_DELETE + { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_NON_STOP_DROPDOWN { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_NON_STOP + { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_GOTO_DROPDOWN { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_GOTO - { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_GOTO_DROPDOWN + { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_FULL_LOAD_DROPDOWN { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_FULL_LOAD + { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_UNLOAD_DROPDOWN { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_UNLOAD { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_REFIT { WWT_EMPTY, RESIZE_NONE, 14, 0, 0, 76, 87, 0x0, STR_NULL}, // ORDER_WIDGET_SERVICE diff -r d8811e327d12 -r cd9968b6f96b src/pathfind.cpp --- a/src/pathfind.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/pathfind.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -112,9 +112,28 @@ static void TPFModeShip(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction) { - RememberData rd; + assert(tpf->tracktype == TRANSPORT_WATER); - assert(tpf->tracktype == TRANSPORT_WATER); + if (IsTileType(tile, MP_TUNNELBRIDGE)) { + /* wrong track type */ + if (GetTunnelBridgeTransportType(tile) != tpf->tracktype) return; + + DiagDirection dir = GetTunnelBridgeDirection(tile); + /* entering tunnel / bridge? */ + if (dir == direction) { + TileIndex endtile = GetOtherTunnelBridgeEnd(tile); + + tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1; + + TPFSetTileBit(tpf, tile, 14); + TPFSetTileBit(tpf, endtile, 14); + + tile = endtile; + } else { + /* leaving tunnel / bridge? */ + if (ReverseDiagDir(dir) != direction) return; + } + } /* This addition will sometimes overflow by a single tile. * The use of TILE_MASK here makes sure that we still point at a valid @@ -133,7 +152,7 @@ do { Track track = RemoveFirstTrack(&bits); if (bits != TRACK_BIT_NONE) only_one_track = false; - rd = tpf->rd; + RememberData rd = tpf->rd; /* Change direction 4 times only */ if (!only_one_track && track != tpf->rd.last_choosen_track) { diff -r d8811e327d12 -r cd9968b6f96b src/players.cpp --- a/src/players.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/players.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -28,6 +28,7 @@ #include "vehicle_func.h" #include "sound_func.h" #include "core/alloc_func.hpp" +#include "core/sort_func.hpp" #include "autoreplace_func.h" #include "autoreplace_gui.h" #include "string_func.h" @@ -818,6 +819,8 @@ { if (flags & DC_EXEC) _current_player = OWNER_NONE; + InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0); + switch (p1) { case 0: { /* Create a new player */ /* Joining Client: @@ -1019,12 +1022,9 @@ } /** Sort all players given their performance */ -static int CDECL HighScoreSorter(const void *a, const void *b) +static int CDECL HighScoreSorter(const Player* const *a, const Player* const *b) { - const Player *pa = *(const Player* const*)a; - const Player *pb = *(const Player* const*)b; - - return pb->old_economy[0].performance_history - pa->old_economy[0].performance_history; + return (*b)->old_economy[0].performance_history - (*a)->old_economy[0].performance_history; } /* Save the highscores in a network game when it has ended */ @@ -1038,7 +1038,8 @@ /* Sort all active players with the highest score first */ FOR_ALL_PLAYERS(p) if (p->is_active) pl[count++] = p; - qsort((Player*)pl, count, sizeof(pl[0]), HighScoreSorter); + + GSortT(pl, count, &HighScoreSorter); { uint i; @@ -1270,8 +1271,11 @@ _player_colors[index] = p->player_color; /* This is needed so an AI is attached to a loaded AI */ - if (p->is_ai && (!_networking || _network_server) && _ai.enabled) + if (p->is_ai && (!_networking || _network_server) && _ai.enabled) { + /* Clear the memory of the new AI, otherwise we might be doing wrong things. */ + memset(&_players_ainew[index], 0, sizeof(PlayerAiNew)); AI_StartNewAI(p->index); + } } } diff -r d8811e327d12 -r cd9968b6f96b src/rail.h --- a/src/rail.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/rail.h Tue Jun 17 13:22:13 2008 +0000 @@ -38,6 +38,7 @@ SpriteID single_s; ///< single piece of rail in the southern corner SpriteID single_e; ///< single piece of rail in the eastern corner SpriteID single_w; ///< single piece of rail in the western corner + SpriteID single_sloped;///< single piecs of rail for slopes SpriteID crossing; ///< level crossing, rail in X direction SpriteID tunnel; ///< tunnel sprites base } base_sprites; diff -r d8811e327d12 -r cd9968b6f96b src/rail_cmd.cpp --- a/src/rail_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/rail_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1382,7 +1382,10 @@ cost.AddCost(ret); } - if (water_ground) { + /* when bankrupting, don't make water dirty, there could be a ship on lower halftile */ + if (water_ground && !(flags & DC_BANKRUPT)) { + if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; + /* The track was removed, and left a coast tile. Now also clear the water. */ if (flags & DC_EXEC) DoClearSquare(tile); cost.AddCost(_price.clear_water); @@ -2112,6 +2115,19 @@ static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side) { + /* Case of half tile slope with water. */ + if (mode == TRANSPORT_WATER && IsPlainRailTile(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER) { + TrackBits tb = GetTrackBits(tile); + switch (tb) { + default: NOT_REACHED(); + case TRACK_BIT_UPPER: tb = TRACK_BIT_LOWER; break; + case TRACK_BIT_LOWER: tb = TRACK_BIT_UPPER; break; + case TRACK_BIT_LEFT: tb = TRACK_BIT_RIGHT; break; + case TRACK_BIT_RIGHT: tb = TRACK_BIT_LEFT; break; + } + return CombineTrackStatus(TrackBitsToTrackdirBits(tb), TRACKDIR_BIT_NONE); + } + if (mode != TRANSPORT_RAIL) return 0; TrackBits trackbits = TRACK_BIT_NONE; diff -r d8811e327d12 -r cd9968b6f96b src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/roadveh_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -194,7 +194,7 @@ uint num_vehicles = 1 + CountArticulatedParts(p1, false); /* Allow for the front and the articulated parts, plus one to "terminate" the list. */ - Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); + Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1); memset(vl, 0, sizeof(*vl) * (num_vehicles + 1)); if (!Vehicle::AllocateList(vl, num_vehicles)) { @@ -1714,6 +1714,7 @@ _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || (IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) && + v->owner == GetRoadOwner(v->tile, v->u.road.roadtype) && GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { diff -r d8811e327d12 -r cd9968b6f96b src/saveload.cpp --- a/src/saveload.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/saveload.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -95,6 +95,7 @@ typedef void (*AsyncSaveFinishProc)(); static AsyncSaveFinishProc _async_save_finish = NULL; +static ThreadObject *_save_thread; /** * Called by save thread to tell we finished saving. @@ -117,6 +118,12 @@ _async_save_finish(); _async_save_finish = NULL; + + if (_save_thread != NULL) { + _save_thread->Join(); + delete _save_thread; + _save_thread = NULL; + } } /** @@ -1545,8 +1552,6 @@ SaveFileDone(); } -static ThreadObject *_save_thread; - /** We have written the whole game into memory, _Savegame_pool, now find * and appropiate compressor and start writing to file. */ @@ -1617,6 +1622,7 @@ if (_save_thread == NULL) return; _save_thread->Join(); + delete _save_thread; _save_thread = NULL; } diff -r d8811e327d12 -r cd9968b6f96b src/settings.cpp --- a/src/settings.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/settings.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1510,7 +1510,7 @@ SDTG_STR("sounddriver", SLE_STRB,C|S,0, _ini_sounddriver, NULL, STR_NULL, NULL), SDTG_STR("blitter", SLE_STRB,C|S,0, _ini_blitter, NULL, STR_NULL, NULL), SDTG_STR("language", SLE_STRB, S, 0, _dynlang.curr_file, NULL, STR_NULL, NULL), - SDTG_LIST("resolution", SLE_UINT16, S, 0, _cur_resolution, "640,480", STR_NULL, NULL), + SDTG_CONDLIST("resolution", SLE_INT, 2, S, 0, _cur_resolution, "640,480", STR_NULL, NULL, 0, SL_MAX_VERSION), // workaround for implicit lengthof() in SDTG_LIST SDTG_STR("screenshot_format",SLE_STRB, S, 0, _screenshot_format_name,NULL, STR_NULL, NULL), SDTG_STR("savegame_format", SLE_STRB, S, 0, _savegame_format, NULL, STR_NULL, NULL), SDTG_BOOL("rightclick_emulate", S, 0, _rightclick_emulate, false, STR_NULL, NULL), diff -r d8811e327d12 -r cd9968b6f96b src/settings_gui.cpp --- a/src/settings_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/settings_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -93,8 +93,8 @@ int i; for (i = 0; i != _num_resolutions; i++) { - if (_resolutions[i][0] == _screen.width && - _resolutions[i][1] == _screen.height) { + if (_resolutions[i].width == _screen.width && + _resolutions[i].height == _screen.height) { break; } } @@ -302,7 +302,7 @@ break; case GAMEOPT_RESOLUTION_BTN: // Change resolution - if (index < _num_resolutions && ChangeResInGame(_resolutions[index][0], _resolutions[index][1])) { + if (index < _num_resolutions && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { this->SetDirty(); } break; diff -r d8811e327d12 -r cd9968b6f96b src/ship_cmd.cpp --- a/src/ship_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/ship_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -599,90 +599,102 @@ BeginVehicleMove(v); GetNewVehiclePosResult gp = GetNewVehiclePos(v); - if (gp.old_tile == gp.new_tile) { - /* Staying in tile */ - if (v->IsInDepot()) { - gp.x = v->x_pos; - gp.y = v->y_pos; - } else { - /* Not inside depot */ - r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); - if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction; + if (v->u.ship.state != TRACK_BIT_WORMHOLE) { + /* Not on a bridge */ + if (gp.old_tile == gp.new_tile) { + /* Staying in tile */ + if (v->IsInDepot()) { + gp.x = v->x_pos; + gp.y = v->y_pos; + } else { + /* Not inside depot */ + r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); + if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction; - /* A leave station order only needs one tick to get processed, so we can - * always skip ahead. */ - if (v->current_order.IsType(OT_LEAVESTATION)) { - v->current_order.Free(); - InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); - } else if (v->dest_tile != 0) { - /* We have a target, let's see if we reached it... */ - if (v->current_order.IsType(OT_GOTO_STATION) && - IsBuoyTile(v->dest_tile) && - DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) { - /* We got within 3 tiles of our target buoy, so let's skip to our - * next order */ - UpdateVehicleTimetable(v, true); - v->cur_order_index++; - v->current_order.MakeDummy(); - InvalidateVehicleOrder(v); - } else { - /* Non-buoy orders really need to reach the tile */ - if (v->dest_tile == gp.new_tile) { - if (v->current_order.IsType(OT_GOTO_DEPOT)) { - if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { - VehicleEnterDepot(v); - return; - } - } else if (v->current_order.IsType(OT_GOTO_STATION)) { - v->last_station_visited = v->current_order.GetDestination(); + /* A leave station order only needs one tick to get processed, so we can + * always skip ahead. */ + if (v->current_order.IsType(OT_LEAVESTATION)) { + v->current_order.Free(); + InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); + } else if (v->dest_tile != 0) { + /* We have a target, let's see if we reached it... */ + if (v->current_order.IsType(OT_GOTO_STATION) && + IsBuoyTile(v->dest_tile) && + DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) { + /* We got within 3 tiles of our target buoy, so let's skip to our + * next order */ + UpdateVehicleTimetable(v, true); + v->cur_order_index++; + v->current_order.MakeDummy(); + InvalidateVehicleOrder(v); + } else { + /* Non-buoy orders really need to reach the tile */ + if (v->dest_tile == gp.new_tile) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { + if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { + VehicleEnterDepot(v); + return; + } + } else if (v->current_order.IsType(OT_GOTO_STATION)) { + v->last_station_visited = v->current_order.GetDestination(); - /* Process station in the orderlist. */ - Station *st = GetStation(v->current_order.GetDestination()); - if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations - ShipArrivesAt(v, st); - v->BeginLoading(); - } else { // leave stations without docks right aways - v->current_order.MakeLeaveStation(); - v->cur_order_index++; - InvalidateVehicleOrder(v); + /* Process station in the orderlist. */ + Station *st = GetStation(v->current_order.GetDestination()); + if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations + ShipArrivesAt(v, st); + v->BeginLoading(); + } else { // leave stations without docks right aways + v->current_order.MakeLeaveStation(); + v->cur_order_index++; + InvalidateVehicleOrder(v); + } } } } } } + } else { + DiagDirection diagdir; + /* New tile */ + if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) { + goto reverse_direction; + } + + dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile); + assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW); + diagdir = DirToDiagDir(dir); + tracks = GetAvailShipTracks(gp.new_tile, diagdir); + if (tracks == TRACK_BIT_NONE) goto reverse_direction; + + /* Choose a direction, and continue if we find one */ + track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks); + if (track == INVALID_TRACK) goto reverse_direction; + + b = _ship_subcoord[diagdir][track]; + + gp.x = (gp.x & ~0xF) | b[0]; + gp.y = (gp.y & ~0xF) | b[1]; + + /* Call the landscape function and tell it that the vehicle entered the tile */ + r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); + if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction; + + if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { + v->tile = gp.new_tile; + v->u.ship.state = TrackToTrackBits(track); + } + + v->direction = (Direction)b[2]; } } else { - DiagDirection diagdir; - /* New tile */ - if (TileX(gp.new_tile) >= MapMaxX() || TileY(gp.new_tile) >= MapMaxY()) { - goto reverse_direction; + /* On a bridge */ + if (!IsTileType(gp.new_tile, MP_TUNNELBRIDGE) || !HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { + v->x_pos = gp.x; + v->y_pos = gp.y; + VehiclePositionChanged(v); + if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v); + return; } - - dir = ShipGetNewDirectionFromTiles(gp.new_tile, gp.old_tile); - assert(dir == DIR_NE || dir == DIR_SE || dir == DIR_SW || dir == DIR_NW); - diagdir = DirToDiagDir(dir); - tracks = GetAvailShipTracks(gp.new_tile, diagdir); - if (tracks == TRACK_BIT_NONE) goto reverse_direction; - - /* Choose a direction, and continue if we find one */ - track = ChooseShipTrack(v, gp.new_tile, diagdir, tracks); - if (track == INVALID_TRACK) goto reverse_direction; - - b = _ship_subcoord[diagdir][track]; - - gp.x = (gp.x & ~0xF) | b[0]; - gp.y = (gp.y & ~0xF) | b[1]; - - /* Call the landscape function and tell it that the vehicle entered the tile */ - r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y); - if (HasBit(r, VETS_CANNOT_ENTER)) goto reverse_direction; - - if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { - v->tile = gp.new_tile; - v->u.ship.state = TrackToTrackBits(track); - } - - v->direction = (Direction)b[2]; } /* update image of ship, as well as delta XY */ diff -r d8811e327d12 -r cd9968b6f96b src/signs_func.h --- a/src/signs_func.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/signs_func.h Tue Jun 17 13:22:13 2008 +0000 @@ -15,6 +15,7 @@ /* signs_gui.cpp */ void ShowRenameSignWindow(const Sign *si); +void HandleClickOnSign(const Sign *si); void ShowSignList(); diff -r d8811e327d12 -r cd9968b6f96b src/signs_gui.cpp --- a/src/signs_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/signs_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -8,6 +8,7 @@ #include "textbuf_gui.h" #include "window_gui.h" #include "player_gui.h" +#include "player_func.h" #include "signs_base.h" #include "signs_func.h" #include "debug.h" @@ -301,6 +302,15 @@ _query_sign_edit_widgets, }; +void HandleClickOnSign(const Sign *si) +{ + if (_ctrl_pressed && si->owner == _local_player) { + RenameSign(si->index, ""); + return; + } + ShowRenameSignWindow(si); +} + void ShowRenameSignWindow(const Sign *si) { /* Delete all other edit windows and the save window */ diff -r d8811e327d12 -r cd9968b6f96b src/slope_func.h --- a/src/slope_func.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/slope_func.h Tue Jun 17 13:22:13 2008 +0000 @@ -347,13 +347,11 @@ * Returns the foundation needed to flatten a slope. * The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED. * - * @pre The slope must not be steep. * @param s The current #Slope. * @return The needed #Foundation. */ static inline Foundation FlatteningFoundation(Slope s) { - assert(!IsSteepSlope(s)); return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED); } diff -r d8811e327d12 -r cd9968b6f96b src/sortlist_type.h --- a/src/sortlist_type.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/sortlist_type.h Tue Jun 17 13:22:13 2008 +0000 @@ -7,6 +7,8 @@ #include "core/enum_type.hpp" #include "core/bitmath_func.hpp" +#include "core/mem_func.hpp" +#include "core/sort_func.hpp" #include "misc/smallvec.h" #include "date_type.h" @@ -30,7 +32,7 @@ public: typedef int CDECL SortFunction(const T*, const T*); -public: // Temporary: public for conversion only +protected: SortFunction* const *func_list; ///< The sort criteria functions SortListFlags flags; ///< used to control sorting/resorting/etc. uint8 sort_type; ///< what criteria to sort on @@ -55,21 +57,6 @@ this->resort_timer = DAY_TICKS * 10; } - /** - * Reverse the list - */ - void Reverse() - { - assert(this->IsSortable()); - - T *a = this->data; - T *b = a + (this->items - 1); - - do { - Swap(*a, *b); - } while (++a < --b); - } - public: GUIList() : func_list(NULL), @@ -174,25 +161,23 @@ * Since that is the worst condition for the sort function * reverse the list here. */ - FORCEINLINE void ToggleSortOrder() + void ToggleSortOrder() { this->flags ^= VL_DESC; - if (this->IsSortable()) this->Reverse(); + if (this->IsSortable()) MemReverseT(this->data, this->items); } /** - * GnomeSort algorithm - * This sorting uses a slightly modifyied Gnome search. - * The basic Gnome search trys to sort already sorted - * list parts. The modification skips these. For the first - * sorting we use qsort since it is faster for irregular - * sorted data. + * Sort the list. + * For the first sorting we use qsort since it is + * faster for irregular sorted data. After that we + * use gsort. * * @param compare The function to compare two list items * @return true if the list sequence has been altered * */ - FORCEINLINE bool Sort(SortFunction *compare) + bool Sort(SortFunction *compare) { /* Do not sort if the resort bit is not set */ if (!HASBITS(this->flags, VL_RESORT)) return false; @@ -208,40 +193,12 @@ if (HASBITS(this->flags, VL_FIRST_SORT)) { CLRBITS(this->flags, VL_FIRST_SORT); - qsort(this->data, this->items, sizeof(T), (int (CDECL *)(const void *, const void *))compare); - if (desc) this->Reverse(); + QSortT(this->data, this->items, compare, desc); return true; } - T *a = this->data; - T *b = a + 1; - - uint length = this->items; - uint offset = 0; // Jump variable - - while (length > 1) { - const int diff = compare(a, b); - if ((!desc && diff <= 0) || (desc && diff >= 0)) { - if (offset != 0) { - /* Jump back to the last direction switch point */ - a += offset; - b += offset; - offset = 0; - continue; - } - a++; - b++; - length--; - } else { - Swap(*a, *b); - if (a != this->data) { - offset++; - a--; - b--; - } - } - } + GSortT(this->data, this->items, compare, desc); return true; } @@ -292,7 +249,7 @@ void RebuildDone() { CLRBITS(this->flags, VL_REBUILD); - SETBITS(this->flags, VL_RESORT); + SETBITS(this->flags, VL_RESORT | VL_FIRST_SORT); } }; diff -r d8811e327d12 -r cd9968b6f96b src/station_cmd.cpp --- a/src/station_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/station_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1102,7 +1102,7 @@ tile_delta = (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); track = AxisToTrack(axis); - layout_ptr = (byte*)alloca(numtracks * plat_len); + layout_ptr = AllocaM(byte, numtracks * plat_len); GetStationLayout(layout_ptr, numtracks, plat_len, statspec); numtracks_orig = numtracks; @@ -1584,7 +1584,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) { /* Make sure the specified tile is a road stop of the correct type */ - if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != p2) return CMD_ERROR; + if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile) || (uint32)GetRoadStopType(tile) != GB(p2, 0, 1)) return CMD_ERROR; Station *st = GetStationByTile(tile); /* Save the stop info before it is removed */ bool is_drive_through = IsDriveThroughStopTile(tile); diff -r d8811e327d12 -r cd9968b6f96b src/strings.cpp --- a/src/strings.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/strings.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1213,7 +1213,7 @@ if (IsInsideMM(ind, (SPECSTR_RESOLUTION_START - 0x70E4), (SPECSTR_RESOLUTION_END - 0x70E4) + 1)) { int i = ind - (SPECSTR_RESOLUTION_START - 0x70E4); buff += snprintf( - buff, last - buff + 1, "%dx%d", _resolutions[i][0], _resolutions[i][1] + buff, last - buff + 1, "%dx%d", _resolutions[i].width, _resolutions[i].height ); return buff; } diff -r d8811e327d12 -r cd9968b6f96b src/table/bridge_land.h --- a/src/table/bridge_land.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/table/bridge_land.h Tue Jun 17 13:22:13 2008 +0000 @@ -28,6 +28,12 @@ # define MW(a) {a, PALETTE_TO_STRUCT_WHITE} # define MC(a) {a, PALETTE_TO_STRUCT_CONCRETE} +static const PalSpriteID _aqueduct_sprites[] = { + { SPR_AQUEDUCT_MIDDLE_X, PAL_NONE }, { 0x0, PAL_NONE }, { SPR_AQUEDUCT_PILLAR_X, PAL_NONE }, { 0x0, PAL_NONE }, + { SPR_AQUEDUCT_MIDDLE_Y, PAL_NONE }, { 0x0, PAL_NONE }, { SPR_AQUEDUCT_PILLAR_Y, PAL_NONE }, { 0x0, PAL_NONE }, + { SPR_AQUEDUCT_RAMP_SW, PAL_NONE }, { SPR_AQUEDUCT_RAMP_SE, PAL_NONE }, { SPR_AQUEDUCT_RAMP_NE, PAL_NONE }, { SPR_AQUEDUCT_RAMP_NW, PAL_NONE }, +}; + static const PalSpriteID _bridge_sprite_table_4_0[] = { { 0x9A9, PAL_NONE }, { 0x99F, PAL_NONE }, { 0x9B1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A5, PAL_NONE }, { 0x997, PAL_NONE }, { 0x9AD, PAL_NONE }, { 0x0, PAL_NONE }, diff -r d8811e327d12 -r cd9968b6f96b src/table/files.h --- a/src/table/files.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/table/files.h Tue Jun 17 13:22:13 2008 +0000 @@ -33,7 +33,7 @@ { "TRGT.GRF", {0xfc, 0xde, 0x1d, 0x7e, 0x8a, 0x74, 0x19, 0x7d, 0x72, 0xa6, 0x26, 0x95, 0x88, 0x4b, 0x90, 0x9e} } }, { "SAMPLE.CAT", {0x42, 0x2e, 0xa3, 0xdd, 0x07, 0x4d, 0x28, 0x59, 0xbb, 0x51, 0x63, 0x9a, 0x6e, 0x0e, 0x85, 0xda} }, - { "OPENTTDD.GRF", {0xfa, 0x57, 0xbe, 0xb3, 0xb7, 0xe1, 0x9b, 0xa2, 0x38, 0x8f, 0x1a, 0xb7, 0xce, 0x2a, 0x93, 0x59} } + { "OPENTTDD.GRF", {0xbe, 0x26, 0xaf, 0xdf, 0x8f, 0x24, 0xba, 0x48, 0x8c, 0x87, 0xdd, 0xbc, 0xb3, 0xf1, 0x53, 0xae} } }; static FileList files_win = { @@ -46,5 +46,5 @@ { "TRGTR.GRF", {0xde, 0x53, 0x65, 0x05, 0x17, 0xfe, 0x66, 0x1c, 0xea, 0xa3, 0x13, 0x8c, 0x6e, 0xdb, 0x0e, 0xb8} } }, { "SAMPLE.CAT", {0x92, 0x12, 0xe8, 0x1e, 0x72, 0xba, 0xdd, 0x4b, 0xbe, 0x1e, 0xae, 0xae, 0x66, 0x45, 0x8e, 0x10} }, - { "OPENTTDW.GRF", {0x3e, 0xe0, 0x24, 0xcd, 0x32, 0xa0, 0xd1, 0xd3, 0x21, 0xbc, 0x31, 0x7f, 0x22, 0x13, 0x6e, 0x81} } + { "OPENTTDW.GRF", {0xa4, 0xbf, 0xe6, 0x1d, 0xdf, 0xef, 0x50, 0x8a, 0x15, 0x73, 0xa6, 0x63, 0x9d, 0x0f, 0x52, 0xb3} } }; diff -r d8811e327d12 -r cd9968b6f96b src/table/railtypes.h --- a/src/table/railtypes.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/table/railtypes.h Tue Jun 17 13:22:13 2008 +0000 @@ -14,6 +14,7 @@ { /* Main Sprites */ { SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X, SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST, + SPR_TRACKS_FOR_SLOPES_RAIL_BASE, SPR_CROSSING_OFF_X_RAIL, SPR_TUNNEL_ENTRY_REAR_RAIL }, @@ -69,6 +70,7 @@ { /* Main Sprites */ { SPR_RAIL_TRACK_Y, SPR_RAIL_TRACK_N_S, SPR_RAIL_TRACK_BASE, SPR_RAIL_SINGLE_Y, SPR_RAIL_SINGLE_X, SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST, + SPR_TRACKS_FOR_SLOPES_RAIL_BASE, SPR_CROSSING_OFF_X_RAIL, SPR_TUNNEL_ENTRY_REAR_RAIL }, @@ -128,6 +130,7 @@ { /* Main Sprites */ { SPR_MONO_TRACK_Y, SPR_MONO_TRACK_N_S, SPR_MONO_TRACK_BASE, SPR_MONO_SINGLE_Y, SPR_MONO_SINGLE_X, SPR_MONO_SINGLE_NORTH, SPR_MONO_SINGLE_SOUTH, SPR_MONO_SINGLE_EAST, SPR_MONO_SINGLE_WEST, + SPR_TRACKS_FOR_SLOPES_MONO_BASE, SPR_CROSSING_OFF_X_MONO, SPR_TUNNEL_ENTRY_REAR_MONO }, @@ -183,6 +186,7 @@ { /* Main sprites */ { SPR_MGLV_TRACK_Y, SPR_MGLV_TRACK_N_S, SPR_MGLV_TRACK_BASE, SPR_MGLV_SINGLE_Y, SPR_MGLV_SINGLE_X, SPR_MGLV_SINGLE_NORTH, SPR_MGLV_SINGLE_SOUTH, SPR_MGLV_SINGLE_EAST, SPR_MGLV_SINGLE_WEST, + SPR_TRACKS_FOR_SLOPES_MAGLEV_BASE, SPR_CROSSING_OFF_X_MAGLEV, SPR_TUNNEL_ENTRY_REAR_MAGLEV }, diff -r d8811e327d12 -r cd9968b6f96b src/table/sprites.h --- a/src/table/sprites.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/table/sprites.h Tue Jun 17 13:22:13 2008 +0000 @@ -49,7 +49,7 @@ /* Extra graphic spritenumbers */ SPR_OPENTTD_BASE = 4896, - OPENTTD_SPRITE_COUNT = 145, + OPENTTD_SPRITE_COUNT = 147, /* Halftile-selection sprites */ SPR_HALFTILE_SELECTION_FLAT = SPR_OPENTTD_BASE, @@ -132,7 +132,26 @@ SPR_CANALS_BASE = SPR_SIGNALS_BASE + PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, CANALS_SPRITE_COUNT = 65, - SPR_SLOPES_BASE = SPR_CANALS_BASE + CANALS_SPRITE_COUNT, + /* Sprites for the Aqueduct. */ + SPR_AQUEDUCT_BASE = SPR_CANALS_BASE + CANALS_SPRITE_COUNT, + SPR_AQUEDUCT_RAMP_SW = SPR_AQUEDUCT_BASE + 0, + SPR_AQUEDUCT_RAMP_SE = SPR_AQUEDUCT_BASE + 1, + SPR_AQUEDUCT_RAMP_NE = SPR_AQUEDUCT_BASE + 2, + SPR_AQUEDUCT_RAMP_NW = SPR_AQUEDUCT_BASE + 3, + SPR_AQUEDUCT_MIDDLE_X = SPR_AQUEDUCT_BASE + 4, + SPR_AQUEDUCT_MIDDLE_Y = SPR_AQUEDUCT_BASE + 5, + SPR_AQUEDUCT_PILLAR_X = SPR_AQUEDUCT_BASE + 6, + SPR_AQUEDUCT_PILLAR_Y = SPR_AQUEDUCT_BASE + 7, + AQUEDUCT_SPRITE_COUNT = 8, + + /* Sprites for 'highlighting' tracks on sloped land. */ + SPR_TRACKS_FOR_SLOPES_BASE = SPR_AQUEDUCT_BASE + AQUEDUCT_SPRITE_COUNT, + SPR_TRACKS_FOR_SLOPES_RAIL_BASE = SPR_TRACKS_FOR_SLOPES_BASE + 0, + SPR_TRACKS_FOR_SLOPES_MONO_BASE = SPR_TRACKS_FOR_SLOPES_BASE + 4, + SPR_TRACKS_FOR_SLOPES_MAGLEV_BASE = SPR_TRACKS_FOR_SLOPES_BASE + 8, + TRACKS_FOR_SLOPES_SPRITE_COUNT = 12, + + SPR_SLOPES_BASE = SPR_TRACKS_FOR_SLOPES_BASE + TRACKS_FOR_SLOPES_SPRITE_COUNT, SPR_SLOPES_INCLINED_OFFSET = 15, SPR_SLOPES_VIRTUAL_BASE = SPR_SLOPES_BASE - SPR_SLOPES_INCLINED_OFFSET, // The original foundations (see SPR_FOUNDATION_BASE below) are mapped before the additional foundations. SPR_TRKFOUND_BLOCK_SIZE = 22, // The normal track foundation sprites are organized in blocks of 22. @@ -1244,6 +1263,7 @@ SPR_IMG_SHIP_DEPOT = 748, SPR_IMG_SHIP_DOCK = 746, SPR_IMG_BOUY = 693, + SPR_IMG_AQUEDUCT = SPR_OPENTTD_BASE + 145, /* music_gui.c */ SPR_IMG_SKIP_TO_PREV = 709, @@ -1346,6 +1366,7 @@ SPR_CURSOR_CANAL = SPR_OPENTTD_BASE + 89, SPR_CURSOR_LOCK = SPR_OPENTTD_BASE + 87, SPR_CURSOR_RIVER = SPR_OPENTTD_BASE + 137, + SPR_CURSOR_AQUEDUCT = SPR_OPENTTD_BASE + 146, /* shared road & rail cursors */ SPR_CURSOR_BRIDGE = 2593, diff -r d8811e327d12 -r cd9968b6f96b src/terraform_gui.cpp --- a/src/terraform_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/terraform_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -135,7 +135,7 @@ DoCommandP(end_tile, start_tile, _ctrl_pressed, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS)); break; case DDSP_CREATE_RIVER: - DoCommandP(end_tile, start_tile, 2, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_BUILD_CANALS)); + DoCommandP(end_tile, start_tile, 2, CcBuildCanal, CMD_BUILD_CANAL | CMD_MSG(STR_CANT_PLACE_RIVERS)); break; default: return false; diff -r d8811e327d12 -r cd9968b6f96b src/thread_pthread.cpp --- a/src/thread_pthread.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/thread_pthread.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -102,8 +102,6 @@ pthread_join(m_thr, NULL); m_thr = 0; - - delete this; } /* virtual */ bool IsCurrent() @@ -136,20 +134,14 @@ /* The new thread stops here so the calling thread can complete pthread_create() call */ sem_wait(&m_sem_start); - /* Did this thread die naturally/via exit, or did it join? */ - bool exit = false; - /* Call the proc of the creator to continue this thread */ try { m_proc(m_param); } catch (...) { - exit = true; } /* Notify threads waiting for our completion */ sem_post(&m_sem_stop); - - if (exit) delete this; } }; diff -r d8811e327d12 -r cd9968b6f96b src/toolbar_gui.cpp --- a/src/toolbar_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/toolbar_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -58,6 +58,55 @@ TB_LOWER }; +enum ToolbarNormalWidgets { + TBN_PAUSE = 0, + TBN_FASTFORWARD, + TBN_SETTINGS, + TBN_SAVEGAME, + TBN_SMALLMAP, + TBN_TOWNDIRECTORY, + TBN_SUBSIDIES, + TBN_STATIONS, + TBN_FINANCES, + TBN_PLAYERS, + TBN_GRAPHICS, + TBN_LEAGUE, + TBN_INDUSTRIES, + TBN_VEHICLESTART, ///< trains, actually. So following are trucks, boats and planes + TBN_TRAINS = TBN_VEHICLESTART, + TBN_ROADVEHS, + TBN_SHIPS, + TBN_AIRCRAFTS, + TBN_ZOOMIN, + TBN_ZOOMOUT, + TBN_RAILS, + TBN_ROADS, + TBN_WATER, + TBN_AIR, + TBN_LANDSCAPE, + TBN_MUSICSOUND, + TBN_NEWSREPORT, + TBN_HELP, + TBN_SWITCHBAR, ///< only available when toolbar has been split +}; + +enum ToolbarScenEditorWidgets { + TBSE_PAUSE = 0, + TBSE_FASTFORWARD, + TBSE_SAVESCENARIO = 3, + TBSE_SPACERPANEL, + TBSE_DATEBACKWARD = 6, + TBSE_DATEFORWARD, + TBSE_ZOOMIN = 9, + TBSE_ZOOMOUT, + TBSE_LANDGENERATE, + TBSE_TOWNGENERATE, + TBSE_INDUSTRYGENERATE, + TBSE_BUILDROAD, + TBSE_PLANTTREES, + TBSE_PLACESIGNS, +}; + static ToolbarMode _toolbar_mode; static void SelectSignTool() @@ -140,17 +189,17 @@ if (IsTransparencySet(TO_HOUSES)) SetBit(x, 12); if (IsTransparencySet(TO_SIGNS)) SetBit(x, 13); - PopupMainToolbMenu(w, 2, STR_02C4_GAME_OPTIONS, 14, 0, 0, x); + PopupMainToolbMenu(w, TBN_SETTINGS, STR_02C4_GAME_OPTIONS, 14, 0, 0, x); } static void MenuClickSettings(int index) { switch (index) { - case 0: ShowGameOptions(); return; - case 1: ShowGameDifficulty(); return; - case 2: ShowPatchesSelection(); return; - case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig); return; - case 4: ShowTransparencyToolbar(); break; + case 0: ShowGameOptions(); return; + case 1: ShowGameDifficulty(); return; + case 2: ShowPatchesSelection(); return; + case 3: ShowNewGRFSettings(!_networking, true, true, &_grfconfig); return; + case 4: ShowTransparencyToolbar(); break; case 6: ToggleBit(_display_opt, DO_SHOW_TOWN_NAMES); break; case 7: ToggleBit(_display_opt, DO_SHOW_STATION_NAMES); break; @@ -168,12 +217,12 @@ static void ToolbarSaveClick(Window *w) { - PopupMainToolbMenu(w, 3, STR_015C_SAVE_GAME, 4); + PopupMainToolbMenu(w, TBN_SAVEGAME, STR_015C_SAVE_GAME, 4); } static void ToolbarScenSaveOrLoad(Window *w) { - PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 6); + PopupMainToolbMenu(w, TBSE_SAVESCENARIO, STR_0292_SAVE_SCENARIO, 6); } static void MenuClickSaveLoad(int index) @@ -200,7 +249,7 @@ static void ToolbarMapClick(Window *w) { - PopupMainToolbMenu(w, 4, STR_02DE_MAP_OF_WORLD, 3); + PopupMainToolbMenu(w, TBN_SMALLMAP, STR_02DE_MAP_OF_WORLD, 3); } static void MenuClickMap(int index) @@ -226,7 +275,7 @@ static void ToolbarTownClick(Window *w) { - PopupMainToolbMenu(w, 5, STR_02BB_TOWN_DIRECTORY, 1); + PopupMainToolbMenu(w, TBN_TOWNDIRECTORY, STR_02BB_TOWN_DIRECTORY, 1); } static void MenuClickTown(int index) @@ -238,7 +287,7 @@ static void ToolbarSubsidiesClick(Window *w) { - PopupMainToolbMenu(w, 6, STR_02DD_SUBSIDIES, 1); + PopupMainToolbMenu(w, TBN_SUBSIDIES, STR_02DD_SUBSIDIES, 1); } static void MenuClickSubsidies(int index) @@ -250,7 +299,7 @@ static void ToolbarStationsClick(Window *w) { - PopupMainPlayerToolbMenu(w, 7, 0); + PopupMainPlayerToolbMenu(w, TBN_STATIONS, 0); } static void MenuClickStations(int index) @@ -262,7 +311,7 @@ static void ToolbarFinancesClick(Window *w) { - PopupMainPlayerToolbMenu(w, 8, 0); + PopupMainPlayerToolbMenu(w, TBN_FINANCES, 0); } static void MenuClickFinances(int index) @@ -274,7 +323,7 @@ static void ToolbarPlayersClick(Window *w) { - PopupMainPlayerToolbMenu(w, 9, 0); + PopupMainPlayerToolbMenu(w, TBN_PLAYERS, 0); } static void MenuClickCompany(int index) @@ -291,7 +340,7 @@ static void ToolbarGraphsClick(Window *w) { - PopupMainToolbMenu(w, 10, STR_0154_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8); + PopupMainToolbMenu(w, TBN_GRAPHICS, STR_0154_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8); } static void MenuClickGraphs(int index) @@ -313,7 +362,7 @@ static void ToolbarLeagueClick(Window *w) { - PopupMainToolbMenu(w, 11, STR_015A_COMPANY_LEAGUE_TABLE, 2); + PopupMainToolbMenu(w, TBN_LEAGUE, STR_015A_COMPANY_LEAGUE_TABLE, 2); } static void MenuClickLeague(int index) @@ -329,7 +378,7 @@ static void ToolbarIndustryClick(Window *w) { /* Disable build-industry menu if we are a spectator */ - PopupMainToolbMenu(w, 12, STR_INDUSTRY_DIR, 2, (_current_player == PLAYER_SPECTATOR) ? (1 << 1) : 0); + PopupMainToolbMenu(w, TBN_INDUSTRIES, STR_INDUSTRY_DIR, 2, (_current_player == PLAYER_SPECTATOR) ? 2 : 0); } static void MenuClickIndustry(int index) @@ -350,7 +399,7 @@ FOR_ALL_VEHICLES(v) { if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner); } - PopupMainPlayerToolbMenu(w, 13 + veh, dis); + PopupMainPlayerToolbMenu(w, TBN_VEHICLESTART + veh, dis); } @@ -405,7 +454,7 @@ static void ToolbarZoomInClick(Window *w) { if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { - w->HandleButtonClick(17); + w->HandleButtonClick(TBN_ZOOMIN); SndPlayFx(SND_15_BEEP); } } @@ -415,7 +464,7 @@ static void ToolbarZoomOutClick(Window *w) { if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) { - w->HandleButtonClick(18); + w->HandleButtonClick(TBN_ZOOMOUT); SndPlayFx(SND_15_BEEP); } } @@ -425,7 +474,7 @@ static void ToolbarBuildRailClick(Window *w) { const Player *p = GetPlayer(_local_player); - PopupMainToolbMenu(w, 19, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes, _last_built_railtype); + PopupMainToolbMenu(w, TBN_RAILS, STR_1015_RAILROAD_CONSTRUCTION, RAILTYPE_END, ~p->avail_railtypes, _last_built_railtype); } static void MenuClickBuildRail(int index) @@ -440,7 +489,7 @@ { const Player *p = GetPlayer(_local_player); /* The standard road button is *always* available */ - PopupMainToolbMenu(w, 20, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | ROADTYPES_ROAD), _last_built_roadtype); + PopupMainToolbMenu(w, TBN_ROADS, STR_180A_ROAD_CONSTRUCTION, 2, ~(p->avail_roadtypes | ROADTYPES_ROAD), _last_built_roadtype); } static void MenuClickBuildRoad(int index) @@ -453,7 +502,7 @@ static void ToolbarBuildWaterClick(Window *w) { - PopupMainToolbMenu(w, 21, STR_9800_DOCK_CONSTRUCTION, 1); + PopupMainToolbMenu(w, TBN_WATER, STR_9800_DOCK_CONSTRUCTION, 1); } static void MenuClickBuildWater(int index) @@ -465,7 +514,7 @@ static void ToolbarBuildAirClick(Window *w) { - PopupMainToolbMenu(w, 22, STR_A01D_AIRPORT_CONSTRUCTION, 1); + PopupMainToolbMenu(w, TBN_AIR, STR_A01D_AIRPORT_CONSTRUCTION, 1); } static void MenuClickBuildAir(int index) @@ -477,7 +526,7 @@ static void ToolbarForestClick(Window *w) { - PopupMainToolbMenu(w, 23, STR_LANDSCAPING, 3); + PopupMainToolbMenu(w, TBN_LANDSCAPE, STR_LANDSCAPING, 3); } static void MenuClickForest(int index) @@ -493,7 +542,7 @@ static void ToolbarMusicClick(Window *w) { - PopupMainToolbMenu(w, 24, STR_01D3_SOUND_MUSIC, 1); + PopupMainToolbMenu(w, TBN_MUSICSOUND, STR_01D3_SOUND_MUSIC, 1); } static void MenuClickMusicWindow(int index) @@ -505,7 +554,7 @@ static void ToolbarNewspaperClick(Window *w) { - PopupMainToolbMenu(w, 25, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3); + PopupMainToolbMenu(w, TBN_NEWSREPORT, STR_0200_LAST_MESSAGE_NEWS_REPORT, 3); } static void MenuClickNewspaper(int index) @@ -521,7 +570,7 @@ static void ToolbarHelpClick(Window *w) { - PopupMainToolbMenu(w, 26, STR_02D5_LAND_BLOCK_INFO, 6); + PopupMainToolbMenu(w, TBN_HELP, STR_02D5_LAND_BLOCK_INFO, 6); } static void MenuClickSmallScreenshot() @@ -556,7 +605,7 @@ } SplitToolbar(w); - w->HandleButtonClick(27); + w->HandleButtonClick(TBN_SWITCHBAR); SetWindowDirty(w); SndPlayFx(SND_15_BEEP); } @@ -567,7 +616,7 @@ { /* don't allow too fast scrolling */ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - w->HandleButtonClick(6); + w->HandleButtonClick(TBSE_DATEBACKWARD); w->SetDirty(); _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year - 1, MIN_YEAR, MAX_YEAR); @@ -580,7 +629,7 @@ { /* don't allow too fast scrolling */ if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) { - w->HandleButtonClick(7); + w->HandleButtonClick(TBSE_DATEFORWARD); w->SetDirty(); _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + 1, MIN_YEAR, MAX_YEAR); @@ -598,7 +647,7 @@ static void ToolbarScenZoomIn(Window *w) { if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { - w->HandleButtonClick(9); + w->HandleButtonClick(TBSE_ZOOMIN); SndPlayFx(SND_15_BEEP); } } @@ -606,14 +655,14 @@ static void ToolbarScenZoomOut(Window *w) { if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) { - w->HandleButtonClick(10); + w->HandleButtonClick(TBSE_ZOOMOUT); SndPlayFx(SND_15_BEEP); } } static void ToolbarScenGenLand(Window *w) { - w->HandleButtonClick(11); + w->HandleButtonClick(TBSE_LANDGENERATE); SndPlayFx(SND_15_BEEP); ShowEditorTerraformToolbar(); @@ -622,35 +671,35 @@ static void ToolbarScenGenTown(Window *w) { - w->HandleButtonClick(12); + w->HandleButtonClick(TBSE_TOWNGENERATE); SndPlayFx(SND_15_BEEP); ShowBuildTownWindow(); } static void ToolbarScenGenIndustry(Window *w) { - w->HandleButtonClick(13); + w->HandleButtonClick(TBSE_INDUSTRYGENERATE); SndPlayFx(SND_15_BEEP); ShowBuildIndustryWindow(); } static void ToolbarScenBuildRoad(Window *w) { - w->HandleButtonClick(14); + w->HandleButtonClick(TBSE_BUILDROAD); SndPlayFx(SND_15_BEEP); ShowBuildRoadScenToolbar(); } static void ToolbarScenPlantTrees(Window *w) { - w->HandleButtonClick(15); + w->HandleButtonClick(TBSE_PLANTTREES); SndPlayFx(SND_15_BEEP); ShowBuildTreesToolbar(); } static void ToolbarScenPlaceSign(Window *w) { - w->HandleButtonClick(16); + w->HandleButtonClick(TBSE_PLACESIGNS); SndPlayFx(SND_15_BEEP); SelectSignTool(); } @@ -666,16 +715,17 @@ /* There are 27 buttons plus some spacings if the space allows it */ uint button_width; uint spacing; - if (w->width >= 27 * 22) { + if (w->width >= (int)w->widget_count * 22) { button_width = 22; - spacing = w->width - (27 * button_width); + spacing = w->width - (w->widget_count * button_width); } else { - button_width = w->width / 27; + button_width = w->width / w->widget_count; spacing = 0; } + uint extra_spacing_at[] = { 4, 8, 13, 17, 19, 24, 0 }; - - for (uint i = 0, x = 0, j = 0; i < 27; i++) { + uint i = 0; + for (uint x = 0, j = 0; i < w->widget_count; i++) { if (extra_spacing_at[j] == i) { j++; uint add = spacing / (lengthof(extra_spacing_at) - j); @@ -685,11 +735,11 @@ w->widget[i].type = WWT_IMGBTN; w->widget[i].left = x; - x += (spacing != 0) ? button_width : (w->width - x) / (27 - i); + x += (spacing != 0) ? button_width : (w->width - x) / (w->widget_count - i); w->widget[i].right = x - 1; } - w->widget[27].type = WWT_EMPTY; + w->widget[i].type = WWT_EMPTY; // i now points to the last item _toolbar_mode = TB_NORMAL; } @@ -730,7 +780,7 @@ assert(max_icons >= 14 && max_icons <= 19); /* first hide all icons */ - for (uint i = 0; i < 27; i++) { + for (uint i = 0; i < w->widget_count; i++) { w->widget[i].type = WWT_EMPTY; } @@ -782,8 +832,8 @@ struct MainToolbarWindow : Window { MainToolbarWindow(const WindowDesc *desc) : Window(desc) { - this->SetWidgetDisabledState(0, _networking && !_network_server); // if not server, disable pause button - this->SetWidgetDisabledState(1, _networking); // if networking, disable fast-forward button + this->SetWidgetDisabledState(TBN_PAUSE, _networking && !_network_server); // if not server, disable pause button + this->SetWidgetDisabledState(TBN_FASTFORWARD, _networking); // if networking, disable fast-forward button CLRBITS(this->flags4, WF_WHITE_BORDER_MASK); @@ -801,12 +851,12 @@ /* If spectator, disable all construction buttons * ie : Build road, rail, ships, airports and landscaping * Since enabled state is the default, just disable when needed */ - this->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, 19, 20, 21, 22, 23, WIDGET_LIST_END); + this->SetWidgetsDisabledState(_current_player == PLAYER_SPECTATOR, TBN_RAILS, TBN_ROADS, TBN_WATER, TBN_AIR, TBN_LANDSCAPE, WIDGET_LIST_END); /* disable company list drop downs, if there are no companies */ - this->SetWidgetsDisabledState(ActivePlayerCount() == 0, 7, 8, 13, 14, 15, 16, WIDGET_LIST_END); + this->SetWidgetsDisabledState(ActivePlayerCount() == TBN_PAUSE, TBN_STATIONS, TBN_FINANCES, TBN_TRAINS, TBN_ROADVEHS, TBN_SHIPS, TBN_AIRCRAFTS, WIDGET_LIST_END); - this->SetWidgetDisabledState(19, !CanBuildVehicleInfrastructure(VEH_TRAIN)); - this->SetWidgetDisabledState(22, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)); + this->SetWidgetDisabledState(TBN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN)); + this->SetWidgetDisabledState(TBN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)); this->DrawWidgets(); } @@ -866,22 +916,16 @@ _place_proc(tile); } - virtual void OnPlaceObjectAbort() - { - this->RaiseWidget(25); - this->SetDirty(); - } - virtual void OnTick() { - if (this->IsWidgetLowered(0) != !!_pause_game) { - this->ToggleWidgetLoweredState(0); - this->InvalidateWidget(0); + if (this->IsWidgetLowered(TBN_PAUSE) != !!_pause_game) { + this->ToggleWidgetLoweredState(TBN_PAUSE); + this->InvalidateWidget(TBN_PAUSE); } - if (this->IsWidgetLowered(1) != !!_fast_forward) { - this->ToggleWidgetLoweredState(1); - this->InvalidateWidget(1); + if (this->IsWidgetLowered(TBN_FASTFORWARD) != !!_fast_forward) { + this->ToggleWidgetLoweredState(TBN_FASTFORWARD); + this->InvalidateWidget(TBN_FASTFORWARD); } } @@ -896,7 +940,7 @@ virtual void OnTimeout() { - for (uint i = 2; i < this->widget_count; i++) { + for (uint i = TBN_SETTINGS; i < this->widget_count; i++) { if (this->IsWidgetLowered(i)) { this->RaiseWidget(i); this->InvalidateWidget(i); @@ -906,7 +950,7 @@ virtual void OnInvalidateData(int data) { - if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18); + if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBN_ZOOMIN, TBN_ZOOMOUT); } }; @@ -989,6 +1033,7 @@ }; struct ScenarioEditorToolbarWindow : Window { +public: ScenarioEditorToolbarWindow(const WindowDesc *desc) : Window(desc) { CLRBITS(this->flags4, WF_WHITE_BORDER_MASK); @@ -1000,8 +1045,8 @@ virtual void OnPaint() { - this->SetWidgetDisabledState(6, _settings_newgame.game_creation.starting_year <= MIN_YEAR); - this->SetWidgetDisabledState(7, _settings_newgame.game_creation.starting_year >= MAX_YEAR); + this->SetWidgetDisabledState(TBSE_DATEBACKWARD, _settings_newgame.game_creation.starting_year <= MIN_YEAR); + this->SetWidgetDisabledState(TBSE_DATEFORWARD, _settings_newgame.game_creation.starting_year >= MAX_YEAR); /* Draw brown-red toolbar bg. */ GfxFillRect(0, 0, this->width - 1, this->height - 1, 0xB2); @@ -1010,12 +1055,13 @@ this->DrawWidgets(); SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); - DrawStringCenteredTruncated(this->widget[6].right, this->widget[7].left, 6, STR_00AF, TC_FROMSTRING); + DrawStringCenteredTruncated(this->widget[TBSE_DATEBACKWARD].right, this->widget[TBSE_DATEFORWARD].left, 6, STR_00AF, TC_FROMSTRING); /* We hide this panel when the toolbar space gets too small */ - if (this->widget[4].left != this->widget[4].right) { - DrawStringCenteredTruncated(this->widget[4].left + 1, this->widget[4].right - 1, 1, STR_0221_OPENTTD, TC_FROMSTRING); - DrawStringCenteredTruncated(this->widget[4].left + 1, this->widget[4].right - 1, 11, STR_0222_SCENARIO_EDITOR, TC_FROMSTRING); + const Widget *panel = &this->widget[TBSE_SPACERPANEL]; + if (panel->left != panel->right) { + DrawStringCenteredTruncated(panel->left + 1, panel->right - 1, 1, STR_0221_OPENTTD, TC_FROMSTRING); + DrawStringCenteredTruncated(panel->left + 1, panel->right - 1, 11, STR_0222_SCENARIO_EDITOR, TC_FROMSTRING); } } @@ -1046,13 +1092,13 @@ case WKC_NUM_PLUS: case WKC_EQUALS: case WKC_SHIFT | WKC_EQUALS: - case WKC_SHIFT | WKC_F5: ToolbarZoomInClick(this); break; + case WKC_SHIFT | WKC_F5: ToolbarScenZoomIn(this); break; /* those following are all fall through */ case WKC_NUM_MINUS: case WKC_MINUS: case WKC_SHIFT | WKC_MINUS: - case WKC_SHIFT | WKC_F6: ToolbarZoomOutClick(this); break; + case WKC_SHIFT | WKC_F6: ToolbarScenZoomOut(this); break; case 'L': ShowEditorTerraformToolbar(); break; case 'M': ShowSmallMap(); break; @@ -1067,12 +1113,6 @@ _place_proc(tile); } - virtual void OnPlaceObjectAbort() - { - this->RaiseWidget(25); - this->SetDirty(); - } - virtual void OnResize(Point new_size, Point delta) { /* There are 15 buttons plus some spacings if the space allows it. @@ -1093,8 +1133,7 @@ } uint extra_spacing_at[] = { 3, 4, 7, 8, 10, 16, 0 }; - /* Yes, it defines about 27 widgets for this toolbar */ - for (uint i = 0, x = 0, j = 0, b = 0; i < 27; i++) { + for (uint i = 0, x = 0, j = 0, b = 0; i < this->widget_count; i++) { switch (i) { case 4: this->widget[i].left = x; @@ -1142,20 +1181,20 @@ virtual void OnTick() { - if (this->IsWidgetLowered(0) != !!_pause_game) { - this->ToggleWidgetLoweredState(0); + if (this->IsWidgetLowered(TBSE_PAUSE) != !!_pause_game) { + this->ToggleWidgetLoweredState(TBSE_PAUSE); this->SetDirty(); } - if (this->IsWidgetLowered(1) != !!_fast_forward) { - this->ToggleWidgetLoweredState(1); + if (this->IsWidgetLowered(TBSE_FASTFORWARD) != !!_fast_forward) { + this->ToggleWidgetLoweredState(TBSE_FASTFORWARD); this->SetDirty(); } } virtual void OnInvalidateData(int data) { - if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, 17, 18); + if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, TBSE_ZOOMIN, TBSE_ZOOMOUT); } }; @@ -1409,7 +1448,7 @@ { this->flags4 &= ~WF_WHITE_BORDER_MASK; this->sel_index = (_local_player != PLAYER_SPECTATOR) ? _local_player : GetPlayerIndexFromMenu(0); - if (_networking && main_button == 9) { + if (_networking && main_button == TBN_PLAYERS) { if (_local_player != PLAYER_SPECTATOR) { this->sel_index++; } else { @@ -1433,7 +1472,7 @@ byte num = ActivePlayerCount(); /* Increase one to fit in PlayerList in the menu when in network */ - if (_networking && this->main_button == 9) num++; + if (_networking && this->main_button == TBN_PLAYERS) num++; if (this->item_count != num) { this->item_count = num; @@ -1457,7 +1496,7 @@ int gray = this->gray_items; /* 9 = playerlist */ - if (_networking && this->main_button == 9) { + if (_networking && this->main_button == TBN_PLAYERS) { if (sel == 0) { GfxFillRect(x, y, x + 238, y + 9, 0); } @@ -1496,7 +1535,7 @@ this->UpdatePlayerMenuHeight(); /* We have a new entry at the top of the list of menu 9 when networking * so keep that in count */ - if (_networking && this->main_button == 9) { + if (_networking && this->main_button == TBN_PLAYERS) { if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1; } else { index = GetPlayerIndexFromMenu(index); @@ -1511,7 +1550,7 @@ /* We have a new entry at the top of the list of menu 9 when networking * so keep that in count */ - if (_networking && this->main_button == 9) { + if (_networking && this->main_button == TBN_PLAYERS) { if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1; } else { index = GetPlayerIndexFromMenu(index); diff -r d8811e327d12 -r cd9968b6f96b src/town_cmd.cpp --- a/src/town_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/town_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1642,13 +1642,14 @@ * @param random_bits required for newgrf houses * @pre house can be built here */ -static inline void ClearMakeHouseTile(TileIndex tile, TownID tid, byte counter, byte stage, HouseID type, byte random_bits) +static inline void ClearMakeHouseTile(TileIndex tile, Town *t, byte counter, byte stage, HouseID type, byte random_bits) { CommandCost cc = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR); assert(CmdSucceeded(cc)); - MakeHouseTile(tile, tid, counter, stage, type, random_bits); + IncreaseBuildingCount(t, type); + MakeHouseTile(tile, t->index, counter, stage, type, random_bits); if (GetHouseSpecs(type)->building_flags & BUILDING_IS_ANIMATED) AddAnimatedTile(tile); MarkTileDirtyByTile(tile); @@ -1665,14 +1666,14 @@ * @param random_bits required for newgrf houses * @pre house can be built here */ -static void MakeTownHouse(TileIndex t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits) +static void MakeTownHouse(TileIndex t, Town *town, byte counter, byte stage, HouseID type, byte random_bits) { BuildingFlags size = GetHouseSpecs(type)->building_flags; - ClearMakeHouseTile(t, tid, counter, stage, type, random_bits); - if (size & BUILDING_2_TILES_Y) ClearMakeHouseTile(t + TileDiffXY(0, 1), tid, counter, stage, ++type, random_bits); - if (size & BUILDING_2_TILES_X) ClearMakeHouseTile(t + TileDiffXY(1, 0), tid, counter, stage, ++type, random_bits); - if (size & BUILDING_HAS_4_TILES) ClearMakeHouseTile(t + TileDiffXY(1, 1), tid, counter, stage, ++type, random_bits); + ClearMakeHouseTile(t, town, counter, stage, type, random_bits); + if (size & BUILDING_2_TILES_Y) ClearMakeHouseTile(t + TileDiffXY(0, 1), town, counter, stage, ++type, random_bits); + if (size & BUILDING_2_TILES_X) ClearMakeHouseTile(t + TileDiffXY(1, 0), town, counter, stage, ++type, random_bits); + if (size & BUILDING_HAS_4_TILES) ClearMakeHouseTile(t + TileDiffXY(1, 1), town, counter, stage, ++type, random_bits); } @@ -1929,11 +1930,6 @@ } if ((hs->extra_flags & BUILDING_IS_HISTORICAL) && !_generating_world) continue; - - if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { - uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile); - if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue; - } } if (_cur_year < hs->min_year || _cur_year > hs->max_year) continue; @@ -1947,7 +1943,7 @@ SetBit(oneof, TOWN_HAS_STADIUM); } - if (HASBITS(t->flags12 , oneof)) continue; + if (HASBITS(t->flags12, oneof)) continue; /* Make sure there is no slope? */ bool noslope = (hs->building_flags & TILE_NOT_SLOPED) != 0; @@ -1963,9 +1959,13 @@ /* 1x1 house checks are already done */ } + if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) { + uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile); + if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue; + } + /* build the house */ t->num_houses++; - IncreaseBuildingCount(t, house); /* Special houses that there can be only one of. */ t->flags12 |= oneof; @@ -1986,7 +1986,7 @@ } } - MakeTownHouse(tile, t->index, construction_counter, construction_stage, house, Random()); + MakeTownHouse(tile, t, construction_counter, construction_stage, house, Random()); return true; } @@ -1995,9 +1995,10 @@ } -static void DoClearTownHouseHelper(TileIndex tile) +static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house) { assert(IsTileType(tile, MP_HOUSE)); + DecreaseBuildingCount(t, house); DoClearSquare(tile); DeleteAnimatedTile(tile); } @@ -2046,7 +2047,6 @@ } t->num_houses--; - DecreaseBuildingCount(t, house); /* Clear flags for houses that only may exist once/town. */ if (hs->building_flags & BUILDING_IS_CHURCH) { @@ -2057,10 +2057,10 @@ /* Do the actual clearing of tiles */ uint eflags = hs->building_flags; - DoClearTownHouseHelper(tile); - if (eflags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0)); - if (eflags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1)); - if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1)); + DoClearTownHouseHelper(tile, t, house); + if (eflags & BUILDING_2_TILES_Y) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house); + if (eflags & BUILDING_2_TILES_X) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house); + if (eflags & BUILDING_HAS_4_TILES) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house); } static bool IsUniqueTownName(const char *name) diff -r d8811e327d12 -r cd9968b6f96b src/town_gui.cpp --- a/src/town_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/town_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -545,7 +545,7 @@ SetVScrollCount(this, this->towns.Length()); this->DrawWidgets(); - this->DrawSortButtonState(this->towns.sort_type == 0 ? TDW_SORTNAME : TDW_SORTPOPULATION, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP); + this->DrawSortButtonState(this->towns.SortType() == 0 ? TDW_SORTNAME : TDW_SORTPOPULATION, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP); { int n = 0; diff -r d8811e327d12 -r cd9968b6f96b src/town_map.h --- a/src/town_map.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/town_map.h Tue Jun 17 13:22:13 2008 +0000 @@ -265,7 +265,7 @@ } /** - * Set the year that this house was constructed (between 1920 and 2175). + * Set the year that this house was constructed. * @param t the tile of this house * @param year the year to set * @pre IsTileType(t, MP_HOUSE) && IsHouseCompleted(t) @@ -273,11 +273,11 @@ static inline void SetHouseConstructionYear(TileIndex t, Year year) { assert(IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)); - _m[t].m5 = Clamp(year - ORIGINAL_BASE_YEAR, 0, 0xFF); + _m[t].m5 = Clamp(year - GetHouseSpecs(GetHouseType(t))->min_year, 0, 0xFF); } /** - * Get the year that this house was constructed (between 1920 and 2175). + * Get the year that this house was constructed. * @param t the tile of this house * @pre IsTileType(t, MP_HOUSE) * @return year @@ -285,7 +285,7 @@ static inline Year GetHouseConstructionYear(TileIndex t) { assert(IsTileType(t, MP_HOUSE)); - return IsHouseCompleted(t) ? _m[t].m5 + ORIGINAL_BASE_YEAR : 0; + return IsHouseCompleted(t) ? _m[t].m5 + GetHouseSpecs(GetHouseType(t))->min_year : 0; } /** diff -r d8811e327d12 -r cd9968b6f96b src/town_type.h --- a/src/town_type.h Tue Jun 17 10:32:49 2008 +0000 +++ b/src/town_type.h Tue Jun 17 13:22:13 2008 +0000 @@ -51,9 +51,6 @@ RATING_TUNNEL_BRIDGE_DOWN_STEP = -250, RATING_TUNNEL_BRIDGE_MINIMUM = 0, - RATING_INDUSTRY_DOWN_STEP = -1500, - RATING_INDUSTRY_MINIMUM = RATING_MINIMUM, - RATING_ROAD_DOWN_STEP_INNER = -50, ///< removing a roadpiece in the middle RATING_ROAD_DOWN_STEP_EDGE = -18, ///< removing a roadpiece at the edge RATING_ROAD_MINIMUM = -100, diff -r d8811e327d12 -r cd9968b6f96b src/train_cmd.cpp --- a/src/train_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/train_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -211,6 +211,8 @@ u->u.rail.first_engine = v == u ? INVALID_ENGINE : first_engine; u->u.rail.railtype = rvi_u->railtype; + if (IsTrainEngine(u)) first_engine = u->engine_type; + /* Set user defined data to its default value */ u->u.rail.user_def_data = rvi_u->user_def_data; } @@ -225,8 +227,6 @@ if (!HasBit(EngInfo(u->engine_type)->misc_flags, EF_RAIL_TILTS)) train_can_tilt = false; - if (IsTrainEngine(u)) first_engine = u->engine_type; - /* Cache wagon override sprite group. NULL is returned if there is none */ u->u.rail.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->u.rail.first_engine); @@ -549,7 +549,7 @@ if (!IsCompatibleRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR; /* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */ - Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); + Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1); memset(vl, 0, sizeof(*vl) * (num_vehicles + 1)); if (!Vehicle::AllocateList(vl, num_vehicles)) @@ -716,7 +716,7 @@ if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR; /* Allow for the dual-heads and the articulated parts, plus one to "terminate" the list. */ - Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); + Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1); memset(vl, 0, sizeof(*vl) * (num_vehicles + 1)); if (!Vehicle::AllocateList(vl, num_vehicles)) { diff -r d8811e327d12 -r cd9968b6f96b src/tunnelbridge_cmd.cpp --- a/src/tunnelbridge_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/tunnelbridge_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -227,9 +227,11 @@ if (!ValParamRailtype(railtype)) return CMD_ERROR; break; + case TRANSPORT_WATER: + break; + default: - /* For now, only TRANSPORT_RAIL and TRANSPORT_ROAD are allowed. - * But let not this stops us for preparing the future */ + /* Airports don't have tunnels. */ return CMD_ERROR; } @@ -250,9 +252,11 @@ return_cmd_error(STR_500A_START_AND_END_MUST_BE_IN); } - /* set and test bridge length, availability */ bridge_len = sx + sy - x - y - 1; - if (!CheckBridge_Stuff(bridge_type, bridge_len)) return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE); + if (transport_type != TRANSPORT_WATER) { + /* set and test bridge length, availability */ + if (!CheckBridge_Stuff(bridge_type, bridge_len)) return_cmd_error(STR_5015_CAN_T_BUILD_BRIDGE_HERE); + } /* retrieve landscape height and ensure it's on land */ tile_start = TileXY(x, y); @@ -311,7 +315,7 @@ } else { /* Build a new bridge. */ - bool allow_on_slopes = (!_is_old_ai_player && _settings_game.construction.build_on_slopes); + bool allow_on_slopes = (!_is_old_ai_player && _settings_game.construction.build_on_slopes && transport_type != TRANSPORT_WATER); /* Try and clear the start landscape */ ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR); @@ -331,6 +335,8 @@ if (CmdFailed(terraform_cost_south) || (terraform_cost_south.GetCost() != 0 && !allow_on_slopes)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); cost.AddCost(terraform_cost_south); + + if (transport_type == TRANSPORT_WATER && (tileh_start == SLOPE_FLAT || tileh_end == SLOPE_FLAT)) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION); } if (!replace_bridge) { @@ -368,6 +374,11 @@ MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), roadtypes); break; + case TRANSPORT_WATER: + MakeAqueductBridgeRamp(tile_start, owner, dir); + MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir)); + break; + default: NOT_REACHED(); break; @@ -445,6 +456,9 @@ bridge_len = CalcBridgeLenCostFactor(bridge_len); cost.AddCost((int64)bridge_len * _price.build_bridge * GetBridgeSpec(bridge_type)->price >> 8); + + /* Aqueducts are a little more expensive. */ + if (transport_type == TRANSPORT_WATER) cost.AddCost((int64)bridge_len * _price.clear_water); } return cost; @@ -724,7 +738,7 @@ * @param y Sprite Y position of front pillar. * @param z_bridge Absolute height of bridge bottom. */ -static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, BridgeType type, int x, int y, int z_bridge) +static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo* ti, Axis axis, bool drawfarpillar, int x, int y, int z_bridge) { /* Do not draw bridge pillars if they are invisible */ if (IsInvisibilitySet(TO_BRIDGES)) return; @@ -732,8 +746,6 @@ SpriteID image = psid->sprite; if (image != 0) { - bool drawfarpillar = !HasBit(GetBridgeSpec(type)->flags, 0); - /* "side" specifies the side the pillars stand on. * The length of the pillars is then set to the height of the bridge over the corners of this edge. * @@ -926,7 +938,11 @@ if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head /* Table number 6 always refers to the bridge heads for any bridge type */ - psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; + if (transport_type != TRANSPORT_WATER) { + psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; + } else { + psid = _aqueduct_sprites + base_offset; + } if (!ice) { DrawClearLandTile(ti, 3); @@ -1023,44 +1039,43 @@ /* Z position of the bridge sprites relative to bridge height (downwards) */ static const int BRIDGE_Z_START = 3; - const PalSpriteID* psid; - uint base_offset; - TileIndex rampnorth; - TileIndex rampsouth; - TransportType transport_type; - Axis axis; - uint piece; - BridgeType type; - int x; - int y; - uint z; - if (!IsBridgeAbove(ti->tile)) return; - rampnorth = GetNorthernBridgeEnd(ti->tile); - rampsouth = GetSouthernBridgeEnd(ti->tile); - transport_type = GetTunnelBridgeTransportType(rampsouth); + TileIndex rampnorth = GetNorthernBridgeEnd(ti->tile); + TileIndex rampsouth = GetSouthernBridgeEnd(ti->tile); + TransportType transport_type = GetTunnelBridgeTransportType(rampsouth); - axis = GetBridgeAxis(ti->tile); - piece = CalcBridgePiece( + Axis axis = GetBridgeAxis(ti->tile); + uint piece = CalcBridgePiece( GetTunnelBridgeLength(ti->tile, rampnorth) + 1, GetTunnelBridgeLength(ti->tile, rampsouth) + 1 ); - type = GetBridgeType(rampsouth); - if (transport_type == TRANSPORT_RAIL) { - base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset; + const PalSpriteID *psid; + bool drawfarpillar; + if (transport_type != TRANSPORT_WATER) { + BridgeType type = GetBridgeType(rampsouth); + drawfarpillar = !HasBit(GetBridgeSpec(type)->flags, 0); + + uint base_offset; + if (transport_type == TRANSPORT_RAIL) { + base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset; + } else { + base_offset = 8; + } + + psid = base_offset + GetBridgeSpriteTable(type, piece); } else { - base_offset = 8; + drawfarpillar = true; + psid = _aqueduct_sprites; } - psid = base_offset + GetBridgeSpriteTable(type, piece); if (axis != AXIS_X) psid += 4; - x = ti->x; - y = ti->y; + int x = ti->x; + int y = ti->y; uint bridge_z = GetBridgeHeight(rampsouth); - z = bridge_z - BRIDGE_Z_START; + uint z = bridge_z - BRIDGE_Z_START; /* Add a bounding box, that separates the bridge from things below it. */ AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR); @@ -1125,7 +1140,7 @@ } } else if (_settings_client.gui.bridge_pillars) { /* draw pillars below for high bridges */ - DrawBridgePillars(psid, ti, axis, type, x, y, z); + DrawBridgePillars(psid, ti, axis, drawfarpillar, x, y, z); } } @@ -1182,11 +1197,12 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) { + TransportType tt = GetTunnelBridgeTransportType(tile); + if (IsTunnel(tile)) { - td->str = (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) ? - STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; - } else { //so it must be a bridge - td->str = GetBridgeSpec(GetBridgeType(tile))->transport_name[GetTunnelBridgeTransportType(tile)]; + td->str = (tt == TRANSPORT_RAIL) ? STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; + } else { // IsBridge(tile) + td->str = (tt == TRANSPORT_WATER) ? STR_AQUEDUCT : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt]; } td->owner[0] = GetTileOwner(tile); } @@ -1246,9 +1262,9 @@ if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR))) { /* When clearing the bridge/tunnel failed there are still vehicles on/in * the bridge/tunnel. As all *our* vehicles are already removed, they - * must be of another owner. Therefor this must be a road bridge/tunnel. + * must be of another owner. Therefore this can't be rail tunnel/bridge. * In that case we can safely reassign the ownership to OWNER_NONE. */ - assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD); + assert(GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL); SetTileOwner(tile, OWNER_NONE); } } @@ -1342,7 +1358,7 @@ } } else { // IsBridge(tile) - if (v->IsPrimaryVehicle()) { + if (v->IsPrimaryVehicle() && v->type != VEH_SHIP) { /* modify speed of vehicle */ uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed; @@ -1358,29 +1374,51 @@ case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; case DIAGDIR_NW: if ((y & 0xF) != 0) return VETSB_CONTINUE; break; } - if (v->type == VEH_TRAIN) { - v->u.rail.track = TRACK_BIT_WORMHOLE; - ClrBit(v->u.rail.flags, VRF_GOINGUP); - ClrBit(v->u.rail.flags, VRF_GOINGDOWN); - } else { - v->u.road.state = RVSB_WORMHOLE; + switch (v->type) { + case VEH_TRAIN: + v->u.rail.track = TRACK_BIT_WORMHOLE; + ClrBit(v->u.rail.flags, VRF_GOINGUP); + ClrBit(v->u.rail.flags, VRF_GOINGDOWN); + break; + + case VEH_ROAD: + v->u.road.state = RVSB_WORMHOLE; + break; + + case VEH_SHIP: + v->u.ship.state = TRACK_BIT_WORMHOLE; + break; + + default: NOT_REACHED(); } return VETSB_ENTERED_WORMHOLE; } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { v->tile = tile; - if (v->type == VEH_TRAIN) { - if (v->u.rail.track == TRACK_BIT_WORMHOLE) { - v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); - return VETSB_ENTERED_WORMHOLE; - } - } else { - if (v->u.road.state == RVSB_WORMHOLE) { - v->u.road.state = _road_exit_tunnel_state[dir]; - v->u.road.frame = 0; - return VETSB_ENTERED_WORMHOLE; - } + switch (v->type) { + case VEH_TRAIN: + if (v->u.rail.track == TRACK_BIT_WORMHOLE) { + v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); + return VETSB_ENTERED_WORMHOLE; + } + break; + + case VEH_ROAD: + if (v->u.road.state == RVSB_WORMHOLE) { + v->u.road.state = _road_exit_tunnel_state[dir]; + v->u.road.frame = 0; + return VETSB_ENTERED_WORMHOLE; + } + break; + + case VEH_SHIP: + if (v->u.ship.state == TRACK_BIT_WORMHOLE) { + v->u.ship.state = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); + return VETSB_ENTERED_WORMHOLE; + } + break; + + default: NOT_REACHED(); } - return VETSB_CONTINUE; } } return VETSB_CONTINUE; @@ -1388,7 +1426,7 @@ static CommandCost TerraformTile_TunnelBridge(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new) { - if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() && IsBridge(tile)) { + if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() && IsBridge(tile) && GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) { DiagDirection direction = GetTunnelBridgeDirection(tile); Axis axis = DiagDirToAxis(direction); CommandCost res; diff -r d8811e327d12 -r cd9968b6f96b src/vehicle.cpp --- a/src/vehicle.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/vehicle.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -206,7 +206,7 @@ /** Procedure called for every vehicle found in tunnel/bridge in the hash map */ static void *GetVehicleTunnelBridgeProc(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN && v->type != VEH_ROAD) return NULL; + if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return NULL; _error_message = VehicleInTheWayErrMsg(v); return v; diff -r d8811e327d12 -r cd9968b6f96b src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/vehicle_gui.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -31,6 +31,8 @@ #include "vehicle_func.h" #include "autoreplace_gui.h" #include "core/alloc_func.hpp" +#include "core/mem_func.hpp" +#include "core/sort_func.hpp" #include "string_func.h" #include "settings_type.h" #include "widgets/dropdown_func.h" @@ -42,9 +44,8 @@ #include "table/strings.h" Sorting _sorting; -static bool _internal_sort_order; // descending/ascending -typedef int CDECL VehicleSortListingTypeFunction(const void*, const void*); +typedef int CDECL VehicleSortListingTypeFunction(const Vehicle* const *, const Vehicle* const *); static VehicleSortListingTypeFunction VehicleNumberSorter; static VehicleSortListingTypeFunction VehicleNameSorter; @@ -89,40 +90,30 @@ void BuildVehicleList(VehicleListBase *vl, PlayerID owner, uint16 index, uint16 window_type) { - if (!(vl->vehicles.flags & VL_REBUILD)) return; + if (!vl->vehicles.NeedRebuild()) return; DEBUG(misc, 3, "Building vehicle list for player %d at station %d", owner, index); GenerateVehicleSortList(&vl->vehicles, vl->vehicle_type, owner, index, window_type); - vl->vehicles.flags &= ~VL_REBUILD; - vl->vehicles.flags |= VL_RESORT; + vl->vehicles.RebuildDone(); } /* cached values for VehicleNameSorter to spare many GetString() calls */ static const Vehicle *_last_vehicle[2] = { NULL, NULL }; -static char _last_name[2][64] = { "", "" }; void SortVehicleList(VehicleListBase *vl) { - if (!(vl->vehicles.flags & VL_RESORT)) return; + if (vl->vehicles.Sort(_vehicle_sorter[vl->vehicles.SortType()])) return; /* invalidate cached values for name sorter - vehicle names could change */ _last_vehicle[0] = _last_vehicle[1] = NULL; - - _internal_sort_order = (vl->vehicles.flags & VL_DESC) != 0; - qsort((void*)vl->vehicles.Begin(), vl->vehicles.Length(), sizeof(*vl->vehicles.Begin()), - _vehicle_sorter[vl->vehicles.sort_type]); - - vl->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; - vl->vehicles.flags &= ~VL_RESORT; } void DepotSortList(VehicleList *list) { - _internal_sort_order = 0; if (list->Length() < 2) return; - qsort((void*)list->Begin(), list->Length(), sizeof(*list->Begin()), _vehicle_sorter[0]); + QSortT(list->Begin(), list->Length(), _vehicle_sorter[0]); } /** draw the vehicle profit button in the vehicle list window. */ @@ -507,183 +498,136 @@ } -/* if the sorting criteria had the same value, sort vehicle by unitnumber */ -#define VEHICLEUNITNUMBERSORTER(r, a, b) {if (r == 0) {r = a->unitnumber - b->unitnumber;}} - -static int CDECL VehicleNumberSorter(const void *a, const void *b) -{ - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r = va->unitnumber - vb->unitnumber; - - return (_internal_sort_order & 1) ? -r : r; -} - -static int CDECL VehicleNameSorter(const void *a, const void *b) +/** Sort vehicles by their number */ +static int CDECL VehicleNumberSorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r; - - if (va != _last_vehicle[0]) { - _last_vehicle[0] = va; - SetDParam(0, va->index); - GetString(_last_name[0], STR_VEHICLE_NAME, lastof(_last_name[0])); - } - - if (vb != _last_vehicle[1]) { - _last_vehicle[1] = vb; - SetDParam(0, vb->index); - GetString(_last_name[1], STR_VEHICLE_NAME, lastof(_last_name[1])); - } - - r = strcmp(_last_name[0], _last_name[1]); // sort by name - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + return (*a)->unitnumber - (*b)->unitnumber; } -static int CDECL VehicleAgeSorter(const void *a, const void *b) +/** Sort vehicles by their name */ +static int CDECL VehicleNameSorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r = va->age - vb->age; - - VEHICLEUNITNUMBERSORTER(r, va, vb); + static char last_name[2][64]; - return (_internal_sort_order & 1) ? -r : r; -} + if (*a != _last_vehicle[0]) { + _last_vehicle[0] = *a; + SetDParam(0, (*a)->index); + GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0])); + } -static int CDECL VehicleProfitThisYearSorter(const void *a, const void *b) -{ - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r = ClampToI32(va->GetDisplayProfitThisYear() - vb->GetDisplayProfitThisYear()); + if (*b != _last_vehicle[1]) { + _last_vehicle[1] = *b; + SetDParam(0, (*b)->index); + GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1])); + } - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + int r = strcmp(last_name[0], last_name[1]); + return (r != 0) ? r : VehicleNumberSorter(a, b); } -static int CDECL VehicleProfitLastYearSorter(const void *a, const void *b) +/** Sort vehicles by their age */ +static int CDECL VehicleAgeSorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r = ClampToI32(va->GetDisplayProfitLastYear() - vb->GetDisplayProfitLastYear()); - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + int r = (*a)->age - (*b)->age; + return (r != 0) ? r : VehicleNumberSorter(a, b); } -static int CDECL VehicleCargoSorter(const void *a, const void *b) +/** Sort vehicles by this year profit */ +static int CDECL VehicleProfitThisYearSorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - const Vehicle* v; - AcceptedCargo cargoa; - AcceptedCargo cargob; + int r = ClampToI32((*a)->GetDisplayProfitThisYear() - (*b)->GetDisplayProfitThisYear()); + return (r != 0) ? r : VehicleNumberSorter(a, b); +} + +/** Sort vehicles by last year profit */ +static int CDECL VehicleProfitLastYearSorter(const Vehicle* const *a, const Vehicle* const *b) +{ + int r = ClampToI32((*a)->GetDisplayProfitLastYear() - (*b)->GetDisplayProfitLastYear()); + return (r != 0) ? r : VehicleNumberSorter(a, b); +} + +/** Sort vehicles by their cargo */ +static int CDECL VehicleCargoSorter(const Vehicle* const *a, const Vehicle* const *b) +{ + const Vehicle *v; + AcceptedCargo diff; + MemSetT(diff, 0); + + /* Append the cargo of the connected weagons */ + for (v = *a; v != NULL; v = v->Next()) diff[v->cargo_type] += v->cargo_cap; + for (v = *b; v != NULL; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap; + int r = 0; - - memset(cargoa, 0, sizeof(cargoa)); - memset(cargob, 0, sizeof(cargob)); - for (v = va; v != NULL; v = v->Next()) cargoa[v->cargo_type] += v->cargo_cap; - for (v = vb; v != NULL; v = v->Next()) cargob[v->cargo_type] += v->cargo_cap; - for (CargoID i = 0; i < NUM_CARGO; i++) { - r = cargoa[i] - cargob[i]; + r = diff[i]; if (r != 0) break; } - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; -} - -static int CDECL VehicleReliabilitySorter(const void *a, const void *b) -{ - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r = va->reliability - vb->reliability; - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; -} - -static int CDECL VehicleMaxSpeedSorter(const void *a, const void *b) -{ - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r; - - if (va->type == VEH_TRAIN && vb->type == VEH_TRAIN) { - r = va->u.rail.cached_max_speed - vb->u.rail.cached_max_speed; - } else { - r = va->max_speed - vb->max_speed; - } - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + return (r != 0) ? r : VehicleNumberSorter(a, b); } -static int CDECL VehicleModelSorter(const void *a, const void *b) +/** Sort vehicles by their reliability */ +static int CDECL VehicleReliabilitySorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - int r = va->engine_type - vb->engine_type; - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + int r = (*a)->reliability - (*b)->reliability; + return (r != 0) ? r : VehicleNumberSorter(a, b); } -static int CDECL VehicleValueSorter(const void *a, const void *b) +/** Sort vehicles by their max speed */ +static int CDECL VehicleMaxSpeedSorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle* va = *(const Vehicle**)a; - const Vehicle* vb = *(const Vehicle**)b; - const Vehicle *u; - Money valuea = 0, valueb = 0; - - for (u = va; u != NULL; u = u->Next()) valuea += u->value; - for (u = vb; u != NULL; u = u->Next()) valueb += u->value; - - int r = ClampToI32(valuea - valueb); - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + int r = 0; + if ((*a)->type == VEH_TRAIN && (*b)->type == VEH_TRAIN) { + r = (*a)->u.rail.cached_max_speed - (*b)->u.rail.cached_max_speed; + } else { + r = (*a)->max_speed - (*b)->max_speed; + } + return (r != 0) ? r : VehicleNumberSorter(a, b); } -static int CDECL VehicleLengthSorter(const void *a, const void *b) +/** Sort vehicles by model */ +static int CDECL VehicleModelSorter(const Vehicle* const *a, const Vehicle* const *b) { - const Vehicle *va = *(const Vehicle**)a; - const Vehicle *vb = *(const Vehicle**)b; + int r = (*a)->engine_type - (*b)->engine_type; + return (r != 0) ? r : VehicleNumberSorter(a, b); +} + +/** Sort vehciles by their value */ +static int CDECL VehicleValueSorter(const Vehicle* const *a, const Vehicle* const *b) +{ + const Vehicle *u; + Money diff = 0; + + for (u = *a; u != NULL; u = u->Next()) diff += u->value; + for (u = *b; u != NULL; u = u->Next()) diff -= u->value; + + int r = ClampToI32(diff); + return (r != 0) ? r : VehicleNumberSorter(a, b); +} + +/** Sort vehicles by their length */ +static int CDECL VehicleLengthSorter(const Vehicle* const *a, const Vehicle* const *b) +{ int r = 0; - - switch (va->type) { + switch ((*a)->type) { case VEH_TRAIN: - r = va->u.rail.cached_total_length - vb->u.rail.cached_total_length; + r = (*a)->u.rail.cached_total_length - (*b)->u.rail.cached_total_length; break; - case VEH_ROAD: - for (const Vehicle *u = va; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length; - for (const Vehicle *u = vb; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length; - break; + case VEH_ROAD: { + const Vehicle *u; + for (u = *a; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length; + for (u = *b; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length; + } break; default: NOT_REACHED(); } - - VEHICLEUNITNUMBERSORTER(r, va, vb); - - return (_internal_sort_order & 1) ? -r : r; + return (r != 0) ? r : VehicleNumberSorter(a, b); } void InitializeGUI() { - memset(&_sorting, 0, sizeof(_sorting)); + MemSetT(&_sorting, 0); } /** Assigns an already open vehicle window to a new vehicle. @@ -915,15 +859,16 @@ default: NOT_REACHED(); break; } - this->vehicles.flags = VL_REBUILD | (this->sorting->order ? VL_DESC : VL_NONE); - this->vehicles.sort_type = this->sorting->criteria; - this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; // Set up resort timer + this->vehicles.SetListing(*this->sorting); + this->vehicles.ForceRebuild(); + this->vehicles.NeedResort(); this->FindWindowPlacementAndResize(desc); } ~VehicleListWindow() { + *this->sorting = this->vehicles.GetListing(); } virtual void OnPaint() @@ -988,9 +933,9 @@ this->DrawWidgets(); /* draw sorting criteria string */ - DrawString(85, 15, _vehicle_sort_listing[this->vehicles.sort_type], TC_BLACK); + DrawString(85, 15, _vehicle_sort_listing[this->vehicles.SortType()], TC_BLACK); /* draw arrow pointing up/down for ascending/descending sorting */ - this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.flags & VL_DESC ? SBS_DOWN : SBS_UP); + this->DrawSortButtonState(VLW_WIDGET_SORT_ORDER, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP); max = min(this->vscroll.pos + this->vscroll.cap, this->vehicles.Length()); for (i = this->vscroll.pos; i < max; ++i) { @@ -1030,14 +975,11 @@ { switch (widget) { case VLW_WIDGET_SORT_ORDER: /* Flip sorting method ascending/descending */ - this->vehicles.flags ^= VL_DESC; - this->vehicles.flags |= VL_RESORT; - - this->sorting->order = !!(this->vehicles.flags & VL_DESC); + this->vehicles.ToggleSortOrder(); this->SetDirty(); break; case VLW_WIDGET_SORT_BY_PULLDOWN:/* Select sorting criteria dropdown menu */ - ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.sort_type, VLW_WIDGET_SORT_BY_PULLDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10)); + ShowDropDownMenu(this, _vehicle_sort_listing, this->vehicles.SortType(), VLW_WIDGET_SORT_BY_PULLDOWN, 0, (this->vehicle_type == VEH_TRAIN || this->vehicle_type == VEH_ROAD) ? 0 : (1 << 10)); return; case VLW_WIDGET_LIST: { /* Matrix to show vehicles */ uint32 id_v = (pt.y - PLY_WND_PRC__OFFSET_TOP_WIDGET) / this->resize.step_height; @@ -1090,12 +1032,7 @@ { switch (widget) { case VLW_WIDGET_SORT_BY_PULLDOWN: - if (this->vehicles.sort_type != index) { - /* value has changed -> resort */ - this->vehicles.flags |= VL_RESORT; - this->vehicles.sort_type = index; - this->sorting->criteria = this->vehicles.sort_type; - } + this->vehicles.SetSortType(index); break; case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN: assert(this->vehicles.Length() != 0); @@ -1128,13 +1065,11 @@ virtual void OnTick() { if (_pause_game != 0) return; - if (--this->vehicles.resort_timer == 0) { + if (this->vehicles.NeedResort()) { StationID station = ((this->window_number & VLW_MASK) == VLW_STATION_LIST) ? GB(this->window_number, 16, 16) : INVALID_STATION; PlayerID owner = (PlayerID)this->caption_color; DEBUG(misc, 3, "Periodic resort %d list player %d at station %d", this->vehicle_type, owner, station); - this->vehicles.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; - this->vehicles.flags |= VL_RESORT; this->SetDirty(); } } @@ -1147,7 +1082,11 @@ virtual void OnInvalidateData(int data) { - this->vehicles.flags |= (data == 0 ? VL_REBUILD : VL_RESORT); + if (data == 0) { + this->vehicles.ForceRebuild(); + } else { + this->vehicles.ForceResort(); + } } }; diff -r d8811e327d12 -r cd9968b6f96b src/video/cocoa/cocoa_v.mm --- a/src/video/cocoa/cocoa_v.mm Tue Jun 17 10:32:49 2008 +0000 +++ b/src/video/cocoa/cocoa_v.mm Tue Jun 17 13:22:13 2008 +0000 @@ -206,8 +206,8 @@ count = _cocoa_subdriver->ListModes(modes, lengthof(modes)); for (i = 0; i < count; i++) { - _resolutions[i][0] = modes[i].x; - _resolutions[i][1] = modes[i].y; + _resolutions[i].width = modes[i].x; + _resolutions[i].height = modes[i].y; } _num_resolutions = count; @@ -317,8 +317,8 @@ /* Don't create a window or enter fullscreen if we're just going to show a dialog. */ if (_cocoa_video_dialog) return NULL; - width = _cur_resolution[0]; - height = _cur_resolution[1]; + width = _cur_resolution.width; + height = _cur_resolution.height; bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth(); _cocoa_subdriver = QZ_CreateSubdriver(width, height, bpp, _fullscreen, true); diff -r d8811e327d12 -r cd9968b6f96b src/video/dedicated_v.cpp --- a/src/video/dedicated_v.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/video/dedicated_v.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -138,10 +138,10 @@ { int bpp = BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth(); if (bpp == 0) _dedicated_video_mem = NULL; - else _dedicated_video_mem = MallocT(_cur_resolution[0] * _cur_resolution[1] * (bpp / 8)); + else _dedicated_video_mem = MallocT(_cur_resolution.width * _cur_resolution.height * (bpp / 8)); - _screen.width = _screen.pitch = _cur_resolution[0]; - _screen.height = _cur_resolution[1]; + _screen.width = _screen.pitch = _cur_resolution.width; + _screen.height = _cur_resolution.height; ScreenSizeChanged(); SetDebugString("net=6"); diff -r d8811e327d12 -r cd9968b6f96b src/video/null_v.cpp --- a/src/video/null_v.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/video/null_v.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -15,8 +15,8 @@ const char *VideoDriver_Null::Start(const char* const *parm) { this->ticks = GetDriverParamInt(parm, "ticks", 1000); - _screen.width = _screen.pitch = _cur_resolution[0]; - _screen.height = _cur_resolution[1]; + _screen.width = _screen.pitch = _cur_resolution.width; + _screen.height = _cur_resolution.height; ScreenSizeChanged(); /* Do not render, nor blit */ diff -r d8811e327d12 -r cd9968b6f96b src/video/sdl_v.cpp --- a/src/video/sdl_v.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/video/sdl_v.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -96,7 +96,7 @@ } } -static const uint16 default_resolutions[][2] = { +static const Dimension default_resolutions[] = { { 640, 480}, { 800, 600}, {1024, 768}, @@ -134,12 +134,12 @@ if (w >= 640 && h >= 480) { int j; for (j = 0; j < n; j++) { - if (_resolutions[j][0] == w && _resolutions[j][1] == h) break; + if (_resolutions[j].width == w && _resolutions[j].height == h) break; } if (j == n) { - _resolutions[j][0] = w; - _resolutions[j][1] = h; + _resolutions[j].width = w; + _resolutions[j].height = h; if (++n == lengthof(_resolutions)) break; } } @@ -160,21 +160,21 @@ // is the wanted mode among the available modes? for (i = 0; i != _num_resolutions; i++) { - if (*w == _resolutions[i][0] && *h == _resolutions[i][1]) return; + if (*w == _resolutions[i].width && *h == _resolutions[i].height) return; } // use the closest possible resolution best = 0; - delta = abs((_resolutions[0][0] - *w) * (_resolutions[0][1] - *h)); + delta = abs((_resolutions[0].width - *w) * (_resolutions[0].height - *h)); for (i = 1; i != _num_resolutions; ++i) { - uint newdelta = abs((_resolutions[i][0] - *w) * (_resolutions[i][1] - *h)); + uint newdelta = abs((_resolutions[i].width - *w) * (_resolutions[i].height - *h)); if (newdelta < delta) { best = i; delta = newdelta; } } - *w = _resolutions[best][0]; - *h = _resolutions[best][1]; + *w = _resolutions[best].width; + *h = _resolutions[best].height; } #ifndef ICON_DIR @@ -441,7 +441,7 @@ DEBUG(driver, 1, "SDL: using driver '%s'", buf); GetVideoModes(); - CreateMainSurface(_cur_resolution[0], _cur_resolution[1]); + CreateMainSurface(_cur_resolution.width, _cur_resolution.height); MarkWholeScreenDirty(); SDL_CALL SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); @@ -534,7 +534,7 @@ { _fullscreen = fullscreen; GetVideoModes(); // get the list of available video modes - if (_num_resolutions == 0 || !this->ChangeResolution(_cur_resolution[0], _cur_resolution[1])) { + if (_num_resolutions == 0 || !this->ChangeResolution(_cur_resolution.width, _cur_resolution.height)) { // switching resolution failed, put back full_screen to original status _fullscreen ^= true; return false; diff -r d8811e327d12 -r cd9968b6f96b src/video/video_driver.hpp --- a/src/video/video_driver.hpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/video/video_driver.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -6,6 +6,7 @@ #define VIDEO_VIDEO_DRIVER_HPP #include "../driver.h" +#include "../core/geometry_type.hpp" class VideoDriver: public Driver { public: @@ -35,7 +36,7 @@ extern VideoDriver *_video_driver; extern char _ini_videodriver[32]; extern int _num_resolutions; -extern uint16 _resolutions[32][2]; -extern uint16 _cur_resolution[2]; +extern Dimension _resolutions[32]; +extern Dimension _cur_resolution; #endif /* VIDEO_VIDEO_DRIVER_HPP */ diff -r d8811e327d12 -r cd9968b6f96b src/video/win32_v.cpp --- a/src/video/win32_v.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/video/win32_v.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -36,7 +36,7 @@ bool _window_maximize; uint _display_hz; uint _fullscreen_bpp; -static uint16 _bck_resolution[2]; +static Dimension _bck_resolution; #if !defined(UNICODE) uint _codepage; #endif @@ -371,10 +371,7 @@ return 0; case WM_DESTROY: - if (_window_maximize) { - _cur_resolution[0] = _bck_resolution[0]; - _cur_resolution[1] = _bck_resolution[1]; - } + if (_window_maximize) _cur_resolution = _bck_resolution; return 0; case WM_LBUTTONDOWN: @@ -530,10 +527,7 @@ /* Set maximized flag when we maximize (obviously), but also when we * switched to fullscreen from a maximized state */ _window_maximize = (wParam == SIZE_MAXIMIZED || (_window_maximize && _fullscreen)); - if (_window_maximize) { - _bck_resolution[0] = _cur_resolution[0]; - _bck_resolution[1] = _cur_resolution[1]; - } + if (_window_maximize) _bck_resolution = _cur_resolution; ClientSizeChanged(LOWORD(lParam), HIWORD(lParam)); } return 0; @@ -713,7 +707,7 @@ return true; } -static const uint16 default_resolutions[][2] = { +static const Dimension default_resolutions[] = { { 640, 480 }, { 800, 600 }, { 1024, 768 }, @@ -746,7 +740,7 @@ uint j; for (j = 0; j < n; j++) { - if (_resolutions[j][0] == dm.dmPelsWidth && _resolutions[j][1] == dm.dmPelsHeight) break; + if (_resolutions[j].width == (int)dm.dmPelsWidth && _resolutions[j].height == (int)dm.dmPelsHeight) break; } /* In the previous loop we have checked already existing/added resolutions if @@ -754,8 +748,8 @@ * looped all and found none, add the new one to the list. If we have reached the * maximum amount of resolutions, then quit querying the display */ if (j == n) { - _resolutions[j][0] = dm.dmPelsWidth; - _resolutions[j][1] = dm.dmPelsHeight; + _resolutions[j].width = dm.dmPelsWidth; + _resolutions[j].height = dm.dmPelsHeight; if (++n == lengthof(_resolutions)) break; } } @@ -784,13 +778,13 @@ FindResolutions(); - DEBUG(driver, 2, "Resolution for display: %dx%d", _cur_resolution[0], _cur_resolution[1]); + DEBUG(driver, 2, "Resolution for display: %dx%d", _cur_resolution.width, _cur_resolution.height); // fullscreen uses those - _wnd.width_org = _cur_resolution[0]; - _wnd.height_org = _cur_resolution[1]; + _wnd.width_org = _cur_resolution.width; + _wnd.height_org = _cur_resolution.height; - AllocateDibSection(_cur_resolution[0], _cur_resolution[1]); + AllocateDibSection(_cur_resolution.width, _cur_resolution.height); MakeWindow(_fullscreen); MarkWholeScreenDirty(); diff -r d8811e327d12 -r cd9968b6f96b src/viewport.cpp --- a/src/viewport.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/viewport.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -81,7 +81,7 @@ const SubSprite *sub; ///< only draw a rectangular part of the sprite int32 x; int32 y; - ChildScreenSpriteToDraw *next; + int next; ///< next child to draw (-1 at the end) }; struct ParentSpriteToDraw { @@ -103,7 +103,6 @@ int zmax; ///< maximal world Z coordinate of bounding box int first_child; ///< the first child to draw. - int last_child; ///< the last sprite to draw. bool comparison_done; ///< Used during sprite sorting: true if sprite has been compared with all other sprites }; @@ -677,10 +676,9 @@ ps->zmax = z + max(bb_offset_z, dz) - 1; ps->comparison_done = false; - ps->first_child = _vd.child_screen_sprites_to_draw.items; - ps->last_child = _vd.child_screen_sprites_to_draw.items; - - _vd.last_child = &ps->last_child; + ps->first_child = -1; + + _vd.last_child = &ps->first_child; if (_vd.combine_sprites == 1) _vd.combine_sprites = 2; } @@ -718,17 +716,22 @@ pal = PALETTE_TO_TRANSPARENT; } - /* Append the sprite to the active ChildSprite list. - * If the active ParentSprite is a foundation, update last_foundation_child as well. */ + *_vd.last_child = _vd.child_screen_sprites_to_draw.items; + ChildScreenSpriteToDraw *cs = _vd.child_screen_sprites_to_draw.Append(); cs->image = image; cs->pal = pal; cs->sub = sub; cs->x = x; cs->y = y; - cs->next = NULL; - - *_vd.last_child = _vd.child_screen_sprites_to_draw.items; + cs->next = -1; + + /* Append the sprite to the active ChildSprite list. + * If the active ParentSprite is a foundation, update last_foundation_child as well. + * Note: ChildSprites of foundations are NOT sequential in the vector, as selection sprites are added at last. */ + if (_vd.last_foundation_child[0] == _vd.last_child) _vd.last_foundation_child[0] = &cs->next; + if (_vd.last_foundation_child[1] == _vd.last_child) _vd.last_foundation_child[1] = &cs->next; + _vd.last_child = &cs->next; } /* Returns a StringSpriteToDraw */ @@ -1375,8 +1378,10 @@ const ParentSpriteToDraw *ps = *it; if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y, ps->sub); - const ChildScreenSpriteToDraw *last = csstdv->Get(ps->last_child); - for (const ChildScreenSpriteToDraw *cs = csstdv->Get(ps->first_child); cs != last; cs++) { + int child_idx = ps->first_child; + while (child_idx >= 0) { + const ChildScreenSpriteToDraw *cs = csstdv->Get(child_idx); + child_idx = cs->next; DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub); } } @@ -1895,7 +1900,7 @@ y < si->sign.top + 12 && x >= si->sign.left && x < si->sign.left + si->sign.width_1) { - ShowRenameSignWindow(si); + HandleClickOnSign(si); return true; } } @@ -1909,7 +1914,7 @@ y < si->sign.top + 24 && x >= si->sign.left && x < si->sign.left + si->sign.width_1 * 2) { - ShowRenameSignWindow(si); + HandleClickOnSign(si); return true; } } @@ -1925,7 +1930,7 @@ y < si->sign.top + ScaleByZoom(12, vp->zoom) && x >= si->sign.left && x < si->sign.left + ScaleByZoom(si->sign.width_2, vp->zoom)) { - ShowRenameSignWindow(si); + HandleClickOnSign(si); return true; } } diff -r d8811e327d12 -r cd9968b6f96b src/water_cmd.cpp --- a/src/water_cmd.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/water_cmd.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -40,6 +40,7 @@ #include "newgrf_cargo.h" #include "effectvehicle_func.h" #include "oldpool_func.h" +#include "tunnelbridge_map.h" #include "table/sprites.h" #include "table/strings.h" @@ -482,13 +483,19 @@ { switch (GetTileType(tile)) { case MP_WATER: - if (!IsCoast(tile)) return true; - switch (GetTileSlope(tile, NULL)) { - case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE); - case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW); - case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW); - case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE); - default: return false; + switch (GetWaterTileType(tile)) { + default: NOT_REACHED(); + case WATER_TILE_DEPOT: case WATER_TILE_CLEAR: return true; + case WATER_TILE_LOCK: return DiagDirToAxis(GetLockDirection(tile)) == DiagDirToAxis(DirToDiagDir(from)); + + case WATER_TILE_COAST: + switch (GetTileSlope(tile, NULL)) { + case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE); + case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW); + case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW); + case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE); + default: return false; + } } case MP_RAILWAY: @@ -506,6 +513,7 @@ case MP_STATION: return IsCustomFSMportsSpecIndex(tile) || IsOilRig(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT) || IsBuoy(tile); case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0; + case MP_TUNNELBRIDGE: return GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER && ReverseDiagDir(GetTunnelBridgeDirection(tile)) == DirToDiagDir(from); default: return false; } } @@ -726,15 +734,16 @@ { switch (GetWaterTileType(tile)) { case WATER_TILE_CLEAR: - if (!IsCanal(tile)) { - td->str = STR_3804_WATER; - } else { - td->str = STR_LANDINFO_CANAL; + switch (GetWaterClass(tile)) { + case WATER_CLASS_SEA: td->str = STR_3804_WATER; break; + case WATER_CLASS_CANAL: td->str = STR_LANDINFO_CANAL; break; + case WATER_CLASS_RIVER: td->str = STR_LANDINFO_RIVER; break; + default: assert(0); break; } break; case WATER_TILE_COAST: td->str = STR_3805_COAST_OR_RIVERBANK; break; - case WATER_TILE_LOCK : td->str = STR_LANDINFO_LOCK; break; - case WATER_TILE_DEPOT: td->str = STR_3806_SHIP_DEPOT; break; + case WATER_TILE_LOCK : td->str = STR_LANDINFO_LOCK; break; + case WATER_TILE_DEPOT: td->str = STR_3806_SHIP_DEPOT; break; default: assert(0); break; } diff -r d8811e327d12 -r cd9968b6f96b src/win32.cpp --- a/src/win32.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/win32.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -474,7 +474,7 @@ _ident = GetTickCount(); // something pretty unique - MakeCRCTable((uint32*)alloca(256 * sizeof(uint32))); + MakeCRCTable(AllocaM(uint32, 256)); _crash_msg = output = (char*)LocalAlloc(LMEM_FIXED, 8192); { diff -r d8811e327d12 -r cd9968b6f96b src/window.cpp --- a/src/window.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/window.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -1809,7 +1809,6 @@ DecreaseWindowCounters(); HandlePlacePresize(); UpdateTileSelection(); - HandleKeyScrolling(); if (!VpHandlePlaceSizingDrag()) return; if (!HandleDragDrop()) return; @@ -1949,6 +1948,7 @@ */ void InputLoop() { + HandleKeyScrolling(); HandleMouseEvents(); HandleAutoscroll(); } diff -r d8811e327d12 -r cd9968b6f96b src/yapf/follow_track.hpp --- a/src/yapf/follow_track.hpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/yapf/follow_track.hpp Tue Jun 17 13:22:13 2008 +0000 @@ -264,7 +264,7 @@ } // tunnel holes and bridge ramps can be entered only from proper direction - if (!IsWaterTT() && IsTileType(m_new_tile, MP_TUNNELBRIDGE)) { + if (IsTileType(m_new_tile, MP_TUNNELBRIDGE)) { if (IsTunnel(m_new_tile)) { if (!m_is_tunnel) { DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_new_tile); diff -r d8811e327d12 -r cd9968b6f96b src/yapf/yapf_ship.cpp --- a/src/yapf/yapf_ship.cpp Tue Jun 17 10:32:49 2008 +0000 +++ b/src/yapf/yapf_ship.cpp Tue Jun 17 13:22:13 2008 +0000 @@ -109,6 +109,9 @@ /* new trackdir does not match the next one when going straight */ c += 10; } + + c += YAPF_TILE_LENGTH * tf->m_tiles_skipped; + // apply it n.m_cost = n.m_parent->m_cost + c; return true;