Index: Makefile =================================================================== --- Makefile (revision 9744) +++ Makefile (working copy) @@ -76,6 +76,8 @@ else LDFLAGS += -mwindows endif +elif ifeq ($(OSTYPE),linux) + LD_FLAGS += "-Wl,-Bstatic" endif ifeq ($(BACKEND),sdl2) @@ -101,6 +103,11 @@ CFLAGS += -O1 endif +ifneq ($(LTO),) + CFLAGS += -flto + LDFLAGS += -flto +endif + ifdef DEBUG MSG_LEVEL ?= 3 PROFILE ?= 0 Index: config.template =================================================================== --- config.template (revision 9744) +++ config.template (working copy) @@ -47,6 +47,9 @@ # using zstd compression library #USE_ZSTD := 1 +# enable link time optimizations +#LTO := 1 + # using FluidSynth for MIDI playback (SDL2 backend needed for Linux/MacOS, SDL2 or GDI for MinGW) #USE_FLUIDSYNTH_MIDI := 1 Index: dataobj/ribi.h =================================================================== --- dataobj/ribi.h (revision 9744) +++ dataobj/ribi.h (working copy) @@ -1,3 +1,4 @@ + /* * This file is part of the Simutrans project under the Artistic License. * (see LICENSE.txt) @@ -192,6 +193,7 @@ static const ribi doppelr[16]; /// Lookup table to convert ribi to dir. static const dir dirs[16]; + public: /// Table containing the four compass directions static const ribi nesw[4]; @@ -198,9 +200,11 @@ /// Convert building layout to ribi (four rotations), use doppelt in case of two rotations static const ribi layout_to_ribi[4]; // building layout to ribi (for four rotations, for two use doppelt()! + static bool is_perpendicular(ribi x, ribi y); + +#ifdef RIBI_LOOKUP static bool is_twoway(ribi x) { return (flags[x]&twoway)!=0; } static bool is_threeway(ribi x) { return (flags[x]&threeway)!=0; } - static bool is_perpendicular(ribi x, ribi y); static bool is_single(ribi x) { return (flags[x] & single) != 0; } static bool is_bend(ribi x) { return (flags[x] & bend) != 0; } static bool is_straight(ribi x) { return (flags[x] & (straight_ns | straight_ew)) != 0; } @@ -209,9 +213,34 @@ /// Convert single/straight direction into their doubled form (n, ns -> ns), map all others to zero static ribi doubles(ribi x) { return doppelr[x]; } + /// Backward direction for single ribi's, bitwise-NOT for all others static ribi backward(ribi x) { return backwards[x]; } + /// Convert ribi to dir + static dir get_dir(ribi x) { return dirs[x]; } +#else +#ifdef USE_GCC_POPCOUNT + static uint8 get_numways(ribi x) { return (__builtin_popcount(x)); } + static bool is_twoway(ribi x) { return get_numways(x) == 2; } + static bool is_threeway(ribi x) { return get_numways(x) > 2; } + static bool is_single(ribi x) { return get_numways(x) == 1; } +#else + static bool is_twoway(ribi x) { return (0x1668 >> x) & 1; } + static bool is_threeway(ribi x) { return (0xE880 >> x) & 1; } + static bool is_single(ribi x) { return (0x0116 >> x) & 1; } +#endif + static bool is_bend(ribi x) { return (0x1248 >> x) & 1; } + static bool is_straight(ribi x) { return (0x0536 >> x) & 1; } + static bool is_straight_ns(ribi x) { return (0x0032 >> x) & 1; } + static bool is_straight_ew(ribi x) { return (0x0504 >> x) & 1; } + + static ribi doubles(ribi x) { return (INT64_C(0x00000A0A00550A50) >> (x * 4)) & 0x0F; } + static ribi backward(ribi x) { return (INT64_C(0x01234A628951C84F) >> (x * 4)) & 0x0F; } + + /// Convert ribi to dir + static dir get_dir(ribi x) { return (INT64_C(0x0002007103006540) >> (x * 4)) & 0x7; } +#endif /** * Same as backward, but for single directions only. * Effectively does bit rotation. Avoids lookup table backwards. @@ -227,9 +256,6 @@ static ribi rotate90l(ribi x) { return ((x | x<<4) >> 1) & 0xf; } static ribi rotate45(ribi x) { return (is_single(x) ? x|rotate90(x) : x&rotate90(x)); } // 45 to the right static ribi rotate45l(ribi x) { return (is_single(x) ? x|rotate90l(x) : x&rotate90l(x)); } // 45 to the left - - /// Convert ribi to dir - static dir get_dir(ribi x) { return dirs[x]; } }; /**