# HG changeset patch
# User celestar
# Date 1181736356 0
# Node ID 1ac8aac923850195dc5b072f46790c86cbb9fca1
# Parent 0b8b245a2391891b03002951b531d8c3cb8d483c
(svn r10136) [gamebalance] -Sync: r9900:10100 from trunk
diff -r 0b8b245a2391 -r 1ac8aac92385 Makefile.in
--- a/Makefile.in Wed Jun 13 11:45:14 2007 +0000
+++ b/Makefile.in Wed Jun 13 12:05:56 2007 +0000
@@ -31,10 +31,14 @@
OSXAPP = !!OSXAPP!!
REVISION = !!REVISION!!
AWK = !!AWK!!
+DISTCC = !!DISTCC!!
RES := $(shell if ! [ -f $(CONFIG_CACHE_SOURCE_LIST) ] || [ -n "`cmp $(CONFIG_CACHE_SOURCE_LIST) $(SOURCE_LIST)`" ]; then cp $(SOURCE_LIST) $(CONFIG_CACHE_SOURCE_LIST); fi )
all: config.cache
+ifdef DISTCC
+ @if [ -z "`echo '$(MFLAGS)' | grep '\-j'`" ]; then echo; echo "WARNING: you enabled distcc support, but you don't seem to be using the -jN paramter"; echo; fi
+endif
@for dir in $(DIRS); do \
$(MAKE) -C $$dir all; \
done
@@ -99,6 +103,9 @@
run-gdb: all
$(Q)cd !!BIN_DIR!! && gdb --ex run --args ./!!TTD!! $(OPENTTD_ARGS)
+run-prof: all
+ $(Q)cd !!BIN_DIR!! && ./!!TTD!! $(OPENTTD_ARGS) && gprof !!TTD!! | less
+
%.o:
@for dir in $(SRC_DIRS); do \
$(MAKE) -C $$dir $(@:src/%=%); \
diff -r 0b8b245a2391 -r 1ac8aac92385 Makefile.src.in
--- a/Makefile.src.in Wed Jun 13 11:45:14 2007 +0000
+++ b/Makefile.src.in Wed Jun 13 12:05:56 2007 +0000
@@ -96,8 +96,15 @@
REV_MODIFIED := $(shell svnversion $(SRC_DIR) | sed -n 's/.*\(M\).*/\1/p' )
# Find the revision like: rXXXX-branch
REV := $(shell LC_ALL=C svn info $(SRC_DIR) | $(AWK) '/^URL:.*branch/ { split($$2, a, "/"); BRANCH="-"a[5] } /^Last Changed Rev:/ { REV="r"$$4"$(REV_MODIFIED)" } END { print REV BRANCH }')
+else
+# Are we a git dir?
+ifeq ($(shell if test -d $(SRC_DIR)/../.git; then echo 1; fi), 1)
+# Find the revision like: rXXXXM
+REV := g$(shell if head=`git rev-parse --verify HEAD 2>/dev/null`; then echo "$$head" | cut -c1-8; fi)$(shell if git diff-index HEAD | read dummy; then echo M; fi)$(shell git branch|grep '[*]'|sed 's/\* /-/;s/^-master$$//')
endif
endif
+endif
+
# Make sure we have something in REV
ifeq ($(REV),)
REV := norev000
diff -r 0b8b245a2391 -r 1ac8aac92385 bin/data/flags.grf
Binary file bin/data/flags.grf has changed
diff -r 0b8b245a2391 -r 1ac8aac92385 bin/data/oneway.grf
Binary file bin/data/oneway.grf has changed
diff -r 0b8b245a2391 -r 1ac8aac92385 bin/data/openttd.grf
Binary file bin/data/openttd.grf has changed
diff -r 0b8b245a2391 -r 1ac8aac92385 bin/data/tramtrkw.grf
Binary file bin/data/tramtrkw.grf has changed
diff -r 0b8b245a2391 -r 1ac8aac92385 changelog.txt
--- a/changelog.txt Wed Jun 13 11:45:14 2007 +0000
+++ b/changelog.txt Wed Jun 13 12:05:56 2007 +0000
@@ -1,7 +1,38 @@
+0.5.2 (2007-05-29)
+------------------------------------------------------------------------
+- Feature: Add threading support for MorphOS (r9759)
+- Fix: Bridges and tunnels were not always removed on bankruptcy, thus leaving tunnels/bridges with an invalid owner that would crash the game when clicking with the query tool on them (r9966)
+- Fix: Null pointer dereference under MorphOS and AmigaOS (r9861)
+
+
+0.5.2-RC1 (2007-05-16)
+------------------------------------------------------------------------
+- Feature: Windows 95/98/ME check in Windows 2000/XP/2003/Vista builds (r9834)
+- Feature: Add password protected status to 'players' (network server) console command (r9771)
+- Feature: Add server_lang in [network] section of openttd.cfg (r9716)
+- Fix: Loading some TTDP savegames caused an instant assertion on loading (r9857)
+- Fix: [NewGRF] Catch occurance of division-by-zero in varaction handling (r9837)
+- Fix: Only non dedicated servers cannot have 0 players [FS#765] (r9785)
+- Fix: Remove arbitrary limit on length of NewGRF strings (r9775)
+- Fix: [NewGRF] Ignore axis-bit of station tile layouts [FS#756] (r9758)
+- Fix: [win32] Dead key and open/close console. (r9728)
+- Fix: When you have closed the "Load game"/"New game" windows which you started from the "start server" menu, you shouldn't start a server when starting a new game [SF#1244842] (r9757)
+- Fix: Trains were lost after autorenewal/autoreplace [FS#732] (r9753)
+- Fix: Stop flooded towns from building roads on water [FS#598] (r9743)
+- Fix: Station signs were not resized when the language changed [FS#672] (r9741)
+- Fix: In news history, newlines were not replaced with spaces [FS#677] (r9731)
+- Fix: Crash when destroying bridge with train partially on it [FS#738] (r9726)
+- Fix: Planes made a 270 degree turn instead of a 90 degree turn on the southern runway of the intercontinental airport [FS#743] (r9725)
+- Fix: In-game private messages did not work for clients with high ClientIDs (r9719)
+- Fix: Do not allow building of rail vehicles whose railtype is not available (r9718)
+- Fix: [YAPF] The guessed path was ignored for ships [FS#736] (r9694)
+
+
0.5.1 (2007-04-20)
------------------------------------------------------------------------
(None)
+
0.5.1-RC3 (2007-04-17)
------------------------------------------------------------------------
- Feature: Add list_patches to console commands; shows all patches and values (r9565)
diff -r 0b8b245a2391 -r 1ac8aac92385 config.lib
--- a/config.lib Wed Jun 13 11:45:14 2007 +0000
+++ b/config.lib Wed Jun 13 12:05:56 2007 +0000
@@ -5,6 +5,8 @@
}
set_default() {
+ released_version=""
+
ignore_extra_parameters="0"
# We set all kinds of defaults for params. Later on the user can override
# most of them; but if they don't, this default is used.
@@ -42,6 +44,7 @@
enable_universal="1"
enable_osx_g5="0"
enable_unicode="1"
+ with_distcc="1"
with_osx_sysroot="1"
with_application_bundle="1"
with_sdl="1"
@@ -59,7 +62,7 @@
with_fontconfig="1"
with_psp_config="1"
- save_params_array="build host cc_build cc_host cxx_build cxx_host windres strip awk lipo os revision endian config_log prefix_dir binary_dir data_dir icon_dir personal_dir install_dir custom_lang_dir second_data_dir enable_install enable_debug enable_profiling enable_dedicated enable_network enable_static enable_translator enable_assert enable_strip with_osx_sysroot enable_universal enable_osx_g5 enable_unicode with_application_bundle with_sdl with_cocoa with_zlib with_png with_makedepend with_direct_music with_sort with_iconv with_midi with_midi_arg with_libtimidity with_freetype with_fontconfig with_psp_config CC CXX CFLAGS LDFLAGS"
+ save_params_array="build host cc_build cc_host cxx_build cxx_host windres strip awk lipo os revision endian config_log prefix_dir binary_dir data_dir icon_dir personal_dir install_dir custom_lang_dir second_data_dir enable_install enable_debug enable_profiling enable_dedicated enable_network enable_static enable_translator enable_assert enable_strip with_distcc with_osx_sysroot enable_universal enable_osx_g5 enable_unicode with_application_bundle with_sdl with_cocoa with_zlib with_png with_makedepend with_direct_music with_sort with_iconv with_midi with_midi_arg with_libtimidity with_freetype with_fontconfig with_psp_config CC CXX CFLAGS LDFLAGS"
}
detect_params() {
@@ -233,6 +236,10 @@
--with-midi=*) with_midi="$optarg";;
--with-midi-arg=*) with_midi_arg="$optarg";;
+ --without-distcc) with_distcc="0";;
+ --with-distcc) with_distcc="2";;
+ --with-distcc=*) with_distcc="$optarg";;
+
--without-osx-sysroot) with_osx_sysroot="0";;
--with-osx-sysroot) with_osx_sysroot="2";;
--with-osx-sysroot=*) with_osx_sysroot="$optarg";;
@@ -303,10 +310,10 @@
echo " Available options are: --endian=[AUTO|LE|BE]"
exit 1
fi
- # OS only allows DETECT, UNIX, OSX, FREEBSD, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, WINCE, and PSP
- if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|MORPHOS|BEOS|SUNOS|CYGWIN|MINGW|OS2|WINCE|PSP)$'`" ]; then
+ # OS only allows DETECT, UNIX, OSX, FREEBSD, OPENBSD, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, WINCE, and PSP
+ if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|OPENBSD|MORPHOS|BEOS|SUNOS|CYGWIN|MINGW|OS2|WINCE|PSP)$'`" ]; then
echo "configure: error: invalid option --os=$os"
- echo " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|MORPHOS|BEOS|SUNOS|CYGWIN|MINGW|OS2|WINCE|PSP]"
+ echo " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|OPENBSD|MORPHOS|BEOS|SUNOS|CYGWIN|MINGW|OS2|WINCE|PSP]"
exit 1
fi
# enable_debug should be between 0 and 4
@@ -510,6 +517,35 @@
log 1 "checking stripping... skipped"
fi
+ if [ "$with_distcc" = "0" ]; then
+ log 1 "checking distcc... no"
+ elif [ "$with_distcc" = "1" ]; then
+ with_distcc="0"
+
+ log 1 "checking distcc... no (only used when forced)"
+ elif [ "$with_distcc" = "2" ]; then
+ distcc="distcc"
+ else
+ distcc="$with_distcc"
+ fi
+ if [ "$with_distcc" != "0" ]; then
+ res="`$distcc --version 2>/dev/null | head -n 1 | cut -b 0-6`"
+ if [ "$res" != "distcc" ]; then
+ distcc=""
+ log 1 "checking distcc... no"
+ if [ "$with_distcc" = "2" ]; then
+ log 1 "configure: error: no distcc detected, but was forced to be used"
+ exit 1
+ fi
+ if [ "$with_distcc" != "1" ]; then
+ log 1 "configure: error: '$with_distcc' doesn't seem a distcc to me"
+ exit 1
+ fi
+ fi
+
+ log 1 "checking distcc... $distcc"
+ fi
+
if [ "$os" != "OSX" ] && [ "$with_osx_sysroot" != "0" ]; then
if [ "$with_osx_sysroot" = "1" ]; then
with_osx_sysroot="0"
@@ -609,6 +645,47 @@
exit 1
fi
fi
+
+ if [ -n "$released_version" ]; then
+ log 1 "checking revision... release ($released_version)"
+ if [ -n "$revision" ] && [ "$revision" != "$released_version" ]; then
+ log 1 "WARNING: overriding of the revision is NOT possible for releases"
+ log 1 "WARNING: the given revision is IGNORED"
+
+ sleep 5
+ fi
+ revision=$released_version
+ else
+ if [ -n "$revision" ]; then
+ log 1 "checking revision... $revision"
+ log 1 "WARNING: we do not advise you to use this setting"
+ log 1 "WARNING: in most cases it is not safe for network use"
+ log 1 "WARNING: USE WITH CAUTION!"
+
+ sleep 5
+ elif [ -f "$ROOT_DIR/version" ]; then
+ revision="`cat $ROOT_DIR/version`"
+
+ log 1 "checking revision... $revision"
+ elif [ -d "$ROOT_DIR/.svn" ] && [ -n "`svn help`" ]; then
+ revision=""
+ log 1 "checking revision... svn detection"
+ elif [ -d "$ROOT_DIR/.git" ] && [ -n "`git help`" ]; then
+ revision=""
+ log 1 "checking revision... git detection"
+ else
+ revision=""
+ log 1 "checking revision... no detection"
+ log 1 "WARNING: there is no means to determine the version."
+ log 1 "WARNING: please use a subversion or git checkout of OpenTTD."
+ log 1 "WARNING: this version will be allowed by all game servers,"
+ log 1 "WARNING: but you will be kicked from all incompatible"
+ log 1 "WARNING: servers as you will desync."
+ log 1 "WARNING: USE WITH CAUTION!"
+
+ sleep 5
+ fi
+ fi
}
make_cflags_and_ldflags() {
@@ -709,7 +786,7 @@
fi
fi
- if [ "$os" != "CYGWIN" ] && [ "$os" != "FREEBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ]; then
+ if [ "$os" != "CYGWIN" ] && [ "$os" != "FREEBSD" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ]; then
LIBS="$LIBS -lpthread"
LIBS="$LIBS -lrt"
fi
@@ -733,6 +810,10 @@
CFLAGS="$CFLAGS -Wno-strict-prototypes"
fi
+ if [ "$os" = "OPENBSD" ]; then
+ LIBS="$LIBS -pthread"
+ fi
+
if [ "$os" = "OSX" ]; then
LDFLAGS="$LDFLAGS -framework Cocoa"
if [ "$enable_dedicated" = "0" ]; then
@@ -745,7 +826,7 @@
fi
# Most targets act like UNIX, just with some additions
- if [ "$os" = "BEOS" ] || [ "$os" = "OSX" ] || [ "$os" = "MORPHOS" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "SUNOS" ] || [ "$os" = "OS2" ]; then
+ if [ "$os" = "BEOS" ] || [ "$os" = "OSX" ] || [ "$os" = "MORPHOS" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "SUNOS" ] || [ "$os" = "OS2" ]; then
CFLAGS="$CFLAGS -DUNIX"
fi
# And others like Windows
@@ -927,23 +1008,6 @@
fi
fi
- if [ -n "$revision" ]; then
- log 1 "checking revision... $revision"
- log 1 "WARNING: we do not advise you to use this setting"
- log 1 "WARNING: in most cases it is not safe for network use"
- log 1 "WARNING: USE WITH CAUTION!"
-
- sleep 5
- elif [ -f "$ROOT_DIR/version" ]; then
- revision="`cat $ROOT_DIR/version`"
-
- log 1 "checking revision... $revision"
- else
- revision=""
-
- log 1 "checking revision... svn detection"
- fi
-
log 1 "using CFLAGS... $CFLAGS $CC_CFLAGS"
log 1 "using LDFLAGS... $LIBS $LDFLAGS"
@@ -958,6 +1022,14 @@
else
makedepend=""
fi
+
+ if [ "$with_distcc" != "0" ]; then
+ cc_host="$distcc $cc_host"
+ cxx_host="$distcc $cxx_host"
+ log 1 ""
+ log 1 " NOTICE: remind yourself to use 'make -jN' to make use of distcc"
+ log 1 ""
+ fi
}
check_compiler() {
@@ -1239,13 +1311,14 @@
detect_os() {
if [ "$os" = "DETECT" ]; then
- # Detect UNIX, OSX, FREEBSD, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, WINCE, and PSP
+ # Detect UNIX, OSX, FREEBSD, OPENBSD, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, WINCE, and PSP
# Try first via dumpmachine, then via uname
os=`echo "$host" | tr '[A-Z]' '[a-z]' | $awk '
/linux/ { print "UNIX"; exit}
/darwin/ { print "OSX"; exit}
/freebsd/ { print "FREEBSD"; exit}
+ /openbsd/ { print "OPENBSD"; exit}
/morphos/ { print "MORPHOS"; exit}
/beos/ { print "BEOS"; exit}
/sunos/ { print "SUNOS"; exit}
@@ -1262,6 +1335,7 @@
/linux/ { print "UNIX"; exit}
/darwin/ { print "OSX"; exit}
/freebsd/ { print "FREEBSD"; exit}
+ /openbsd/ { print "OPENBSD"; exit}
/morphos/ { print "MORPHOS"; exit}
/beos/ { print "BEOS"; exit}
/sunos/ { print "SUNOS"; exit}
@@ -1273,8 +1347,8 @@
if [ -z "$os" ]; then
log 1 "detecting OS... none detected"
- log 1 "I couldn't detect your OS. Please use --with-os=OS to force one"
- log 1 "Allowed values are: UNIX, OSX, FREEBSD, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, WINCE, and PSP"
+ log 1 "I couldn't detect your OS. Please use --os=OS to force one"
+ log 1 "Allowed values are: UNIX, OSX, FREEBSD, OPENBSD, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, WINCE, and PSP"
exit 1
fi
@@ -1862,6 +1936,7 @@
s#!!AWK!!#$awk#g;
s#!!GCC295!!#$gcc295#g;
s#!!ENABLE_INSTALL!!#$enable_install#g;
+ s#!!DISTCC!!#$distcc#g;
"
}
@@ -1960,8 +2035,8 @@
echo " --awk=AWK the awk to use in configure [awk]"
echo " --lipo=LIPO the lipo to use (OSX ONLY) [HOST-lipo]"
echo " --os=OS the OS we are compiling for [DETECT]"
- echo " DETECT/UNIX/OSX/FREEBSD/MORPHOS/BEOS/"
- echo " SUNOS/CYGWIN/MINGW/OS2/WINCE/PSP"
+ echo " DETECT/UNIX/OSX/FREEBSD/OPENBSD/MORPHOS/"
+ echo " BEOS/SUNOS/CYGWIN/MINGW/OS2/WINCE/PSP"
echo " --endian=ENDIAN set the endian of the HOST (AUTO/LE/BE)"
echo " --revision=rXXXX overwrite the revision detection."
echo " Use with care!"
diff -r 0b8b245a2391 -r 1ac8aac92385 configure
--- a/configure Wed Jun 13 11:45:14 2007 +0000
+++ b/configure Wed Jun 13 12:05:56 2007 +0000
@@ -45,8 +45,8 @@
set_default
detect_params "$@"
+check_params
save_params
-check_params
make_cflags_and_ldflags
EXE=""
diff -r 0b8b245a2391 -r 1ac8aac92385 docs/landscape.html
--- a/docs/landscape.html Wed Jun 13 11:45:14 2007 +0000
+++ b/docs/landscape.html Wed Jun 13 12:05:56 2007 +0000
@@ -355,9 +355,9 @@
m5 bit 6 set = with signals:
- - m2 bits 7..4: bit clear = signal shows red; same bits as in m3
- - m2 bit 2: set = semaphore signals, clear = light signals
- - m2 bits 1..0 : type of signal
+
- m4 bits 7..4: bit clear = signal shows red; same bits as in m3
+ - m2 bit 2 (6): set = semaphore signals, clear = light signals (lower and right tracks)
+ - m2 bits 1..0 (5..4): type of signal (lower and right tracks)
00: |
@@ -475,9 +475,9 @@
|
- - m5 bits 7..4 clear: road
+
- m5 bits 7..6 clear: road
- - m1: owner of the road
+ - m1: owner of the road type #1
- m2: Index into the array of towns, 0 for non-town roads
- m3 bit 7 set = on snow or desert
- m3 bits 6..4:
@@ -513,7 +513,7 @@
|
- m3 bits 3..0: counter for the roadworks
- - m5 bits 3..0: road layout: bit set = road piece present:
+
- m4 bits 3..0: road layout road type #1: bit set = road piece present:
bit 0: |
@@ -533,25 +533,36 @@
+ - m4 bits 7..4: road layout road type #2
+
- m5 bits 5..4: bits to disallow vehicles to go a specific direction
+
- m5 bits 3..0: owner of road type #2
+
- m6 bits 5..2: road layout road type #3
+
- m7 bits 7..5: road types
+
- m7 bits 4..0: owner of road type #3
+
- m5 bit 5 set: road depot
+ m5 bit 7 set, bit 6 clear: road depot
- m1: owner of the depot
- m3 bit 7 set = on snow or desert (not displayed, but set internally)
- m5 bits 3..0 - direction: exit towards: 0 = NE, 1 = SE, 2 = SW, 3 = NW
+ - m7 bits 7..5: road types
- m5 bit 4 set, bits 7..5 clear: level crossing
+ m5 bit 6 set, bit 7 clear: level crossing
- m1: owner of the railway track
- m2: Index into the array of towns, 0 for non-town roads
- m3 bit 7 set = on snow or desert
- m3 bits 6..4: 0 - on bare land, 1 - on grass, 2 or higher - paved
- m3 bits 3..0: track type
- - m4: owner of the road
- - m5 bit 3: clear - road in the X direction, set - road in the Y direction (railway track always perpendicular)
- - m5 bit 2: set if crossing lights are on
+ - m4 bit 6: clear - road in the X direction, set - road in the Y direction (railway track always perpendicular)
+ - m4 bit 5: set if crossing lights are on
+ - m4 bits 4..0: owner of the road type #1
+ - m5 bits 3..0: owner of road type #2
+
- m7 bits 7..5: road types
+
- m7 bits 4..0: owner of road type #3
m6 bits 7..6 : Possibility of a bridge above, in the direction specified
diff -r 0b8b245a2391 -r 1ac8aac92385 docs/landscape_grid.html
--- a/docs/landscape_grid.html Wed Jun 13 11:45:14 2007 +0000
+++ b/docs/landscape_grid.html Wed Jun 13 12:05:56 2007 +0000
@@ -88,9 +88,9 @@
rail |
XXXX XXXX |
XXXX XXXX |
- OOOO OOOO XXXX XXXX |
+ OOOO OOOO OXXX OXXX |
XXXX XXXX |
- OOOO OXXX |
+ XXXX XXXX |
XXXX XXXX |
XXOO OOXX |
OOOO OOOO |
@@ -123,11 +123,11 @@
XXXX XXXX |
XXXX XXXX |
XXXX XXXX XXXX XXXX |
- OOOO OOOO |
XXXX XXXX |
XXXX XXXX |
- XXOO OOXX |
- OOOO OOOO |
+ XXXX XXXX |
+ XXXX XXXX |
+ XXXX XXXX |
level crossing |
@@ -135,10 +135,10 @@
-inherit- |
-inherit- |
XXXX XXXX |
+ OXXX XXXX |
+ XXOO XXXX |
+ XXOO OOXX |
XXXX XXXX |
- XXXX XXOO |
- XXOO OOXX |
- OOOO OOOO |
road depot |
@@ -147,9 +147,9 @@
OOOO OOOO OOOO OOOO |
XOOO OOOO |
OOOO OOOO |
- XXXX XXXX |
+ XXOO XXXX |
XXOO OOXX |
- OOOO OOOO |
+ XXXO OOOO |
3 |
diff -r 0b8b245a2391 -r 1ac8aac92385 docs/openttd.6
--- a/docs/openttd.6 Wed Jun 13 11:45:14 2007 +0000
+++ b/docs/openttd.6 Wed Jun 13 12:05:56 2007 +0000
@@ -1,6 +1,6 @@
.\" Hey, EMACS: -*- nroff -*-
.\" Please adjust this date whenever revising the manpage.
-.Dd April 20, 2007
+.Dd May 29, 2007
.Dt OPENTTD 6
.Sh NAME
.Nm openttd
diff -r 0b8b245a2391 -r 1ac8aac92385 known-bugs.txt
--- a/known-bugs.txt Wed Jun 13 11:45:14 2007 +0000
+++ b/known-bugs.txt Wed Jun 13 12:05:56 2007 +0000
@@ -15,16 +15,13 @@
If the bug report is closed, it has been fixed, which then can be verified
in the latest SVN version.
-Bugs for 0.5.1
+Bugs for 0.5.2
------------------------------------------------------------------------
URL: http://bugs.openttd.org
-735 Plural rule not expanded correctly when non-numeric placeholder uses
--732 Trains are lost after autorenewal/autoreplace
-716 Train Crash in Depot
--677 Badspacing in news summaries
-674 Map signs allow less nonenglish characters than english ones
--672 Non-transparent station names' backgrounds do not resize properly upon language change
-669 Docks/Airports/RV Stations can be built without available vehicles
-646 AI builds useless stations
-601 Airports can't get flooded when they have planes in them
@@ -36,7 +33,7 @@
-546 Overflows due to inflation
-540 Planes vanished when offered exclusive
-539 Trains can cash the same cargo multiple times
--522 overflow on vehicle costs
+-522 Overflow on vehicle costs
-508 Destroying trees and replanting => raised rating
-502 OSX can incorrectly print "dbg: [sl] Cannot open savegame 'data/opntitle.dat' for saving/loading."
-501 Mouse pointer gets hidden, when draging out of window and back again. Only affects Wacom etc.
@@ -52,7 +49,7 @@
-355 graphics bugs with trains - water, tunnels
-354 Maglev Trains faster than All Planes
-339 Crash in Quicktime when exiting game
--299 disable 90 deg turns patch - AI builds 90 deg turns
+-299 Disable 90 deg turns patch - AI builds 90 deg turns
-290 NPF - no path to depot from tunnel
-282 AI Players do not clear loans as soon as they could
-274 Autoclean ignores any share holdings
@@ -61,11 +58,11 @@
-216 AI build train vans one van less
-202 2 Locomotives in 1 Train - Selling one results in Age of the other one Being 0
-193 Inconsistent directory usage on Mac OS X
--165 vehicle length not taken into account
+-165 Vehicle length not taken into account
-153 Language crash with app renaming OSX
-119 Clipping problems with vehicles on slopes
- 89 Able to build railways/stations before engines become available
-- 65 short wagons bug
+- 65 Short wagons bug
- 51 Windows doesn't support CUSTOM_LANG_DIR
- 47 Low rating calculation and cargo loading priority
@@ -77,30 +74,25 @@
-1459262 Towns building too many roads way too long now
-1458995 Another bug with smooth_economy
-1393415 NPF & one-way sigs
--1244842 Multiplayer interface bug (0.4.0.1)
--1212267 station visited twice when servicing
+-1212267 Station visited twice when servicing
-1208170 Duplicate station names can be created
-1116638 "More, but smaller changes" deficiency
--1106356 re-offered prototypes
+-1106356 Re-offered prototypes
-Minor Bugs for 0.5.1
------------------------------------------------------------------------
URL: http://sourceforge.net/tracker/?atid=669662&group_id=103924&func=browse
-1461629 [r4180]Subsidy calculated wrong
--1412031 fast forward scrolling is also fast forward :)
--1387424 overtake insolvent company is to cheap
+-1412031 Fast forward scrolling is also fast forward :)
-1382782 Loan interest calculated 'wrong'
--1201284 permanent hilight in a depot
+-1201284 Permanent hilight in a depot
-1185852 Scrollbars get arbitrarily small
--1160732 little bug with transparency
--1117731 Editor-StartingDate
--1108046 game freezes
+-1160732 Little bug with transparency
+-1108046 Game freezes
-1102174 Bug if 3 people buy 25% shares in one company
-1084620 Minor bug considering buses/trucks
--1034310 color mauve in diagrams
+-1034310 Color mauve in diagrams
-1030661 It's possible to build a tunnel under oil wells
-- 987891 Large UFO destruction bug
- 987883 Aircraft landing/taking off
-- 987880 company league table updating
-- 985924 aircraft taxi speed
+- 987880 Company league table updating
+- 985924 Aircraft taxi speed
diff -r 0b8b245a2391 -r 1ac8aac92385 os/debian/changelog
--- a/os/debian/changelog Wed Jun 13 11:45:14 2007 +0000
+++ b/os/debian/changelog Wed Jun 13 12:05:56 2007 +0000
@@ -4,17 +4,29 @@
-- Matthijs Kooijman Mon, 26 Feb 2007 21:07:05 +0100
+openttd (0.5.2-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Matthijs Kooijman Tue, 29 May 2007 20:00:00 +0100
+
+openttd (0.5.2~rc1-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Matthijs Kooijman Wed, 16 May 2007 23:35:39 +0100
+
openttd (0.5.1-1) unstable; urgency=low
* New upstream release.
- -- Matthijs Kooijman Fri, 20 Aprr 2007 21:45:32 +0100
+ -- Matthijs Kooijman Fri, 20 Apr 2007 21:45:32 +0100
openttd (0.5.1~rc3-1) unstable; urgency=low
* New upstream release.
- -- Matthijs Kooijman Tue, 17 Aprr 2007 22:00:46 +0100
+ -- Matthijs Kooijman Tue, 17 Apr 2007 22:00:46 +0100
openttd (0.5.1~rc2-1) unstable; urgency=low
diff -r 0b8b245a2391 -r 1ac8aac92385 os/win32/installer/install.nsi
--- a/os/win32/installer/install.nsi Wed Jun 13 11:45:14 2007 +0000
+++ b/os/win32/installer/install.nsi Wed Jun 13 12:05:56 2007 +0000
@@ -1,6 +1,6 @@
!define APPNAME "OpenTTD" ; Define application name
-!define APPVERSION "0.5.1" ; Define application version
-!define INSTALLERVERSION 32 ; NEED TO UPDATE THIS FOR EVERY RELEASE!!!
+!define APPVERSION "0.5.2" ; Define application version
+!define INSTALLERVERSION 34 ; NEED TO UPDATE THIS FOR EVERY RELEASE!!!
!define APPURLLINK "http://www.openttd.org"
!define APPNAMEANDVERSION "${APPNAME} ${APPVERSION}"
@@ -81,6 +81,7 @@
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\readme.txt"
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
+!define MUI_WELCOMEFINISHPAGE_CUSTOMFUNCTION_INIT DisableBack
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
@@ -355,26 +356,30 @@
hasCD:
FunctionEnd
-;---------------------------------------------------------------------
-; Custom page function to show notices for running OpenTTD
+;----------------------------------------------------------------------------------
+; Disable the "Back" button on finish page if the installer is run on Win9x systems
+Function DisableBack
+ Call GetWindowsVersion
+ Pop $R0
+ StrCmp $R0 "win9x" 0 WinNT
+ !insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "Settings" "BackEnabled" "0"
+WinNT:
+ ClearErrors
+FunctionEnd
+
+;----------------------------------------------------------------------------------
+; Custom page function to show notices for running OpenTTD (only for win32 systems)
; We have extracted this custom page as Notice in the .onInit function
Function ShowWarningsPage
+ Call GetWindowsVersion
+ Pop $R0
+ ; Don't show the UNICODE notice if the installer is run on Win9x systems
+ StrCmp $R0 "win9x" 0 WinNT
+ Abort
+WinNT:
!insertmacro MUI_HEADER_TEXT "Installation Complete" "Important notices for OpenTTD usage."
!insertmacro MUI_INSTALLOPTIONS_EXTRACT_AS "notice.ini" "Notice"
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "Notice"
-
- Call GetWindowsVersion
- Pop $R0
-
- ; Hide the MSLU text if the installer is not run on Win9x systems
- StrCmp $R0 "winnt" 0 Win9x
- !insertmacro MUI_INSTALLOPTIONS_READ $R1 "Notice" "Field 1" "HWND" ; MSLU groupbox
- ShowWindow $R1 0
- !insertmacro MUI_INSTALLOPTIONS_READ $R1 "Notice" "Field 2" "HWND" ; MSLU text
- ShowWindow $R1 0
- !insertmacro MUI_INSTALLOPTIONS_READ $R1 "Notice" "Field 3" "HWND" ; MSLU link
- ShowWindow $R1 0
-Win9x:
ClearErrors
!insertmacro MUI_INSTALLOPTIONS_SHOW
FunctionEnd
diff -r 0b8b245a2391 -r 1ac8aac92385 os/win32/installer/notice.ini
--- a/os/win32/installer/notice.ini Wed Jun 13 11:45:14 2007 +0000
+++ b/os/win32/installer/notice.ini Wed Jun 13 12:05:56 2007 +0000
@@ -1,41 +1,17 @@
; Ini file generated by the HM NIS Edit IO designer.
[Settings]
-NumFields=6
+NumFields=3
+CancelEnabled=0
[Field 1]
Type=Groupbox
-Text=Notice for Windows 9x/ME users!
-Left=8
-Right=292
-Top=80
-Bottom=138
-
-[Field 2]
-Type=Label
-Text=OpenTTD will not work without the Microsoft Layer for Unicode installed.\r\nDue to licensing issues we cannot bundle this file with the installer. Please download MSLU from the Microsoft website and extract UnicoWS.dll to the same directory as the openttd executabe.
-Left=13
-Right=284
-Top=91
-Bottom=127
-
-[Field 3]
-Type=Link
-Text=Microsoft Layer for Unicode
-State=http://www.microsoft.com/downloads/details.aspx?FamilyId=73BA7BD7-ED06-4F0D-80A4-2A7EEAEE17E2&displaylang=en
-Left=197
-Right=284
-Top=127
-Bottom=135
-
-[Field 4]
-Type=Groupbox
Text=UNICODE support
Left=8
Right=292
Top=0
Bottom=75
-[Field 5]
+[Field 2]
Type=Label
Text=This version of OpenTTD has support for UNICODE, allowing users to use non-ASCII character sets such as Russian or Japanese.\r\nSelecting such a language will result in an unusable and garbled interface. You will need to specify a font that has support for these characters in openttd.cfg, or alternatively use an appropiate grf file.\r\n\r\nFor more information please refer to the readme or the wiki.
Left=13
@@ -43,7 +19,7 @@
Top=9
Bottom=65
-[Field 6]
+[Field 3]
Type=Link
Text=OpenTTD wiki
Left=238
diff -r 0b8b245a2391 -r 1ac8aac92385 projects/openttd.vcproj
--- a/projects/openttd.vcproj Wed Jun 13 11:45:14 2007 +0000
+++ b/projects/openttd.vcproj Wed Jun 13 12:05:56 2007 +0000
@@ -164,6 +164,9 @@
RelativePath=".\..\src\airport.cpp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -752,6 +756,14 @@
>
+
+
+
+
@@ -948,6 +960,10 @@
>
+
+
@@ -1493,6 +1509,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 0b8b245a2391 -r 1ac8aac92385 readme.txt
--- a/readme.txt Wed Jun 13 11:45:14 2007 +0000
+++ b/readme.txt Wed Jun 13 12:05:56 2007 +0000
@@ -1,6 +1,6 @@
OpenTTD README
-Last updated: 2007-04-20
-Release version: 0.5.1
+Last updated: 2007-05-29
+Release version: 0.5.2
------------------------------------------------------------------------
@@ -75,6 +75,7 @@
Linux - SDL
MacOS X (universal) - Cocoa video and sound drivers (SDL works too, but not 100% and not as a universal binary)
MorphOS - SDL
+ OpenBSD - SDL
OS/2 - SDL
Windows - Win32 GDI (faster) or SDL
@@ -174,6 +175,10 @@
graphics/png is optional for screenshots in the PNG format.
Use "gmake", but do a "./configure" before the first build.
+OpenBSD:
+ Use "gmake", but do a "./configure" before the first build.
+ Note that you need the port devel/sdl to compile OpenTTD.
+
MorphOS:
Use "make". However, for the first build one has to do a "./configure" first.
Note that you need the MorphOS SDK, latest libnix updates (else C++ parts of
@@ -312,6 +317,7 @@
Richard Kempton (RichK67) - Additional airports, initial TGP implementation
Michael Blunck - For revolutionizing TTD with awesome graphics
George - Canal graphics
+ David Dallaston (Pikka) - Tram tracks
All Translators - For their support to make OpenTTD a truly international game
Bug Reporters - Thanks for all bug reports
Chris Sawyer - For an amazing game!
diff -r 0b8b245a2391 -r 1ac8aac92385 source.list
--- a/source.list Wed Jun 13 11:45:14 2007 +0000
+++ b/source.list Wed Jun 13 12:05:56 2007 +0000
@@ -1,5 +1,6 @@
# Source Files
airport.cpp
+articulated_vehicles.cpp
autoreplace_cmd.cpp
aystar.cpp
bmp.cpp
@@ -98,6 +99,8 @@
aircraft.h
airport.h
airport_movement.h
+articulated_vehicles.h
+autoreplace_cmd.h
aystar.h
bmp.h
cargotype.h
@@ -147,6 +150,7 @@
newgrf_config.h
newgrf_engine.h
newgrf_house.h
+newgrf_industries.h
newgrf_sound.h
newgrf_spritegroup.h
newgrf_station.h
@@ -288,6 +292,20 @@
ai/trolly/shared.cpp
ai/trolly/trolly.cpp
+# Blitters
+blitter/8bpp_debug.cpp
+blitter/8bpp_debug.hpp
+blitter/8bpp_optimized.cpp
+blitter/8bpp_optimized.hpp
+blitter/8bpp_slow.cpp
+blitter/8bpp_slow.hpp
+blitter/blitter.hpp
+
+# Sprite loaders
+spriteloader/grf.cpp
+spriteloader/grf.hpp
+spriteloader/spriteloader.hpp
+
# NewGRF
newgrf.cpp
newgrf_canal.cpp
@@ -296,6 +314,7 @@
newgrf_config.cpp
newgrf_engine.cpp
newgrf_house.cpp
+newgrf_industries.cpp
newgrf_sound.cpp
newgrf_spritegroup.cpp
newgrf_station.cpp
diff -r 0b8b245a2391 -r 1ac8aac92385 src/ai/default/default.cpp
--- a/src/ai/default/default.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/ai/default/default.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -67,7 +67,7 @@
static TrackBits GetRailTrackStatus(TileIndex tile)
{
- uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL);
+ uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
return (TrackBits)(byte) (r | r >> 8);
}
@@ -622,7 +622,6 @@
int dist;
uint same_station = 0;
- // Make sure distance to closest station is < 37 pixels.
from_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->from);
to_tile = GET_TOWN_OR_INDUSTRY_TILE(fr->to);
@@ -646,7 +645,19 @@
return false;
}
- if (dist != 0xFFFF && dist > 37) return false;
+ /* Requiring distance to nearest station to be always under 37 tiles may be suboptimal,
+ * Especially for longer aircraft routes that start and end pretty at any arbitrary place on map
+ * While it may be nice for AI to cluster their creations together, hardcoded limit is not ideal.
+ * If AI will randomly start on some isolated spot, it will never get out of there.
+ * AI will have chance of randomly rejecting routes further than 37 tiles from their network,
+ * so there will be some attempt to cluster the network together */
+
+ /* Random value between 37 and 292. Low values are exponentially more likely
+ * With 50% chance the value will be under 52 tiles */
+ int min_distance = 36 + 1 << (Random() % 9); // 0..8
+
+ /* Make sure distance to closest station is < min_distance tiles. */
+ if (dist != 0xFFFF && dist > min_distance) return false;
if (p->ai.route_type_mask != 0 &&
!(p->ai.route_type_mask & bitmask) &&
@@ -672,8 +683,8 @@
const Industry* i = (const Industry*)fr->from;
const IndustrySpec *indsp = GetIndustrySpec(i->type);
- if (i->pct_transported[fr->cargo != indsp->produced_cargo[0]] > 0x99 ||
- i->total_production[fr->cargo != indsp->produced_cargo[0]] == 0) {
+ if (i->last_month_pct_transported[fr->cargo != indsp->produced_cargo[0]] > 0x99 ||
+ i->last_month_production[fr->cargo != indsp->produced_cargo[0]] == 0) {
return false;
}
}
@@ -1371,15 +1382,55 @@
FoundRoute fr;
int i;
+ /* Get aircraft that would be bought for this route
+ * (probably, as conditions may change before the route is fully built,
+ * like running out of money and having to select different aircraft, etc ...) */
+ EngineID veh = AiChooseAircraftToBuild(p->player_money, p->ai.build_kind != 0 ? 0 : AIR_CTOL);
+
+ /* No aircraft buildable mean no aircraft route */
+ if (veh == INVALID_ENGINE) return;
+
+ const AircraftVehicleInfo *avi = AircraftVehInfo(veh);
+
+ /* For passengers, "optimal" number of days in transit is about 80 to 100
+ * Calculate "maximum optimal number of squares" from speed for 80 days
+ * 20 days should be enough for takeoff, land, taxi, etc ...
+ *
+ * "A vehicle traveling at 100kph will cross 5.6 tiles per day" ->
+ * Since in table aircraft speeds are in "real km/h", this should be accurate
+ * We get max_squares = avi->max_speed * 5.6 / 100.0 * 80 */
+ int max_squares = avi->max_speed * 448 / 100;
+
+ /* For example this will be 10456 tiles for 2334 km/h aircrafts with realistic aircraft speeds
+ * and 836 with "unrealistic" speeds, much more than the original 95 squares limit
+ *
+ * Size of the map, if not rectangular, it is the larger dimension of it
+ */
+ int map_size = max(MapSizeX(), MapSizeY());
+
+ /* Minimum distance between airports is half of map size, clamped between 1% and 20% of optimum.
+ * May prevent building plane routes at all on small maps, but they will be ineffective there, so
+ * it is feature, not a bug.
+ * On smaller distances, buses or trains are usually more effective approach anyway.
+ * Additional safeguard is needing at least 20 squares,
+ * which may trigger in highly unusual configurations */
+ int min_squares = max(20, max(max_squares / 100, min(max_squares / 5, map_size / 2)));
+
+ /* Should not happen, unless aircraft with real speed under approx. 5 km/h is selected.
+ * No such exist, unless using some NewGRF with ballons, zeppelins or similar
+ * slow-moving stuff. In that case, bail out, it is faster to walk by foot anyway :). */
+ if (max_squares < min_squares) return;
+
i = 60;
for (;;) {
+
// look for one from the subsidy list
AiFindSubsidyPassengerRoute(&fr);
- if (IS_INT_INSIDE(fr.distance, 0, 95 + 1)) break;
+ if (IS_INT_INSIDE(fr.distance, min_squares, max_squares + 1)) break;
// try a random one
AiFindRandomPassengerRoute(&fr);
- if (IS_INT_INSIDE(fr.distance, 0, 95 + 1)) break;
+ if (IS_INT_INSIDE(fr.distance, min_squares, max_squares + 1)) break;
// only test 60 times
if (--i == 0) return;
@@ -1408,7 +1459,19 @@
p->ai.build_kind = 0;
p->ai.num_build_rec = 2;
p->ai.num_loco_to_build = 1;
- p->ai.num_want_fullload = 1;
+ /* Using full load always may not be the best.
+ * Pick random value and rely on selling the vehicle & route
+ * afterwards if the choice was utterly wrong (or maybe altering the value if AI is improved)
+ * When traffic is very low or very assymetric, is is better not to full load
+ * When traffic is high, full/non-full make no difference
+ * It should be better to run with aircraft only one way full 6 times per year,
+ * rather than two way full 1 times.
+ * Practical experiments with AI show that the non-full-load aircrafts are usually
+ * those that survive
+ * Also, non-full load is more resistant against starving (by building better stations
+ * or using exclusive rights)
+ */
+ p->ai.num_want_fullload = CHANCE16(1, 5); // 20% chance
// p->ai.loco_id = INVALID_VEHICLE;
p->ai.order_list_blocks[0] = 0;
p->ai.order_list_blocks[1] = 1;
@@ -1862,7 +1925,7 @@
arpfd.tile2 = p->ai.cur_tile_a;
arpfd.flag = false;
arpfd.count = 0;
- FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, (DiagDirection)(p->ai.cur_dir_a ^ 2),
+ FollowTrack(p->ai.cur_tile_a + TileOffsByDiagDir(p->ai.cur_dir_a), 0x2000 | TRANSPORT_RAIL, 0, (DiagDirection)(p->ai.cur_dir_a ^ 2),
(TPFEnumProc*)AiEnumFollowTrack, NULL, &arpfd);
return arpfd.count > 8;
}
@@ -2600,10 +2663,10 @@
} else if (p->mode == 1) {
if (_want_road_truck_station) {
// Truck station
- ret = DoCommand(c, p->attr, RoadStop::TRUCK, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_STOP);
+ ret = DoCommand(c, p->attr, ROADTYPES_ROAD << 2 | RoadStop::TRUCK, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_STOP);
} else {
// Bus station
- ret = DoCommand(c, p->attr, RoadStop::BUS, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_STOP);
+ ret = DoCommand(c, p->attr, ROADTYPES_ROAD << 2 | RoadStop::BUS, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_BUILD_ROAD_STOP);
}
clear_town_stuff:;
@@ -2824,13 +2887,13 @@
tile = TILE_MASK(p->ai.cur_tile_a + TileOffsByDiagDir(dir));
if (IsRoadStopTile(tile) || IsTileDepotType(tile, TRANSPORT_ROAD)) return false;
- bits = GetTileTrackStatus(tile, TRANSPORT_ROAD) & _ai_road_table_and[dir];
+ bits = GetTileTrackStatus(tile, TRANSPORT_ROAD, ROADTYPES_ROAD) & _ai_road_table_and[dir];
if (bits == 0) return false;
are.best_dist = (uint)-1;
for_each_bit(i, bits) {
- FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, (DiagDirection)_dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
+ FollowTrack(tile, 0x3000 | TRANSPORT_ROAD, ROADTYPES_ROAD, (DiagDirection)_dir_by_track[i], (TPFEnumProc*)AiEnumFollowRoad, NULL, &are);
}
if (DistanceManhattan(tile, are.dest) <= are.best_dist) return false;
@@ -2888,7 +2951,7 @@
}
// Is building a (rail)bridge possible at this place (type doesn't matter)?
- if (CmdFailed(DoCommand(tile_new, tile, 0x8000, DC_AUTO, CMD_BUILD_BRIDGE)))
+ if (CmdFailed(DoCommand(tile_new, tile, ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE)))
return;
AiBuildRoadRecursive(arf, tile_new, dir2);
@@ -3038,13 +3101,13 @@
*/
for (i = 10; i != 0; i--) {
if (CheckBridge_Stuff(i, bridge_len)) {
- int32 cost = DoCommand(tile, p->ai.cur_tile_a, i + (0x80 << 8), DC_AUTO, CMD_BUILD_BRIDGE);
+ int32 cost = DoCommand(tile, p->ai.cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE);
if (!CmdFailed(cost) && cost < (p->player_money >> 5)) break;
}
}
// Build it
- DoCommand(tile, p->ai.cur_tile_a, i + (0x80 << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
+ DoCommand(tile, p->ai.cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
p->ai.state_counter = 0;
} else if (arf.best_ptr[0] & 0x40) {
diff -r 0b8b245a2391 -r 1ac8aac92385 src/ai/trolly/build.cpp
--- a/src/ai/trolly/build.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/ai/trolly/build.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -42,9 +42,9 @@
return AI_DoCommand(tile, direction + (numtracks << 8) + (length << 16), 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_RAILROAD_STATION);
if (type == AI_BUS)
- return AI_DoCommand(tile, direction, RoadStop::BUS, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
+ return AI_DoCommand(tile, direction, ROADTYPES_ROAD << 2 | RoadStop::BUS, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
- return AI_DoCommand(tile, direction, RoadStop::TRUCK, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
+ return AI_DoCommand(tile, direction, ROADTYPES_ROAD << 2 | RoadStop::TRUCK, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
}
@@ -75,7 +75,7 @@
if (p->ainew.tbt == AI_TRAIN) {
return AI_DoCommand(tile_a, tile_b, (0x00 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
} else {
- return AI_DoCommand(tile_a, tile_b, (0x80 << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
+ return AI_DoCommand(tile_a, tile_b, ((0x80 | ROADTYPES_ROAD) << 8) + type2, flag | DC_AUTO, CMD_BUILD_BRIDGE);
}
}
@@ -162,7 +162,7 @@
} else {
// Tunnel code
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
- cost += AI_DoCommand(route[part], 0x200, 0, flag, CMD_BUILD_TUNNEL);
+ cost += AI_DoCommand(route[part], 0x200 | ROADTYPES_ROAD, 0, flag, CMD_BUILD_TUNNEL);
PathFinderInfo->position++;
// TODO: problems!
if (CmdFailed(cost)) {
diff -r 0b8b245a2391 -r 1ac8aac92385 src/ai/trolly/pathfinder.cpp
--- a/src/ai/trolly/pathfinder.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/ai/trolly/pathfinder.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -237,17 +237,10 @@
if (IsTunnel(atile)) {
if (GetTunnelDirection(atile) != i) continue;
} else {
- if ((_m[atile].m5 & 1) != DiagDirToAxis(i)) continue;
+ if (GetBridgeRampDirection(atile) != i) continue;
}
}
}
- // But also if we are on a bridge, we can only move a certain direction
- if (!PathFinderInfo->rail_or_road && IsRoad(ctile)) {
- if (IsTileType(ctile, MP_TUNNELBRIDGE)) {
- // An existing bridge/tunnel... let's test the direction ;)
- if ((_m[ctile].m5 & 1) != (i & 1)) continue;
- }
- }
if ((AI_PATHFINDER_FLAG_BRIDGE & current->path.node.user_data[0]) != 0 ||
(AI_PATHFINDER_FLAG_TUNNEL & current->path.node.user_data[0]) != 0) {
@@ -291,9 +284,9 @@
dir = 0;
} else {
// It already has road.. check if we miss any bits!
- if ((_m[ctile].m5 & dir) != dir) {
+ if ((GetAnyRoadBits(ctile, ROADTYPE_ROAD) & dir) != dir) {
// We do miss some pieces :(
- dir &= ~_m[ctile].m5;
+ dir &= ~GetAnyRoadBits(ctile, ROADTYPE_ROAD);
} else {
dir = 0;
}
diff -r 0b8b245a2391 -r 1ac8aac92385 src/ai/trolly/trolly.cpp
--- a/src/ai/trolly/trolly.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/ai/trolly/trolly.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -280,9 +280,9 @@
// No limits on delevering stations!
// Or for industry that does not give anything yet
- if (indsp->produced_cargo[0] == CT_INVALID || i->total_production[0] == 0) return true;
+ if (indsp->produced_cargo[0] == CT_INVALID || i->last_month_production[0] == 0) return true;
- if (i->total_production[0] - i->total_transported[0] < AI_CHECKCITY_NEEDED_CARGO) return false;
+ if (i->last_month_production[0] - i->last_month_transported[0] < AI_CHECKCITY_NEEDED_CARGO) return false;
// Check if we have build a station in this town the last 6 months
// else we don't do it. This is done, because stat updates can be slow
@@ -322,7 +322,7 @@
// We are about to add one...
count++;
// Check if we the city can provide enough cargo for this amount of stations..
- if (count * AI_CHECKCITY_CARGO_PER_STATION > i->total_production[0]) return false;
+ if (count * AI_CHECKCITY_CARGO_PER_STATION > i->last_month_production[0]) return false;
// All check are okay, so we can build here!
return true;
@@ -468,12 +468,12 @@
// TODO: in max_cargo, also check other cargo (beside [0])
// First we check if the from_ic produces cargo that this ic accepts
- if (indsp_from->produced_cargo[0] != CT_INVALID && ind_from->total_production[0] != 0) {
+ if (indsp_from->produced_cargo[0] != CT_INVALID && ind_from->last_month_production[0] != 0) {
for (i = 0; i < lengthof(indsp_temp->accepts_cargo); i++) {
if (indsp_temp->accepts_cargo[i] == CT_INVALID) break;
if (indsp_from->produced_cargo[0] == indsp_temp->accepts_cargo[i]) {
// Found a compatible industry
- max_cargo = ind_from->total_production[0] - ind_from->total_transported[0];
+ max_cargo = ind_from->last_month_production[0] - ind_from->last_month_transported[0];
found = true;
p->ainew.from_deliver = true;
p->ainew.to_deliver = false;
@@ -481,14 +481,14 @@
}
}
}
- if (!found && indsp_temp->produced_cargo[0] != CT_INVALID && ind_temp->total_production[0] != 0) {
+ if (!found && indsp_temp->produced_cargo[0] != CT_INVALID && ind_temp->last_month_production[0] != 0) {
// If not check if the current ic produces cargo that the from_ic accepts
for (i = 0; i < lengthof(indsp_from->accepts_cargo); i++) {
if (indsp_from->accepts_cargo[i] == CT_INVALID) break;
if (indsp_from->produced_cargo[0] == indsp_from->accepts_cargo[i]) {
// Found a compatbiel industry
found = true;
- max_cargo = ind_temp->total_production[0] - ind_temp->total_transported[0];
+ max_cargo = ind_temp->last_month_production[0] - ind_temp->last_month_transported[0];
p->ainew.from_deliver = false;
p->ainew.to_deliver = true;
break;
@@ -898,9 +898,9 @@
// Calculating tiles a day a vehicle moves is not easy.. this is how it must be done!
tiles_a_day = RoadVehInfo(i)->max_speed * DAY_TICKS / 256 / 16;
if (p->ainew.from_deliver) {
- max_cargo = GetIndustry(p->ainew.from_ic)->total_production[0];
+ max_cargo = GetIndustry(p->ainew.from_ic)->last_month_production[0];
} else {
- max_cargo = GetIndustry(p->ainew.to_ic)->total_production[0];
+ max_cargo = GetIndustry(p->ainew.to_ic)->last_month_production[0];
}
// This is because moving 60% is more than we can dream of!
@@ -1224,7 +1224,7 @@
// Skip the first order if it is a second vehicle
// This to make vehicles go different ways..
if (p->ainew.cur_veh & 1)
- AI_DoCommand(0, p->ainew.veh_id, 0, DC_EXEC, CMD_SKIP_ORDER);
+ AI_DoCommand(0, p->ainew.veh_id, 1, DC_EXEC, CMD_SKIP_TO_ORDER);
// 3, 2, 1... go! (give START_STOP command ;))
AI_DoCommand(0, p->ainew.veh_id, 0, DC_EXEC, CMD_START_STOP_ROADVEH);
diff -r 0b8b245a2391 -r 1ac8aac92385 src/aircraft.h
--- a/src/aircraft.h Wed Jun 13 11:45:14 2007 +0000
+++ b/src/aircraft.h Wed Jun 13 12:05:56 2007 +0000
@@ -135,6 +135,7 @@
void UpdateDeltaXY(Direction direction);
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_AIRCRAFT_INC : EXPENSES_AIRCRAFT_RUN; }
WindowClass GetVehicleListWindowClass() const { return WC_AIRCRAFT_LIST; }
+ bool IsPrimaryVehicle() const { return IsNormalAircraft(this); }
};
#endif /* AIRCRAFT_H */
diff -r 0b8b245a2391 -r 1ac8aac92385 src/airport_gui.cpp
--- a/src/airport_gui.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/airport_gui.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -34,12 +34,12 @@
static void PlaceAirport(TileIndex tile)
{
- DoCommandP(tile, _selected_airport_type, 0, CcBuildAirport, CMD_BUILD_AIRPORT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_A001_CAN_T_BUILD_AIRPORT_HERE));
+ DoCommandP(tile, _selected_airport_type, _ctrl_pressed, CcBuildAirport, CMD_BUILD_AIRPORT | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_A001_CAN_T_BUILD_AIRPORT_HERE));
}
static void PlaceAir_DemolishArea(TileIndex tile)
{
- VpStartPlaceSizing(tile, VPM_X_AND_Y, GUI_PlaceProc_None);
+ VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DEMOLISH_AREA);
}
@@ -95,7 +95,7 @@
break;
case WE_PLACE_MOUSEUP:
- if (e->we.place.pt.x != -1) {
+ if (e->we.place.pt.x != -1 && e->we.place.select_proc == DDSP_DEMOLISH_AREA) {
DoCommandP(e->we.place.tile, e->we.place.starttile, 0, CcPlaySound10, CMD_CLEAR_AREA | CMD_MSG(STR_00B5_CAN_T_CLEAR_THIS_AREA));
}
break;
diff -r 0b8b245a2391 -r 1ac8aac92385 src/articulated_vehicles.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/articulated_vehicles.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,113 @@
+/* $Id$ */
+
+/** @file articulated_vehicles.cpp */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "command.h"
+#include "vehicle.h"
+#include "articulated_vehicles.h"
+#include "engine.h"
+#include "train.h"
+#include "roadveh.h"
+#include "newgrf_callbacks.h"
+#include "newgrf_engine.h"
+
+
+uint CountArticulatedParts(EngineID engine_type)
+{
+ if (!HASBIT(EngInfo(engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return 0;
+
+ uint i;
+ for (i = 1; i < 10; i++) {
+ uint16 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, engine_type, NULL);
+ if (callback == CALLBACK_FAILED || callback == 0xFF) break;
+ }
+
+ return i - 1;
+}
+
+void AddArticulatedParts(Vehicle **vl, VehicleType type)
+{
+ const Vehicle *v = vl[0];
+ Vehicle *u = vl[0];
+
+ if (!HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_ARTIC_ENGINE)) return;
+
+ for (uint i = 1; i < 10; i++) {
+ uint16 callback = GetVehicleCallback(CBID_TRAIN_ARTIC_ENGINE, i, 0, v->engine_type, v);
+ if (callback == CALLBACK_FAILED || callback == 0xFF) return;
+
+ /* Attempt to use pre-allocated vehicles until they run out. This can happen
+ * if the callback returns different values depending on the cargo type. */
+ u->next = vl[i];
+ if (u->next == NULL) u->next = AllocateVehicle();
+ if (u->next == NULL) return;
+
+ u = u->next;
+
+ EngineID engine_type = GetFirstEngineOfType(type) + GB(callback, 0, 7);
+ bool flip_image = HASBIT(callback, 7);
+
+ /* get common values from first engine */
+ u->direction = v->direction;
+ u->owner = v->owner;
+ u->tile = v->tile;
+ u->x_pos = v->x_pos;
+ u->y_pos = v->y_pos;
+ u->z_pos = v->z_pos;
+ u->build_year = v->build_year;
+ u->vehstatus = v->vehstatus & ~VS_STOPPED;
+
+ u->cargo_subtype = 0;
+ u->max_speed = 0;
+ u->max_age = 0;
+ u->engine_type = engine_type;
+ u->value = 0;
+ u->subtype = 0;
+ u->cur_image = 0xAC2;
+ u->random_bits = VehicleRandomBits();
+
+ switch (type) {
+ default: NOT_REACHED();
+
+ case VEH_TRAIN: {
+ const RailVehicleInfo *rvi_artic = RailVehInfo(engine_type);
+
+ u = new (u) Train();
+ u->u.rail.track = v->u.rail.track;
+ u->u.rail.railtype = v->u.rail.railtype;
+ u->u.rail.first_engine = v->engine_type;
+
+ u->spritenum = rvi_artic->image_index;
+ u->cargo_type = rvi_artic->cargo_type;
+ u->cargo_cap = rvi_artic->capacity;
+
+ SetArticulatedPart(u);
+ } break;
+
+ case VEH_ROAD: {
+ const RoadVehicleInfo *rvi_artic = RoadVehInfo(engine_type);
+
+ u = new (u) RoadVehicle();
+ u->u.road.first_engine = v->engine_type;
+ u->u.road.cached_veh_length = GetRoadVehLength(u);
+ u->u.road.state = RVSB_IN_DEPOT;
+
+ u->u.road.roadtype = v->u.road.roadtype;
+ u->u.road.compatible_roadtypes = v->u.road.compatible_roadtypes;
+
+ u->spritenum = rvi_artic->image_index;
+ u->cargo_type = rvi_artic->cargo_type;
+ u->cargo_cap = rvi_artic->capacity;
+
+ SetRoadVehArticPart(u);
+ } break;
+ }
+
+ if (flip_image) u->spritenum++;
+
+ VehiclePositionChanged(u);
+ }
+}
diff -r 0b8b245a2391 -r 1ac8aac92385 src/articulated_vehicles.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/articulated_vehicles.h Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,11 @@
+/* $Id$ */
+
+/** @file articulated_vehicles.h */
+
+#ifndef ARTICULATED_VEHICLES_H
+#define ARTICULATED_VEHICLES_H
+
+uint CountArticulatedParts(EngineID engine_type);
+void AddArticulatedParts(Vehicle **vl, VehicleType type);
+
+#endif /* ARTICULATED_VEHICLES_H */
diff -r 0b8b245a2391 -r 1ac8aac92385 src/autoreplace_cmd.cpp
--- a/src/autoreplace_cmd.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/autoreplace_cmd.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -171,7 +171,12 @@
return cost;
}
- if (replacement_cargo_type != CT_NO_REFIT) cost += GetRefitCost(new_engine_type); // add refit cost
+ if (replacement_cargo_type != CT_NO_REFIT) {
+ /* add refit cost */
+ int32 refit_cost = GetRefitCost(new_engine_type);
+ if (old_v->type == VEH_TRAIN && IsMultiheaded(old_v)) refit_cost += refit_cost; // pay for both ends
+ cost += refit_cost;
+ }
if (flags & DC_EXEC) {
new_v = GetVehicle(_new_vehicle_id);
@@ -195,9 +200,14 @@
* We add the new engine after the old one instead of replacing it. It will give the same result anyway when we
* sell the old engine in a moment
*/
- DoCommand(0, (GetPrevVehicleInChain(old_v)->index << 16) | new_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ /* Get the vehicle in front of the one we move out */
+ Vehicle *front = GetPrevVehicleInChain(old_v);
+ /* If the vehicle in front is the rear end of a dualheaded engine, then we need to use the one in front of that one */
+ if (IsMultiheaded(front) && !IsTrainEngine(front)) front = GetPrevVehicleInChain(front);
/* Now we move the old one out of the train */
DoCommand(0, (INVALID_VEHICLE << 16) | old_v->index, 0, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
+ /* Add the new vehicle */
+ DoCommand(0, (front->index << 16) | new_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
} else {
// copy/clone the orders
DoCommand(0, (old_v->index << 16) | new_v->index, IsOrderListShared(old_v) ? CO_SHARE : CO_COPY, DC_EXEC, CMD_CLONE_ORDER);
@@ -224,10 +234,6 @@
if (temp_v != NULL) {
DoCommand(0, (new_v->index << 16) | temp_v->index, 1, DC_EXEC, CMD_MOVE_RAIL_VEHICLE);
}
- } else if (!IsDefaultGroupID(old_v->group_id) && IsValidGroupID(old_v->group_id)) {
- /* Increase the new num engines of the group for the ships, aircraft, and road vehicles
- The old new num engine is decrease in the destroyvehicle function */
- GetGroup(old_v->group_id)->num_engines[new_v->engine_type]++;
}
}
/* We are done setting up the new vehicle. Now we move the cargo from the old one to the new one */
@@ -240,9 +246,19 @@
GetName(vehicle_name, old_v->string_id & 0x7FF, lastof(vehicle_name));
}
} else { // flags & DC_EXEC not set
+ int32 tmp_move = 0;
+ if (old_v->type == VEH_TRAIN && IsFrontEngine(old_v) && old_v->next != NULL) {
+ /* Verify that the wagons can be placed on the engine in question.
+ * This is done by building an engine, test if the wagons can be added and then sell the test engine. */
+ DoCommand(old_v->tile, new_engine_type, 3, DC_EXEC, GetCmdBuildVeh(old_v));
+ Vehicle *temp = GetVehicle(_new_vehicle_id);
+ tmp_move = DoCommand(0, (temp->index << 16) | old_v->next->index, 1, 0, CMD_MOVE_RAIL_VEHICLE);
+ DoCommand(0, temp->index, 0, DC_EXEC, GetCmdSellVeh(old_v));
+ }
+
/* Ensure that the player will not end up having negative money while autoreplacing
* This is needed because the only other check is done after the income from selling the old vehicle is substracted from the cost */
- if (p->money64 < (cost + total_cost)) {
+ if (CmdFailed(tmp_move) || p->money64 < (cost + total_cost)) {
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
SubtractMoneyFromPlayer(-sell_value); // Pay back the loan
return CMD_ERROR;
@@ -338,6 +354,8 @@
/* Now replace the vehicle */
temp_cost = ReplaceVehicle(&w, flags, cost);
+ if (CmdFailed(temp_cost)) break; // replace failed for some reason. Leave the vehicle alone
+
if (flags & DC_EXEC &&
(w->type != VEH_TRAIN || w->u.rail.first_engine == INVALID_ENGINE)) {
/* now we bought a new engine and sold the old one. We need to fix the
@@ -346,10 +364,7 @@
*/
v = w;
}
-
- if (!CmdFailed(temp_cost)) {
- cost += temp_cost;
- }
+ cost += temp_cost;
} while (w->type == VEH_TRAIN && (w = GetNextVehicle(w)) != NULL);
if (!(flags & DC_EXEC) && (p->money64 < (int32)(cost + p->engine_renew_money) || cost == 0)) {
diff -r 0b8b245a2391 -r 1ac8aac92385 src/autoreplace_gui.cpp
--- a/src/autoreplace_gui.cpp Wed Jun 13 11:45:14 2007 +0000
+++ b/src/autoreplace_gui.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -160,6 +160,9 @@
/* This is for engines we can replace to and they should depend on what we selected to replace from */
if (!IsEngineBuildable(e, type, _local_player)) continue; // we need to be able to build the engine
if (!EnginesGotCargoInCommon(e, WP(w, replaceveh_d).sel_engine[0])) continue; // the engines needs to be able to carry the same cargo
+
+ /* Road vehicles can't be replaced by trams and vice-versa */
+ if (type == VEH_ROAD && HASBIT(EngInfo(WP(w, replaceveh_d).sel_engine[0])->misc_flags, EF_ROAD_TRAM) != HASBIT(EngInfo(e)->misc_flags, EF_ROAD_TRAM)) continue;
if (e == WP(w, replaceveh_d).sel_engine[0]) continue; // we can't replace an engine into itself (that would be autorenew)
}
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/8bpp_debug.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/8bpp_debug.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,51 @@
+#include "../stdafx.h"
+#include "../zoom.hpp"
+#include "../gfx.h"
+#include "../functions.h"
+#include "8bpp_debug.hpp"
+
+static FBlitter_8bppDebug iFBlitter_8bppDebug;
+
+void Blitter_8bppDebug::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+{
+ const byte *src, *src_line;
+ Pixel8 *dst, *dst_line;
+
+ /* Find where to start reading in the source sprite */
+ src_line = (const byte *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
+ dst_line = (Pixel8 *)bp->dst + bp->top * bp->pitch + bp->left;
+
+ for (int y = 0; y < bp->height; y++) {
+ dst = dst_line;
+ dst_line += bp->pitch;
+
+ src = src_line;
+ src_line += bp->sprite_width * ScaleByZoom(1, zoom);
+
+ for (int x = 0; x < bp->width; x++) {
+ if (*src != 0) *dst = *src;
+ dst++;
+ src += ScaleByZoom(1, zoom);
+ }
+ assert(src <= src_line);
+ }
+}
+
+Sprite *Blitter_8bppDebug::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
+{
+ Sprite *dest_sprite;
+ dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sprite->height * sprite->width);
+
+ dest_sprite->height = sprite->height;
+ dest_sprite->width = sprite->width;
+ dest_sprite->x_offs = sprite->x_offs;
+ dest_sprite->y_offs = sprite->y_offs;
+
+ /* Write a random color as sprite; this makes debugging really easy */
+ uint color = InteractiveRandom() % 150 + 2;
+ for (int i = 0; i < sprite->height * sprite->width; i++) {
+ dest_sprite->data[i] = (sprite->data[i].m == 0) ? 0 : color;
+ }
+
+ return dest_sprite;
+}
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/8bpp_debug.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/8bpp_debug.hpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+/** @file debug.hpp */
+
+#ifndef BLITTER_8BPP_DEBUG_HPP
+#define BLITTER_8BPP_DEBUG_HPP
+
+#include "blitter.hpp"
+
+typedef Pixel Pixel8;
+
+class Blitter_8bppDebug : public Blitter {
+public:
+ uint8 GetScreenDepth() { return 8; }
+
+ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
+
+ Sprite *Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator);
+};
+
+class FBlitter_8bppDebug: public BlitterFactory {
+public:
+ /* virtual */ const char *GetName() { return "8bpp-debug"; }
+
+ /* virtual */ const char *GetDescription() { return "8bpp Debug Blitter (testing only)"; }
+
+ /* virtual */ Blitter *CreateInstance() { return new Blitter_8bppDebug(); }
+};
+
+#endif /* BLITTER_8BPP_DEBUG_HPP */
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/8bpp_optimized.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/8bpp_optimized.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,198 @@
+#include "../stdafx.h"
+#include "../zoom.hpp"
+#include "../gfx.h"
+#include "../debug.h"
+#include "8bpp_optimized.hpp"
+
+static FBlitter_8bppOptimized iFBlitter_8bppOptimized;
+
+void Blitter_8bppOptimized::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+{
+ const byte *src, *src_next;
+ Pixel8 *dst, *dst_line;
+ uint offset = 0;
+
+ /* Find the offset of this zoom-level */
+ offset = ((const byte *)bp->sprite)[(int)zoom * 2] | ((const byte *)bp->sprite)[(int)zoom * 2 + 1] << 8;
+
+ /* Find where to start reading in the source sprite */
+ src = (const byte *)bp->sprite + offset;
+ dst_line = (Pixel8 *)bp->dst + bp->top * bp->pitch + bp->left;
+
+ /* Skip over the top lines in the source image */
+ for (int y = 0; y < bp->skip_top; y++) {
+ uint trans, pixels;
+ for (;;) {
+ trans = *src++;
+ pixels = *src++;
+ if (trans == 0 && pixels == 0) break;
+ src += pixels;
+ }
+ }
+
+ src_next = src;
+
+ for (int y = 0; y < bp->height; y++) {
+ dst = dst_line;
+ dst_line += bp->pitch;
+
+ uint skip_left = bp->skip_left;
+ int width = bp->width;
+
+ for (;;) {
+ src = src_next;
+ uint8 trans = *src++;
+ uint8 pixels = *src++;
+ src_next = src + pixels;
+ if (trans == 0 && pixels == 0) break;
+ if (width <= 0) continue;
+
+ if (skip_left != 0) {
+ if (skip_left < trans) {
+ trans -= skip_left;
+ skip_left = 0;
+ } else {
+ skip_left -= trans;
+ trans = 0;
+ }
+ if (skip_left < pixels) {
+ src += skip_left;
+ pixels -= skip_left;
+ skip_left = 0;
+ } else {
+ src += pixels;
+ skip_left -= pixels;
+ pixels = 0;
+ }
+ }
+ if (skip_left != 0) continue;
+
+ /* Skip transparent pixels */
+ dst += trans;
+ width -= trans;
+ if (width <= 0) continue;
+ if (pixels > width) pixels = width;
+ width -= pixels;
+
+ switch (mode) {
+ case BM_COLOUR_REMAP:
+ for (uint x = 0; x < pixels; x++) {
+ if (bp->remap[*src] != 0) *dst = bp->remap[*src];
+ dst++; src++;
+ }
+ break;
+
+ case BM_TRANSPARENT:
+ for (uint x = 0; x < pixels; x++) {
+ *dst = bp->remap[*dst];
+ dst++; src++;
+ }
+ break;
+
+ default:
+ memcpy(dst, src, pixels);
+ dst += pixels; src += pixels;
+ break;
+ }
+ }
+ }
+}
+
+Sprite *Blitter_8bppOptimized::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
+{
+ Sprite *dest_sprite;
+ byte *temp_dst;
+ uint memory = 0;
+ uint index = 0;
+
+ /* Make memory for all zoom-levels */
+ memory += (int)ZOOM_LVL_END * sizeof(uint16);
+ for (int i = 0; i < (int)ZOOM_LVL_END; i++) {
+ memory += UnScaleByZoom(sprite->height, (ZoomLevel)i) * UnScaleByZoom(sprite->width, (ZoomLevel)i);
+ index += 2;
+ }
+
+ /* We have no idea how much memory we really need, so just guess something */
+ memory *= 5;
+ temp_dst = MallocT(memory);
+
+ /* Make the sprites per zoom-level */
+ for (int i = 0; i < (int)ZOOM_LVL_END; i++) {
+ /* Store the scaled image */
+ const SpriteLoader::CommonPixel *src;
+
+ /* Store the index table */
+ temp_dst[i * 2] = index & 0xFF;
+ temp_dst[i * 2 + 1] = (index >> 8) & 0xFF;
+
+ byte *dst = &temp_dst[index];
+
+ for (int y = 0; y < UnScaleByZoom(sprite->height, (ZoomLevel)i); y++) {
+ uint trans = 0;
+ uint pixels = 0;
+ uint last_color = 0;
+ uint count_index = 0;
+ uint rx = 0;
+ src = &sprite->data[ScaleByZoom(y, (ZoomLevel)i) * sprite->width];
+
+ for (int x = 0; x < UnScaleByZoom(sprite->width, (ZoomLevel)i); x++) {
+ uint color = 0;
+
+ /* Get the color keeping in mind the zoom-level */
+ for (int j = 0; j < ScaleByZoom(1, (ZoomLevel)i); j++) {
+ if (src->m != 0) color = src->m;
+ src++;
+ rx++;
+ /* Because of the scaling it might happen we read outside the buffer. Avoid that. */
+ if (rx == sprite->width) break;
+ }
+
+ if (last_color == 0 || color == 0) {
+ if (count_index != 0) {
+ /* Write how many non-transparent bytes we get */
+ temp_dst[count_index] = pixels;
+ pixels = 0;
+ count_index = 0;
+ }
+ /* As long as we find transparency bytes, keep counting */
+ if (color == 0) {
+ last_color = 0;
+ trans++;
+ continue;
+ }
+ /* No longer transparency, so write the amount of transparent bytes */
+ *dst = trans;
+ dst++; index++;
+ trans = 0;
+ /* Reserve a byte for the pixel counter */
+ count_index = index;
+ dst++; index++;
+ }
+ last_color = color;
+ pixels++;
+ *dst = color;
+ dst++; index++;
+ }
+
+ if (count_index != 0) temp_dst[count_index] = pixels;
+
+ /* Write line-ending */
+ *dst = 0; dst++; index++;
+ *dst = 0; dst++; index++;
+ }
+ }
+
+ /* Safety check, to make sure we guessed the size correctly */
+ assert(index < memory);
+
+ /* Allocate the exact amount of memory we need */
+ dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + index);
+
+ dest_sprite->height = sprite->height;
+ dest_sprite->width = sprite->width;
+ dest_sprite->x_offs = sprite->x_offs;
+ dest_sprite->y_offs = sprite->y_offs;
+ memcpy(dest_sprite->data, temp_dst, index);
+
+ return dest_sprite;
+}
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/8bpp_optimized.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/8bpp_optimized.hpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+/** @file 8bpp_nice.hpp */
+
+#ifndef BLITTER_8BPP_OPTIMIZED_HPP
+#define BLITTER_8BPP_OPTIMIZED_HPP
+
+#include "blitter.hpp"
+
+typedef Pixel Pixel8;
+
+class Blitter_8bppOptimized : public Blitter {
+public:
+ uint8 GetScreenDepth() { return 8; }
+
+ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
+
+ Sprite *Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator);
+};
+
+class FBlitter_8bppOptimized: public BlitterFactory {
+public:
+ /* virtual */ const char *GetName() { return "8bpp-optimzed"; }
+
+ /* virtual */ const char *GetDescription() { return "8bpp Optimized Blitter (compression + all-ZoomLevel cache)"; }
+
+ /* virtual */ Blitter *CreateInstance() { return new Blitter_8bppOptimized(); }
+};
+
+#endif /* BLITTER_8BPP_OPTIMIZED_HPP */
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/8bpp_slow.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/8bpp_slow.cpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,63 @@
+#include "../stdafx.h"
+#include "../zoom.hpp"
+#include "../gfx.h"
+#include "8bpp_slow.hpp"
+
+static FBlitter_8bppSimple iFBlitter_8bppSimple;
+
+void Blitter_8bppSimple::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom)
+{
+ const byte *src, *src_line;
+ Pixel8 *dst, *dst_line;
+
+ /* Find where to start reading in the source sprite */
+ src_line = (const byte *)bp->sprite + (bp->skip_top * bp->sprite_width + bp->skip_left) * ScaleByZoom(1, zoom);
+ dst_line = (Pixel8 *)bp->dst + bp->top * bp->pitch + bp->left;
+
+ for (int y = 0; y < bp->height; y++) {
+ dst = dst_line;
+ dst_line += bp->pitch;
+
+ src = src_line;
+ src_line += bp->sprite_width * ScaleByZoom(1, zoom);
+
+ for (int x = 0; x < bp->width; x++) {
+ uint color = 0;
+
+ switch (mode) {
+ case BM_COLOUR_REMAP:
+ color = bp->remap[*src];
+ break;
+
+ case BM_TRANSPARENT:
+ if (*src != 0) color = bp->remap[*dst];
+ break;
+
+ default:
+ color = *src;
+ break;
+ }
+ if (color != 0) *dst = color;
+ dst++;
+ src += ScaleByZoom(1, zoom);
+ }
+ }
+}
+
+Sprite *Blitter_8bppSimple::Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator)
+{
+ Sprite *dest_sprite;
+ dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sprite->height * sprite->width);;
+
+ dest_sprite->height = sprite->height;
+ dest_sprite->width = sprite->width;
+ dest_sprite->x_offs = sprite->x_offs;
+ dest_sprite->y_offs = sprite->y_offs;
+
+ /* Copy over only the 'remap' channel, as that is what we care about in 8bpp */
+ for (int i = 0; i < sprite->height * sprite->width; i++) {
+ dest_sprite->data[i] = sprite->data[i].m;
+ }
+
+ return dest_sprite;
+}
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/8bpp_slow.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/8bpp_slow.hpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+/** @file 8bpp.hpp */
+
+#ifndef BLITTER_8BPP_SIMPLE_HPP
+#define BLITTER_8BPP_SIMPLE_HPP
+
+#include "blitter.hpp"
+
+typedef Pixel Pixel8;
+
+class Blitter_8bppSimple : public Blitter {
+public:
+ uint8 GetScreenDepth() { return 8; }
+
+ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
+
+ Sprite *Encode(SpriteLoader::Sprite *sprite, Blitter::AllocatorProc *allocator);
+};
+
+class FBlitter_8bppSimple: public BlitterFactory {
+public:
+ /* virtual */ const char *GetName() { return "8bpp-simple"; }
+
+ /* virtual */ const char *GetDescription() { return "8bpp Simple Blitter (relative slow, but never wrong)"; }
+
+ /* virtual */ Blitter *CreateInstance() { return new Blitter_8bppSimple(); }
+};
+
+#endif /* BLITTER_8BPP_SIMPLE_HPP */
diff -r 0b8b245a2391 -r 1ac8aac92385 src/blitter/blitter.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/blitter/blitter.hpp Wed Jun 13 12:05:56 2007 +0000
@@ -0,0 +1,170 @@
+/* $Id$ */
+
+/** @file blitter.hpp */
+
+#ifndef BLITTER_HPP
+#define BLITTER_HPP
+
+#include "../spriteloader/spriteloader.hpp"
+#include "../spritecache.h"
+#include
+#include