Merge included files fix
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
notifications:
|
notifications:
|
||||||
|
global:
|
||||||
|
irc:
|
||||||
|
- openttd
|
||||||
|
- openttd.notice
|
||||||
|
|
||||||
push:
|
push:
|
||||||
irc:
|
only:
|
||||||
- openttd
|
- master
|
||||||
- openttd.notice
|
only-by:
|
||||||
|
- DorpsGek
|
||||||
|
commit-comment:
|
||||||
pull-request:
|
pull-request:
|
||||||
irc:
|
|
||||||
- openttd
|
|
||||||
- openttd.notice
|
|
||||||
issue:
|
issue:
|
||||||
irc:
|
|
||||||
- openttd
|
|
||||||
- openttd.notice
|
|
||||||
|
|||||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
custom: https://www.openttd.org/donate.html
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -13,6 +13,9 @@ bin/baseset/*
|
|||||||
!bin/baseset/no_sound.obs
|
!bin/baseset/no_sound.obs
|
||||||
!bin/baseset/no_music.obm
|
!bin/baseset/no_music.obm
|
||||||
!bin/baseset/orig_*.obm
|
!bin/baseset/orig_*.obm
|
||||||
|
!bin/game
|
||||||
|
bin/game/*
|
||||||
|
!bin/game/compat*.nut
|
||||||
!bin/scripts
|
!bin/scripts
|
||||||
bin/scripts/*
|
bin/scripts/*
|
||||||
!bin/scripts/*.example
|
!bin/scripts/*.example
|
||||||
@@ -53,4 +56,4 @@ src/os/windows/ottdres.rc
|
|||||||
|
|
||||||
/bin/data/*
|
/bin/data/*
|
||||||
/game
|
/game
|
||||||
/openttd
|
/openttd
|
||||||
|
|||||||
@@ -32,9 +32,3 @@ projects/*.vcproj.*.user
|
|||||||
projects/*.vcxproj.user
|
projects/*.vcxproj.user
|
||||||
src/rev.cpp
|
src/rev.cpp
|
||||||
src/os/windows/ottdres.rc
|
src/os/windows/ottdres.rc
|
||||||
|
|
||||||
save/*
|
|
||||||
local/*
|
|
||||||
export/*
|
|
||||||
release/*
|
|
||||||
|
|
||||||
|
|||||||
2
.ottdrev
2
.ottdrev
@@ -1 +1 @@
|
|||||||
1.9.0-beta2 20190209 0 6e211908588ab5272336d0d2db3bbb4020f7004f
|
1.10.0-beta1 20191030 0 9f50c754ffee52211e61d88e6d5fc296dfc585e0 1 0
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2019-02-09 21:41 UTC
|
2019-10-30 17:46 UTC
|
||||||
|
|||||||
343
COPYING
343
COPYING
@@ -1,343 +0,0 @@
|
|||||||
This is the license which applies to OpenTTD with the exception of some
|
|
||||||
3rd party modules. See README.md for details
|
|
||||||
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Lesser General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License.
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
bin/game/compat_1.10.nut
Normal file
8
bin/game/compat_1.10.nut
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
OpenTTD and strgen
|
|
||||||
Last updated: 2009-06-30
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Table of contents
|
|
||||||
-----------------
|
|
||||||
1.0) strgen usage
|
|
||||||
* 1.1) Examples
|
|
||||||
* 1.2) strgen command switches
|
|
||||||
|
|
||||||
|
|
||||||
1.0) strgen usage
|
|
||||||
---- ------------
|
|
||||||
This guide is only interesting for people who want to alter something
|
|
||||||
themselves without access to translator.openttd.org. Please note that
|
|
||||||
your compiled language file will only be compatible with the OpenTTD version
|
|
||||||
you have downloaded english.txt, the master language file, for. While this is
|
|
||||||
not always true, namely when changes in the code have not touched language
|
|
||||||
files, your safest bet is to assume this 'limitation'.
|
|
||||||
As a first step you need to compile strgen. This is as easy as typing
|
|
||||||
'make strgen'. You can download the precompile strgen from:
|
|
||||||
http://www.openttd.org/download-strgen
|
|
||||||
|
|
||||||
strgen takes as argument a txt file and translates it to a lng file, allowing
|
|
||||||
it to be used inside OpenTTD. strgen needs the master language file
|
|
||||||
english.txt to work. Below are some examples of strgen usage.
|
|
||||||
|
|
||||||
1.1) Examples
|
|
||||||
---- --------
|
|
||||||
Example 1:
|
|
||||||
if you are in the root of your working copy (git repository), you should type
|
|
||||||
strgen/strgen -s lang lang/english.txt
|
|
||||||
to compile englist.txt into english.lng. It will be placed in the lang dir
|
|
||||||
|
|
||||||
Example 2:
|
|
||||||
you only have the strgen executable (no working copy) and you want to compile
|
|
||||||
a txt file in the same directory. You should type
|
|
||||||
./strgen english.txt
|
|
||||||
and you will get and english.lng in the same dir
|
|
||||||
|
|
||||||
Example 3:
|
|
||||||
you have strgen somewhere, english.txt in /usr/openttd/lang and you want the
|
|
||||||
resulting language file to go to /tmp. Use
|
|
||||||
./strgen -s /usr/openttd/lang -d /tmp english.txt
|
|
||||||
|
|
||||||
You can interchange english.txt to whichever language you want to generate a
|
|
||||||
.lng file for.
|
|
||||||
|
|
||||||
1.2) strgen command switches
|
|
||||||
---- -----------------------
|
|
||||||
-v | --version
|
|
||||||
strgen will tell what git revision it was last modified
|
|
||||||
|
|
||||||
-t | --todo
|
|
||||||
strgen will add <TODO> to any untranslated/missing strings and use the english
|
|
||||||
strings while compiling the language file
|
|
||||||
|
|
||||||
-w | --warning
|
|
||||||
strgen will print any missing strings or wrongly translated (bad format)
|
|
||||||
to standard error output(stderr)
|
|
||||||
|
|
||||||
-h | --help | -?
|
|
||||||
Print out a summarized help message explaining these switches
|
|
||||||
|
|
||||||
-s | --source_dir
|
|
||||||
strgen will search for the master file english.txt in the directory specified
|
|
||||||
by this switch instead of the current directory
|
|
||||||
|
|
||||||
-d | --dest_dir
|
|
||||||
strgen will put <language>.lng in the directory specified by this switch; if
|
|
||||||
no dest_dir is given, output is the same as source_dir
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
OpenTTD: OS/2 version
|
|
||||||
=====================
|
|
||||||
|
|
||||||
OpenTTD has been ported to work on OS/2 4.x or later (including
|
|
||||||
eComStation). The game should work as well as it does on Windows
|
|
||||||
or other platforms: the main issues you may encounter are graphics
|
|
||||||
card problems, but that is really the fault of SDL.
|
|
||||||
|
|
||||||
=========================
|
|
||||||
USING OPENTTD FOR OS/2
|
|
||||||
=========================
|
|
||||||
|
|
||||||
LIBRARIES REQUIRED FOR END USERS
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
SDL.DLL (SDL 1.2.7) and FSLib.dll are required to use this program:
|
|
||||||
these can be downloaded from the Files section at
|
|
||||||
http://sourceforge.net/projects/openttd/ - see "os2-useful-v1.1.zip".
|
|
||||||
Version 20051222 of SDL or later is required. This can be found at
|
|
||||||
http://sdl.netlabs.org/.
|
|
||||||
|
|
||||||
Please note that earlier SDL releases will probably NOT work with
|
|
||||||
OpenTTD. If you experience problems with OpenTTD, please check
|
|
||||||
your SDL and FSLib.dll versions (both must match).
|
|
||||||
|
|
||||||
Note that to actually play the game, I have found in my own
|
|
||||||
experience that a version of the Scitech Display Drivers or its later
|
|
||||||
incarnation (see www.scitech.com) are necessary for it to work. If
|
|
||||||
you have trouble with your native drivers, try the Scitech drivers
|
|
||||||
and see if they help the problem.
|
|
||||||
|
|
||||||
KNOWN ISSUES
|
|
||||||
------------
|
|
||||||
|
|
||||||
- If an error occurs during loading, the OS/2 error message window
|
|
||||||
is not always displayed.
|
|
||||||
|
|
||||||
A NOTE ABOUT MUSIC
|
|
||||||
------------------
|
|
||||||
|
|
||||||
OpenTTD includes a music driver which uses the MCI MIDI system. Unfortunately,
|
|
||||||
due to the lack of proper MIDI hardware myself, I have been unable to test it,
|
|
||||||
but during testing, I found that when MIDI was enabled, I got no sound
|
|
||||||
effects. I therefore decided to DISABLE music by default.
|
|
||||||
|
|
||||||
To enable music, start OpenTTD with the command line:
|
|
||||||
|
|
||||||
openttd -m os2
|
|
||||||
|
|
||||||
If I hear enough responses that both music and sound work together (it might
|
|
||||||
just be my system), I'll have the defaults changed.
|
|
||||||
|
|
||||||
Please note also that the GCC version does not currently support the MCI MIDI
|
|
||||||
system.
|
|
||||||
|
|
||||||
|
|
||||||
A NOTE ABOUT DEDICATED MULTIPLAYER SERVERS
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
To start a dedicated multiplayer server, you should run the dedicated.cmd
|
|
||||||
file. This enables OpenTTD to open up a VIO console window to display
|
|
||||||
its output and gather any necessary input. Running "openttd -D"
|
|
||||||
directly will result in the console not being displayed. You may
|
|
||||||
still pass any other parameters ('-D' is already passed) to
|
|
||||||
dedicated.cmd.
|
|
||||||
|
|
||||||
You can find the dedicated.cmd file in the os/os2 directory.
|
|
||||||
|
|
||||||
=========================
|
|
||||||
BUILDING THE OS/2 VERSION
|
|
||||||
=========================
|
|
||||||
|
|
||||||
Compiler
|
|
||||||
--------
|
|
||||||
|
|
||||||
Innotek GCC, an OS/2 port of the popular GCC compiler, was used to build OpenTTD.
|
|
||||||
See www.innotek.de for more information. You WILL need a reasonably UNIX-like
|
|
||||||
build environment in order to build OpenTTD successfully - the following link
|
|
||||||
may help to set one up (although some of the links from that page are broken):
|
|
||||||
|
|
||||||
http://www.mozilla.org/ports/os2/gccsetup.html
|
|
||||||
|
|
||||||
Alternatively, Paul Smedley's ready-to-go GCC build environment has been known to
|
|
||||||
successfully build the game:
|
|
||||||
|
|
||||||
http://www.smedley.info/os2ports/index.php?page=build-environment
|
|
||||||
|
|
||||||
To build, you should, if your environment is set up well enough, be able to just
|
|
||||||
type `./configure' (or `sh configure' if you're using the OS/2 shell) and `make'.
|
|
||||||
|
|
||||||
You may have to manually specify `--os OS2' on the configure command line, as
|
|
||||||
configure cannot always detect OS/2 correctly.
|
|
||||||
|
|
||||||
A note on Open Watcom
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Open Watcom C/C++ was previously used to build OpenTTD (version 0.4.x and earlier).
|
|
||||||
However, due to advanced C++ features used in the YAPF portion of OpenTTD 0.5
|
|
||||||
in particular, the compiler is no longer able to build the game at the moment.
|
|
||||||
Hopefully one day Open Watcom will be able to catch up and we will be able to build
|
|
||||||
the game once again (it's easier than getting an OS/2 UNIX-like environment set up
|
|
||||||
in my opinion!), but until then, OpenTTD 0.5 and later can only be built with GCC.
|
|
||||||
|
|
||||||
Libraries Required
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The following libraries are required. To build zlib and libpng, I
|
|
||||||
simply added the required files (watch out for sample programs, etc)
|
|
||||||
to an IDE project file and built a library. Do not use the makefiles
|
|
||||||
provided, they are not designed for Watcom (apart from SDL):
|
|
||||||
|
|
||||||
- zlib
|
|
||||||
http://www.zlib.org/
|
|
||||||
|
|
||||||
- libpng
|
|
||||||
http://www.libpng.org/
|
|
||||||
|
|
||||||
- SDL for OS/2
|
|
||||||
ftp://ftp.netlabs.org/pub/sdl/sdl-1.2.7-src-20051222.zip used for
|
|
||||||
0.4.7
|
|
||||||
|
|
||||||
- Freetype
|
|
||||||
http://freetype.sourceforge.net/
|
|
||||||
|
|
||||||
Currently, there are no pre-built libraries available for GCC. If you manage to get
|
|
||||||
OpenTTD working on Watcom though (do let us know if this is the case!), pre-built
|
|
||||||
versions can be downloaded from the Files section at
|
|
||||||
http://sourceforge.net/projects/openttd/ - see "os2-useful-v1.1.zip".
|
|
||||||
|
|
||||||
Contact Information
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
If you have any questions regarding OS/2 issues, please contact me
|
|
||||||
(owen@owenrudge.net) and I'll try to help you out. For general OpenTTD
|
|
||||||
issues, see the Contacting section of readme.txt.
|
|
||||||
|
|
||||||
Thanks to Paul Smedley for his help with getting OpenTTD to compile under GCC on OS/2.
|
|
||||||
|
|
||||||
- Owen Rudge, 24th June 2007
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
# Compiling OpenTTD using Microsoft Visual C++
|
|
||||||
|
|
||||||
Last updated: 2018-12-27
|
|
||||||
|
|
||||||
## Supported MSVC compilers
|
|
||||||
|
|
||||||
OpenTTD includes projects for Visual Studio 2015 Update 3 or more recent.
|
|
||||||
You can download the free Visual Studio Community Edition from Microsoft at
|
|
||||||
https://visualstudio.microsoft.com/vs/community/.
|
|
||||||
|
|
||||||
## Required files
|
|
||||||
|
|
||||||
### Microsoft platform files
|
|
||||||
|
|
||||||
OpenTTD needs the Platform SDK, if it isn't installed already. This can be
|
|
||||||
done during installing Visual Studio, by selecting
|
|
||||||
`Visual C++ MFC for x86 and x64` (and possibly
|
|
||||||
`Visual C++ ATL for x86 and x64` depending on your version). If not, you
|
|
||||||
can get it at this location:
|
|
||||||
|
|
||||||
- [MS Windows Platform SDK](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk)
|
|
||||||
|
|
||||||
Install the SDK by following the instructions as given.
|
|
||||||
|
|
||||||
### OpenTTD dependencies
|
|
||||||
|
|
||||||
Dependencies for OpenTTD on Windows are handled via
|
|
||||||
[vcpkg](https://github.com/Microsoft/vcpkg/). First you need to install vcpkg
|
|
||||||
by following the `Quick Start` intructions of their
|
|
||||||
[README](https://github.com/Microsoft/vcpkg/blob/master/README.md).
|
|
||||||
|
|
||||||
After this, you can install the dependencies OpenTTD needs. We advise to use
|
|
||||||
the `static` versions, and OpenTTD currently needs the following dependencies:
|
|
||||||
|
|
||||||
- freetype
|
|
||||||
- liblzma
|
|
||||||
- libpng
|
|
||||||
- lzo
|
|
||||||
- zlib
|
|
||||||
|
|
||||||
To install both the x64 (64bit) and x86 (32bit) variants, you can use:
|
|
||||||
|
|
||||||
```ps
|
|
||||||
.\vcpkg install freetype:x64-windows-static liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static
|
|
||||||
.\vcpkg install freetype:x86-windows-static liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static
|
|
||||||
```
|
|
||||||
|
|
||||||
## TTD Graphics files
|
|
||||||
|
|
||||||
See section 4.1 of README.md for the required 3rdparty files and how to install them.
|
|
||||||
|
|
||||||
## Compiling
|
|
||||||
|
|
||||||
Open the appropriate `sln` (Solution) file for your version of Visual Studio:
|
|
||||||
|
|
||||||
- VS 2015: projects/openttd_vs140.sln
|
|
||||||
- VS 2017: projects/openttd_vs141.sln
|
|
||||||
- VS 2019: projects/openttd_vs142.sln
|
|
||||||
|
|
||||||
Set the build mode to `Release` in
|
|
||||||
`Build > Configuration manager > Active solution configuration`.
|
|
||||||
You can now compile.
|
|
||||||
|
|
||||||
If everything works well the binary should be in `objs\Win[32|64]\Release\openttd.exe`
|
|
||||||
and in `bin\openttd.exe`
|
|
||||||
|
|
||||||
## Problems
|
|
||||||
|
|
||||||
If compilation fails, double-check that you are using the latest github
|
|
||||||
source. If it still doesn't work, check in on IRC (irc://irc.oftc.net/openttd),
|
|
||||||
to ask for help.
|
|
||||||
@@ -1,219 +0,0 @@
|
|||||||
OpenTTD's admin network
|
|
||||||
Last updated: 2011-01-20
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Table of contents
|
|
||||||
-----------------
|
|
||||||
1.0) Preface
|
|
||||||
2.0) Joining the network
|
|
||||||
3.0) Asking for updates
|
|
||||||
* 3.1) Polling manually
|
|
||||||
4.0) Sending rcon commands
|
|
||||||
5.0) Sending chat
|
|
||||||
* 5.1) Receiving chat
|
|
||||||
6.0) Disconnecting
|
|
||||||
7.0) Certain packet information
|
|
||||||
|
|
||||||
|
|
||||||
1.0) Preface
|
|
||||||
---- -------
|
|
||||||
The admin network provides a dedicated network protocol designed for other
|
|
||||||
applications to communicate with OpenTTD. Connected applications can execute
|
|
||||||
console commands remotely (rcon commands) with no further authentication.
|
|
||||||
Furthermore information about clients and companies can be provided.
|
|
||||||
|
|
||||||
Admin applications remain connected when starting a new game or loading a saved
|
|
||||||
game in contrast to normal OpenTTD clients that get disconnected.
|
|
||||||
|
|
||||||
This document describes the admin network and its protocol.
|
|
||||||
|
|
||||||
Please refer to the mentioned enums in src/network/core/tcp_admin.h
|
|
||||||
|
|
||||||
Please also note that further improvements to the admin protocol can mean that
|
|
||||||
more packet types will be sent by the server. For forward compatibility it is
|
|
||||||
therefore wise to ignore unknown packets. Future improvements might also add
|
|
||||||
additional data to packets. This data should be ignored. Data will never be
|
|
||||||
removed from packets in later versions, except the possibility that complete
|
|
||||||
packets are dropped in favour of a new packet.
|
|
||||||
This though will be reflected in the protocol version as announced in the
|
|
||||||
ADMIN_PACKET_SERVER_PROTOCOL in section 2.0).
|
|
||||||
|
|
||||||
A reference implementation in Java for a client connecting to the admin interface
|
|
||||||
can be found at: http://dev.openttdcoop.org/projects/joan
|
|
||||||
|
|
||||||
|
|
||||||
2.0) Joining the network
|
|
||||||
---- -------------------
|
|
||||||
Create a TCP connection to the server on port 3977. The application is
|
|
||||||
expected to authenticate within 10 seconds.
|
|
||||||
|
|
||||||
To authenticate send a ADMIN_PACKET_ADMIN_JOIN packet.
|
|
||||||
|
|
||||||
The server will reply with ADMIN_PACKET_SERVER_PROTOCOL followed directly by
|
|
||||||
ADMIN_PACKET_SERVER_WELCOME.
|
|
||||||
|
|
||||||
ADMIN_PACKET_SERVER_PROTOCOL contains details about the protocol version.
|
|
||||||
It is the job of your application to check this number and decide whether
|
|
||||||
it will remain connected or not.
|
|
||||||
Furthermore, this packet holds details on every AdminUpdateType and the
|
|
||||||
supported AdminFrequencyTypes (bitwise representation).
|
|
||||||
|
|
||||||
ADMIN_PACKET_SERVER_WELCOME contains details on the server and the map,
|
|
||||||
e.g. if the server is dedicated, its NetworkLanguage, size of the Map, etc.
|
|
||||||
|
|
||||||
Once you have received ADMIN_PACKET_SERVER_WELCOME you are connected and
|
|
||||||
authorized to do your thing.
|
|
||||||
The server will not provide any game related updates unless you ask for them.
|
|
||||||
There are four packets the server will none the less send, if applicable:
|
|
||||||
- ADMIN_PACKET_SERVER_ERROR
|
|
||||||
- ADMIN_PACKET_SERVER_WELCOME
|
|
||||||
- ADMIN_PACKET_SERVER_NEWGAME
|
|
||||||
- ADMIN_PACKET_SERVER_SHUTDOWN
|
|
||||||
|
|
||||||
However, ADMIN_PACKET_SERVER_WELCOME only after a ADMIN_PACKET_SERVER_NEWGAME
|
|
||||||
|
|
||||||
|
|
||||||
3.0) Asking for updates
|
|
||||||
---- ------------------
|
|
||||||
Asking for updates is done with ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY.
|
|
||||||
With this packet you define which update you wish to receive at which
|
|
||||||
frequency.
|
|
||||||
|
|
||||||
Note: not every update type supports every frequency. If in doubt, you can
|
|
||||||
verify against the data received in ADMIN_PACKET_SERVER_PROTOCOL.
|
|
||||||
|
|
||||||
The server will not confirm your registered update. However, asking for an
|
|
||||||
invalid AdminUpdateType or a not supported AdminUpdateFrequency you will be
|
|
||||||
disconnected from the server with NETWORK_ERROR_ILLEGAL_PACKET.
|
|
||||||
|
|
||||||
Additional debug information can be found with a debug level of net=3.
|
|
||||||
|
|
||||||
ADMIN_UPDATE_DATE results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_DATE
|
|
||||||
|
|
||||||
ADMIN_UPDATE_CLIENT_INFO results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_CLIENT_JOIN
|
|
||||||
- ADMIN_PACKET_SERVER_CLIENT_INFO
|
|
||||||
- ADMIN_PACKET_SERVER_CLIENT_UPDATE
|
|
||||||
- ADMIN_PACKET_SERVER_CLIENT_QUIT
|
|
||||||
- ADMIN_PACKET_SERVER_CLIENT_ERROR
|
|
||||||
|
|
||||||
ADMIN_UPDATE_COMPANY_INFO results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_COMPANY_NEW
|
|
||||||
- ADMIN_PACKET_SERVER_COMPANY_INFO
|
|
||||||
- ADMIN_PACKET_SERVER_COMPANY_UPDATE
|
|
||||||
- ADMIN_PACKET_SERVER_COMPANY_REMOVE
|
|
||||||
|
|
||||||
ADMIN_UPDATE_COMPANY_ECONOMY results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_COMPANY_ECONOMY
|
|
||||||
|
|
||||||
ADMIN_UPDATE_COMPANY_STATS results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_COMPANY_STATS
|
|
||||||
|
|
||||||
ADMIN_UPDATE_CHAT results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_CHAT
|
|
||||||
|
|
||||||
ADMIN_UPDATE_CONSOLE results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_CONSOLE
|
|
||||||
|
|
||||||
|
|
||||||
ADMIN_UPDATE_CMD_LOGGING results in the server sending:
|
|
||||||
- ADMIN_PACKET_SERVER_CMD_LOGGING
|
|
||||||
|
|
||||||
3.1) Polling manually
|
|
||||||
---- ----------------
|
|
||||||
Certain AdminUpdateTypes can also be polled:
|
|
||||||
- ADMIN_UPDATE_DATE
|
|
||||||
- ADMIN_UPDATE_CLIENT_INFO
|
|
||||||
- ADMIN_UPDATE_COMPANY_INFO
|
|
||||||
- ADMIN_UPDATE_COMPANY_ECONOMY
|
|
||||||
- ADMIN_UPDATE_COMPANY_STATS
|
|
||||||
- ADMIN_UPDATE_CMD_NAMES
|
|
||||||
|
|
||||||
ADMIN_UPDATE_CLIENT_INFO and ADMIN_UPDATE_COMPANY_INFO accept an additional
|
|
||||||
parameter. This parameter is used to specify a certain client or company.
|
|
||||||
Setting this parameter to UINT32_MAX (0xFFFFFFFF) will tell the server you
|
|
||||||
want to receive updates for all clients or companies.
|
|
||||||
|
|
||||||
Not supported AdminUpdateType in the poll will result in the server
|
|
||||||
disconnecting the application with NETWORK_ERROR_ILLEGAL_PACKET.
|
|
||||||
|
|
||||||
Additional debug information can be found with a debug level of net=3.
|
|
||||||
|
|
||||||
|
|
||||||
4.0) Sending rcon commands
|
|
||||||
---- ---------------------
|
|
||||||
Rcon runs separate from the ADMIN_UPDATE_CONSOLE AdminUpdateType. Requesting
|
|
||||||
the execution of a remote console command is done with the packet
|
|
||||||
ADMIN_PACKET_ADMIN_RCON.
|
|
||||||
|
|
||||||
Note: No additional authentication is required for rcon commands.
|
|
||||||
|
|
||||||
The server will reply with one or more ADMIN_PACKET_SERVER_RCON packets.
|
|
||||||
Finally an ADMIN_PACKET_ADMIN_RCON_END packet will be sent. Applications
|
|
||||||
will not receive the answer twice if they have asked for the AdminUpdateType
|
|
||||||
ADMIN_UPDATE_CONSOLE, as the result is not printed on the servers console
|
|
||||||
(just like clients rcon commands).
|
|
||||||
|
|
||||||
Furthermore, sending a 'say' command (or any similar command) will not
|
|
||||||
be sent back into the admin network.
|
|
||||||
Chat from the server itself will only be sent to the admin network when it
|
|
||||||
was not sent from the admin network.
|
|
||||||
|
|
||||||
Note that when content is queried or updated via rcon, the processing
|
|
||||||
happens asynchronously. But the ADMIN_PACKET_ADMIN_RCON_END packet is sent
|
|
||||||
already right after the content is requested as there's no immediate output.
|
|
||||||
Thus other packages and the output of content rcon command may be sent at
|
|
||||||
an arbitrary later time, mixing into the output of other console activity,
|
|
||||||
e.g. also of possible subsequent other rcon commands sent.
|
|
||||||
|
|
||||||
|
|
||||||
5.0) Sending chat
|
|
||||||
---- ------------
|
|
||||||
Sending a ADMIN_PACKET_ADMIN_CHAT results in chat originating from the server.
|
|
||||||
|
|
||||||
Currently four types of chat are supported:
|
|
||||||
- NETWORK_ACTION_CHAT
|
|
||||||
- NETWORK_ACTION_CHAT_CLIENT
|
|
||||||
- NETWORK_ACTION_CHAT_COMPANY
|
|
||||||
- NETWORK_ACTION_SERVER_MESSAGE
|
|
||||||
|
|
||||||
NETWORK_ACTION_SERVER_MESSAGE can be sent to a single client or company
|
|
||||||
using the respective DestType and ID.
|
|
||||||
This is a message prefixed with the 3 stars, e.g. *** foo has joined the game
|
|
||||||
|
|
||||||
5.1) Receiving chat
|
|
||||||
---- -------------
|
|
||||||
Register ADMIN_UPDATE_CHAT at ADMIN_FREQUENCY_AUTOMATIC to receive chat.
|
|
||||||
The application will be able to receive all chat the server can see.
|
|
||||||
|
|
||||||
The configuration option network.server_admin_chat specifies whether
|
|
||||||
private chat for to the server is distributed into the admin network.
|
|
||||||
|
|
||||||
|
|
||||||
6.0) Disconnecting
|
|
||||||
---- -------------
|
|
||||||
It is a kind thing to say good bye before leaving. Do this by sending the
|
|
||||||
ADMIN_PACKET_ADMIN_QUIT packet.
|
|
||||||
|
|
||||||
|
|
||||||
7.0) Certain packet information
|
|
||||||
---- --------------------------
|
|
||||||
All ADMIN_PACKET_SERVER_* packets have an enum value greater 100.
|
|
||||||
|
|
||||||
ADMIN_PACKET_SERVER_WELCOME
|
|
||||||
Either directly follows ADMIN_PACKET_SERVER_PROTOCOL or is sent
|
|
||||||
after a new game has been started or a map loaded, i.e. also
|
|
||||||
after ADMIN_PACKET_SERVER_NEWGAME.
|
|
||||||
|
|
||||||
ADMIN_PACKET_SERVER_CLIENT_JOIN and ADMIN_PACKET_SERVER_COMPANY_NEW
|
|
||||||
These packets directly follow their respective INFO packets. If you receive
|
|
||||||
a CLIENT_JOIN / COMPANY_NEW packet without having received the INFO packet
|
|
||||||
it may be a good idea to POLL for the specific ID.
|
|
||||||
|
|
||||||
ADMIN_PACKET_SERVER_CMD_NAMES and ADMIN_PACKET_SERVER_CMD_LOGGING
|
|
||||||
Data provided with these packets is not stable and will not be
|
|
||||||
treated as such. Do not rely on IDs or names to be constant
|
|
||||||
across different versions / revisions of OpenTTD.
|
|
||||||
Data provided in this packet is for logging purposes only.
|
|
||||||
268
docs/desync.txt
268
docs/desync.txt
@@ -1,268 +0,0 @@
|
|||||||
Some explanations about Desyncs
|
|
||||||
Last updated: 2014-02-23
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Table of contents
|
|
||||||
-----------------
|
|
||||||
1.0) Desync theory
|
|
||||||
* 1.1) OpenTTD multiplayer architecture
|
|
||||||
* 1.2) What is a Desync and how is it detected
|
|
||||||
* 1.3) Typical causes of Desyncs
|
|
||||||
2.0) What to do in case of a Desync
|
|
||||||
* 2.1) Cache debugging
|
|
||||||
* 2.2) Desync recording
|
|
||||||
3.0) Evaluating the Desync records
|
|
||||||
* 3.1) Replaying
|
|
||||||
* 3.2) Evaluation the replay
|
|
||||||
* 3.3) Comparing savegames
|
|
||||||
|
|
||||||
|
|
||||||
1.1) OpenTTD multiplayer architecture
|
|
||||||
---- --------------------------------
|
|
||||||
OpenTTD has a huge gamestate, which changes all of the time.
|
|
||||||
The savegame contains the complete gamestate at a specific point
|
|
||||||
in time. But this state changes completely each tick: Vehicles move
|
|
||||||
and trees grow.
|
|
||||||
|
|
||||||
However, most of these changes in the gamestate are deterministic:
|
|
||||||
Without a player interfering a vehicle follows its orders always
|
|
||||||
in the same way, and trees always grow the same.
|
|
||||||
|
|
||||||
In OpenTTD multiplayer synchronisation works by creating a savegame
|
|
||||||
when clients join, and then transfering that savegame to the client,
|
|
||||||
so it has the complete gamestate at a fixed point in time.
|
|
||||||
|
|
||||||
Afterwards clients only receive 'commands', that is: Stuff which is
|
|
||||||
not predictable, like
|
|
||||||
- player actions
|
|
||||||
- AI actions
|
|
||||||
- GameScript actions
|
|
||||||
- Admin Port command
|
|
||||||
- rcon commands
|
|
||||||
- ...
|
|
||||||
|
|
||||||
These commands contain the information on how to execute the command,
|
|
||||||
and when to execute it. Time is measured in 'network frames'.
|
|
||||||
Mind that network frames to not match ingame time. Network frames
|
|
||||||
also run while the game is paused, to give a defined behaviour to
|
|
||||||
stuff that is executing while the game is paused.
|
|
||||||
|
|
||||||
The deterministic part of the gamestate is run by the clients on
|
|
||||||
their own. All they get from the server is the instruction to
|
|
||||||
run the gamestate up to a certain network time, which basically
|
|
||||||
says that there are no commands scheduled in that time.
|
|
||||||
|
|
||||||
When a client (which includes the server itself) wants to execute
|
|
||||||
a command (i.e. a non-predictable action), it does this by
|
|
||||||
- calling DoCommandP resp. DoCommandPInternal
|
|
||||||
- These functions first do a local test-run of the command to
|
|
||||||
check simple preconditions. (Just to give the client an
|
|
||||||
immediate response without bothering the server and waiting for
|
|
||||||
the response.) The test-run may not actually change the
|
|
||||||
gamestate, all changes must be discarded.
|
|
||||||
- If the local test-run succeeds the command is sent to the server.
|
|
||||||
- The server inserts the command into the command queue, which
|
|
||||||
assigns a network frame to the commands, i.e. when it shall be
|
|
||||||
executed on all clients.
|
|
||||||
- Enhanced with this specific timestamp, the command is send to all
|
|
||||||
clients, which execute the command simultaneously in the same
|
|
||||||
network frame in the same order.
|
|
||||||
|
|
||||||
1.2) What is a Desync and how is it detected
|
|
||||||
---- ---------------------------------------
|
|
||||||
In the ideal case all clients have the same gamestate as the server
|
|
||||||
and run in sync. That is, vehicle movement is the same on all
|
|
||||||
clients, and commands are executed the same everywhere and
|
|
||||||
have the same results.
|
|
||||||
|
|
||||||
When a Desync happens, it means that the gamestates on the clients
|
|
||||||
(including the server) are no longer the same. Just imagine
|
|
||||||
that a vehicle picks the left line instead of the right line at
|
|
||||||
a junction on one client.
|
|
||||||
|
|
||||||
The important thing here is, that noone notices when a Desync
|
|
||||||
occurs. The desync client will continue to simulate the gamestate
|
|
||||||
and execute commands from the server. Once the gamestate differs
|
|
||||||
it will increasingly spiral out of control: If a vehicle picks a
|
|
||||||
different route, it will arrive at a different time at a station,
|
|
||||||
which will load different cargo, which causes other vehicles to
|
|
||||||
load other stuff, which causes industries to notice different
|
|
||||||
servicing, which causes industries to change production, ...
|
|
||||||
the client could run all day in a different universe.
|
|
||||||
|
|
||||||
To limit how long a Desync can remain unnoticed, the server
|
|
||||||
transfers some checksums every now and then for the gamestate.
|
|
||||||
Currently this checksum is the state of the random number
|
|
||||||
generator of the game logic. A lot of things in OpenTTD depend
|
|
||||||
on the RNG, and if the gamestate differs, it is likely that the
|
|
||||||
RNG is called at different times, and the state differs when
|
|
||||||
checked.
|
|
||||||
|
|
||||||
The clients compare this 'checksum' with the checksum of their
|
|
||||||
own gamestate at the specific network frame. If they differ,
|
|
||||||
the client disconnects with a Desync error.
|
|
||||||
|
|
||||||
The important thing here is: The detection of the Desync is
|
|
||||||
only an ultimate failure detection. It does not give any
|
|
||||||
indication on when the Desync happened. The Desync may after
|
|
||||||
all have occurred long ago, and just did not affect the checksum
|
|
||||||
up to now. The checksum may have matched 10 times or more
|
|
||||||
since the Desync happend, and only now the Desync has spiraled
|
|
||||||
enough to finally affect the checksum. (There was once a desync
|
|
||||||
which was only noticed by the checksum after 20 game years.)
|
|
||||||
|
|
||||||
1.3) Typical causes of Desyncs
|
|
||||||
---- -------------------------
|
|
||||||
Desyncs can be caused by the following scenarios:
|
|
||||||
- The savegame does not describe the complete gamestate.
|
|
||||||
- Some information which affects the progression of the
|
|
||||||
gamestate is not saved in the savegame.
|
|
||||||
- Some information which affects the progression of the
|
|
||||||
gamestate is not loaded from the savegame.
|
|
||||||
This includes the case that something is not completely
|
|
||||||
reset before loading the savegame, so data from the
|
|
||||||
previous game is carried over to the new one.
|
|
||||||
- The gamestate does not behave deterministic.
|
|
||||||
- Cache mismatch: The game logic depends on some cached
|
|
||||||
values, which are not invalidated properly. This is
|
|
||||||
the usual case for NewGRF-specific Desyncs.
|
|
||||||
- Undefined behaviour: The game logic performs multiple
|
|
||||||
things in an undefined order or with an undefined
|
|
||||||
result. E.g. when sorting something with a key while
|
|
||||||
some keys are equal. Or some computation that depends
|
|
||||||
on the CPU architecture (32/64 bit, little/big endian).
|
|
||||||
- The gamestate is modified when it shall not be modified.
|
|
||||||
- The test-run of a command alters the gamestate.
|
|
||||||
- The gamestate is altered by a player or script without
|
|
||||||
using commands.
|
|
||||||
|
|
||||||
|
|
||||||
2.1) Cache debugging
|
|
||||||
---- ---------------
|
|
||||||
Desyncs which are caused by inproper cache validation can
|
|
||||||
often be found by enabling cache validation:
|
|
||||||
- Start OpenTTD with '-d desync=2'.
|
|
||||||
- This will enable validation of caches every tick.
|
|
||||||
That is, cached values are recomputed every tick and compared
|
|
||||||
to the cached value.
|
|
||||||
- Differences are logged to 'commands-out.log' in the autosave
|
|
||||||
folder.
|
|
||||||
|
|
||||||
Mind that this type of debugging can also be done in singleplayer.
|
|
||||||
|
|
||||||
2.2) Desync recording
|
|
||||||
---- ----------------
|
|
||||||
If you have a server, which happens to encounter Desyncs often,
|
|
||||||
you can enable recording of the gamestate alterations. This
|
|
||||||
will later allow the replay the gamestate and locate the Desync
|
|
||||||
cause.
|
|
||||||
|
|
||||||
There are two levels of Desync recording, which are enabled
|
|
||||||
via '-d desync=2' resp. '-d desync=3'. Both will record all
|
|
||||||
commands to a file 'commands-out.log' in the autosave folder.
|
|
||||||
|
|
||||||
If you have the savegame from the start of the server, and
|
|
||||||
this command log you can replay the whole game. (see Section 3.1)
|
|
||||||
|
|
||||||
If you do not start the server from a savegame, there will
|
|
||||||
also be a savegame created just after a map has been generated.
|
|
||||||
The savegame will be named 'dmp_cmds_*.sav' and be put into
|
|
||||||
the autosave folder.
|
|
||||||
|
|
||||||
In addition to that '-d desync=3' also creates regular savegames
|
|
||||||
at defined spots in network time. (more defined than regular
|
|
||||||
autosaves). These will be created in the autosave folder
|
|
||||||
and will also be named 'dmp_cmds_*.sav'.
|
|
||||||
|
|
||||||
These saves allow comparing the gamestate with the original
|
|
||||||
gamestate during replaying, and thus greatly help debugging.
|
|
||||||
However, they also take a lot of disk space.
|
|
||||||
|
|
||||||
|
|
||||||
3.1) Replaying
|
|
||||||
---- ---------
|
|
||||||
To replay a Desync recording, you need these files:
|
|
||||||
- The savegame from when the server was started, resp.
|
|
||||||
the automatically created savegame from when the map
|
|
||||||
was generated.
|
|
||||||
- The 'commands-out.log' file.
|
|
||||||
- Optionally the 'dmp_cmds_*.sav'.
|
|
||||||
Put these files into a safe spot. (Not your autosave folder!)
|
|
||||||
|
|
||||||
Next, prepare your OpenTTD for replaying:
|
|
||||||
- Get the same version of OpenTTD as the original server was running.
|
|
||||||
- Uncomment/enable the define 'DEBUG_DUMP_COMMANDS' in
|
|
||||||
'src/network/network_func.h'.
|
|
||||||
(DEBUG_FAILED_DUMP_COMMANDS is explained later)
|
|
||||||
- Put the 'commands-out.log' into the root save folder, and rename
|
|
||||||
it to 'commands.log'.
|
|
||||||
- Run 'openttd -D -d desync=3 -g startsavegame.sav'.
|
|
||||||
This replays the server log and creates new 'commands-out.log'
|
|
||||||
and 'dmp_cmds_*.sav' in your autosave folder.
|
|
||||||
|
|
||||||
3.2) Evaluation the replay
|
|
||||||
---- ---------------------
|
|
||||||
The replaying will also compare the checksums which are part of
|
|
||||||
the 'commands-out.log' with the replayed gamestate.
|
|
||||||
If they differ, it will trigger a 'NOT_REACHED'.
|
|
||||||
|
|
||||||
If the replay succeeds without mismatch, that is the replay reproduces
|
|
||||||
the original server state:
|
|
||||||
- Repeat the replay starting from incrementally later 'dmp_cmds_*.sav'
|
|
||||||
while truncating the 'commands.log' at the beginning appropriately.
|
|
||||||
The 'dmp_cmds_*.sav' can be your own ones from the first reply, or
|
|
||||||
the ones from the original server (if you have them).
|
|
||||||
(This simulates the view of joining clients during the game.)
|
|
||||||
- If one of those replays fails, you have located the Desync between
|
|
||||||
the last dmp_cmds that reproduces the replay and the first one
|
|
||||||
that fails.
|
|
||||||
|
|
||||||
If the replay does not succeed without mismatch, you can check the logs
|
|
||||||
whether there were failed commands. Then you may try to replay with
|
|
||||||
DEBUG_FAILED_DUMP_COMMANDS enabled. If the replay then fails, the
|
|
||||||
command test-run of the failed command modified the game state.
|
|
||||||
|
|
||||||
If you have the original 'dmp_cmds_*.sav', you can also compare those
|
|
||||||
savegames with your own ones from the replay. You can also comment/disable
|
|
||||||
the 'NOT_REACHED' mentioned above, to get another 'dmp_cmds_*.sav' from
|
|
||||||
the replay after the mismatch has already been detected.
|
|
||||||
See Section 3.2 on how to compare savegames.
|
|
||||||
If the saves differ you have located the Desync between the last dmp_cmds
|
|
||||||
that match and the first one that does not. The difference of the saves
|
|
||||||
may point you in the direction of what causes it.
|
|
||||||
|
|
||||||
If the replay succeeds without mismatch, and you do not have any
|
|
||||||
'dmp_cmd_*.sav' from the original server, it is a lost case.
|
|
||||||
Enable creation of the 'dmp_cmd_*.sav' on the server, and wait for the
|
|
||||||
next Desync.
|
|
||||||
|
|
||||||
Finally, you can also compare the 'commands-out.log' from the original
|
|
||||||
server with the one from the replay. They will differ in stuff like
|
|
||||||
dates, and the original log will contain the chat, but otherwise they
|
|
||||||
should match.
|
|
||||||
|
|
||||||
3.2) Comparing savegames
|
|
||||||
---- -------------------
|
|
||||||
The binary form of the savegames from the original server and from
|
|
||||||
your replay will always differ:
|
|
||||||
- The savegame contains paths to used NewGRF files.
|
|
||||||
- The gamelog will log your loading of the savegame.
|
|
||||||
- The savegame data of AIs and the Gamescript will differ.
|
|
||||||
Scripts are not run during the replay, only their recorded commands
|
|
||||||
are replayed. Their internal state will thus not change in the
|
|
||||||
replay and will differ.
|
|
||||||
|
|
||||||
To compare savegame more semantically, there exist some ugly hackish
|
|
||||||
tools at:
|
|
||||||
http://devs.openttd.org/~frosch/texts/zpipe.c
|
|
||||||
http://devs.openttd.org/~frosch/texts/printhunk.c
|
|
||||||
|
|
||||||
The first one decompresses OpenTTD savegames. The second one creates
|
|
||||||
a textual representation of an uncompressed savegame, by parsing hunks
|
|
||||||
and arrays and such. With both tools you need to be a bit careful
|
|
||||||
since they work on stdin and stdout, which may not deal well with
|
|
||||||
binary data.
|
|
||||||
|
|
||||||
If you have the textual representation of the savegames, you can
|
|
||||||
compare them with regular diff tools.
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
Some clarifications about the link graph
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
InitializeLinkGraphs joins all threads, so if the game is abandoned
|
|
||||||
with some threads still running, they're joined as soon as the next game
|
|
||||||
(possibly the title game) is started. See also InitializeGame.
|
|
||||||
|
|
||||||
The MCF (multi-commodity flow) algorithm can be quite CPU-hungry as it's
|
|
||||||
NP-hard and takes exponential time (though with a very small constant
|
|
||||||
factor) in the number of nodes.
|
|
||||||
This is why it is run in a separate thread where possible. However after
|
|
||||||
some time the thread is joined and if it hasn't finished by then the game
|
|
||||||
will hang. This problem gets worse if we are running on a platform without
|
|
||||||
threads. However, as those are usually the ones with less CPU power I
|
|
||||||
assume the contention for the CPU would make the game hard to play even
|
|
||||||
with threads or even without cargodist (autosave ...). I might be wrong,
|
|
||||||
but I won't put any work into this before someone shows me some problem.
|
|
||||||
|
|
||||||
You can configure the link graph recalculation time. A link graph
|
|
||||||
recalculation time of X days means that each link graph job has X days
|
|
||||||
to run before it is joined. The downside is that the flow stats won't be
|
|
||||||
updated before the job is finished and thus a high value means less
|
|
||||||
updates and longer times until changes in capacities are accounted for.
|
|
||||||
If you play a very large map with a complicated link graph you may want to
|
|
||||||
raise the time setting to avoid lags. The same holds for systems with slow
|
|
||||||
CPUs.
|
|
||||||
|
|
||||||
Another option to avoid excessive lags is to reduce the accuracy of link
|
|
||||||
graph calculations. Generally the accuracy is inversely correlated to the
|
|
||||||
CPU requirements of the MCF algorithm.
|
|
||||||
@@ -1,219 +0,0 @@
|
|||||||
Multiplayer manual for OpenTTD
|
|
||||||
Last updated: 2011-02-16
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Table of contents
|
|
||||||
-----------------
|
|
||||||
1.0) Starting a server
|
|
||||||
2.0) Connecting to a server
|
|
||||||
* 2.1) Connecting to a server over the console
|
|
||||||
3.0) Playing internet games
|
|
||||||
4.0) Tips for servers
|
|
||||||
* 4.1) Imposing landscaping limits
|
|
||||||
5.0) Some useful things
|
|
||||||
6.0) Troubleshooting
|
|
||||||
|
|
||||||
|
|
||||||
1.0) Starting a server
|
|
||||||
---- -----------------
|
|
||||||
- Make sure that you have your firewall of the computer as well as possible
|
|
||||||
routers or modems of the server configured such that:
|
|
||||||
* port 3979 is free for both UDP and TCP connections in- and outgoing
|
|
||||||
* port 3978 is free outbound for UDP in order to advertise with the master
|
|
||||||
server (if desired). Otherwise you'll have to tell players your IP.
|
|
||||||
* port 3977 if use of the admin interface is desired (see admin_network.txt)
|
|
||||||
- Click "multiplayer" on the startup screen
|
|
||||||
- Click "start server"
|
|
||||||
- Type in a game name
|
|
||||||
- Select the type of game ('LAN/Internet' or 'Internet (advertise)'. With the
|
|
||||||
last one other people are able to see you online. Else they need your IP and
|
|
||||||
port to join)
|
|
||||||
- Click "start game", "load game" or "load scenario"
|
|
||||||
- Start playing
|
|
||||||
|
|
||||||
|
|
||||||
2.0) Connecting to a server
|
|
||||||
---- ----------------------
|
|
||||||
- Click "multiplayer" on the startup screen
|
|
||||||
|
|
||||||
- If you want to connect to any network game in your LAN click on 'LAN', then
|
|
||||||
on 'Find Server'
|
|
||||||
- If you want to see which servers all online on the Internet, click on
|
|
||||||
'Internet' and 'Find Server'
|
|
||||||
|
|
||||||
- If there were more than one server
|
|
||||||
- select one in the list below the buttons
|
|
||||||
- click on 'join game'
|
|
||||||
|
|
||||||
- If you want to play and you have the ip or hostname of the game server you
|
|
||||||
want connect to.
|
|
||||||
- click add server
|
|
||||||
- type in the ip address or hostname
|
|
||||||
- if you want to add a port use :<port>
|
|
||||||
|
|
||||||
- Now you can select a company and press: "Join company", to help that company
|
|
||||||
- Or you can press "Spectate game", to spectate the game
|
|
||||||
- Or you can press "New company", and start your own company (if there are
|
|
||||||
slots free)
|
|
||||||
|
|
||||||
- You see a progressbar how far you are with joining the server.
|
|
||||||
|
|
||||||
- Happy playing
|
|
||||||
|
|
||||||
2.1) Connecting to a server over the console
|
|
||||||
---- ---------------------------------------
|
|
||||||
- Open the console and type in the following command:
|
|
||||||
connect <ip/host>:<port>#<company-no>
|
|
||||||
|
|
||||||
|
|
||||||
3.0) Playing internet games
|
|
||||||
---- ----------------------
|
|
||||||
- Servers with a red dot behind it have a different version then you have. You
|
|
||||||
will not be able to join those servers.
|
|
||||||
|
|
||||||
- Servers with a yellow dot behind it have NewGRFs that you do not have. You
|
|
||||||
will not be able to join those servers. However, via "NewGRF Settings" and
|
|
||||||
"Find missing content online" you might be able to download the needed
|
|
||||||
NewGRFs after which you can join the server.
|
|
||||||
|
|
||||||
- It can happen that a connection is that slow, or you have that many clients
|
|
||||||
connected to your server, that your clients start to loose their connection.
|
|
||||||
Some things you can do about it:
|
|
||||||
- [network] frame_freq:
|
|
||||||
change it in console with: 'set network.frame_freq <number>'
|
|
||||||
the number should be between the 0 and 10, not much higher. It indicates
|
|
||||||
the delay between clicking and showing up. The higher, the more you notice
|
|
||||||
it, but the less bandwidth you use.
|
|
||||||
A good value for Internet-games is 2 or 3.
|
|
||||||
|
|
||||||
- [network] sync_freq:
|
|
||||||
change it in console with: 'set network.sync_freq <number>'
|
|
||||||
the number should be between the 50 and 1000, not much lower, not much
|
|
||||||
higher. It indicates the time between sync-frames. A sync-frame is a frame
|
|
||||||
which checks if all clients are still in sync. When the value it too high,
|
|
||||||
clients can desync in 1960, but the server detects it in 1970. Not really
|
|
||||||
handy. The lower the value, the more bandwidth it uses.
|
|
||||||
|
|
||||||
NB: changing frame_freq has more effect on the bandwidth then sync_freq.
|
|
||||||
|
|
||||||
|
|
||||||
4.0) Tips for servers
|
|
||||||
---- ----------------
|
|
||||||
- You can launch a dedicated server by adding -D as parameter.
|
|
||||||
- In UNIX like systems, you can fork your dedicated server by adding -f as
|
|
||||||
parameter.
|
|
||||||
|
|
||||||
- You can automatically clean companies that do not have a client connected to
|
|
||||||
them, for, let's say, 3 years. You can do this via: 'set autoclean_companies'
|
|
||||||
and 'set autoclean_protected' and 'set autoclean_unprotected'. Unprotected
|
|
||||||
removes a password from a company when it is not used for more then the
|
|
||||||
defined amount of months. 'set autoclean_novehicles' can be used to remove
|
|
||||||
companies without any vehicles quickly.
|
|
||||||
|
|
||||||
- You can also do this manually via the console: 'reset_company'.
|
|
||||||
|
|
||||||
- You can let your server automatically restart a map when, let's say, year 2030
|
|
||||||
is reached. See 'set restart_game_date' for detail.
|
|
||||||
|
|
||||||
- If you want to be on the server-list, enable Advertising. To do this, select
|
|
||||||
'Internet (advertise)' in the Start Server menu, or type in console:
|
|
||||||
'set server_advertise 1'.
|
|
||||||
|
|
||||||
- You can protect your server with a password via the console: 'set server_pw',
|
|
||||||
or via the Start Server menu.
|
|
||||||
|
|
||||||
- When you have many clients connected to your server via Internet, watch your
|
|
||||||
bandwidth (if you have any limit on it, set by your ISP). One client uses
|
|
||||||
about 1.5 kilobytes per second up and down. To decrease this amount, setting
|
|
||||||
'frame_freq' to 1 will reduce it to roughly 1 kilobyte per second per client.
|
|
||||||
|
|
||||||
- OpenTTD's default settings for maximum number of clients, and amount of data
|
|
||||||
from clients to process are chosen to not influence the normal playing of
|
|
||||||
people, but to prevent or at least make it less likely that someone can
|
|
||||||
perform a (distributed) denial-of-service attack on your server by causing
|
|
||||||
an out-of-memory event by flooding the server with data to send to all
|
|
||||||
clients. The major factor in this is the maximum number of clients; with
|
|
||||||
32 clients "only" sending one chat message causes 1024 messages to be
|
|
||||||
distributed in total, with 64 clients that already quadruples to 4096. Given
|
|
||||||
that upstream bandwidth is usually the limiting factor, a queue of packets
|
|
||||||
that need to be sent will be created.
|
|
||||||
To prevent clients from exploiting this "explosion" of packets to send we
|
|
||||||
limit the number of incoming data, resulting in effectively limiting the
|
|
||||||
amount of data that OpenTTD will send to the clients. Even with the default
|
|
||||||
limits it is possible to generate about 70.000 packets per second, or about
|
|
||||||
7 megabit per second of traffic.
|
|
||||||
Given that OpenTTD kicks clients after they have not reacted within about 9
|
|
||||||
seconds from sending a frame update packet it would be possible that OpenTTD
|
|
||||||
keeps about 600.000 packets in memory, using about 50 megabytes of memory.
|
|
||||||
Given that OpenTTD allows short bursts of packets, you can have slightly
|
|
||||||
more packets in memory in case of a distributed denial of service attack.
|
|
||||||
When increasing the amount of incoming data, or the maximum number of
|
|
||||||
clients the amount of memory OpenTTD needs in case of a distributed denial
|
|
||||||
of service attack is linearly related to the amount of incoming data and
|
|
||||||
quadratic to the amount of clients. In short, a rule of thumb for, the
|
|
||||||
maximum memory usage for packets is:
|
|
||||||
#max_clients * #max_clients * bytes_per_frame * 10 KiB.
|
|
||||||
|
|
||||||
4.1) Imposing landscaping limits
|
|
||||||
---- ---------------------------
|
|
||||||
- You can impose limits on companies by the following 4 settings:
|
|
||||||
- terraform_per_64k_frames
|
|
||||||
- terraform_frame_burst
|
|
||||||
- clear_per_64k_frames
|
|
||||||
- clear_frame_burst
|
|
||||||
|
|
||||||
- Explaining 'per_64K_frames' and 'burst'
|
|
||||||
- 'burst' defines 3 things, the maximum limit, the limit of a single action,
|
|
||||||
and the initial value for the limit assigned to a new company.
|
|
||||||
This setting is fairly simple and requires no math.
|
|
||||||
|
|
||||||
A value of 1 means a single tile can be affected by a single action.
|
|
||||||
This results in having to click 400 times when wanting to cover an area
|
|
||||||
of 20 x 20 tiles.
|
|
||||||
|
|
||||||
The default value 4096 covers an area of 64 x 64 tiles.
|
|
||||||
|
|
||||||
- 'per_64k_frames' defines the number of tiles added to each companies limit
|
|
||||||
per frame (however not past the possible maximum value,the 'burst').
|
|
||||||
64k rather resembles the exact number of 65536 frames. So setting this
|
|
||||||
variable to 65536 means: 65536 / 65536 = 1 tile per frame.
|
|
||||||
As a day consists of 74 frames, a company's limit is increased by 74
|
|
||||||
tiles during the course of a single day (2.22 seconds).
|
|
||||||
|
|
||||||
To achieve a 1 tile per day increase the following calculation is needed:
|
|
||||||
1 / 74 (frames per day) * 65536 (per_64k_frames) = 885.62...
|
|
||||||
after rounding: a value of 886 means adding a bit over 1 tile per day.
|
|
||||||
|
|
||||||
There is still enough space to scale this value downwards:
|
|
||||||
decreasing this value to 127 results in a bit over 1 tile added to the
|
|
||||||
allowance per week (7 days).
|
|
||||||
|
|
||||||
To create a setup in which a company gets an initial allowance only,
|
|
||||||
set the value to 0 - no increase of the allowance per frame.
|
|
||||||
|
|
||||||
- Even though construction actions include a clear tile action, they are not
|
|
||||||
affected by the above settings.
|
|
||||||
|
|
||||||
|
|
||||||
5.0) Some useful things
|
|
||||||
---- ------------------
|
|
||||||
- You can protect your company so nobody else can join uninvited. To do this,
|
|
||||||
set a password in your Company Screen
|
|
||||||
|
|
||||||
- You can give other players some money via the ClientList (under the 'head'
|
|
||||||
in the mainbar).
|
|
||||||
|
|
||||||
- You can chat with other players via ENTER or via SHIFT+T or via the ClientList
|
|
||||||
|
|
||||||
- Servers can now kick players, so don't make them use it!
|
|
||||||
|
|
||||||
|
|
||||||
6.0) Troubleshooting
|
|
||||||
---- ---------------
|
|
||||||
- My advertising server does not show up in list at servers.openttd.org
|
|
||||||
Run openttd with the '-d net=2' parameter. That will show which incoming
|
|
||||||
communication is received, whether the replies from the master server or
|
|
||||||
communication from an admin tool reach the programme. See section 1
|
|
||||||
'Starting a server' further up for the ports and protocols used by OpenTTD.
|
|
||||||
The ports can be configured in the config file.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
The files in this directory are not licensed under the same terms as the
|
|
||||||
rest of OpenTTD. Licensing details can be found in OpenTTD's readme.txt
|
|
||||||
and in this directory or subdirectories as well.
|
|
||||||
Binary file not shown.
@@ -1,173 +0,0 @@
|
|||||||
CWSDPMI is Copyright (C) 1995-2000 Charles W Sandmann (sandmann@clio.rice.edu)
|
|
||||||
1206 Braelinn, Sugar Land, TX 77479
|
|
||||||
|
|
||||||
This is release 5. The files in this binary distribution may be redistributed
|
|
||||||
under the GPL (with source) or without the source code provided:
|
|
||||||
|
|
||||||
* CWSDPMI.EXE or CWSDPR0.EXE are not modified in any way except via CWSPARAM.
|
|
||||||
|
|
||||||
* CWSDSTUB.EXE internal contents are not modified in any way except via
|
|
||||||
CWSPARAM or STUBEDIT. It may have a COFF image plus data appended to it.
|
|
||||||
|
|
||||||
* Notice to users that they have the right to receive the source code and/or
|
|
||||||
binary updates for CWSDPMI. Distributors should indicate a site for the
|
|
||||||
source in their documentation.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CWSDPMI was written to provide DPMI services for V2 of DJGPP. It currently
|
|
||||||
does not support 16-bit DPMI applications, or DPMI applications requiring a
|
|
||||||
built in extender. It does support virtual memory and hardware interrupt
|
|
||||||
reflection from real mode to protected mode. DJGPP V1.1x and RSX applications
|
|
||||||
will also run using this server, which can be used to provide enhanced control
|
|
||||||
over hardware interrupts. Some DPMI 1.0 extensions (0x506, 0x507, 0x508) have
|
|
||||||
been implemented.
|
|
||||||
|
|
||||||
CWSDPR0.EXE is an alternate version which runs at ring 0 with virtual memory
|
|
||||||
disabled. It may be used if access to ring-0 features are desired. It
|
|
||||||
currently does not switch stacks on HW interrupts, so some DJGPP features
|
|
||||||
such as SIGINT and SIGFPE are not supported and will generate a double fault
|
|
||||||
or stack fault error (to be fixed someday).
|
|
||||||
|
|
||||||
CWSDSTUB.EXE is a stub loader image for DJGPP which includes CWSDPMI. This
|
|
||||||
allows single executable image distributions. You can use the EXE2COFF
|
|
||||||
program and COPY /B CWSDSTUB.EXE+yourimage yourimage.exe to create a
|
|
||||||
standalone executable image.
|
|
||||||
|
|
||||||
Some of the internal tuning and configuration parameters may be modified
|
|
||||||
in the image using CWSPARAM.EXE (see CWSPARAM.DOC).
|
|
||||||
|
|
||||||
If you want to use CWSDPMI with DJGPP, you expand the distribution into the
|
|
||||||
DJGPP directory tree. CWSDPMI.EXE will be put in the BIN directory with your
|
|
||||||
DJGPP images and it will automatically be loaded when they run.
|
|
||||||
|
|
||||||
Directions for use (server can be used in either of two different ways):
|
|
||||||
|
|
||||||
1) "cwsdpmi" alone with no parameters will terminate and stay resident
|
|
||||||
FOR A SINGLE DPMI PROCESS. This means it unloads itself when your
|
|
||||||
DPMI application exits. This mode is useful in software which needs
|
|
||||||
DPMI services, since CWSDPMI can be exec'ed and then will unload on exit.
|
|
||||||
|
|
||||||
2) "cwsdpmi -p" will terminate and stay resident until you remove it.
|
|
||||||
It can be loaded into UMBs with LH. "cwsdpmi -u" will unload the TSR.
|
|
||||||
|
|
||||||
3) The file used for virtual memory swapping, if desired, is controlled
|
|
||||||
by the "-sc:\cwsdpmi.swp" syntax on the command line. You must specify
|
|
||||||
either a file with full disk/directory syntax, or "-s-" which disables
|
|
||||||
virtual memory.
|
|
||||||
|
|
||||||
4) The default swap file name is c:\cwsdpmi.swp, but this can be changed
|
|
||||||
with the CWSPARAM image, as can some other parameters.
|
|
||||||
|
|
||||||
5) You can disable the DPMI 1.0 extensions by starting the image with the
|
|
||||||
"cwsdpmi -x" syntax. This feature allows you to run programs developed
|
|
||||||
under other DPMI providers which do not behave properly with these
|
|
||||||
extensions enabled (typically use of NULL pointers).
|
|
||||||
|
|
||||||
I would like to give special thanks to DJ Delorie who wrote the original
|
|
||||||
GO32 code on which CWSDPMI is based. Morten Welinder also provided and
|
|
||||||
improved much of the code in this program.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
This section contains a list of the error messages you might see out of
|
|
||||||
CWSDPMI and some details on what they mean.
|
|
||||||
|
|
||||||
Exceptions are only handled by CWSDPMI if the application does not establish
|
|
||||||
an exception handler, exceptions nest 5 deep, or the error is particularly bad:
|
|
||||||
|
|
||||||
"Page fault" -
|
|
||||||
1) an illegal page fault happens in a RMCB or HW interrupt, (lock all pages!)
|
|
||||||
2) all available pages have been locked,
|
|
||||||
3) the application is using non-committed pages for null pointer protection.
|
|
||||||
"Double Fault" - multiple exceptions occurred
|
|
||||||
"Invalid TSS" - typically due to RMCB or HW interrupt being called after the
|
|
||||||
selectors/memory have been deallocated (remember to reset the mouse)
|
|
||||||
"General Protection Fault" - bad parameter sent to a DPMI call
|
|
||||||
|
|
||||||
"80386 required."
|
|
||||||
|
|
||||||
Since 80286 and lesser processors don't have the hardware necessary to
|
|
||||||
run CWSDPMI. No workaround, upgrade.
|
|
||||||
|
|
||||||
"DOS 3 required."
|
|
||||||
|
|
||||||
A few interrupts are used which need DOS 3.0 or higher. I don't expect to
|
|
||||||
ever see this message, since 80386 machines were introduced after DOS 3.0
|
|
||||||
and that check is made first.
|
|
||||||
|
|
||||||
"CWSDPMI V0.90+ (r5) Copyright (C) 2000 CW Sandmann ABSOLUTELY NO WARRANTY"
|
|
||||||
|
|
||||||
An informational message displayed if the program is not run in one-pass mode.
|
|
||||||
|
|
||||||
"Protected mode not accessible."
|
|
||||||
|
|
||||||
This message should only be displayed if running CWSDPMI in a protected
|
|
||||||
environment with no access to protected mode. In this case, DPMI should
|
|
||||||
already be available and CWSDPMI would not be needed. This might happen if
|
|
||||||
a 16-bit DPMI client is loaded and a DJGPP image attempts to load CWSDPMI
|
|
||||||
to provide 32-bit DPMI services under Windows.
|
|
||||||
|
|
||||||
"Warning: cannot open swap file c:\cwsdpmi.swp"
|
|
||||||
|
|
||||||
Maybe you are out of file handles, or the swap file name is incorrectly
|
|
||||||
specified in the image (change the name with cwsparam).
|
|
||||||
|
|
||||||
"No swap space!"
|
|
||||||
|
|
||||||
This message means you tried to use more paging file than CWSDPMI was
|
|
||||||
configured to handle. Since this is protected against in the memory
|
|
||||||
allocation code, you should never see this message.
|
|
||||||
|
|
||||||
"Swap disk full!"
|
|
||||||
|
|
||||||
This means the paging file could not be expanded when trying to page
|
|
||||||
memory out to disk. This would normally not be seen, unless you are
|
|
||||||
writing output to the same disk which holds the paging file. Decrease
|
|
||||||
the amount of memory your DPMI application is using or free up disk space.
|
|
||||||
|
|
||||||
"Interrupt 0x??"
|
|
||||||
|
|
||||||
Your application tried to call an interrupt from protected mode which
|
|
||||||
normally shouldn't be called (something like a data pointer). If the
|
|
||||||
request was allowed to continue it would likely hang your machine. If you
|
|
||||||
see this message and think the interrupt should be allowed to continue, let
|
|
||||||
me know.
|
|
||||||
|
|
||||||
"Error: Using XMS switched CPU into V86 mode."
|
|
||||||
|
|
||||||
This message might be seen if you have your memory manager in AUTO mode. The
|
|
||||||
only workaround in this case is to stop using AUTO mode.
|
|
||||||
|
|
||||||
"Error: could not allocate page table memory"
|
|
||||||
|
|
||||||
The page table memory (a minimum of 16Kb) is allocated from conventional
|
|
||||||
memory (either in the 640Kb region or UMBs). If CWSDPMI cannot allocate the
|
|
||||||
minimum necessary memory, you would see this message. Free up some
|
|
||||||
conventional memory. You may also see this message if a page directory needs
|
|
||||||
to be faulted in, and there are no available pages. This means too many pages
|
|
||||||
have been locked for the allocated page tables available. While CWSDPMI
|
|
||||||
tries to dynamically allocate these if needed, this effort failed. You need
|
|
||||||
to increase the number of page tables with CWSPARAM, or increase the amount
|
|
||||||
of free conventional memory if it is low. If the application which calls
|
|
||||||
CWSDPMI internally manages all the DOS memory, the page tables may need to
|
|
||||||
be pre-allocated at DPMI startup time (if this is needed, try using the
|
|
||||||
run option flag 2 in cwsparam).
|
|
||||||
|
|
||||||
"16-bit DPMI unsupported."
|
|
||||||
|
|
||||||
CWSDPMI is a 32-bit only DPMI server. Ideally, on the request to enter DPMI's
|
|
||||||
PM with a 16-bit request, we would just fail the call setting the carry bit
|
|
||||||
like the DPMI specification describes. Some buggy 16-bit compiler tools don't
|
|
||||||
check the return status and will hang the machine in this case. So, I issue
|
|
||||||
an error message and exit the image instead.
|
|
||||||
|
|
||||||
"Descriptors exhausted."
|
|
||||||
|
|
||||||
An attempt to nest a DPMI client failed in the setup phase due to insufficient
|
|
||||||
free selectors in the LDT.
|
|
||||||
|
|
||||||
"CWSDPMI not removed"
|
|
||||||
|
|
||||||
When the -u parameter is specified, if DPMI is not detected this message is
|
|
||||||
printed. Informational.
|
|
||||||
Binary file not shown.
@@ -1,3 +0,0 @@
|
|||||||
The files in this directory are not licensed under the same terms as the
|
|
||||||
rest of OpenTTD. Licensing details can be found in OpenTTD's readme.txt
|
|
||||||
and in this directory or subdirectories as well.
|
|
||||||
@@ -1,339 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
|
||||||
675 Mass Ave, Cambridge, MA 02139, USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Appendix: How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) 19yy <name of author>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, the commands you use may
|
|
||||||
be called something other than `show w' and `show c'; they could even be
|
|
||||||
mouse-clicks or menu items--whatever suits your program.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
|
||||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
This General Public License does not permit incorporating your program into
|
|
||||||
proprietary programs. If your program is a subroutine library, you may
|
|
||||||
consider it more useful to permit linking proprietary applications with the
|
|
||||||
library. If this is what you want to do, use the GNU Library General
|
|
||||||
Public License instead of this License.
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
This is the file "copying.dj". It does NOT apply to any sources or
|
|
||||||
binaries copyrighted by UCB Berkeley, the Free Software Foundation, or
|
|
||||||
any other agency besides DJ Delorie and others who have agreed to
|
|
||||||
allow their sources to be distributed under these terms.
|
|
||||||
|
|
||||||
Copyright Information for sources and executables that are marked
|
|
||||||
Copyright (C) DJ Delorie
|
|
||||||
7 Kim Lane
|
|
||||||
Rochester NH 03867-2954
|
|
||||||
|
|
||||||
This document is Copyright (C) DJ Delorie and may be distributed
|
|
||||||
verbatim, but changing it is not allowed.
|
|
||||||
|
|
||||||
Source code copyright DJ Delorie is distributed under the terms of the
|
|
||||||
GNU General Public Licence, with the following exceptions:
|
|
||||||
|
|
||||||
* Sources used to build crt0.o, gcrt0.o, libc.a, libdbg.a, and
|
|
||||||
libemu.a are distributed under the terms of the GNU Library General
|
|
||||||
Public License, rather than the GNU GPL.
|
|
||||||
|
|
||||||
* Any existing copyright or authorship information in any given source
|
|
||||||
file must remain intact. If you modify a source file, a notice to that
|
|
||||||
effect must be added to the authorship information in the source file.
|
|
||||||
|
|
||||||
* Runtime binaries, as provided by DJ in DJGPP, may be distributed
|
|
||||||
without sources ONLY if the recipient is given sufficient information
|
|
||||||
to obtain a copy of djgpp themselves. This primarily applies to
|
|
||||||
go32-v2.exe, emu387.dxe, and stubedit.exe.
|
|
||||||
|
|
||||||
* Runtime objects and libraries, as provided by DJ in DJGPP, when
|
|
||||||
linked into an application, may be distributed without sources ONLY
|
|
||||||
if the recipient is given sufficient information to obtain a copy of
|
|
||||||
djgpp themselves. This primarily applies to crt0.o and libc.a.
|
|
||||||
|
|
||||||
-----
|
|
||||||
|
|
||||||
Changes to source code copyright BSD, FSF, or others, by DJ Delorie
|
|
||||||
fall under the terms of the original copyright. Such files usually
|
|
||||||
have multiple copyright notices in them.
|
|
||||||
|
|
||||||
A copy of the files "COPYING" and "COPYING.LIB" are included with this
|
|
||||||
document. If you did not receive a copy of these files, you may
|
|
||||||
obtain one from whence this document was obtained, or by writing:
|
|
||||||
|
|
||||||
Free Software Foundation
|
|
||||||
59 Temple Place - Suite 330
|
|
||||||
Boston, MA 02111-1307
|
|
||||||
USA
|
|
||||||
@@ -1,481 +0,0 @@
|
|||||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
|
||||||
675 Mass Ave, Cambridge, MA 02139, USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
[This is the first released version of the library GPL. It is
|
|
||||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
Licenses are intended to guarantee your freedom to share and change
|
|
||||||
free software--to make sure the software is free for all its users.
|
|
||||||
|
|
||||||
This license, the Library General Public License, applies to some
|
|
||||||
specially designated Free Software Foundation software, and to any
|
|
||||||
other libraries whose authors decide to use it. You can use it for
|
|
||||||
your libraries, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if
|
|
||||||
you distribute copies of the library, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of the library, whether gratis
|
|
||||||
or for a fee, you must give the recipients all the rights that we gave
|
|
||||||
you. You must make sure that they, too, receive or can get the source
|
|
||||||
code. If you link a program with the library, you must provide
|
|
||||||
complete object files to the recipients so that they can relink them
|
|
||||||
with the library, after making changes to the library and recompiling
|
|
||||||
it. And you must show them these terms so they know their rights.
|
|
||||||
|
|
||||||
Our method of protecting your rights has two steps: (1) copyright
|
|
||||||
the library, and (2) offer you this license which gives you legal
|
|
||||||
permission to copy, distribute and/or modify the library.
|
|
||||||
|
|
||||||
Also, for each distributor's protection, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
library. If the library is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original
|
|
||||||
version, so that any problems introduced by others will not reflect on
|
|
||||||
the original authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that companies distributing free
|
|
||||||
software will individually obtain patent licenses, thus in effect
|
|
||||||
transforming the program into proprietary software. To prevent this,
|
|
||||||
we have made it clear that any patent must be licensed for everyone's
|
|
||||||
free use or not licensed at all.
|
|
||||||
|
|
||||||
Most GNU software, including some libraries, is covered by the ordinary
|
|
||||||
GNU General Public License, which was designed for utility programs. This
|
|
||||||
license, the GNU Library General Public License, applies to certain
|
|
||||||
designated libraries. This license is quite different from the ordinary
|
|
||||||
one; be sure to read it in full, and don't assume that anything in it is
|
|
||||||
the same as in the ordinary license.
|
|
||||||
|
|
||||||
The reason we have a separate public license for some libraries is that
|
|
||||||
they blur the distinction we usually make between modifying or adding to a
|
|
||||||
program and simply using it. Linking a program with a library, without
|
|
||||||
changing the library, is in some sense simply using the library, and is
|
|
||||||
analogous to running a utility program or application program. However, in
|
|
||||||
a textual and legal sense, the linked executable is a combined work, a
|
|
||||||
derivative of the original library, and the ordinary General Public License
|
|
||||||
treats it as such.
|
|
||||||
|
|
||||||
Because of this blurred distinction, using the ordinary General
|
|
||||||
Public License for libraries did not effectively promote software
|
|
||||||
sharing, because most developers did not use the libraries. We
|
|
||||||
concluded that weaker conditions might promote sharing better.
|
|
||||||
|
|
||||||
However, unrestricted linking of non-free programs would deprive the
|
|
||||||
users of those programs of all benefit from the free status of the
|
|
||||||
libraries themselves. This Library General Public License is intended to
|
|
||||||
permit developers of non-free programs to use free libraries, while
|
|
||||||
preserving your freedom as a user of such programs to change the free
|
|
||||||
libraries that are incorporated in them. (We have not seen how to achieve
|
|
||||||
this as regards changes in header files, but we have achieved it as regards
|
|
||||||
changes in the actual functions of the Library.) The hope is that this
|
|
||||||
will lead to faster development of free libraries.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow. Pay close attention to the difference between a
|
|
||||||
"work based on the library" and a "work that uses the library". The
|
|
||||||
former contains code derived from the library, while the latter only
|
|
||||||
works together with the library.
|
|
||||||
|
|
||||||
Note that it is possible for a library to be covered by the ordinary
|
|
||||||
General Public License rather than by this special one.
|
|
||||||
|
|
||||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License Agreement applies to any software library which
|
|
||||||
contains a notice placed by the copyright holder or other authorized
|
|
||||||
party saying it may be distributed under the terms of this Library
|
|
||||||
General Public License (also called "this License"). Each licensee is
|
|
||||||
addressed as "you".
|
|
||||||
|
|
||||||
A "library" means a collection of software functions and/or data
|
|
||||||
prepared so as to be conveniently linked with application programs
|
|
||||||
(which use some of those functions and data) to form executables.
|
|
||||||
|
|
||||||
The "Library", below, refers to any such software library or work
|
|
||||||
which has been distributed under these terms. A "work based on the
|
|
||||||
Library" means either the Library or any derivative work under
|
|
||||||
copyright law: that is to say, a work containing the Library or a
|
|
||||||
portion of it, either verbatim or with modifications and/or translated
|
|
||||||
straightforwardly into another language. (Hereinafter, translation is
|
|
||||||
included without limitation in the term "modification".)
|
|
||||||
|
|
||||||
"Source code" for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For a library, complete source code means
|
|
||||||
all the source code for all modules it contains, plus any associated
|
|
||||||
interface definition files, plus the scripts used to control compilation
|
|
||||||
and installation of the library.
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running a program using the Library is not restricted, and output from
|
|
||||||
such a program is covered only if its contents constitute a work based
|
|
||||||
on the Library (independent of the use of the Library in a tool for
|
|
||||||
writing it). Whether that is true depends on what the Library does
|
|
||||||
and what the program that uses the Library does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Library's
|
|
||||||
complete source code as you receive it, in any medium, provided that
|
|
||||||
you conspicuously and appropriately publish on each copy an
|
|
||||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
|
||||||
all the notices that refer to this License and to the absence of any
|
|
||||||
warranty; and distribute a copy of this License along with the
|
|
||||||
Library.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy,
|
|
||||||
and you may at your option offer warranty protection in exchange for a
|
|
||||||
fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
|
||||||
of it, thus forming a work based on the Library, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The modified work must itself be a software library.
|
|
||||||
|
|
||||||
b) You must cause the files modified to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
c) You must cause the whole of the work to be licensed at no
|
|
||||||
charge to all third parties under the terms of this License.
|
|
||||||
|
|
||||||
d) If a facility in the modified Library refers to a function or a
|
|
||||||
table of data to be supplied by an application program that uses
|
|
||||||
the facility, other than as an argument passed when the facility
|
|
||||||
is invoked, then you must make a good faith effort to ensure that,
|
|
||||||
in the event an application does not supply such function or
|
|
||||||
table, the facility still operates, and performs whatever part of
|
|
||||||
its purpose remains meaningful.
|
|
||||||
|
|
||||||
(For example, a function in a library to compute square roots has
|
|
||||||
a purpose that is entirely well-defined independent of the
|
|
||||||
application. Therefore, Subsection 2d requires that any
|
|
||||||
application-supplied function or table used by this function must
|
|
||||||
be optional: if the application does not supply it, the square
|
|
||||||
root function must still compute square roots.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Library,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Library, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote
|
|
||||||
it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Library.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Library
|
|
||||||
with the Library (or with a work based on the Library) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
|
||||||
License instead of this License to a given copy of the Library. To do
|
|
||||||
this, you must alter all the notices that refer to this License, so
|
|
||||||
that they refer to the ordinary GNU General Public License, version 2,
|
|
||||||
instead of to this License. (If a newer version than version 2 of the
|
|
||||||
ordinary GNU General Public License has appeared, then you can specify
|
|
||||||
that version instead if you wish.) Do not make any other change in
|
|
||||||
these notices.
|
|
||||||
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
|
||||||
subsequent copies and derivative works made from that copy.
|
|
||||||
|
|
||||||
This option is useful when you wish to copy part of the code of
|
|
||||||
the Library into a program that is not a library.
|
|
||||||
|
|
||||||
4. You may copy and distribute the Library (or a portion or
|
|
||||||
derivative of it, under Section 2) in object code or executable form
|
|
||||||
under the terms of Sections 1 and 2 above provided that you accompany
|
|
||||||
it with the complete corresponding machine-readable source code, which
|
|
||||||
must be distributed under the terms of Sections 1 and 2 above on a
|
|
||||||
medium customarily used for software interchange.
|
|
||||||
|
|
||||||
If distribution of object code is made by offering access to copy
|
|
||||||
from a designated place, then offering equivalent access to copy the
|
|
||||||
source code from the same place satisfies the requirement to
|
|
||||||
distribute the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
5. A program that contains no derivative of any portion of the
|
|
||||||
Library, but is designed to work with the Library by being compiled or
|
|
||||||
linked with it, is called a "work that uses the Library". Such a
|
|
||||||
work, in isolation, is not a derivative work of the Library, and
|
|
||||||
therefore falls outside the scope of this License.
|
|
||||||
|
|
||||||
However, linking a "work that uses the Library" with the Library
|
|
||||||
creates an executable that is a derivative of the Library (because it
|
|
||||||
contains portions of the Library), rather than a "work that uses the
|
|
||||||
library". The executable is therefore covered by this License.
|
|
||||||
Section 6 states terms for distribution of such executables.
|
|
||||||
|
|
||||||
When a "work that uses the Library" uses material from a header file
|
|
||||||
that is part of the Library, the object code for the work may be a
|
|
||||||
derivative work of the Library even though the source code is not.
|
|
||||||
Whether this is true is especially significant if the work can be
|
|
||||||
linked without the Library, or if the work is itself a library. The
|
|
||||||
threshold for this to be true is not precisely defined by law.
|
|
||||||
|
|
||||||
If such an object file uses only numerical parameters, data
|
|
||||||
structure layouts and accessors, and small macros and small inline
|
|
||||||
functions (ten lines or less in length), then the use of the object
|
|
||||||
file is unrestricted, regardless of whether it is legally a derivative
|
|
||||||
work. (Executables containing this object code plus portions of the
|
|
||||||
Library will still fall under Section 6.)
|
|
||||||
|
|
||||||
Otherwise, if the work is a derivative of the Library, you may
|
|
||||||
distribute the object code for the work under the terms of Section 6.
|
|
||||||
Any executables containing that work also fall under Section 6,
|
|
||||||
whether or not they are linked directly with the Library itself.
|
|
||||||
|
|
||||||
6. As an exception to the Sections above, you may also compile or
|
|
||||||
link a "work that uses the Library" with the Library to produce a
|
|
||||||
work containing portions of the Library, and distribute that work
|
|
||||||
under terms of your choice, provided that the terms permit
|
|
||||||
modification of the work for the customer's own use and reverse
|
|
||||||
engineering for debugging such modifications.
|
|
||||||
|
|
||||||
You must give prominent notice with each copy of the work that the
|
|
||||||
Library is used in it and that the Library and its use are covered by
|
|
||||||
this License. You must supply a copy of this License. If the work
|
|
||||||
during execution displays copyright notices, you must include the
|
|
||||||
copyright notice for the Library among them, as well as a reference
|
|
||||||
directing the user to the copy of this License. Also, you must do one
|
|
||||||
of these things:
|
|
||||||
|
|
||||||
a) Accompany the work with the complete corresponding
|
|
||||||
machine-readable source code for the Library including whatever
|
|
||||||
changes were used in the work (which must be distributed under
|
|
||||||
Sections 1 and 2 above); and, if the work is an executable linked
|
|
||||||
with the Library, with the complete machine-readable "work that
|
|
||||||
uses the Library", as object code and/or source code, so that the
|
|
||||||
user can modify the Library and then relink to produce a modified
|
|
||||||
executable containing the modified Library. (It is understood
|
|
||||||
that the user who changes the contents of definitions files in the
|
|
||||||
Library will not necessarily be able to recompile the application
|
|
||||||
to use the modified definitions.)
|
|
||||||
|
|
||||||
b) Accompany the work with a written offer, valid for at
|
|
||||||
least three years, to give the same user the materials
|
|
||||||
specified in Subsection 6a, above, for a charge no more
|
|
||||||
than the cost of performing this distribution.
|
|
||||||
|
|
||||||
c) If distribution of the work is made by offering access to copy
|
|
||||||
from a designated place, offer equivalent access to copy the above
|
|
||||||
specified materials from the same place.
|
|
||||||
|
|
||||||
d) Verify that the user has already received a copy of these
|
|
||||||
materials or that you have already sent this user a copy.
|
|
||||||
|
|
||||||
For an executable, the required form of the "work that uses the
|
|
||||||
Library" must include any data and utility programs needed for
|
|
||||||
reproducing the executable from it. However, as a special exception,
|
|
||||||
the source code distributed need not include anything that is normally
|
|
||||||
distributed (in either source or binary form) with the major
|
|
||||||
components (compiler, kernel, and so on) of the operating system on
|
|
||||||
which the executable runs, unless that component itself accompanies
|
|
||||||
the executable.
|
|
||||||
|
|
||||||
It may happen that this requirement contradicts the license
|
|
||||||
restrictions of other proprietary libraries that do not normally
|
|
||||||
accompany the operating system. Such a contradiction means you cannot
|
|
||||||
use both them and the Library together in an executable that you
|
|
||||||
distribute.
|
|
||||||
|
|
||||||
7. You may place library facilities that are a work based on the
|
|
||||||
Library side-by-side in a single library together with other library
|
|
||||||
facilities not covered by this License, and distribute such a combined
|
|
||||||
library, provided that the separate distribution of the work based on
|
|
||||||
the Library and of the other library facilities is otherwise
|
|
||||||
permitted, and provided that you do these two things:
|
|
||||||
|
|
||||||
a) Accompany the combined library with a copy of the same work
|
|
||||||
based on the Library, uncombined with any other library
|
|
||||||
facilities. This must be distributed under the terms of the
|
|
||||||
Sections above.
|
|
||||||
|
|
||||||
b) Give prominent notice with the combined library of the fact
|
|
||||||
that part of it is a work based on the Library, and explaining
|
|
||||||
where to find the accompanying uncombined form of the same work.
|
|
||||||
|
|
||||||
8. You may not copy, modify, sublicense, link with, or distribute
|
|
||||||
the Library except as expressly provided under this License. Any
|
|
||||||
attempt otherwise to copy, modify, sublicense, link with, or
|
|
||||||
distribute the Library is void, and will automatically terminate your
|
|
||||||
rights under this License. However, parties who have received copies,
|
|
||||||
or rights, from you under this License will not have their licenses
|
|
||||||
terminated so long as such parties remain in full compliance.
|
|
||||||
|
|
||||||
9. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Library or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Library (or any work based on the
|
|
||||||
Library), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Library or works based on it.
|
|
||||||
|
|
||||||
10. Each time you redistribute the Library (or any work based on the
|
|
||||||
Library), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute, link with or modify the Library
|
|
||||||
subject to these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Library at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Library by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Library.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under any
|
|
||||||
particular circumstance, the balance of the section is intended to apply,
|
|
||||||
and the section as a whole is intended to apply in other circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
12. If the distribution and/or use of the Library is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Library under this License may add
|
|
||||||
an explicit geographical distribution limitation excluding those countries,
|
|
||||||
so that distribution is permitted only in or among countries not thus
|
|
||||||
excluded. In such case, this License incorporates the limitation as if
|
|
||||||
written in the body of this License.
|
|
||||||
|
|
||||||
13. The Free Software Foundation may publish revised and/or new
|
|
||||||
versions of the Library General Public License from time to time.
|
|
||||||
Such new versions will be similar in spirit to the present version,
|
|
||||||
but may differ in detail to address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Library
|
|
||||||
specifies a version number of this License which applies to it and
|
|
||||||
"any later version", you have the option of following the terms and
|
|
||||||
conditions either of that version or of any later version published by
|
|
||||||
the Free Software Foundation. If the Library does not specify a
|
|
||||||
license version number, you may choose any version ever published by
|
|
||||||
the Free Software Foundation.
|
|
||||||
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
|
||||||
programs whose distribution conditions are incompatible with these,
|
|
||||||
write to the author to ask for permission. For software which is
|
|
||||||
copyrighted by the Free Software Foundation, write to the Free
|
|
||||||
Software Foundation; we sometimes make exceptions for this. Our
|
|
||||||
decision will be guided by the two goals of preserving the free status
|
|
||||||
of all derivatives of our free software and of promoting the sharing
|
|
||||||
and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
|
||||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
||||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
|
||||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
|
||||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
|
||||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
|
||||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
||||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
|
||||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
|
||||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
||||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
|
||||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
|
||||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
|
||||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
|
||||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|
||||||
DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Appendix: How to Apply These Terms to Your New Libraries
|
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
|
||||||
possible use to the public, we recommend making it free software that
|
|
||||||
everyone can redistribute and change. You can do so by permitting
|
|
||||||
redistribution under these terms (or, alternatively, under the terms of the
|
|
||||||
ordinary General Public License).
|
|
||||||
|
|
||||||
To apply these terms, attach the following notices to the library. It is
|
|
||||||
safest to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least the
|
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the library's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
|
||||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
|
||||||
necessary. Here is a sample; alter the names:
|
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
|
||||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1990
|
|
||||||
Ty Coon, President of Vice
|
|
||||||
|
|
||||||
That's all there is to it!
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
|
|
||||||
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
|
|
||||||
/* Updated 2008 to use fread/fopen and friends instead of read/open so it compiles with GCC on Unix (Rubidium) */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
exe2aout(char *fname)
|
|
||||||
{
|
|
||||||
unsigned short header[3];
|
|
||||||
FILE *ifile;
|
|
||||||
FILE *ofile;
|
|
||||||
char buf[4096];
|
|
||||||
int rbytes;
|
|
||||||
char *dot = strrchr(fname, '.');
|
|
||||||
if (!dot || strlen(dot) != 4
|
|
||||||
|| tolower(dot[1]) != 'e'
|
|
||||||
|| tolower(dot[2]) != 'x'
|
|
||||||
|| tolower(dot[3]) != 'e')
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: Arguments MUST end with a .exe extension\n", fname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ifile = fopen(fname, "rb");
|
|
||||||
if (!ifile)
|
|
||||||
{
|
|
||||||
perror(fname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fread(header, sizeof(header), 1, ifile);
|
|
||||||
if (header[0] == 0x5a4d)
|
|
||||||
{
|
|
||||||
long header_offset = (long)header[2]*512L;
|
|
||||||
if (header[1])
|
|
||||||
header_offset += (long)header[1] - 512L;
|
|
||||||
fseek(ifile, header_offset, SEEK_SET);
|
|
||||||
header[0] = 0;
|
|
||||||
fread(header, sizeof(header), 1, ifile);
|
|
||||||
if ((header[0] != 0x010b) && (header[0] != 0x014c))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "`%s' does not have a COFF/AOUT program appended to it\n", fname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fseek(ifile, header_offset, SEEK_SET);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "`%s' is not an .EXE file\n", fname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
*dot = 0;
|
|
||||||
ofile = fopen(fname, "w+b");
|
|
||||||
if (!ofile)
|
|
||||||
{
|
|
||||||
perror(fname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((rbytes=fread(buf, 1, 4096, ifile)) > 0)
|
|
||||||
{
|
|
||||||
int wb = fwrite(buf, 1, rbytes, ofile);
|
|
||||||
if (wb < 0)
|
|
||||||
{
|
|
||||||
perror(fname);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (wb < rbytes)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "`%s': disk full\n", fname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(ifile);
|
|
||||||
fclose(ofile);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (argc == 1) printf("Usage: %s <exename>", argv[0]);
|
|
||||||
for (i=1; i<argc; i++)
|
|
||||||
exe2aout(argv[i]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# $Id$
|
|
||||||
|
|
||||||
cd `dirname $0`
|
|
||||||
cc -o exe2coff/exe2coff exe2coff/exe2coff.c || exit
|
|
||||||
cp $1 binary.exe || exit
|
|
||||||
./exe2coff/exe2coff binary.exe || exit
|
|
||||||
cat cwsdpmi/cwsdstub.exe binary > binary.exe || exit
|
|
||||||
mv binary.exe $1
|
|
||||||
rm binary exe2coff/exe2coff
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file sort_func.hpp Functions related to sorting operations. */
|
|
||||||
|
|
||||||
#ifndef SORT_FUNC_HPP
|
|
||||||
#define SORT_FUNC_HPP
|
|
||||||
|
|
||||||
#include "mem_func.hpp"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type safe qsort()
|
|
||||||
*
|
|
||||||
* @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 <typename T>
|
|
||||||
static inline 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 modified Gnome search. The basic
|
|
||||||
* Gnome search tries 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 <typename T>
|
|
||||||
static inline 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 */
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file libtimidity.cpp Playing music via the timidity library. */
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "../openttd.h"
|
|
||||||
#include "../sound_type.h"
|
|
||||||
#include "../debug.h"
|
|
||||||
#include "libtimidity.h"
|
|
||||||
#include "midifile.hpp"
|
|
||||||
#include "../base_media_base.h"
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <timidity.h>
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
/** The state of playing. */
|
|
||||||
enum MidiState {
|
|
||||||
MIDI_STOPPED = 0,
|
|
||||||
MIDI_PLAYING = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
MidIStream *stream;
|
|
||||||
MidSongOptions options;
|
|
||||||
MidSong *song;
|
|
||||||
|
|
||||||
MidiState status;
|
|
||||||
uint32 song_length;
|
|
||||||
uint32 song_position;
|
|
||||||
} _midi; ///< Metadata about the midi we're playing.
|
|
||||||
|
|
||||||
/** Factory for the libtimidity driver. */
|
|
||||||
static FMusicDriver_LibTimidity iFMusicDriver_LibTimidity;
|
|
||||||
|
|
||||||
const char *MusicDriver_LibTimidity::Start(const char * const *param)
|
|
||||||
{
|
|
||||||
_midi.status = MIDI_STOPPED;
|
|
||||||
_midi.song = NULL;
|
|
||||||
|
|
||||||
if (mid_init(param == NULL ? NULL : const_cast<char *>(param[0])) < 0) {
|
|
||||||
/* If init fails, it can be because no configuration was found.
|
|
||||||
* If it was not forced via param, try to load it without a
|
|
||||||
* configuration. Who knows that works. */
|
|
||||||
if (param != NULL || mid_init_no_config() < 0) {
|
|
||||||
return "error initializing timidity";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG(driver, 1, "successfully initialised timidity");
|
|
||||||
|
|
||||||
_midi.options.rate = 44100;
|
|
||||||
_midi.options.format = MID_AUDIO_S16LSB;
|
|
||||||
_midi.options.channels = 2;
|
|
||||||
_midi.options.buffer_size = _midi.options.rate;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicDriver_LibTimidity::Stop()
|
|
||||||
{
|
|
||||||
if (_midi.status == MIDI_PLAYING) this->StopSong();
|
|
||||||
mid_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicDriver_LibTimidity::PlaySong(const MusicSongInfo &song)
|
|
||||||
{
|
|
||||||
std::string filename = MidiFile::GetSMFFile(song);
|
|
||||||
|
|
||||||
this->StopSong();
|
|
||||||
if (filename.empty()) return;
|
|
||||||
|
|
||||||
_midi.stream = mid_istream_open_file(filename.c_str());
|
|
||||||
if (_midi.stream == NULL) {
|
|
||||||
DEBUG(driver, 0, "Could not open music file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_midi.song = mid_song_load(_midi.stream, &_midi.options);
|
|
||||||
mid_istream_close(_midi.stream);
|
|
||||||
_midi.song_length = mid_song_get_total_time(_midi.song);
|
|
||||||
|
|
||||||
if (_midi.song == NULL) {
|
|
||||||
DEBUG(driver, 1, "Invalid MIDI file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mid_song_start(_midi.song);
|
|
||||||
_midi.status = MIDI_PLAYING;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicDriver_LibTimidity::StopSong()
|
|
||||||
{
|
|
||||||
_midi.status = MIDI_STOPPED;
|
|
||||||
/* mid_song_free cannot handle NULL! */
|
|
||||||
if (_midi.song != NULL) mid_song_free(_midi.song);
|
|
||||||
_midi.song = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MusicDriver_LibTimidity::IsSongPlaying()
|
|
||||||
{
|
|
||||||
if (_midi.status == MIDI_PLAYING) {
|
|
||||||
_midi.song_position = mid_song_get_time(_midi.song);
|
|
||||||
if (_midi.song_position >= _midi.song_length) {
|
|
||||||
_midi.status = MIDI_STOPPED;
|
|
||||||
_midi.song_position = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (_midi.status == MIDI_PLAYING);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicDriver_LibTimidity::SetVolume(byte vol)
|
|
||||||
{
|
|
||||||
if (_midi.song != NULL) mid_song_set_volume(_midi.song, vol);
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file libtimidity.h Base for LibTimidity music playback. */
|
|
||||||
|
|
||||||
#ifndef MUSIC_LIBTIMIDITY_H
|
|
||||||
#define MUSIC_LIBTIMIDITY_H
|
|
||||||
|
|
||||||
#include "music_driver.hpp"
|
|
||||||
|
|
||||||
/** Music driver making use of libtimidity. */
|
|
||||||
class MusicDriver_LibTimidity : public MusicDriver {
|
|
||||||
public:
|
|
||||||
/* virtual */ const char *Start(const char * const *param);
|
|
||||||
|
|
||||||
/* virtual */ void Stop();
|
|
||||||
|
|
||||||
/* virtual */ void PlaySong(const MusicSongInfo &song);
|
|
||||||
|
|
||||||
/* virtual */ void StopSong();
|
|
||||||
|
|
||||||
/* virtual */ bool IsSongPlaying();
|
|
||||||
|
|
||||||
/* virtual */ void SetVolume(byte vol);
|
|
||||||
/* virtual */ const char *GetName() const { return "libtimidity"; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Factory for the libtimidity driver. */
|
|
||||||
class FMusicDriver_LibTimidity : public DriverFactoryBase {
|
|
||||||
public:
|
|
||||||
FMusicDriver_LibTimidity() : DriverFactoryBase(Driver::DT_MUSIC, 5, "libtimidity", "LibTimidity MIDI Driver") {}
|
|
||||||
/* virtual */ Driver *CreateInstance() const { return new MusicDriver_LibTimidity(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* MUSIC_LIBTIMIDITY_H */
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file opf_ship.cpp Implementation of the oldest supported ship pathfinder. */
|
|
||||||
|
|
||||||
#include "../../stdafx.h"
|
|
||||||
#include "../../tunnelbridge_map.h"
|
|
||||||
#include "../../tunnelbridge.h"
|
|
||||||
#include "../../ship.h"
|
|
||||||
#include "../../core/random_func.hpp"
|
|
||||||
|
|
||||||
#include "../../safeguards.h"
|
|
||||||
|
|
||||||
struct RememberData {
|
|
||||||
uint16 cur_length;
|
|
||||||
byte depth;
|
|
||||||
Track last_choosen_track;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TrackPathFinder {
|
|
||||||
TileIndex skiptile;
|
|
||||||
TileIndex dest_coords;
|
|
||||||
uint best_bird_dist;
|
|
||||||
uint best_length;
|
|
||||||
RememberData rd;
|
|
||||||
TrackdirByte the_dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool ShipTrackFollower(TileIndex tile, TrackPathFinder *pfs, uint length)
|
|
||||||
{
|
|
||||||
/* Found dest? */
|
|
||||||
if (tile == pfs->dest_coords) {
|
|
||||||
pfs->best_bird_dist = 0;
|
|
||||||
|
|
||||||
pfs->best_length = minu(pfs->best_length, length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip this tile in the calculation */
|
|
||||||
if (tile != pfs->skiptile) {
|
|
||||||
pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile));
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void TPFModeShip(TrackPathFinder *tpf, TileIndex tile, DiagDirection direction)
|
|
||||||
{
|
|
||||||
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
|
||||||
/* wrong track type */
|
|
||||||
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) return;
|
|
||||||
|
|
||||||
DiagDirection dir = GetTunnelBridgeDirection(tile);
|
|
||||||
/* entering tunnel / bridge? */
|
|
||||||
if (dir == direction) {
|
|
||||||
TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
|
|
||||||
|
|
||||||
tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1;
|
|
||||||
|
|
||||||
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
|
|
||||||
* tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail. */
|
|
||||||
tile = TILE_MASK(tile + TileOffsByDiagDir(direction));
|
|
||||||
|
|
||||||
if (++tpf->rd.cur_length > 50) return;
|
|
||||||
|
|
||||||
TrackBits bits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(direction);
|
|
||||||
if (bits == TRACK_BIT_NONE) return;
|
|
||||||
|
|
||||||
assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY());
|
|
||||||
|
|
||||||
bool only_one_track = true;
|
|
||||||
do {
|
|
||||||
Track track = RemoveFirstTrack(&bits);
|
|
||||||
if (bits != TRACK_BIT_NONE) only_one_track = false;
|
|
||||||
RememberData rd = tpf->rd;
|
|
||||||
|
|
||||||
/* Change direction 4 times only */
|
|
||||||
if (!only_one_track && track != tpf->rd.last_choosen_track) {
|
|
||||||
if (++tpf->rd.depth > 4) {
|
|
||||||
tpf->rd = rd;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tpf->rd.last_choosen_track = track;
|
|
||||||
}
|
|
||||||
|
|
||||||
tpf->the_dir = TrackEnterdirToTrackdir(track, direction);
|
|
||||||
|
|
||||||
if (!ShipTrackFollower(tile, tpf, tpf->rd.cur_length)) {
|
|
||||||
TPFModeShip(tpf, tile, TrackdirToExitdir(tpf->the_dir));
|
|
||||||
}
|
|
||||||
|
|
||||||
tpf->rd = rd;
|
|
||||||
} while (bits != TRACK_BIT_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OPFShipFollowTrack(TileIndex tile, DiagDirection direction, TrackPathFinder *tpf)
|
|
||||||
{
|
|
||||||
assert(IsValidDiagDirection(direction));
|
|
||||||
|
|
||||||
/* initialize path finder variables */
|
|
||||||
tpf->rd.cur_length = 0;
|
|
||||||
tpf->rd.depth = 0;
|
|
||||||
tpf->rd.last_choosen_track = INVALID_TRACK;
|
|
||||||
|
|
||||||
ShipTrackFollower(tile, tpf, 0);
|
|
||||||
TPFModeShip(tpf, tile, direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Directions to search towards given track bits and the ship's enter direction. */
|
|
||||||
static const DiagDirection _ship_search_directions[6][4] = {
|
|
||||||
{ DIAGDIR_NE, INVALID_DIAGDIR, DIAGDIR_SW, INVALID_DIAGDIR },
|
|
||||||
{ INVALID_DIAGDIR, DIAGDIR_SE, INVALID_DIAGDIR, DIAGDIR_NW },
|
|
||||||
{ INVALID_DIAGDIR, DIAGDIR_NE, DIAGDIR_NW, INVALID_DIAGDIR },
|
|
||||||
{ DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR, DIAGDIR_SW },
|
|
||||||
{ DIAGDIR_NW, DIAGDIR_SW, INVALID_DIAGDIR, INVALID_DIAGDIR },
|
|
||||||
{ INVALID_DIAGDIR, INVALID_DIAGDIR, DIAGDIR_SE, DIAGDIR_NE },
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Track to "direction (& 3)" mapping. */
|
|
||||||
static const byte _pick_shiptrack_table[6] = {DIR_NE, DIR_SE, DIR_E, DIR_E, DIR_N, DIR_N};
|
|
||||||
|
|
||||||
static uint FindShipTrack(const Ship *v, TileIndex tile, DiagDirection dir, TrackBits bits, TileIndex skiptile, Track *track)
|
|
||||||
{
|
|
||||||
TrackPathFinder pfs;
|
|
||||||
uint best_bird_dist = 0;
|
|
||||||
uint best_length = 0;
|
|
||||||
byte ship_dir = v->direction & 3;
|
|
||||||
|
|
||||||
pfs.dest_coords = v->dest_tile;
|
|
||||||
pfs.skiptile = skiptile;
|
|
||||||
|
|
||||||
Track best_track = INVALID_TRACK;
|
|
||||||
|
|
||||||
assert(bits != TRACK_BIT_NONE);
|
|
||||||
do {
|
|
||||||
Track i = RemoveFirstTrack(&bits);
|
|
||||||
|
|
||||||
pfs.best_bird_dist = UINT_MAX;
|
|
||||||
pfs.best_length = UINT_MAX;
|
|
||||||
|
|
||||||
OPFShipFollowTrack(tile, _ship_search_directions[i][dir], &pfs);
|
|
||||||
|
|
||||||
if (best_track != INVALID_TRACK) {
|
|
||||||
if (pfs.best_bird_dist != 0) {
|
|
||||||
/* neither reached the destination, pick the one with the smallest bird dist */
|
|
||||||
if (pfs.best_bird_dist > best_bird_dist) goto bad;
|
|
||||||
if (pfs.best_bird_dist < best_bird_dist) goto good;
|
|
||||||
} else {
|
|
||||||
if (pfs.best_length > best_length) goto bad;
|
|
||||||
if (pfs.best_length < best_length) goto good;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we reach this position, there's two paths of equal value so far.
|
|
||||||
* pick one randomly. */
|
|
||||||
uint r = GB(Random(), 0, 8);
|
|
||||||
if (_pick_shiptrack_table[i] == ship_dir) r += 80;
|
|
||||||
if (_pick_shiptrack_table[best_track] == ship_dir) r -= 80;
|
|
||||||
if (r <= 127) goto bad;
|
|
||||||
}
|
|
||||||
good:;
|
|
||||||
best_track = i;
|
|
||||||
best_bird_dist = pfs.best_bird_dist;
|
|
||||||
best_length = pfs.best_length;
|
|
||||||
bad:;
|
|
||||||
|
|
||||||
} while (bits != TRACK_BIT_NONE);
|
|
||||||
|
|
||||||
*track = best_track;
|
|
||||||
return best_bird_dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the best track to choose on the next tile and
|
|
||||||
* returns INVALID_TRACK when it is better to reverse.
|
|
||||||
* @param v The ship.
|
|
||||||
* @param tile The tile we are about to enter.
|
|
||||||
* @param enterdir The direction entering the tile.
|
|
||||||
* @param tracks The tracks available on new tile.
|
|
||||||
* @param[out] path_found Whether a path has been found.
|
|
||||||
* @return Best track on next tile or INVALID_TRACK when better to reverse.
|
|
||||||
*/
|
|
||||||
Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)
|
|
||||||
{
|
|
||||||
assert(IsValidDiagDirection(enterdir));
|
|
||||||
|
|
||||||
TileIndex tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir));
|
|
||||||
Track track;
|
|
||||||
|
|
||||||
/* Let's find out how far it would be if we would reverse first */
|
|
||||||
uint rev_dist = UINT_MAX; // distance if we reverse
|
|
||||||
Track cur_track = TrackdirToTrack(v->GetVehicleTrackdir()); // track on the current tile
|
|
||||||
DiagDirection rev_enterdir = ReverseDiagDir(enterdir);
|
|
||||||
TrackBits rev_tracks = TrackStatusToTrackBits(GetTileTrackStatus(tile2, TRANSPORT_WATER, 0)) &
|
|
||||||
DiagdirReachesTracks(rev_enterdir);
|
|
||||||
|
|
||||||
if (HasTrack(rev_tracks, cur_track)) {
|
|
||||||
rev_dist = FindShipTrack(v, tile2, rev_enterdir, TrackToTrackBits(cur_track), tile, &track);
|
|
||||||
if (rev_dist != UINT_MAX) rev_dist++; // penalty for reversing
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And if we would not reverse? */
|
|
||||||
uint dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track);
|
|
||||||
|
|
||||||
/* Due to the way this pathfinder works we cannot determine whether we're lost or not. */
|
|
||||||
path_found = true;
|
|
||||||
if (dist <= rev_dist) return track;
|
|
||||||
return INVALID_TRACK; // We could better reverse
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file opf_ship.h Original pathfinder for ships; very simple. */
|
|
||||||
|
|
||||||
#ifndef OPF_SHIP_H
|
|
||||||
#define OPF_SHIP_H
|
|
||||||
|
|
||||||
#include "../../direction_type.h"
|
|
||||||
#include "../../tile_type.h"
|
|
||||||
#include "../../track_type.h"
|
|
||||||
#include "../../vehicle_type.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the best path for given ship using OPF.
|
|
||||||
* @param v the ship that needs to find a path
|
|
||||||
* @param tile the tile to find the path from (should be next tile the ship is about to enter)
|
|
||||||
* @param enterdir diagonal direction which the ship will enter this new tile from
|
|
||||||
* @param tracks available tracks on the new tile (to choose from)
|
|
||||||
* @param path_found [out] Whether a path has been found (true) or has been guessed (false)
|
|
||||||
* @return the best trackdir for next turn or INVALID_TRACK if the path could not be found
|
|
||||||
*/
|
|
||||||
Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found);
|
|
||||||
|
|
||||||
#endif /* OPF_SHIP_H */
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file thread.h Base of all threads. */
|
|
||||||
|
|
||||||
#ifndef THREAD_H
|
|
||||||
#define THREAD_H
|
|
||||||
|
|
||||||
/** Definition of all thread entry functions. */
|
|
||||||
typedef void (*OTTDThreadFunc)(void *);
|
|
||||||
|
|
||||||
/** Signal used for signalling we knowingly want to end the thread. */
|
|
||||||
class OTTDThreadExitSignal { };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Thread Object which works on all our supported OSes.
|
|
||||||
*/
|
|
||||||
class ThreadObject {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Virtual destructor to allow 'delete' operator to work properly.
|
|
||||||
*/
|
|
||||||
virtual ~ThreadObject() {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Exit this thread.
|
|
||||||
*/
|
|
||||||
virtual bool Exit() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Join this thread.
|
|
||||||
*/
|
|
||||||
virtual void Join() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a thread; proc will be called as first function inside the thread,
|
|
||||||
* with optional params.
|
|
||||||
* @param proc The procedure to call inside the thread.
|
|
||||||
* @param param The params to give with 'proc'.
|
|
||||||
* @param thread Place to store a pointer to the thread in. May be NULL.
|
|
||||||
* @param name A name for the thread. May be NULL.
|
|
||||||
* @return True if the thread was started correctly.
|
|
||||||
*/
|
|
||||||
static bool New(OTTDThreadFunc proc, void *param, ThreadObject **thread = NULL, const char *name = NULL);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cross-platform Mutex
|
|
||||||
*/
|
|
||||||
class ThreadMutex {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Create a new mutex.
|
|
||||||
*/
|
|
||||||
static ThreadMutex *New();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Virtual Destructor to avoid compiler warnings.
|
|
||||||
*/
|
|
||||||
virtual ~ThreadMutex() {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Begin the critical section
|
|
||||||
* @param allow_recursive Whether recursive locking is intentional.
|
|
||||||
* If false, NOT_REACHED() will be called when the mutex is already locked
|
|
||||||
* by the current thread.
|
|
||||||
*/
|
|
||||||
virtual void BeginCritical(bool allow_recursive = false) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End of the critical section
|
|
||||||
* @param allow_recursive Whether recursive unlocking is intentional.
|
|
||||||
* If false, NOT_REACHED() will be called when the mutex was locked more
|
|
||||||
* than once by the current thread.
|
|
||||||
*/
|
|
||||||
virtual void EndCritical(bool allow_recursive = false) = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wait for a signal to be send.
|
|
||||||
* @pre You must be in the critical section.
|
|
||||||
* @note While waiting the critical section is left.
|
|
||||||
* @post You will be in the critical section.
|
|
||||||
*/
|
|
||||||
virtual void WaitForSignal() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a signal and wake the 'thread' that was waiting for it.
|
|
||||||
*/
|
|
||||||
virtual void SendSignal() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple mutex locker to keep a mutex locked until the locker goes out of scope.
|
|
||||||
*/
|
|
||||||
class ThreadMutexLocker {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Lock the mutex and keep it locked for the life time of this object.
|
|
||||||
* @param mutex Mutex to be locked.
|
|
||||||
*/
|
|
||||||
ThreadMutexLocker(ThreadMutex *mutex) : mutex(mutex) { mutex->BeginCritical(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unlock the mutex.
|
|
||||||
*/
|
|
||||||
~ThreadMutexLocker() { this->mutex->EndCritical(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadMutexLocker(const ThreadMutexLocker &) { NOT_REACHED(); }
|
|
||||||
ThreadMutexLocker &operator=(const ThreadMutexLocker &) { NOT_REACHED(); return *this; }
|
|
||||||
ThreadMutex *mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get number of processor cores in the system, including HyperThreading or similar.
|
|
||||||
* @return Total number of processor cores.
|
|
||||||
*/
|
|
||||||
uint GetCPUCoreCount();
|
|
||||||
|
|
||||||
#endif /* THREAD_H */
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file thread_morphos.cpp MorphOS implementation of Threads. */
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "thread.h"
|
|
||||||
#include "../debug.h"
|
|
||||||
#include "../core/alloc_func.hpp"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <exec/types.h>
|
|
||||||
#include <exec/rawfmt.h>
|
|
||||||
#include <dos/dostags.h>
|
|
||||||
|
|
||||||
#include <proto/dos.h>
|
|
||||||
#include <proto/exec.h>
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* avoid name clashes with MorphOS API functions
|
|
||||||
*/
|
|
||||||
#undef Exit
|
|
||||||
#undef Wait
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NOTE: this code heavily depends on latest libnix updates. So make
|
|
||||||
* sure you link with new stuff which supports semaphore locking of
|
|
||||||
* the IO resources, else it will just go foobar.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
struct OTTDThreadStartupMessage {
|
|
||||||
struct Message msg; ///< standard exec.library message (MUST be the first thing in the message struct!)
|
|
||||||
OTTDThreadFunc func; ///< function the thread will execute
|
|
||||||
void *arg; ///< functions arguments for the thread function
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default OpenTTD STDIO/ERR debug output is not very useful for this, so we
|
|
||||||
* utilize serial/ramdebug instead.
|
|
||||||
*/
|
|
||||||
void KPutStr(CONST_STRPTR format)
|
|
||||||
{
|
|
||||||
RawDoFmt(format, NULL, (void (*)())RAWFMTFUNC_SERIAL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MorphOS version for ThreadObject.
|
|
||||||
*/
|
|
||||||
class ThreadObject_MorphOS : public ThreadObject {
|
|
||||||
private:
|
|
||||||
APTR m_thr; ///< System thread identifier.
|
|
||||||
struct MsgPort *m_replyport;
|
|
||||||
struct OTTDThreadStartupMessage m_msg;
|
|
||||||
bool self_destruct;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Create a sub process and start it, calling proc(param).
|
|
||||||
*/
|
|
||||||
ThreadObject_MorphOS(OTTDThreadFunc proc, void *param, self_destruct) :
|
|
||||||
m_thr(0), self_destruct(self_destruct)
|
|
||||||
{
|
|
||||||
struct Task *parent;
|
|
||||||
|
|
||||||
KPutStr("[OpenTTD] Create thread...\n");
|
|
||||||
|
|
||||||
parent = FindTask(NULL);
|
|
||||||
|
|
||||||
/* Make sure main thread runs with sane priority */
|
|
||||||
SetTaskPri(parent, 0);
|
|
||||||
|
|
||||||
/* Things we'll pass down to the child by utilizing NP_StartupMsg */
|
|
||||||
m_msg.func = proc;
|
|
||||||
m_msg.arg = param;
|
|
||||||
|
|
||||||
m_replyport = CreateMsgPort();
|
|
||||||
|
|
||||||
if (m_replyport != NULL) {
|
|
||||||
struct Process *child;
|
|
||||||
|
|
||||||
m_msg.msg.mn_Node.ln_Type = NT_MESSAGE;
|
|
||||||
m_msg.msg.mn_ReplyPort = m_replyport;
|
|
||||||
m_msg.msg.mn_Length = sizeof(struct OTTDThreadStartupMessage);
|
|
||||||
|
|
||||||
child = CreateNewProcTags(
|
|
||||||
NP_CodeType, CODETYPE_PPC,
|
|
||||||
NP_Entry, ThreadObject_MorphOS::Proxy,
|
|
||||||
NP_StartupMsg, (IPTR)&m_msg,
|
|
||||||
NP_Priority, 5UL,
|
|
||||||
NP_Name, (IPTR)"OpenTTD Thread",
|
|
||||||
NP_PPCStackSize, 131072UL,
|
|
||||||
TAG_DONE);
|
|
||||||
|
|
||||||
m_thr = (APTR) child;
|
|
||||||
|
|
||||||
if (child != NULL) {
|
|
||||||
KPutStr("[OpenTTD] Child process launched.\n");
|
|
||||||
} else {
|
|
||||||
KPutStr("[OpenTTD] Couldn't create child process. (constructors never fail, yeah!)\n");
|
|
||||||
DeleteMsgPort(m_replyport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ ~ThreadObject_MorphOS()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ bool Exit()
|
|
||||||
{
|
|
||||||
struct OTTDThreadStartupMessage *msg;
|
|
||||||
|
|
||||||
/* You can only exit yourself */
|
|
||||||
assert(IsCurrent());
|
|
||||||
|
|
||||||
KPutStr("[Child] Aborting...\n");
|
|
||||||
|
|
||||||
if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) {
|
|
||||||
/* For now we terminate by throwing an error, gives much cleaner cleanup */
|
|
||||||
throw OTTDThreadExitSignal();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void Join()
|
|
||||||
{
|
|
||||||
struct OTTDThreadStartupMessage *reply;
|
|
||||||
|
|
||||||
/* You cannot join yourself */
|
|
||||||
assert(!IsCurrent());
|
|
||||||
|
|
||||||
KPutStr("[OpenTTD] Join threads...\n");
|
|
||||||
KPutStr("[OpenTTD] Wait for child to quit...\n");
|
|
||||||
WaitPort(m_replyport);
|
|
||||||
|
|
||||||
GetMsg(m_replyport);
|
|
||||||
DeleteMsgPort(m_replyport);
|
|
||||||
m_thr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ bool IsCurrent()
|
|
||||||
{
|
|
||||||
return FindTask(NULL) == m_thr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* On thread creation, this function is called, which calls the real startup
|
|
||||||
* function. This to get back into the correct instance again.
|
|
||||||
*/
|
|
||||||
static void Proxy()
|
|
||||||
{
|
|
||||||
struct Task *child = FindTask(NULL);
|
|
||||||
struct OTTDThreadStartupMessage *msg;
|
|
||||||
|
|
||||||
/* Make sure, we don't block the parent. */
|
|
||||||
SetTaskPri(child, -5);
|
|
||||||
|
|
||||||
KPutStr("[Child] Progressing...\n");
|
|
||||||
|
|
||||||
if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) {
|
|
||||||
try {
|
|
||||||
msg->func(msg->arg);
|
|
||||||
} catch(OTTDThreadExitSignal e) {
|
|
||||||
KPutStr("[Child] Returned to main()\n");
|
|
||||||
} catch(...) {
|
|
||||||
NOT_REACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Quit the child, exec.library will reply the startup msg internally. */
|
|
||||||
KPutStr("[Child] Done.\n");
|
|
||||||
|
|
||||||
if (self_destruct) delete this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name)
|
|
||||||
{
|
|
||||||
ThreadObject *to = new ThreadObject_MorphOS(proc, param, thread == NULL);
|
|
||||||
if (thread != NULL) *thread = to;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file thread_none.cpp No-Threads-Available implementation of Threads */
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "thread.h"
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name)
|
|
||||||
{
|
|
||||||
if (thread != NULL) *thread = NULL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Mutex that doesn't do locking because it ain't needed when there're no threads */
|
|
||||||
class ThreadMutex_None : public ThreadMutex {
|
|
||||||
public:
|
|
||||||
virtual void BeginCritical(bool allow_recursive = false) {}
|
|
||||||
virtual void EndCritical(bool allow_recursive = false) {}
|
|
||||||
virtual void WaitForSignal() {}
|
|
||||||
virtual void SendSignal() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ ThreadMutex *ThreadMutex::New()
|
|
||||||
{
|
|
||||||
return new ThreadMutex_None();
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file thread_os2.cpp OS/2 implementation of Threads. */
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "thread.h"
|
|
||||||
|
|
||||||
#define INCL_DOS
|
|
||||||
#include <os2.h>
|
|
||||||
#include <process.h>
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OS/2 version for ThreadObject.
|
|
||||||
*/
|
|
||||||
class ThreadObject_OS2 : public ThreadObject {
|
|
||||||
private:
|
|
||||||
TID thread; ///< System thread identifier.
|
|
||||||
OTTDThreadFunc proc; ///< External thread procedure.
|
|
||||||
void *param; ///< Parameter for the external thread procedure.
|
|
||||||
bool self_destruct; ///< Free ourselves when done?
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Create a thread and start it, calling proc(param).
|
|
||||||
*/
|
|
||||||
ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) :
|
|
||||||
thread(0),
|
|
||||||
proc(proc),
|
|
||||||
param(param),
|
|
||||||
self_destruct(self_destruct)
|
|
||||||
{
|
|
||||||
thread = _beginthread(stThreadProc, NULL, 1048576, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ bool Exit()
|
|
||||||
{
|
|
||||||
_endthread();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void Join()
|
|
||||||
{
|
|
||||||
DosWaitThread(&this->thread, DCWW_WAIT);
|
|
||||||
this->thread = 0;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* On thread creation, this function is called, which calls the real startup
|
|
||||||
* function. This to get back into the correct instance again.
|
|
||||||
*/
|
|
||||||
static void stThreadProc(void *thr)
|
|
||||||
{
|
|
||||||
((ThreadObject_OS2 *)thr)->ThreadProc();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A new thread is created, and this function is called. Call the custom
|
|
||||||
* function of the creator of the thread.
|
|
||||||
*/
|
|
||||||
void ThreadProc()
|
|
||||||
{
|
|
||||||
/* Call the proc of the creator to continue this thread */
|
|
||||||
try {
|
|
||||||
this->proc(this->param);
|
|
||||||
} catch (OTTDThreadExitSignal e) {
|
|
||||||
} catch (...) {
|
|
||||||
NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self_destruct) {
|
|
||||||
this->Exit();
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name)
|
|
||||||
{
|
|
||||||
ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL);
|
|
||||||
if (thread != NULL) *thread = to;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OS/2 version of ThreadMutex.
|
|
||||||
*/
|
|
||||||
class ThreadMutex_OS2 : public ThreadMutex {
|
|
||||||
private:
|
|
||||||
HMTX mutex; ///< The mutex.
|
|
||||||
HEV event; ///< Event for waiting.
|
|
||||||
uint recursive_count; ///< Recursive lock count.
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadMutex_OS2() : recursive_count(0)
|
|
||||||
{
|
|
||||||
DosCreateMutexSem(NULL, &mutex, 0, FALSE);
|
|
||||||
DosCreateEventSem(NULL, &event, 0, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ ~ThreadMutex_OS2()
|
|
||||||
{
|
|
||||||
DosCloseMutexSem(mutex);
|
|
||||||
DosCloseEventSem(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void BeginCritical(bool allow_recursive = false)
|
|
||||||
{
|
|
||||||
/* os2 mutex is recursive by itself */
|
|
||||||
DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT);
|
|
||||||
this->recursive_count++;
|
|
||||||
if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void EndCritical(bool allow_recursive = false)
|
|
||||||
{
|
|
||||||
if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
|
|
||||||
this->recursive_count--;
|
|
||||||
DosReleaseMutexSem(mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void WaitForSignal()
|
|
||||||
{
|
|
||||||
assert(this->recursive_count == 1); // Do we need to call Begin/EndCritical multiple times otherwise?
|
|
||||||
this->EndCritical();
|
|
||||||
DosWaitEventSem(event, SEM_INDEFINITE_WAIT);
|
|
||||||
this->BeginCritical();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void SendSignal()
|
|
||||||
{
|
|
||||||
DosPostEventSem(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ ThreadMutex *ThreadMutex::New()
|
|
||||||
{
|
|
||||||
return new ThreadMutex_OS2();
|
|
||||||
}
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file thread_pthread.cpp POSIX pthread implementation of Threads. */
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "thread.h"
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include "../os/macosx/macos.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* POSIX pthread version for ThreadObject.
|
|
||||||
*/
|
|
||||||
class ThreadObject_pthread : public ThreadObject {
|
|
||||||
private:
|
|
||||||
pthread_t thread; ///< System thread identifier.
|
|
||||||
OTTDThreadFunc proc; ///< External thread procedure.
|
|
||||||
void *param; ///< Parameter for the external thread procedure.
|
|
||||||
bool self_destruct; ///< Free ourselves when done?
|
|
||||||
const char *name; ///< Name for the thread
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Create a pthread and start it, calling proc(param).
|
|
||||||
*/
|
|
||||||
ThreadObject_pthread(OTTDThreadFunc proc, void *param, bool self_destruct, const char *name) :
|
|
||||||
thread(0),
|
|
||||||
proc(proc),
|
|
||||||
param(param),
|
|
||||||
self_destruct(self_destruct),
|
|
||||||
name(name)
|
|
||||||
{
|
|
||||||
pthread_create(&this->thread, NULL, &stThreadProc, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ bool Exit()
|
|
||||||
{
|
|
||||||
assert(pthread_self() == this->thread);
|
|
||||||
/* For now we terminate by throwing an error, gives much cleaner cleanup */
|
|
||||||
throw OTTDThreadExitSignal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void Join()
|
|
||||||
{
|
|
||||||
/* You cannot join yourself */
|
|
||||||
assert(pthread_self() != this->thread);
|
|
||||||
pthread_join(this->thread, NULL);
|
|
||||||
this->thread = 0;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* On thread creation, this function is called, which calls the real startup
|
|
||||||
* function. This to get back into the correct instance again.
|
|
||||||
*/
|
|
||||||
static void *stThreadProc(void *thr)
|
|
||||||
{
|
|
||||||
ThreadObject_pthread *self = (ThreadObject_pthread *) thr;
|
|
||||||
#if defined(__GLIBC__)
|
|
||||||
#if __GLIBC_PREREQ(2, 12)
|
|
||||||
if (self->name) {
|
|
||||||
pthread_setname_np(pthread_self(), self->name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
MacOSSetThreadName(self->name);
|
|
||||||
#endif
|
|
||||||
self->ThreadProc();
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A new thread is created, and this function is called. Call the custom
|
|
||||||
* function of the creator of the thread.
|
|
||||||
*/
|
|
||||||
void ThreadProc()
|
|
||||||
{
|
|
||||||
/* Call the proc of the creator to continue this thread */
|
|
||||||
try {
|
|
||||||
this->proc(this->param);
|
|
||||||
} catch (OTTDThreadExitSignal) {
|
|
||||||
} catch (...) {
|
|
||||||
NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self_destruct) {
|
|
||||||
pthread_detach(pthread_self());
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name)
|
|
||||||
{
|
|
||||||
ThreadObject *to = new ThreadObject_pthread(proc, param, thread == NULL, name);
|
|
||||||
if (thread != NULL) *thread = to;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* POSIX pthread version of ThreadMutex.
|
|
||||||
*/
|
|
||||||
class ThreadMutex_pthread : public ThreadMutex {
|
|
||||||
private:
|
|
||||||
pthread_mutex_t mutex; ///< The actual mutex.
|
|
||||||
pthread_cond_t condition; ///< Data for conditional waiting.
|
|
||||||
pthread_mutexattr_t attr; ///< Attributes set for the mutex.
|
|
||||||
pthread_t owner; ///< Owning thread of the mutex.
|
|
||||||
uint recursive_count; ///< Recursive lock count.
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadMutex_pthread() : owner(0), recursive_count(0)
|
|
||||||
{
|
|
||||||
pthread_mutexattr_init(&this->attr);
|
|
||||||
pthread_mutexattr_settype(&this->attr, PTHREAD_MUTEX_ERRORCHECK);
|
|
||||||
pthread_mutex_init(&this->mutex, &this->attr);
|
|
||||||
pthread_cond_init(&this->condition, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ ~ThreadMutex_pthread()
|
|
||||||
{
|
|
||||||
int err = pthread_cond_destroy(&this->condition);
|
|
||||||
assert(err != EBUSY);
|
|
||||||
err = pthread_mutex_destroy(&this->mutex);
|
|
||||||
assert(err != EBUSY);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsOwnedByCurrentThread() const
|
|
||||||
{
|
|
||||||
return this->owner == pthread_self();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void BeginCritical(bool allow_recursive = false)
|
|
||||||
{
|
|
||||||
/* pthread mutex is not recursive by itself */
|
|
||||||
if (this->IsOwnedByCurrentThread()) {
|
|
||||||
if (!allow_recursive) NOT_REACHED();
|
|
||||||
} else {
|
|
||||||
int err = pthread_mutex_lock(&this->mutex);
|
|
||||||
assert(err == 0);
|
|
||||||
assert(this->recursive_count == 0);
|
|
||||||
this->owner = pthread_self();
|
|
||||||
}
|
|
||||||
this->recursive_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void EndCritical(bool allow_recursive = false)
|
|
||||||
{
|
|
||||||
assert(this->IsOwnedByCurrentThread());
|
|
||||||
if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
|
|
||||||
this->recursive_count--;
|
|
||||||
if (this->recursive_count != 0) return;
|
|
||||||
this->owner = 0;
|
|
||||||
int err = pthread_mutex_unlock(&this->mutex);
|
|
||||||
assert(err == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void WaitForSignal()
|
|
||||||
{
|
|
||||||
uint old_recursive_count = this->recursive_count;
|
|
||||||
this->recursive_count = 0;
|
|
||||||
this->owner = 0;
|
|
||||||
int err = pthread_cond_wait(&this->condition, &this->mutex);
|
|
||||||
assert(err == 0);
|
|
||||||
this->owner = pthread_self();
|
|
||||||
this->recursive_count = old_recursive_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void SendSignal()
|
|
||||||
{
|
|
||||||
int err = pthread_cond_signal(&this->condition);
|
|
||||||
assert(err == 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ ThreadMutex *ThreadMutex::New()
|
|
||||||
{
|
|
||||||
return new ThreadMutex_pthread();
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
/* $Id$ */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of OpenTTD.
|
|
||||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
||||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file thread_win32.cpp Win32 thread implementation of Threads. */
|
|
||||||
|
|
||||||
#include "../stdafx.h"
|
|
||||||
#include "thread.h"
|
|
||||||
#include "../debug.h"
|
|
||||||
#include "../core/alloc_func.hpp"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <process.h>
|
|
||||||
#include "../os/windows/win32.h"
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Win32 thread version for ThreadObject.
|
|
||||||
*/
|
|
||||||
class ThreadObject_Win32 : public ThreadObject {
|
|
||||||
private:
|
|
||||||
HANDLE thread; ///< System thread identifier.
|
|
||||||
uint id; ///< Thread identifier.
|
|
||||||
OTTDThreadFunc proc; ///< External thread procedure.
|
|
||||||
void *param; ///< Parameter for the external thread procedure.
|
|
||||||
bool self_destruct; ///< Free ourselves when done?
|
|
||||||
const char *name; ///< Thread name.
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Create a win32 thread and start it, calling proc(param).
|
|
||||||
*/
|
|
||||||
ThreadObject_Win32(OTTDThreadFunc proc, void *param, bool self_destruct, const char *name) :
|
|
||||||
thread(NULL),
|
|
||||||
id(0),
|
|
||||||
proc(proc),
|
|
||||||
param(param),
|
|
||||||
self_destruct(self_destruct),
|
|
||||||
name(name)
|
|
||||||
{
|
|
||||||
this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id);
|
|
||||||
if (this->thread == NULL) return;
|
|
||||||
ResumeThread(this->thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ ~ThreadObject_Win32()
|
|
||||||
{
|
|
||||||
if (this->thread != NULL) {
|
|
||||||
CloseHandle(this->thread);
|
|
||||||
this->thread = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ bool Exit()
|
|
||||||
{
|
|
||||||
assert(GetCurrentThreadId() == this->id);
|
|
||||||
/* For now we terminate by throwing an error, gives much cleaner cleanup */
|
|
||||||
throw OTTDThreadExitSignal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void Join()
|
|
||||||
{
|
|
||||||
/* You cannot join yourself */
|
|
||||||
assert(GetCurrentThreadId() != this->id);
|
|
||||||
WaitForSingleObject(this->thread, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* On thread creation, this function is called, which calls the real startup
|
|
||||||
* function. This to get back into the correct instance again.
|
|
||||||
*/
|
|
||||||
static uint CALLBACK stThreadProc(void *thr)
|
|
||||||
{
|
|
||||||
((ThreadObject_Win32 *)thr)->ThreadProc();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A new thread is created, and this function is called. Call the custom
|
|
||||||
* function of the creator of the thread.
|
|
||||||
*/
|
|
||||||
void ThreadProc()
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
/* Set thread name for debuggers. Has to be done from the thread due to a race condition in older MS debuggers. */
|
|
||||||
SetWin32ThreadName(-1, this->name);
|
|
||||||
#endif
|
|
||||||
try {
|
|
||||||
this->proc(this->param);
|
|
||||||
} catch (OTTDThreadExitSignal) {
|
|
||||||
} catch (...) {
|
|
||||||
NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self_destruct) delete this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name)
|
|
||||||
{
|
|
||||||
ThreadObject *to = new ThreadObject_Win32(proc, param, thread == NULL, name);
|
|
||||||
if (thread != NULL) *thread = to;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Win32 thread version of ThreadMutex.
|
|
||||||
*/
|
|
||||||
class ThreadMutex_Win32 : public ThreadMutex {
|
|
||||||
private:
|
|
||||||
CRITICAL_SECTION critical_section; ///< The critical section we would enter.
|
|
||||||
HANDLE event; ///< Event for signalling.
|
|
||||||
uint recursive_count; ///< Recursive lock count.
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThreadMutex_Win32() : recursive_count(0)
|
|
||||||
{
|
|
||||||
InitializeCriticalSection(&this->critical_section);
|
|
||||||
this->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ ~ThreadMutex_Win32()
|
|
||||||
{
|
|
||||||
DeleteCriticalSection(&this->critical_section);
|
|
||||||
CloseHandle(this->event);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void BeginCritical(bool allow_recursive = false)
|
|
||||||
{
|
|
||||||
/* windows mutex is recursive by itself */
|
|
||||||
EnterCriticalSection(&this->critical_section);
|
|
||||||
this->recursive_count++;
|
|
||||||
if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void EndCritical(bool allow_recursive = false)
|
|
||||||
{
|
|
||||||
if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
|
|
||||||
this->recursive_count--;
|
|
||||||
LeaveCriticalSection(&this->critical_section);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void WaitForSignal()
|
|
||||||
{
|
|
||||||
assert(this->recursive_count == 1); // Do we need to call Begin/EndCritical multiple times otherwise?
|
|
||||||
this->EndCritical();
|
|
||||||
WaitForSingleObject(this->event, INFINITE);
|
|
||||||
this->BeginCritical();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* virtual */ void SendSignal()
|
|
||||||
{
|
|
||||||
SetEvent(this->event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* static */ ThreadMutex *ThreadMutex::New()
|
|
||||||
{
|
|
||||||
return new ThreadMutex_Win32();
|
|
||||||
}
|
|
||||||
@@ -48,7 +48,6 @@ public:
|
|||||||
StringID string; ///< String ID of item
|
StringID string; ///< String ID of item
|
||||||
|
|
||||||
DropDownListStringItem(StringID string, int result, bool masked) : DropDownListItem(result, masked), string(string) {}
|
DropDownListStringItem(StringID string, int result, bool masked) : DropDownListItem(result, masked), string(string) {}
|
||||||
virtual ~DropDownListStringItem() {}
|
|
||||||
|
|
||||||
bool Selectable() const override { return true; }
|
bool Selectable() const override { return true; }
|
||||||
uint Width() const override;
|
uint Width() const override;
|
||||||
@@ -99,7 +98,6 @@ public:
|
|||||||
uint64 decode_params[10]; ///< Parameters of the string
|
uint64 decode_params[10]; ///< Parameters of the string
|
||||||
|
|
||||||
DropDownListParamStringItem(StringID string, int result, bool masked) : DropDownListStringItem(string, result, masked) {}
|
DropDownListParamStringItem(StringID string, int result, bool masked) : DropDownListStringItem(string, result, masked) {}
|
||||||
virtual ~DropDownListParamStringItem() {}
|
|
||||||
|
|
||||||
StringID String() const override;
|
StringID String() const override;
|
||||||
void SetParam(uint index, uint64 value) { decode_params[index] = value; }
|
void SetParam(uint index, uint64 value) { decode_params[index] = value; }
|
||||||
@@ -113,7 +111,6 @@ public:
|
|||||||
const char *raw_string;
|
const char *raw_string;
|
||||||
|
|
||||||
DropDownListCharStringItem(const char *raw_string, int result, bool masked) : DropDownListStringItem(STR_JUST_RAW_STRING, result, masked), raw_string(raw_string) {}
|
DropDownListCharStringItem(const char *raw_string, int result, bool masked) : DropDownListStringItem(STR_JUST_RAW_STRING, result, masked), raw_string(raw_string) {}
|
||||||
virtual ~DropDownListCharStringItem() {}
|
|
||||||
|
|
||||||
StringID String() const override;
|
StringID String() const override;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user