diff --git a/tnl-1.5.0/README b/tnl-1.5.0/README new file mode 100644 index 0000000000000000000000000000000000000000..7ad48989a24a0aa52d89193be748e7e6431266ce --- /dev/null +++ b/tnl-1.5.0/README @@ -0,0 +1 @@ +This directory holds the complete distribution of TNL 1.5.0 from SourceForge. We will use it as reference during the process of separating the Torque Network Library and the Torque Network Platform. This directory will be removed when the first stable version of TNL 2.0 is released. diff --git a/tnl-1.5.0/tnl/LICENSE.txt b/tnl-1.5.0/tnl/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..855b2a2a63ebee051c5dec9e934cc1c0e2804777 --- /dev/null +++ b/tnl-1.5.0/tnl/LICENSE.txt @@ -0,0 +1,126 @@ +The GNU General Public License (GPL) +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 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. + +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) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General Public License instead of this License. \ No newline at end of file diff --git a/tnl-1.5.0/tnl/Makefile b/tnl-1.5.0/tnl/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..e0a2574fe8001e3f40819f9994fa7e10cb6b9045 --- /dev/null +++ b/tnl-1.5.0/tnl/Makefile @@ -0,0 +1,19 @@ +default: + @$(MAKE) -C tnl + @$(MAKE) -C libtomcrypt + @$(MAKE) -C master + @$(MAKE) -C masterclient + @$(MAKE) -C test + +.PHONY: clean + +clean: + @$(MAKE) -C tnl clean + @$(MAKE) -C libtomcrypt clean + @$(MAKE) -C master clean + @$(MAKE) -C masterclient clean + @$(MAKE) -C test clean + +docs: + @$(MAKE) -C docs + diff --git a/tnl-1.5.0/tnl/ReadMe.html b/tnl-1.5.0/tnl/ReadMe.html new file mode 100644 index 0000000000000000000000000000000000000000..03fda833f4a298c6b0fcf33f76ab798d1ec2fc97 --- /dev/null +++ b/tnl-1.5.0/tnl/ReadMe.html @@ -0,0 +1,115 @@ + + +Torque Network Library Readme + + + +

Torque Network Library

+

Readme

+
(c) GarageGames 2004
+ +

Introduction

+ +

Developing computational simulations is a complex, interdisciplinary undertaking. To take a simulation of any sort and run it in a distributed environment introduces a whole new world of problems to overcome. The Torque Network Library provides a robust framework for message passing and efficient state replication, built on a UDP-based protocol.

+ +

Features

+ + + +

Compiling TNL

+ +

OSX/Xcode

+ +

Under the osx subdirectory there is an XCode project. It is set up to build TNL and the TNLTest app.

+ +

Linux/GCC

+ +

From the top level directory, type

+ +make + +

If you have OpenGL and wxWindows installed, and OpenGL support enabled in wxWindows, you can build the wxgui test client/server program with

+ +cd test && make wxgui + +

The wxgui is not built by default. + +

Windows/VC6/VC7

+ +

There are VC6 and VC7 project workspaces in the root directory of the checkout. Individual project files are in their respective directories.

+ +

Documentation and Online Resources

+ +

The TNL comes with extensive Doxygen documentation. You can access this documentation online at Some URL, or generate it by downloading Doxygen from www.doxygen.org and executing the following command line (assuming you installed Doxygen in the standard place) from the root of your TNL checkout...

+ + + +

This will produce a set of Doxygen docs in the docs\html subdirectory of your TNL checkout. Please note that these docs may ONLY be distributed to other TNL licensees.

+ + + \ No newline at end of file diff --git a/tnl-1.5.0/tnl/cwPrefixWin32.h b/tnl-1.5.0/tnl/cwPrefixWin32.h new file mode 100644 index 0000000000000000000000000000000000000000..c373e5ec778df5573c00758a63c7f8758af96d64 --- /dev/null +++ b/tnl-1.5.0/tnl/cwPrefixWin32.h @@ -0,0 +1,11 @@ +// prefix include file for Metrowerks CodeWarrior + +#define TNL_DEBUG + +// enable to have TNL asserts or logging +//#define TNL_ENABLE_ASSERTS +//#define TNL_ENABLE_LOGGING + +// You might also want to call TNLLogEnable(xyz, true) to enable special +// logging output. xyz could be LogNetConnection, LogNetConnection, e.t.c. +// See tnlLog.h for more logging targets. diff --git a/tnl-1.5.0/tnl/docs/Makefile b/tnl-1.5.0/tnl/docs/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8fb5d400e87ff7b77dda105da8c0e543bc9c79fa --- /dev/null +++ b/tnl-1.5.0/tnl/docs/Makefile @@ -0,0 +1,26 @@ +default: tree html + +tree: doxytree.html.cfg + @echo --- Building docs... + cd .. && doxygen docs/doxytree.html.cfg + @echo --- Copying images... + cp -r images doxytree + rm -rf doxytree/images/CVS + @echo --- Applying frameset patch... + echo `cp -v tree_overlay/* doxytree` + @echo --- Pushing docs live... + mv ../../../htdocs/doxytree ./tmp1 + mv -fv doxytree ../../../htdocs/ + rm -rf ./tmp1 + +html: doxygen.html.cfg + @echo --- Building docs... + cd .. && doxygen docs/doxygen.html.cfg + @echo --- Copying images... + cp -r images doxydocs + rm -rf doxydocs/images/CVS + @echo --- Pushing docs live... + mv ../../../htdocs/doxydocs ./tmp2 + mv -fv doxydocs ../../../htdocs/ + rm -rf ./tmp2 + diff --git a/tnl-1.5.0/tnl/docs/doco.css b/tnl-1.5.0/tnl/docs/doco.css new file mode 100644 index 0000000000000000000000000000000000000000..c1f79abc1b659a9ee9abeef86268ada2a55d2f31 --- /dev/null +++ b/tnl-1.5.0/tnl/docs/doco.css @@ -0,0 +1,382 @@ +.article a { color: #8D0000; font-weight: bold; text-decoration: none } +.article a:visited { color: #AAAAAA; } +.article a:hover { text-decoration: underline; } + +a { color: #8D0000; font-weight: bold; text-decoration: none } +a:visited { color: #AAAAAA; } +a:hover { text-decoration: underline; } + +a.code { + color: #4444EE; + font-weight: normal; + text-decoration: none; +} + +a.coderef { + color: #4444EE; + font-weight: normal; +} + +a:link { + color: #900000; + text-decoration: underline; +} + +a:visited { + color: #900000; + text-decoration: underline; +} + +a:hover { + color: #B52010; + color: #B52010; + text-decoration: underline; +} + +a.code{ + color: #900000; + font-weight: normal; + text-decoration: underline; +} + +a.coderef{ + color: #436976; + font-weight: normal; +} + +a.el { + font-weight: normal; + text-decoration: underline; +} + +a.qindex{ + font-weight: normal; + white-space: nowrap; +} + +a.qindexhl, a.qindexrefhl { + color: #FFFFFF; + font-weight: bold; + text-decoration: none; +} + +a.qindexref{ +} + +body { + background: #FFFFFF; + color: #000000; + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 75%; + margin: 0; +} + +caption, a.elref { + font-weight: bold; +} + +div.ah { + background-color: #000000; + color: #FFFFFF; + font-weight: bold; + margin-bottom: 3px; + margin-top: 3px; +} + +div.footer{ + background: #B0C2D7; + border: 1px solid #436976; + color: #000000; + font-style: normal; + margin-top: 5em; + padding-bottom: 3px; + text-align: center; +} + +div.fragment{ + background: #FFFFDD; + border: 1px solid #CCCCCC; + margin-bottom: 1em; + margin-top: 1em; + padding-left: 1em; + padding-right: 1em; +} + +DIV.fragment { + width: 95%; + background-color: #f0f0f0; + border: 1px solid black; + padding: 5px; + margin-left: 10px; + margin-right: 10px; + font-size: 150%; +} + +div.groupheader{ + border-bottom: 1px solid #557E8C; + font-weight: bold; + margin-bottom: 6px; + margin-left: 16px; + margin-top: 12px; +} + +div.grouptext{ + font-style: italic; + margin-left: 16px; +} + +div.header{ + background: #B0C2D7; + border: 1px solid #436976; + color: #000000; + font-style: normal; + margin-bottom: 1em; + padding-bottom: 3px; + padding-left: 10px; + text-align: left; + text-transform: lowercase; +} + +div.header a, div.footer a{ + color: #436976; + font-size: 90%; + margin-right: 1em; + font-weight: normal; + white-space: nowrap; +} + +div.header a:visited, div.footer a:visited { + color: #325865; +} + +div.header a:hover, div.footer a:hover, a.anchor:hover { + color: #A41005; + text-decoration: none; +} + +div.index { + padding-right: 10px; + text-align: center; +} + +div.maindox { + margin: 2%; + width: 96%; +} + +div.nav { + float: left; +} + +div.qindex { + background-color: #EEEEFF; + border: 4px solid #EEEEFF; + margin-bottom: 2px; + text-align: center; + width: 100%; +} + +dl.el { + margin-left: -1cm; +} + +font.charliteral, span.charliteral { + color: #008080; +} + +font.comment, span.comment { + color: #00A000; +} + +font.keyword, span.keyword { + color: #0000FF; +} + +font.keywordflow, span.keywordflow { + color: #0080F0; +} + +font.keywordtype, span.keywordtype { + color: #0000D0; +} + +font.preprocessor, span.preprocessor { + color: #FF7000; +} + +font.stringliteral, span.stringliteral { + color: #002080; +} + +h1{ + font-size: 220%; + text-align: center; +} + +h2{ + border-bottom: 2px solid #557E8C; + font-size: 170%; +} + +hr { + border: 1px solid #000000; +} + +img.formuladsp { +} + +img.formulainl { + vertical-align: middle; +} + +p.formuladsp { + text-align: center; +} + +td { + font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; + font-size: 75%; +} + +td.indexkey{ + background: #EEEEFF; + font-weight: bold; + margin: 2px 0px; + padding: 2px 10px; +} + +td.indexvalue{ + background: #EEEEFF; + font-style: italic; + margin: 2px 0px; + padding: 2px 10px; +} + +td.md{ + font-weight: bold; + font-size: 85%; +} + +td.mdname, td.mdname1 { + color: #FF9900; + font-weight: bold; + font-size: 85%; +} + +tr.memlist { + background-color: #F0F0F0; +} + +ul { + list-style-type: square; +} + +.mdrow { + padding: 1ex 1em; + font-size: 85%; +} + +.mdtable { + background: #F0F0FA; + margin-bottom: 1ex; +} + +.mdescleft { + background-color: #F0F0FA; + margin: 0px; + padding-left: 8px; +} + +.mdescright { + background-color: #F0F0FA; + font-style: italic; + margin: 0px; + padding-bottom: 0px; + padding-left: 4px; + padding-right: 8px; + width: 100%; +} + +.memitemleft { + background-color: #F0F0FA; + border-top: 2px solid #FFFFFF; + font-size: 85%; + margin: 4px; + padding: 1px 0px 0px 8px; +} + +.memitemright { + background-color: #F0F0FA; + border-top: 2px solid #FFFFFF; + font-size: 85%; + margin: 4px; + padding: 1px 0px 0px 8px; +} + + +/* CSS Document */ +body { + background-color: #FFFFFF; + font-family: Arial, Helvetica, sans-serif; + font-size: 8pt; + color: Black; +} + +hr { + color: #333366; + background-color:transparent +} +i, em { font-style: italic; } +b, strong { font-weight:bold; } +.tiny { font-size: 7pt; } +.grey { + font-size: 8pt; + color: #909090; + background-color:transparent +} + +h1,h2,h3,h4 { color:black; background-color:transparent; font-weight:bold; margin-top:.25em;margin-bottom:.25em } +h1 { font-size:200%; } +h2 { font-size:150%; } +h3 { font-size:120%; } +h4 { font-size:100%; } + + +/* Article Style ----------------*/ +/*-------------------------------*/ +.article { + vertical-align:top; + text-align:left; + font-size: 12px; + color:black; + background-color: #FFFFFF; + padding-top: 4px; + padding-right: 4px; + padding-bottom: 0px; + padding-left: 4px; +} + +.article .title { + vertical-align:top; + background-color: #1A1B4D; + text-align:left; + font-weight: bold; + color: white; + padding:2px 2px 2px 6px; +} + +.article .body { + text-align:left; + border-width:2px; + border-style:solid; + border-color:#1A1B4D; + background-color: white; + color: black; + padding:3px; +} + +.article .freetext { + padding:5px; + font-size: 8px; +} + diff --git a/tnl-1.5.0/tnl/docs/docs.plaintext.txt b/tnl-1.5.0/tnl/docs/docs.plaintext.txt new file mode 100644 index 0000000000000000000000000000000000000000..e5556aef8db9a147dae7ee87f485d8f2380fa26e --- /dev/null +++ b/tnl-1.5.0/tnl/docs/docs.plaintext.txt @@ -0,0 +1,519 @@ +Preface + +The Torque Network Library is a networking API designed to allow developers to easily add world-class multiuser simulation capabilities to their products. The TNL has proven successful in some of the most demanding multiplayer internet games and has gone through years of steady, evolutionary improvement. + +Scope of This Documentation + +Getting Started gives new users the information they need to download TNL source files, set up projects on supported compilers, and build and run the library and example programs. + +History of the TNL gives a brief history of the Torque Network Library from its origins as the network technology behind Sierra/Dynamix's Starsiege: TRIBES to its current status as a standalone network programming solution. + +Introduction to Network Programming Concepts introduces the developer to some of the basic concepts of network programming, including fundamental limitations of data networks, standard protocols, application network topologies, security and the hurdles the TNL will help them overcome in providing a consistent simulation on an unreliable communications medium. + +Introduction to the Torque Network Library Fundamentals describes the general strategies used in the TNL to overcome the inherent limitations of today's networks. + +Torque Network Library Architecture gives an overview of the major classes in the TNL, from the basic Socket layer to the advanced state replication facilities provided by the GhostConnection and NetObject layer. + +Torque Network Library Tutorials and Examples walks the developer through the sample programs provided with the TNL, including a simple, networked "Hello World!" program, the TNLTest graphical multiuser simulation and the master server and masterclient test program. + +We presume the reader is familiar with C++ programming and concepts. + +Acknowledgments +Tom St. Denis - libtomcrypt + +Ari Juels and John Brainard for their work on Client Puzzles. + +Tuomas Aura, Pekka Nikander, and Jussipekka Leiwo of the Helsinki University of Technology for their work on DoS resistant Authenticat with Client Puzzles + + +Getting Started + +Getting started with the Torque Network Library is a fairly simple process. + +1. Get a CVS client for your computer (What is CVS?) + Download WinCVS 1.3 for Windows systems + Download MacCVSX for computers running Mac OS X + Download CVS for linux/unix systems + +2. Use CVS to download the current version of the TNL + Downloading TNL using WinCVS + Downloading TNL using MaxCVSX + Downloading TNL using CVS + +3. Build TNL using your C++ compiler + Build TNL using Microsoft Visual C++ 6.0 + Build TNL using Microsoft Visual Studio .NET 2003 + Build TNL using XCode on Mac OS X + Build TNL using make on linux + +4. Run the example programs + TNLTest - the simple TNL example "game" + master and masterclient - an example master server for listing game servers + +Troubleshooting and Questions + +If you have any difficulties or questions downloading, building and running TNL or the example programs, check the FAQ first to see if an answer to your problem already exists. If that doesn't help, you can search or ask in the TNL Private Forums for assistance. + + +What is CVS +Getting CVS +Downloading CVS +Building TNL +Running example programs + + +With that overview complete, you should now have a working version of the Torque Network Library and its sample programs up and running on your computer. + +History of the Torque Network Library + +Near the end of 1997, a team of developers at Dynamix were hard at work on a new, network only game that would push the requirements of internet gaming technology to a new level. Starsiege: TRIBES allowed up to 32 players to compete in seamless indoor and outdoor areas with futuristic weapons, jet packs and vehicles. + +Unlike other games at the time that were limited to tight indoor environments, the TRIBES environment posed a more difficult set of networking problems. Because of their open nature, clients in the game could often see most of the other players, along with a large number of projecticles and simulated vehicles, turrets and other objects. Also, given the state of most internet connections at the time, it was decided that TRIBES must run well even over a 28.8 kbps modem, imposing a meager 2 Kbytes per second of bandwidth limitation on each client. + +With these requirements in mind, Mark Frohnmayer, Rick Overman and Tim Gift designed a network architecture that would maximize the information value of every bit transmitted over the network, and created a new "Notify" protocol that harnessed the unreliable nature of the network transport medium to eliminate unnecessary retransmission of information. + +The Tribes Network Architecture was further refined during the development of Tribes 2 to server more players (up to 100 in a single gaming area served by a 1GHz Pentium III) and save even more packet data space, introducing the concept of a network string table and only periodic control object state updating during client-side prediction. + +When the Tribes 2 engine became GarageGames' Torque Game Engine, additional iterative improvements were made, including checksums on client state data and a new network interface class to encapsulate the connection startup and prevent connection depletion Denial-of-Service attacks. + +The final step in the history of the Torque Network Library was to refactor its constituent parts into a standalone network technology that didn't require any other components from the Torque Game Engine. As a part of this process, significant library structural improvements were made; every class and class member were documented, and strong encryption support was added. Other new features include a simple and powerful Remote Procedure Call (RPC) mechanism, client puzzles for protecting servers from server CPU depletion Denial-of-Service attacks, and 3rd-party negotiated direct connections to connect clients behind firewalls and NAT (Network Address Translation) routers, making TNL a robust, full-featured, secure networking solution for a wide variety of applications. + + +Introduction to Network Programming Concepts + +Computer networking technology allows computers that share the network to send messages to one another. Computer networks vary greatly in complexity, from two machines connected together with a link cable, to the globe-spanning internet connecting millions of machines together over fiber-optics, satellite links, phone lines and other mediums. + +Fundamental Limitations of Computer Networks + +Computer networks of any size share some common limitations to varying degrees that must be accounted for in network simulations, with the internet being the most limited in all three regards. These three fundamental problems in network simulation are: + +Limited Bandwidth - There is a limit to the rate at which hosts on the network can send data to one another. If a computer is connected to the network with a 56 kbps modem, this might be 5 Kbytes per second, while computers on a local area network might be able to communicate at 128 megabytes per second. For service providers, additional bandwidth capacity can be costly, so even if there is no physical bandwidth limitation, bandwidth conservation is important for many projects. + +Packet Loss - Computer networks are inherently unreliable. Information transmitted over a network may become corrupted in transit, or may be dropped at a router where traffic has become congested. Even when (especially when) using a guaranteed message delivery protocol such as TCP, the unreliable nature of the underlying network still must be taken into account for network applications. + +Latency - Messages sent from one host to another on the network take time to arrive at the destination. The time can be influenced by many factors, including the medium over which the messages travel, how many intermediate hosts must route the message, an the level of traffic congestion at each of those network nodes. Latency becomes particularly problematic in network simulations that attempt to present a real-time interface to the client, when the latency of the connection may be perceptible in time. + +Standard Network Protocols + +When computers communicate over networks, they send and receive data using specific network protocols. These protocols ensure that the computers are using the same specifications to address, forward and process data on the network. The internet, certainly the most widely used computer network today, uses a stack of three primary protocols that facilitate communication over the network. They are: + +IP - Internet Protocol: The Internet Protocol is the basic building block for internet communications. IP is a routing protocol, which means that it is used to route information packets from a source host to a destination host, specified by an IP address. IP packets are not guaranteed to arrive at the destination specified by the sender, and those packets that do arrive are not guaranteed to arrive in the order they were sent. IP packet payloads may also be corrupted when they are delivered. IP is not useful as an application protocol - it is used mainly as a foundation for the higher level TCP and UDP protocols. + +UDP - User Datagram Protocol: The User Datagram Protocol supplies a thin layer on top of IP that performs error detection and application level routing on a single host. UDP packets are addressed using both an IP address to specify the physical host, and a port number, to specify which process on the machine the packet should be delivered to. UDP packets also contain a checksum, so that corrupted packets can be discarded. UDP packets that are corrupted or dropped by an intermediate host are not retransmitted by the sender, because the sender is never notified whether a given packet was delivered or not. + +TCP/IP - Transmission Control Protocol: TCP was designed to make internet programming easier by building a reliable, connection-based protocol on top of the unreliable IP. TCP does this by sending acknowledgements when data packets arrive, and resending data that was dropped. TCP is a stream protocol, so the network connection can be treated like any other file stream in the system. TCP is not suitable for simulation data, because any dropped packets will stall the data pipeline until the dropped data can be retransmitted. + +Network Protocols and TNL + +Some network systems use both TCP and UDP - TCP for messages that must arrive, but are not time sensitive, and UDP for time-sensitive simulation updates. The next chapter discusses why this is not optimal for bandwidth conservation, and explains the protocol solution implemented in TNL. + +Berkeley (BSD) Sockets - the standard network API + +The BSD Sockets API describes a set of C language interface routines for communicating using the TCP protocol suite, including IP and UDP. The sockets API allows processes to open communcation "sockets" that can then be assigned to a particular integer port number on the host. + +Sockets created to use the TCP stream protocol can either be set to "listen()" for connections from remote hosts, or can be set to "connect()" to a remote host that is currently listening for incoming connections. Once a connection is established between two stream sockets, either side can send and receive guaranteed data to the other. + +Sockets can also be created in datagram mode, in which case they will use the underlying UDP protocol for transmission of datagram packets. Since the datagram socket mode is connectionless, the destination IP address and port must be specified with each data packet sent. + +The socket API contains other utility routines for performing operations such as host name resolution and socket options configuration. The Microsoft Windows platform supplies a Windows socket API called Winsock that implements the BSD socket API. + +Application Network Topologies + +Networked applications can be designed to communicate with each other using different topological organization strategies. Some common communcations organization paradigms are discussed below. + +Peer-to-Peer: In a peer-to-peer network application, the client processes involved in the network communicate directly with one another. Though there may be one or more hosts with authoritative control over the network of peers, peer-to-peer applications largely distribute the responsibility for the simulation or application amongst the peers. + +Client-Server: In the client-server model, one host on the network, the server, acts as a central communications hub for all the other hosts (the clients). Typically the server is authoritative, and is responsible for routing communication between the several clients. + +Client-Tiered Server Cluster: In network applications where more clients want to subscribe to a service than can be accomodated by one server, the server's role will be handled by a cluster of servers peered together. The servers in the network communicate using the peer-to-peer model, and communicate with the clients using the client-server model. The servers may also communicate with an authoritative "super-server" to handle logins or resolve conflicts. + +TNL imposes no specific network topology on applications using it. + +Security and Encryption + +When a message is sent between two hosts on a network, that message may pass through any number of intermediate wires, hosts and routers or even sent wirelessly to a satellite or a WiFi base station. This opens up the potential that some third party who has access to any one of the intermediate communication forwarding points may eavesdrop on and/or change the contents of the message. Often networked applications send sensitive user data, like credit card numbers, bank account information or private correspondence. These applications rely on encryption algorithms to protect messages sent over an unsecure network. + +Symmetric Encryption + +Symmetric Encryption algorithms operate under the assumption that the two parties sending messages to each other share a common, secret key. This key is used to encode the data in such a way that only users with the secret key can decode it. In the ideal case, the ciphertext (encoded version of the message) looks like a random string of bits to any eavesdropper. + +There are many Symmetric Encryption algorithms of varying levels of security, but all of them when used alone have several drawbacks. First, both parties to the communication must have a copy of the shared secret key. If a client is attempting to communicate with a service it has never contacted before, and doesn't share a key with, it won't be able to communicate securely with it. Also, although an intermediate eavesdropper cannot read the data sent between the hosts, it can alter the messages, potentially causing one or more of the systems to fail. + +Message Authentication + +In order to detect when a message has been altered by a third party, a secure messaging system will send a message authentication code (MAC) along with the data. The MAC is generated using a cryptographically secure hashing function, such as MD5 or SHA. Secure hash algorithms take an array of bytes and compute a cryptographically secure message digest of some fixed number of bytes - 16 in the case of MD5, 32 for SHA-256 and so on. + +When a message is sent using a symmetric cipher, the hash or some portion of it is encrypted and sent along as well. Any changes in the message will cause the hash algorithm to compute a different hash than that which is encrypted and included with the message, notifying the receiving party that the message has been tampered with. + +Public Key Cryptography and Key Exchange + +Public Key Cryptography algorithms were invented to solve the symmetric key distribution problem. In public key algorithms, each participant in the communication has a key pair composed of a public key and a private key. The theory of public keys suggests that a message encrypted with the public key can only be decrypted with the private key and vice-versa. + +Key exchange algorithms (Diffie-Helman, ECDH) have certain properties such that two users, A and B can share their public keys with each other in plain text, and then, using each other's public key and their own private keys they can generate the same shared secret key. Eavesdroppers can see the public keys, but, because the private keys are never transmitted, cannot know the shared secret. Because public key algorithms are computationally much more expensive than symmetric cryptography, network applications generally use public key cryptography to share a secret key that is then used as a symmetric cipher key. + +Digital Signatures/Certificate Authorization + +Public key algorithms still have one vulnerability, known as the Man-in-the-Middle attack. Basically, an eavesdropper in the communication between A and B can intercept the public keys in transit and substitute its own public key, thereby establishing a secure connection with A and B - decrypting incoming data and reencrypting it with its shared key to the opposite party. + +To combat this attack, the concept of certificates was introduced. In this model, the public key of one or both of the participants in the communication is digitally signed with the private key of some known, trusted Certificate Authority (CA). Then, using the Certificate Authority's public key, the parties to the communication can validate the public key of the opposite parties. + +Security and the TNL + +The TNL uses the publicly available libtomcrypt (http://libtomcrypt.org) as its encryption foundation. The TNL features key exchange, secret session keys, message authentication and certificate verification. See <> for more information. + +More Information on Cryptography + +The preceding sections were only a very high level overview of some cryptographic algorithm theories. For more information, see the USENET cryptography FAQ at http://www.faqs.org/faqs/cryptography-faq/ + +Additional Challenges Facing Network Programmers + +Malicious Attackers and Denial of Service + +A problem facing developers of internet applications and web sites are Denial-of-Service attacks. Malicious users employing custom tools often attempt to shut down publicly available internet servers. There are a variety of well-known categories of DoS attacks. + +Traffic flooding: This attack sends a barrage of data to the public address of the server, in an attempt to overwhelm that server's connection to the internet. This attack often employs many machines, hijacked by the attacker and acting in concert. These attacks are often the most difficult to mount since they require a large number of available machines with high-speed internet access in order to attack a remote host effectively. + +Connection depletion: The connection depletion attack works by exploting a weakness of some connection based communications protocols. Connection depletion attacks work by initiating a constant flow of spurious connection attempts. When a legitimate user attempts to connect to the server, all available pending connection slots are already taken up by the spoofed connection attempts, thereby denying service to valid clients. + +Server CPU depletion: If the server performs public key cryptography as part of the connection sequence, a malicious client could be constructed to initiate bogus connection attempts in an effort to initiate many CPU intesive cryptographic operations on the server. + +The TNL uses a two-phase connection protocol to protect against connection depletion attacks, and implements a client-puzzle algorithm to prevent CPU depletion attacks. Also, TNL is built so that bogus packets are discarded as quickly as possible, preventing flooding attacks from impacting the server CPU. + +Firewalls and Network Address Translation (NAT) routers + +Firewalls are software or hardware devices designed to protect local networks from malicious external attackers. Most firewalls filter all incoming, unsolicited network traffic. NAT routers exist to allow potentially many machines to share a single IP address, but for practical purposes they share similar characteristics with firewalls, by often filtering out unsolicited network traffic. + +In client/server applications, firewalls and NATs aren't generally a problem. When a client behind a firewall or NAT makes a request to the server, the response is allowed to pass through the firewall or NAT because the network traffic was solicited first by the client. + +In peer-to-peer applications, NATs and firewalls pose a greater challenge. if both peers are behind different firewalls, then getting them to communicate to each other requires that they both initiate the connection in order for the other's data to be able to flow through the firewall or NAT. This can be facilitated by a third party server or client that both are able to communicate with directly. + +The TNL provides functionality for arranging a direct connection between two firewalled hosts via a third party master server. See chapter <> for more information. + +Torque Network Library Design Fundamentals + +The Torque Network Library was designed to overcome, as much as possible, the three fundamental limitations of network programming - high packet latency, limited bandwidth and packet loss. The following strategies were identified for each of the limitations: + +Bandwidth conservation + +Bandwidth conservation in multiuser simulations is of premium importance, not only for clients that may be connected over very low bandwidth transports, but also for servers whose operators have to pay for bandwidth usage. Realizing this, the following techniques are used to conserve bandwidth as much as possible: + +Send static data once, or not at all: Often in a networked application, a server will transmit some amount of static data to a client. This data may be initialization parameters for a 3D world, a client's name, or some object state that is immutable for objects of a given type. TNL provides direct facilities for caching string data (client names, mission descriptions, etc), sending a given string only once and an integer representation thereafter. The Torque Game Engine also shows how simulations can cache common object instance data in DataBlock objects, which are transmitted only when a client connects. + +Compress data to the minimum space necessary: When conserving bandwidth, every bit counts. TNL uses a utility class call BitStream to write standard data types into a packet compressed to the minimum number of bits necessary for that data. Boolean values are written as a single bit, integer writes can specify the bit field width, and floating point values can be specified as 0 to 1 compressed to a specified bit count. The BitStream also implements Huffman compression of string data and compression of 3D positions and surface normals. + +Only send information that is relevant to the client: In a client/server simulation, the server often has information that is not relevant at all to some or all of the clients. For example, in a 3D world, if an object is outside the visible distance of a given client, there is no reason to consume valuable packet space describing that object to the client. The TNL allows the application level code to easily specify which objects are relevant, or "in scope" for each client. + +Prioritize object updates: Because bandwidth is limited and there is generally a much greater amount of data a server could send to a given client than it has capacity for, the TNL implements a very fine-grained prioritization scheme for updating objects. User code can determine the policy by which objects are judged to be more or less "important" to each client in the simulation, and objects with more importance are updated with a greater frequency. + +Only update the parts of an object that have changed: Often in a networked simulation, not all object state is updated at the same time - for exampe, a player in a 3D action game may have state that includes the player's current position, velocity, health and ammunition. If the player moves, only the position and velocity states will change, so sending the full state, including the health and ammunition values would waste space unnecessarily. The TNL allows objects individual objects to have state that are updated independently of one another. + +Coping with Packet Loss + +In any networked simulation, packet loss will be a consideration - whether because of network congestion, hardware failure or software defects, some packets will inevitably be lost. One solution to the packet loss problem is to use a guaranteed messaging protocol like TCP/IP. Unfortunately, TCP has some behavioral characteristics that make it a poor choice for real-time networked simulations. + +TCP guarantees that all data sent over the network will arrive, and will arrive in order. This means that if a data packet sent using TCP is dropped in transit, the sending host must retransmit that data before any additional data, that may have already arrived at the remote host, can be processed. In practice this can mean a complete stall of ANY communications for several seconds. Also, TCP may be retransmitting data that is not important from the point of view of the simulation - holding up data that is. + +The other possible protocol choice would be to use UDP for time critical, but unguaranteed data, and use TCP only for data that will not hold up the real-time aspects of the simulation. This solution ends up being non-optimal for several reasons. First, maintaining two communications channels increases the complexity of the networking component. If an object is sent to a client using the guaranteed channel, unguaranteed messages sent to that object at a later time may arrive for processing before the original guaranteed send. Also, because the unguaranteed channel may lose information, the server will have to send more redundant data, with greater frequency. + +To solve these problems, TNL implements a new network protocol that fits somewhere between UDP and TCP in its feature set. This protocol, dubbed the "Notify" protocol, does not attempt to hide the underlying unreliability of the network as TCP does, but at the same time it provides more information to the application than straight UDP. The notify protocol is a connection-oriented unreliable communication protocol with packet delivery notification. When a datagram packet is sent from one process, that process will eventually be notified as to whether that datagram was received or not. Each data packet is sent with a packet header that includes acknowledgement information about packets the sending process has received from the remote process. This negates the need for seperate acknowledgement packets, thereby conserving additional bandwidth. + +The notify protocol foundation allows the TNL to provide a rich set of data transmission policies. Rather than simply grouping data as either guaranteed or unguaranteed, the TNL allows at least five different categorizations of data: + +Guaranteed Ordered data: Guaranteed Ordered data are data that would be sent using a guaranteed delivery protocol like TCP. Messages indicating clients joining a simulation, text messages between clients, and many other types of information would fall into this category. In TNL, Guaranteed Ordered data are sent using Event objects and RPC method calls. When the notify protocol determines that a packet containing guaranteed ordered data was lost, it requeues the data to be sent in a future packet. + +Guaranteed data: TNL processes Guaranteed data is in a way similar to Guaranteed Ordered data, with the only difference being that a client can process Guaranteed data as soon as it arrives, rather than waiting for any ordered data to arrive that was dropped. + +Unguaranteed data: Unguaranteed data is sent, and if the packet it is sent in arrives, is processed. If a packet containing unguaranteed data events is dropped, that data is not resent. The unguaranteed data sending policy could be used for information like real-time voice communication, where a retransmitted voice fragment would be useless. + +Current State data: For many objects in a simulation, the client isn't concerned with "intervening" states of an object on the server, but only its current state. For example, in a 3D action game, if an enemy player moves from point A to B to C, another client in the simulation is only interested in the final position, C of the object. With the notify protocol, TNL is able to resend object state from a dropped packet only if that state was not updated in a subsequent packet. + +Quickest Delivery data: Some information sent in a simulation is of such importance that it must be delivered as quickly as possible. In this situation, data can be sent with every packet until the remote host acknowledges any of the packets known to contain the data. Client movement information is an example of data that might be transmitted using this policy. + +By implementing various data delivery policies, the TNL is able to optimize packet space utilization in high packet loss environments. + +Strategies for Dealing With Latency + +Latency is a function of the time-based limitations of physical data networks. The time it takes information to travel from one host to another is dependent on many factors, and can definitely affect the user's perceptions of what is happening in the simulation. + +For example, in a client-server 3D simulation, suppose the round-trip time between one client and server is 250 milliseconds. If the client is observing an object that is moving. If the server is sending position updates of the object to the client, those positions will be "out of date" by 125 milliseconds by the time they arrive on the client. Also, suppose that the server is sending packets to the client at a rate of 10 packets per second. When the next update for the object arrives at the client, it may have moved a large distance relative to the perceptions of the client. + +Also, if the server is considered to be authoritative over the client's own position in the world, the client would have to wait at least a quarter of a second before its inputs were validated and reflected in its view of the world. This gives the appearance of very perceptible input "lag" on the client. + +In the worst case, the client would always see an out of date version of the server's world, as objects moved they would "pop" from one position to another, and each keypress wouldn't be reflected until a quarter of a second later. For most real-time simulations, this behavior is not optimal. + +Because TNL is predominantly a data transport and connection management API, it doesn't provide facilities for solving these problems directly. TNL provides a simple mechanism for computing the average round-trip time of a connection from which the following solutions to connection latency issues can be implemented: + +Interpolation: Interpolation is used to smoothly move an object from where the client thinks it is to where the server declares it to be over some short period of time. Parameters like position and rotation can be interpolated using linear or cubic interpolation to present a consistent, no "pop" view of the world to the client. The downside of interpolation when used alone is that it actually exacerbates the time difference between the client and the server, because the client is spending even more time than the one-way message time to move the object from its current position to the known server position. + +Extrapolation: To solve the problem of out-of-date state information, extrapolation can be employed. Extrapolation is a best guess of the current state of an object, given a known past state. For example, suppose a player object has a last known position and velocity. Rather than placing the player at the server's stated position, the player object can be placed at the position extrapolated forward by velocity times the time difference. + +In the Torque Game Engine, player objects controlled by other clients are simulated using both interpolation and extrapolation. When a player update is received from the server, the client extrapolates that position forward using the player's velocity and the sum of the time it will use to interpolate and the one-way message time from the server - essentially, the player interpolates to an extrapolated position. Once it has reached the extrapolated end point, the player will continue to extrapolate new positions until another update of the obect is received from the server. + +By using interpolation and extrapolation, the client view can be made to reasonably, smoothly approximate the world of the server, but neither approach is sufficient for real-time objects that are directly controlled by player input. To solve this third, more difficult problem, client-side prediction is employed. + +Client-side prediction is similar to extrapolation, in that the client is attempting to guess the server state of an object the server has authority over. In the case of simple extrapolation, however, the client doesn't have the benefit of the actual input data. Client-side prediction uses the inputs of the user to make a better guess about where the client-controlled object will be. Basically, the client performs the exact same object simulation as the server will eventually perform on that client's input data. As long as the client-controlled object is not acted upon by forces on the server that don't exist on the client or vice versa, the client and server state information for the object should perfectly agree. When they don't agree, interpolation can be employed to smoothly move the client object to the known server position and client-side prediction can be continued. + + +Torque Network Library Archtectural Overview + +The Torque Network Library is built in layers, each adding more functionality to the layer below it. + +The Platform Layer + +At the lowest level, TNL provides a platform independent interface to operating system functions. The platform layer includes functions for querying system time, sleeping the current process and displaying alerts. The platform layer includes wrappers for all of the C standard library functions used in the TNL. + +The platform layer also contains the Socket and Address classes, which provide a cross-platform, simplified interface to datagram sockets and network addresses. + +The NetBase Layer + +The NetBase layer is the foundation upon which most of the classes in TNL are based. At the root of the class hierarchy is the Object base class. Every subclass of Object is associated with an instance of NetClassRep through a set of macros, allowing for instances of that class to be constructed by a class name string or by an automatically assigned class id. + +This id-based instantiation allows objects subclassed from NetEvent and NetObject to be serialized into data packets, transmitted, constructed on a remote host and deserialized. + +Object also has two helper template classes, SafePtr, which provides safe object pointers that become NULL when the referenced object is deleted, and a reference pointer class, RefPtr, that automatically deletes a referenced object when all the references to it are destructed. + +The BitStream and PacketStream classes + +The BitStream class presents a stream interface on top of a buffer of bytes. BitStream provides standard read and write functions for the various TNL basic data types, including integers, characters and floating point values. BitStream also allows fields to be written as bit-fields of specific size. An integer that is always between 3 and 9 inclusive can be written using only 3 bits using the writeRangedU32 method, for example. + +BitStream huffman encodes string data for additional space savings, and provides methods for compressing 3D points and normals, as routines for writing arbitrary buffers of bits. + +The PacketStream subclass of BitStream is simply a thin interface that statically allocates space up to the maximum size of a UDP packet. A routine can declare a stack allocated PacketStream instance, write data into it and send it to a remote address with just a few lines of code. + +The NetInterface and NetConnection Layer + +The NetInterface class wraps a platform Socket instance and manages the set of NetConnection instances that are communicating through that socket. NetInterface is manages the two-phase connection initiation process, dispatch of protocol packets to NetConnection objects, and provides a generic interface for subclasses to define and process their own unconnected datagram packets. + +The NetConnection class implements the connected Notify Protocol layered on UDP. NetConnection manages packet send rates, writes and decodes packet headers, and notifies subclasses when previously sent packets are known to be either received or dropped. + +NetInterface instances can be set to use a public/private key pair for creating secure connections. In order to prevent attackers from depleting server CPU resources, the NetItnerface issues a cryptographically difficult "client puzzle" to each host attempting to connect to the server. Client puzzles have the property that they can be made arbitrarily difficult for the client to solve, but whose solutions can be checked by the server in a trivial amount of time. This way, when a server is under attack from many connection attempts, it can increase the difficulty of the puzzle it issues to connecting clients. + +The ConnectionParameters structure maintains all of the information needed by the NetInterface to negotiate the startup phase of a NetConnection. + +The Event Layer - EventConnection, NetEvent and Remote Procedure Calls + +The EventConnection class subclasses NetConnection to provide several different types of data transmission policies. EventConnection uses the NetEvent class to encapsulate event data to be sent to remote hosts. Subclasses of NetEvent are responsible for serializing and deserializing themselves into BitStreams, as well as processing event data in the proper sequence. + +NetEvent subclasses can use one of three data guarantee policies. They can be declared as GuaranteedOrdered, for ordered, reliable message delivery; Guaranteed, for reliable but possibly out of order delivery, or Unguaranteed, for ordered but not guaranteed messaging. The EventConnection class uses the notify protocol to requeue dropped events for retransmission, and orders the invocations of the events' process methods if ordered processing is requested. + +Because declaring an individual NetEvent subclass for each type of message and payload to be sent over the network, with its corresponding pack, unpack and process routines, can be somewhat tedious, TNL provides a Remote Procedure Call (RPC) framework. Using some macro magic, argument list parsing and a little assembly language, methods in EventConnection subclasses can be declared as RPC methods. When called from C++, the methods construct an event containing the argument data passed to the function and send it to the remote host. When the event is unpacked and processed, the body of the RPC method implementation is executed. + +Ghosting - GhostConnection and NetObject + +The GhostConnection class subclasses EventConnection in order to provide the most-recent and partial object state data update policies. Instances of the NetObject class and its subclasses can be replicated over a connection from one host to another. The GhostConnection class manages the relationship between the original object, and its "ghost" on the client side of the connection. + +In order to best utilize the available bandwidth, the GhostConnection attempts to determine which objects are "interesting" to each client - and among those objects, which ones are most important. If an object is interesting to a client it is said to be "in scope" - for example, a visible enemy to a player in a first person shooter would be in scope. + +Each GhostConnection object maintains a NetObject instance called the scope object - responsible for determining which objects are in scope for that client. Before the GhostConnection writes ghost update information into each packet, it calls the scope object's performScopeQuery method which must determine which objects are "in scope" for that client. + +Each scoped object that needs to be updated is then prioritized based on the return value from the NetObject::getUpdatePriority() function, which by default returns a constant value. This function can be overridden by NetObject subclasses to take into account such factors as the object's distance from the camera, its velocity perpendicular to the view vector, its orientation relative to the view direction and more. + +Rather than always sending the full state of the object each time it is updated across the network, the TNL supports only sending portions of the object's state that have changed. To facilitate this, each NetObject can specify up to 32 independent states that can be modified individually. For example, a player object might have a movement state, detailing its position and velocity, a damage state, detailing its damage level and hit locations, and an animation state, signifying what animation, if any, the player is performing. + +A NetObject can notify the network system when one of its states has changed, allowing the GhostConnections that are ghosting that object to replicate the changed state to the clients for which that object is in scope. + +Encryption and TNL + +The TNL has hooks in various places to use encryption when requested. To enable encrypted connections, the NetInterface must be assigned an instance of AsymmetricKey as a public/private key pair using NetInterface::setPrivateKey. The NetInterface::setRequiresKeyExchange method may then be called to instruct the NetInterface that all incoming connection requests must include a key exchange. + +Asymmetric keys can be constructed with varying levels of security. The TNL uses Elliptic Curve public key crytpography, with key sizes ranging from 20 to 32 bytes. AsymmetricKey instances can be constructed either with a new, random key of a specified size, or can be created from an existing ByteBuffer. + +Once a secure connection handshake is completed, TNL uses the AES symmetric cipher to encode connected packets. The BitStream::hashAndEncrypt and BitStream::decryptAndCheckHash methods use an instance of SymmetricCipher to encrypt and decrypt packets using a shared session key. + +In order to have properly secure communications, the cryptographically strong pseudo-random number generator (PRNG) in TNL must be initialized with good (high entropy) random data. + +Useful Classes + +TNL uses a number of utility classes throughout. Some of these include: + +Vector - The Vector template class is a lightweight version of the STL Vector container. + +DataChunker - The DataChunker class performs small, very low overhead memory allocation out of a pool. Individual allocations cannot be freed, however the entire pool can be freed at once. + +ClassChunker - The ClassChunker template class uses the DataChunker to manage allocation and deallocation of instances of the specific class. ClassChunker maintains a free list for quick allocation and deallocation. + +StringTableEntry - StringTableEntry wraps a ref-counted element in the StringTable, with simple conversion operations to C strings. StringTableEntry instances can be sent in the parameter lists of RPC methods or using the EventConnection::packStringTableEntry method. + +ByteBuffer - The ByteBuffer class wraps a buffer of arbitray binary data. ByteBuffer serves as a base class for BitStream, as well as the cryptographic primitives. + +Debugging and Error Handling + +Correcting bugs in a networked simulation can sometimes be an incredibly difficult task. TNL provides some handy features to make debugging somewhat less challenging: + +Asserts - The TNLAssert and TNLAssertV macros specify a condition that, if false, will cause the application to display an error dialog and halt in the debugger where the assert was hit. Asserts are very useful for sanity-checking arguments to functions, and making sure network data is being properly read from and written to packets. + +Logging - TNL has a set of simple but effective facilities for logging status information. The TNLLogMessage and TNLLogMessageV macros allow the user to specify logging tokens with particular log messages. Logging of messages associated with a given token can be enabled or disabled using the TNLLogEnable macro. Also, the TNLLogBlock macro can be used to log multiple logprintf statements in a single test. Rather than log to a file or other destination, TNL applications must declare at least one instance of a sublclass of TNLLogConsumer. Every TNLLogConsumer instance receives all the logging messages that are currently enabled. + +Debugging object writes into packets - One of the most common errors programmers experience when using TNL is failing to properly match the NetEvent::pack and NetEvent::unpack or NetObject::packUpdate and NetObject::unpackUpdate routines. By default, if TNL_DEBUG is defined, the EventConnection and GhostConnection classes will write extra size information into the packet before each object's data are written. The ConnectionParameters::mDebugObjectSizes flag can be modified directly to further control this behavior. + +Simple Torque Network Library Tutorial: Hello World + +This simple tutorial walks the user through the creation of a very simple networked example program using the RPC functionality of the EventConnection class. This command-line program can be run in either client or server modes. As a client it will attempt to connect to a server at the specified address and send it a message every second. When the server receives a message from a client, it will respond back with a "Hello, World!" message. + +First, create a new source file, "simpleNet.cpp", containing the following lines to start: + +#include "tnl.h" +#include "tnlEventConnection.h" +#include "tnlNetInterface.h" +#include "tnlRPC.h" +#include + +bool gQuit = false; // a flag used when the client wants to quit. + +using namespace TNL; // make sure we can simply use the TNL classes. + +If the compiler complains of missing include files, be sure the "tnl" directory is in the include path. + +Next, create a custom subclass of EventConnection for the example program to communicate across, and declare the client-to-server and server-to-client RPC methods: + +class SimpleEventConnection : public EventConnection +{ + typedef EventConnection Parent; + +public: + // Let the network system know this is a valid network connection. + TNL_DECLARE_NETCONNECTION(SimpleEventConnection); + + // declare the client to server message + TNL_DECLARE_RPC(rpcMessageClientToServer, (const char *theMessageString)); + + // declare the server to client message + TNL_DECLARE_RPC(rpcMessageServerToClient, (const char *theMessageString)); +}; + +The first macro invoked, TNL_DECLARE_NETCONNECTION declares members necessary to make this class work as a connection in TNL. The RPC methods are then declared using the TNL_DECLARE_RPC macro. The first parameter to the macro is the name of the RPC method, which can be invoked like any other member function on the object. The second argument is a parenthesized argument list to the RPC. Although these functions are both declared to take only a single string, RPC method parameter lists can contain all the basic TNL types, as well as StringTableEntry, ByteBuffer and Vector objects. + +Next, define the implementation of the SimpleEventConnection class: + +TNL_IMPLEMENT_NETCONNECTION(SimpleEventConnection, NetClassGroupGame, true); + +TNL_IMPLEMENT_RPC(SimpleEventConnection, rpcMessageClientToServer, (const char *messageString), +NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) +{ + // display the message the client sent + printf("Got message from client: %s\n", messageString); + // send a hello world back to the client. + rpcMessageServerToClient("Hello, World!"); +} + +TNL_IMPLEMENT_RPC(SimpleEventConnection, rpcMessageServerToClient, (const char *messageString), +NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) +{ + // display the message the server sent + printf("Got a message from server: %s\n", messageString); + + // once the client has heard back from the server, it should quit. + gQuit = true; +} + +The TNL_IMPLEMENT_NETCONNECTION macro specifies two properties. The first, NetClassGroupGame declares that this connection traffics only in NetEvent, NetObject and RPC instances that have the NetClassGroupGame mask bit set in their implementations. The second property, as declared by the boolean true specifies that remote hosts can request a connection of type SimpleEventConnection from this process. + +The TNL_IMPLEMENT_RPC macro behaves like a standard function signature declaration, but with some important additions. The first three arguments, class name, method name and arguments are fairly self-explanatory. The fourth argument is the connection type mask, which specifies which types of connections the specified RPC can travel over. Since RPC's (unlike NetEvent and NetObject subclasses) are declared for only a single connection class, this mask should always be the mask associated with the connection type declared in TNL_IMPLEMENT_NETCONNECTION. + +The fifth argument to the macro specifies the guarantee type of the RPC, which can be one of RPCGuaranteedOrdered, RPCGuaranteed or RPCUnguaranteed. The sixth parameter is the direction the RPC is allowed to travel, which when specified can make an application more secure from attacks that modify packets in transit. The last argument is a version number, which can be specified so that older clients can still connect to servers offering newer RPCs. + +The function body of the RPC similar to any other function body with one important difference. When an RPC method is invoked, the function body code is executed on the remote side of the connection. So if the client calls the method rpcMessageClientToServer("Hello?"), the code for the body will execute on the server. + +Now that the connection class is defined, all that is left to do is create the main() function that will start up the instance as either a client or a server. + +int main(int argc, const char **argv) +{ + if(argc != 3) + { + printf("usage: simpletnltest <-server|-client> "); + return 1; + } + bool isClient = !strcmp(argv[1], "-client"); + + // convert the command-line address into TNL address form + Address cmdAddress(argv[2]); + + RefPtr theNetInterface; + if(isClient) + { + Address bindAddress(IPProtocol, Address::Any, 0); + + // create a new NetInterface bound to any interface, any port (0) + theNetInterface = new NetInterface(bindAddress); + + // create a new SimpleEventConnection and tell it to connect to the + // server at cmdAddress. + SimpleEventConnection *newConnection = new SimpleEventConnection; + newConnection->connect(theNetInterface, cmdAddress); + + // post an RPC, to be executed when the connection is established + newConnection->rpcMessageClientToServer("Hello??"); + } + else + { + // create a server net interface, bound to the cmdAddress + theNetInterface = new NetInterface(cmdAddress); + + // notify the NetInterface that it can allow connections + theNetInterface->setAllowsConnections(true); + } + + // now just loop, processing incoming packets and sending outgoing packets + // until the global quit flag is set. + while(!gQuit) + { + theNetInterface->checkIncomingPackets(); + theNetInterface->processConnections(); + Platform::sleep(1); + } + return 0; +} + +Once the code is written, use your compiler to build simpletnltest, making sure to link in the tnl library, along with whatever network libraries your platform requires (wsock32.lib on Windows, for example). + +To test the program, open up two console shells, and in the first, type: + +simpletnltest -server 127.0.0.1:28000 + +This will create an instance of simpletnltest running as a server and bound to port 28000 on the local host machine. In the second window, run another instance as a client, set to connect to the server like this: + +simpletnltest -client 127.0.0.1:28000 + +Once the client runs, the server display should read: + +Got a message from client: Hello? + +and the client window should read: + +Got a message from server: Hello, World! + +The server will continue to accept new connections from clients until it is terminated manually. + +For an example program that uses more of TNL's advanced features, including RPCs with bit compressed arguments, a custom NetInterface subclass, and the NetObject replication system, look at the TNLTest project and documentation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tnl-1.5.0/tnl/docs/doxygen.html.cfg b/tnl-1.5.0/tnl/docs/doxygen.html.cfg new file mode 100644 index 0000000000000000000000000000000000000000..11faf98ef2954c5ff4b2f05c06d4cae52e0e16c6 --- /dev/null +++ b/tnl-1.5.0/tnl/docs/doxygen.html.cfg @@ -0,0 +1,216 @@ +# Doxyfile 1.3-rc2 +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = TNL +PROJECT_NUMBER = 1.1.2 +OUTPUT_DIRECTORY = ./docs +OUTPUT_LANGUAGE = English +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = NO +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 4 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SHOW_USED_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = doxygen.log +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ./tnl/tnl.overview.txt \ + ./tnl/tnl.changelog.txt \ + ./tnl/ \ + ./master/ \ + ./test/ \ + ./zap/ \ + +FILE_PATTERNS = *.h \ + *.txt +RECURSIVE = YES +EXCLUDE = */cvs/* \ + */platformMacCarb/* \ + */platformX86UNIX/* +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = doxydocs +HTML_FILE_EXTENSION = .html +HTML_HEADER = ./docs/header.html +HTML_FOOTER = ./docs/footer.html +HTML_STYLESHEET = ./docs/doco.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = tnl.chm +HHC_LOCATION = . +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = YES +ENUM_VALUES_PER_LINE = 1 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = pdf +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = YES +RTF_HYPERLINKS = YES +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_SCHEMA = +XML_DTD = +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = ./tnl/ +INCLUDE_FILE_PATTERNS = +PREDEFINED = DOXYGENIZING \ + TNL_DEBUG \ + TNL_ENABLE_ASSERTS \ + TNL_ENABLE_LOGGING + +EXPAND_AS_DEFINED = DeclareTemplatizedReadWrite + +SKIP_FUNCTION_MACROS = NO +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = "/cygdrive/c/Progra~1/ATT/Graphviz/bin" +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 4 +GENERATE_LEGEND = YES +DOT_CLEANUP = NO +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = diff --git a/tnl-1.5.0/tnl/docs/footer.html b/tnl-1.5.0/tnl/docs/footer.html new file mode 100644 index 0000000000000000000000000000000000000000..69e967af1aa4d080bfb68e8c46cc538e065d81de --- /dev/null +++ b/tnl-1.5.0/tnl/docs/footer.html @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/tnl-1.5.0/tnl/docs/header.html b/tnl-1.5.0/tnl/docs/header.html new file mode 100644 index 0000000000000000000000000000000000000000..4921f2314c747f1d83c64638b32f80aec25a2100 --- /dev/null +++ b/tnl-1.5.0/tnl/docs/header.html @@ -0,0 +1,64 @@ + + +OpenTNL - $title + + + + + + + + + + + +
+ + + + + + + +
+ +
+ News + SF.net Project + Frequently Asked Questions + Documentation + Downloads + Mailing Lists + How to Contribute + +

+ + SourceForge.net Logo + +
+
+ + Changing the way games are made and played. + +

+ +
+
+
+ + +
+
+
+ $title +
+ +
diff --git a/tnl-1.5.0/tnl/docs/images/gglogo.png b/tnl-1.5.0/tnl/docs/images/gglogo.png new file mode 100644 index 0000000000000000000000000000000000000000..9a9657eb87a862823a145be09c61e07ab10b6063 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/gglogo.png differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_contributors.gif b/tnl-1.5.0/tnl/docs/images/layout_left_contributors.gif new file mode 100644 index 0000000000000000000000000000000000000000..1f8596ce26c540c03b7a336b61f0ad7785b8ddc1 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_contributors.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_documentation.gif b/tnl-1.5.0/tnl/docs/images/layout_left_documentation.gif new file mode 100644 index 0000000000000000000000000000000000000000..439d58ba1e669e2bff015b6e0eb62a327ad39c9b Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_documentation.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_downloads.gif b/tnl-1.5.0/tnl/docs/images/layout_left_downloads.gif new file mode 100644 index 0000000000000000000000000000000000000000..4a4ceac81e9ebcc014c04266434ae665da3a462c Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_downloads.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_faq.gif b/tnl-1.5.0/tnl/docs/images/layout_left_faq.gif new file mode 100644 index 0000000000000000000000000000000000000000..a28cdf7af7455ffe2e20d14b0c37c3a48a649991 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_faq.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_forums.gif b/tnl-1.5.0/tnl/docs/images/layout_left_forums.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ab05374e8597105506bd0571923b7fafcdc6612 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_forums.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_mailing.gif b/tnl-1.5.0/tnl/docs/images/layout_left_mailing.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee8aa78cbf3aa1df50f6b4d1e1fe881b4ebc07ad Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_mailing.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_news.gif b/tnl-1.5.0/tnl/docs/images/layout_left_news.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd27342990fa24a786155d1eb76c13c56019e71c Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_news.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_sf.gif b/tnl-1.5.0/tnl/docs/images/layout_left_sf.gif new file mode 100644 index 0000000000000000000000000000000000000000..856c04227e7e3536772467cba4c158300dfc1526 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_sf.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_left_tnl.gif b/tnl-1.5.0/tnl/docs/images/layout_left_tnl.gif new file mode 100644 index 0000000000000000000000000000000000000000..30c6439f98c5314c1c3fd1f86a7fc040abca8d04 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_left_tnl.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_temp_03.png b/tnl-1.5.0/tnl/docs/images/layout_temp_03.png new file mode 100644 index 0000000000000000000000000000000000000000..abc9f457f632bb6f9b4f39419fa722b5b23d8932 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_temp_03.png differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_temp_05.png b/tnl-1.5.0/tnl/docs/images/layout_temp_05.png new file mode 100644 index 0000000000000000000000000000000000000000..cb4480758e5be31a8d682915f47ef97ac4e9bf66 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_temp_05.png differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_temp_14.png b/tnl-1.5.0/tnl/docs/images/layout_temp_14.png new file mode 100644 index 0000000000000000000000000000000000000000..4e5c47ee575b6f3d7364385ad6caafc357c804a3 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_temp_14.png differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif b/tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif new file mode 100644 index 0000000000000000000000000000000000000000..37a8d42ae50eff3fc5d8e05199fd1c9087acbc13 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/layout_topbar.gif b/tnl-1.5.0/tnl/docs/images/layout_topbar.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c949ee82e44d0f59f86651606391fab95d41e85 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/layout_topbar.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/opentnl.png b/tnl-1.5.0/tnl/docs/images/opentnl.png new file mode 100644 index 0000000000000000000000000000000000000000..bc85b86e7548f5e9c12033594f757caf35d0c51d Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/opentnl.png differ diff --git a/tnl-1.5.0/tnl/docs/images/spacer.gif b/tnl-1.5.0/tnl/docs/images/spacer.gif new file mode 100644 index 0000000000000000000000000000000000000000..5bfd67a2d6f72ac3a55cbfcea5866e841d22f5d9 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/spacer.gif differ diff --git a/tnl-1.5.0/tnl/docs/images/testshot.png b/tnl-1.5.0/tnl/docs/images/testshot.png new file mode 100644 index 0000000000000000000000000000000000000000..14b3cc5373b205499c25e4b9325d855ed15d55b9 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/testshot.png differ diff --git a/tnl-1.5.0/tnl/docs/images/zapshot.png b/tnl-1.5.0/tnl/docs/images/zapshot.png new file mode 100644 index 0000000000000000000000000000000000000000..780066e33f92e31f14323d2096381ee133caf271 Binary files /dev/null and b/tnl-1.5.0/tnl/docs/images/zapshot.png differ diff --git a/tnl-1.5.0/tnl/docs/tree_footer.html b/tnl-1.5.0/tnl/docs/tree_footer.html new file mode 100644 index 0000000000000000000000000000000000000000..3aae021a09837ad31755ffbacb7d569e1f77b661 --- /dev/null +++ b/tnl-1.5.0/tnl/docs/tree_footer.html @@ -0,0 +1,7 @@ + + + diff --git a/tnl-1.5.0/tnl/docs/tree_header.html b/tnl-1.5.0/tnl/docs/tree_header.html new file mode 100644 index 0000000000000000000000000000000000000000..f7b4875b34a11d56bf348dda52a277186439b7e7 --- /dev/null +++ b/tnl-1.5.0/tnl/docs/tree_header.html @@ -0,0 +1,25 @@ + + +OpenTNL - $title + + + + +
+ + +
+
+
+ $title +
+ +
diff --git a/tnl-1.5.0/tnl/exe/OpenAL32.dll b/tnl-1.5.0/tnl/exe/OpenAL32.dll new file mode 100644 index 0000000000000000000000000000000000000000..100012ff423e473554379fdcd0a6278d600a4d7c Binary files /dev/null and b/tnl-1.5.0/tnl/exe/OpenAL32.dll differ diff --git a/tnl-1.5.0/tnl/exe/README.txt b/tnl-1.5.0/tnl/exe/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..a9954aae5c0dbbbd064cdde464705761f17f8598 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/README.txt @@ -0,0 +1,250 @@ + ZAP 1.4.7 + +Introduction +------------ + +Welcome to ZAP, the retro multiplayer team action game! Zap is a +game of action and strategy. In Zap, the goal of the game varies +from level to level, from the following game types: + +Capture the Flag - Team game where the objective is to take the +enemy's flag and return it to your flag. Each capture earns your +team one point. Take care to defend your flag from the enemy -- +you can only score if it is at home! + +Soccer - Team game where the objective is to move the white circle +(the ball) into the goal of the opponent's color. + +Zone Control - Team game with a single flag and multiple "capture zone" +areas. The goal of the game is to escort a team member carrying the +flag to each of the capture zones in the map. When a capture zone +is entered by the flag carrier, the zone turns to that team's color +and the team scores a point. If the capture zone was already owned +by a different team, the team that lost the zone loses a point. If +all the zones on the level are captured by a single team, that scores +a "touchdown", and the zones and flag reset. + +Retrieve - In Retrieve, one or more flags are scattered throughout the level. +Teams compete to bring these flags back to team-colored goal zones. Each +retrieved flag is worth one point to the capturing team. If a team retrieves +all the flags on the level, the team keeps the points for the flags and the +flags reset to their original locations. + +Hunters - Solo game where the objective is to collect flags from +other players and return them to the Nexus for points. Each player +starts with one flag, and drops it if he or she is zapped. Scoring +in Hunters is based on how many flags the player is carrying when +touching the open Nexus. The first flag is worth one point, the +second is worth two, the third 3, and so on. So the total value +of capturing 5 flags would be 5 + 4 + 3 + 2 + 1 = 15 points. If +the Nexus is dark, it is closed -- the upper timer in the lower +right corner counts down to when it will next be open. + +Rabbit - Solo game wherein there is one flag that all players are fighting +to control. Players accumulate points by holding the flag, zapping +the flag carrier or zapping other players while holding the flag. + +Zapmatch - Solo game, often of short duration between levels. Just +zap as many other players as you can! + +Pay special attention to the triangular arrows that move in an ellipse around +the screen -- these indicate the direction to specific game objectives, including +flags to retrieve, zones to capture and friendly or enemy players carrying flags. + +Ship configuration: +Each ship can be configured with 2 modules and 3 weapons. Pressing +the loadout select screen allows the player to choose the next loadout +for his or her ship. This loadout will not become available until the +player either flies over a resupply area (team-color-coded patch), or +respawns (only if there are no resupply areas on the level). + +Modules are special powers that can be activated by pressing the appropriate +module activation key. The modules in Zap, and their function are: + +1. Boost - Gives the ship a boost of speed +2. Shield - Creates a defensive barrier around the ship that reflects shots +3. Repair - Repairs self and nearby teammates that are damaged +4. Sensor - Boosts the screen visible distance of the player +5. Cloak - Turns the ship invisible + +Controls: + +w - move up +S - move down +A - move left +D - move right + +T - chat to team +G - chat global +V - open quick chat menu +R - record voice chat + +C - toggle commander map +SPACE - activate primary module (default = boost) +SHIFT - activate secondary module (default = shield) + +TAB - show scores + +E - next weapon +Q - select weapon and module loadout + +Mouse: + +Mouse button 1 - fire weapon +Mouse button 2 - activate secondary module + +Dual-Analog Controller: + +Left stick - move +Right stick - aim and fire + +Buttons (Logitech Wingman Cordless) +A - cycle to next weapon +B - toggle commander map +C - open quick chat menu +X - select weapon and module loadout +Y - show scores +Z - record voice +right trigger - activate primary module (default = boost) +left trigger - activate secondary module (default = shield) + +Logitech Dual Action +1 - cycle to next weapon +2 - toggle commander map +3 - open quick chat menu +4 - select weapon and module loadout +5 - activate primary module (default = boost) +6 - activate secondary module (default = shield) +7 - show scores +8 - record voice + +Saitek P880 Dual Analog +1 - cycle to next weapon +2 - toggle commander map +3 - open quick chat menu +4 - select weapon and module loadout +5 - show scores +6 - record voice +right trigger - activate primary module (default = boost) +left trigger - activate secondary module (default = shield) + +PS 2 Dual Shock w/USB +X or depress right stick - cycle to next weapon +O - toggle commander map +square - open quick chat menu +triangle - select weapon and module loadout +R1 - activate primary module (default = boost) +L1 - activate secondary module (default = shield) +L2 - show scores +R2 - record voice + +XBox controller +A (green) - cycle to weapon +B (red) - toggle commander map +X (blue) - open quick chat menu +Y (yellow) - select weapon and module loadout +white - show scores +black - record voice +right trigger - activate primary module (default = boost) +left trigger - activate secondary module (default = shield) + +In the game you can press ESC to go to the game options screen. +From there you can access the main options which include setting +full screen mode, enabling relative controls and on the Windows +platform enabling dual analog controller support. + +Command Line Options: + +Note - zap addresses are of the form transport:address:port like: +IP:127.0.0.1:28000 +or IP:Any:28000 +or IP:www.foobar.com:24601 + +-server [bindAddress] hosts a game server/client on the specified + bind address. +-connect [connectAddress] starts as a game client and attempts + to connect to the server at the specified address. +-master [masterAddress] specfies the address of the master server + to connect to. +-dedicated [bindAddress] starts Zap as a dedicated server +-name [playerName] sets the client's name to the specified name + and skips the name entry screen. +-levels ["level1 level2 level3 ... leveln"] sets the specified level + rotation for games +-hostname [hostname] sets the name that will appear in the server + browser when searching for servers. +-maxplayers [number] sets the maximum number of players allowed + on the server +-password [password] sets the password for access to the server. +-adminpassword [password] sets the administrator password for the server. +-joystick [joystickType] enables dual analog control pad. The + joystickType argument can be either 0, 1 or 2. If the right + stick doesn't aim shots properly with 0, try 1 or 2. + + Known controllers: + Logitech Wingman cordless - joystick 0 + Logitech Dual Action - joystick 1 + Saitek P880 Dual Analog - joystick 2 + PS 2 Dual Shock w/USB - joystick 3 + XBox controller - joystick 4 + +-jsave [journalName] saves the log of the play session to the specified + journal file. +-jplay [journalName] replays a saved journal. +-edit [levelName] starts Zap in level editing mode, loading and saving the + specified level. + +Level editor instructions: + +Currently the level editor allows you to edit the barrier and level objects +within levels. + +Mouse functions: + +Left-click - select and move. Clicking on vertices allows movement + of verts, clicking on edges allows movement of the entire barrier border. + To move a vertex or border, click and hold as you drag the object around. + Left click also completes a new barrier border. + If no object is under the mouse, left-clicking will create a + drag selection box for selecting multiple objects. Holding down + the shift key also allows multiple selection of objects. + +Right-click - add barrier vertex. If right clicking on an existing barrier edge, + this will insert a new vertex along that edge at the click point. Otherwise + this either begins a new barrier border or adds a new vertex to the current + new barrier border. + +Keyboard functions: + +W - scroll map up +S - scroll map down +A - scroll map left +D - scroll map right +C - zoom out +E - zoom in +R - reset view to 0,0 in the top left corner +F - flip current selection horizontally +V - flip current selection vertically + +0...9 - set the active team for item construction. This will also set the team + of any selected objects +T - construct a Teleporter at the mouse point +G - construct a Spawn point at the mouse point +B - construct a RepairItem at the mouse point +Y - construct a Turret at the mouse point +H - construct a Force Field projector at the mouse point + +CTRL-D - duplicate current selection +CTRL-Z - undo last operation + +ESC - bring up editor menu + +Credits: + +ZAP is free software provided by GarageGames.com, Inc. +Team members are: + + Mark Frohnmayer + Ben Garney + John Quigley + Robert Blanchett \ No newline at end of file diff --git a/tnl-1.5.0/tnl/exe/bot.sh b/tnl-1.5.0/tnl/exe/bot.sh new file mode 100644 index 0000000000000000000000000000000000000000..b82276422b5843eb7a83411dc961afb3be6d2144 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/bot.sh @@ -0,0 +1,17 @@ +#!/bin/bash +LIMIT=$1 +CONNECTADDR=$2 +SAVEJ=$3 + +if [ "$SAVEJ" = "TRUE" ]; then +JOURNAL=-jsave bot"$a".journal +fi + +for ((a=1; a <= LIMIT ; a++)) # Double parentheses, and "LIMIT" with no "$". +do + echo Bot $a connecting to $1 + ./zapd -name bot"$a" "$JOURNAL" -loss 0.2 -lag 150 -crazybot -connect "$CONNECTADDR" & + echo Waiting 10 seconds for bot to connect... + sleep 4 +done # A construct borrowed from 'ksh93'. + diff --git a/tnl-1.5.0/tnl/exe/build.sh b/tnl-1.5.0/tnl/exe/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..3054a24e4319452ecea5d57f3e1c1d38db34f9da --- /dev/null +++ b/tnl-1.5.0/tnl/exe/build.sh @@ -0,0 +1,69 @@ +PLATFORM=$1 +VERSION=$2 +USER=$3 + +USAGE="build [user]" + +if [ "$PLATFORM" != "win32" -a "$PLATFORM" != "macosx" -a "$PLATFORM" != "linux" -a "$PLATFORM" != "source" ]; then + echo "$USAGE" + exit 1 +fi + +if [ "$VERSION" = "" ]; then + echo "$USAGE" + exit 1 +fi + +if [ "$PLATFORM" = "source" ]; then + +if [ "$USER" = "" ]; then +echo User must be specified for source build! +exit 1 +fi + +rm -rf tnl +cvs -d:ext:"$USER"@cvs.sourceforge.net:/cvsroot/opentnl export -r HEAD tnl +tar -czf tnl-"$VERSION"-source.tar.gz tnl +zip -r tnl-"$VERSION"-source.zip tnl + +fi + + +DIR=zap-"$VERSION" + +echo Writing to dir "$DIR" + +rm -rf "$DIR" +mkdir "$DIR" + +cp README.txt "$DIR" +mkdir "$DIR"/sfx +mkdir "$DIR"/levels + +cp sfx/*.wav "$DIR"/sfx +cp levels/*.txt "$DIR"/levels + +if [ "$PLATFORM" = "win32" ]; then + ./installer/upx.exe --best --crp-ms=999999 --nrv2d -o "$DIR"/glut32.dll glut32.dll + ./installer/upx.exe --best --crp-ms=999999 --nrv2d -o "$DIR"/zap.exe zap.exe + cp OpenAL32.dll "$DIR" + rm "$DIR"-win32.zip + ./installer/makensis-bz2.exe /Dversion="$VERSION" installer/zap.nsi +fi + +if [ "$PLATFORM" = "macosx" ]; then + cp ZAP "$DIR" + strip "$DIR"/ZAP + rm "$DIR"-macosx.tar.gz + tar -czf "$DIR"-macosx.tar.gz "$DIR" +fi + +if [ "$PLATFORM" = "linux" ]; then + cp zap "$DIR" + cp zapded "$DIR" + strip "$DIR"/zap + strip "$DIR"/zapded + rm "$DIR"-x86linux.tar.gz + tar -czf "$DIR"-x86linux.tar.gz "$DIR" +fi + diff --git a/tnl-1.5.0/tnl/exe/glut32.dll b/tnl-1.5.0/tnl/exe/glut32.dll new file mode 100644 index 0000000000000000000000000000000000000000..106646ff710941b60525ad3ee9bd68dc2a27b667 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/glut32.dll differ diff --git a/tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe b/tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe new file mode 100644 index 0000000000000000000000000000000000000000..e916466cffd36680f17edf8668bbfe8f5b0aec64 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe differ diff --git a/tnl-1.5.0/tnl/exe/installer/nsisconf.nsi b/tnl-1.5.0/tnl/exe/installer/nsisconf.nsi new file mode 100644 index 0000000000000000000000000000000000000000..1f6e2b32b5d5c4fd0dca9039a329610ea036e1b7 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/installer/nsisconf.nsi @@ -0,0 +1,27 @@ +; this file sets the defaults that will be used +; this file is treated as if it is in the directory +; that you are building from. i.e. the command +; File whatever.dat +; would need whatever.dat to be in your build directory +; (not necessarily the same directory as this file) + + +; if you want to change the default icon or bitmaps, you can do it here. +;Icon "C:\program files\nsis\newicon.ico" +;EnabledBitmap "C:\program files\nsis\newenabled.bmp" +;DisabledBitmap "C:\program files\nsis\newdisabled.bmp" + +; if you want to define symbols, whatever, you can do that to. +;!define poo + + +; Datablock optimizations can save size, and are fast now. +; SetDatablockOptimize off + +;use one of these if you have upx or petite installed +;note that your exe packer should not pack the first icon :) +;and paths should ideally be absolute (since you could be +;building your installer anywhere) + +;!packhdr tmp.dat "C:\program files\upx\upx -9 -q tmp.dat" +;!packhdr tmp.dat "C:\program files\petite\petite -9 -b0 -r** -p0 -y tmp.dat" diff --git a/tnl-1.5.0/tnl/exe/installer/nsisdl.dll b/tnl-1.5.0/tnl/exe/installer/nsisdl.dll new file mode 100644 index 0000000000000000000000000000000000000000..c3d9281892e3a1fff86905072eedf0e198951656 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/installer/nsisdl.dll differ diff --git a/tnl-1.5.0/tnl/exe/installer/upx.exe b/tnl-1.5.0/tnl/exe/installer/upx.exe new file mode 100644 index 0000000000000000000000000000000000000000..b0b309ac7caf4876bfec221e7a9fc6a1ab77aba6 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/installer/upx.exe differ diff --git a/tnl-1.5.0/tnl/exe/installer/zap.nsi b/tnl-1.5.0/tnl/exe/installer/zap.nsi new file mode 100644 index 0000000000000000000000000000000000000000..1ad8786ce01642afe3e17302a045e8f12aab52e0 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/installer/zap.nsi @@ -0,0 +1,82 @@ +; zap.nsi +; +; This script is perhaps one of the simplest NSIs you can make. All of the +; optional settings are left to their default settings. The instalelr simply +; prompts the user asking them where to install, and drops of notepad.exe +; there. If your Windows directory is not C:\windows, change it below. +; + +; This script assumes that there is a /Dversion=curVersion + +; The name of the installer +Name "Zap!" +BrandingText " " + +; The file to write +OutFile "Zap-${version}-Installer.exe" + +; The default installation directory +InstallDir $PROGRAMFILES\Zap +AutoCloseWindow true +; Icon ".\main.ico" + +; The text to prompt the user to enter a directory +DirText "This will install Zap! version ${version} on your computer. Choose a directory" + +; The stuff to install +Section "Zap! Game Files (required)" + ; Set output path to the installation directory. + SetOutPath $INSTDIR + ; Put file there + File /r "zap-${version}\*.*" + Delete $INSTDIR\uninst-zap.exe + WriteUninstaller $INSTDIR\uninst-zap.exe + MessageBox MB_YESNO|MB_ICONQUESTION \ + "Zap! has been installed. Would you like to add shortcuts in the start menu?" \ + IDNO NoStartMenu + SetOutPath $SMPROGRAMS\Zap + WriteINIStr "$SMPROGRAMS\Zap\Zap Home Page.url" \ + "InternetShortcut" "URL" "http://www.zapthegame.com/" + CreateShortCut "$SMPROGRAMS\Zap\Uninstall Zap!.lnk" \ + "$INSTDIR\uninst-zap.exe" + SetOutPath $INSTDIR + CreateShortCut "$SMPROGRAMS\Zap\Zap!.lnk" \ + "$INSTDIR\zap.exe" + NoStartMenu: + MessageBox MB_YESNO|MB_ICONQUESTION \ + "Would you like to add a desktop icon for Zap?" IDNO NoDesktopIcon + SetOutPath $INSTDIR + CreateShortCut "$DESKTOP\Zap!.lnk" "$INSTDIR\Zap.exe" + NoDesktopIcon: + WriteRegStr HKLM SOFTWARE\Zap "" $INSTDIR + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Zap" \ + "DisplayName" "Zap! (remove only)" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Zap" \ + "UninstallString" '"$INSTDIR\uninst-zap.exe"' + MessageBox MB_YESNO|MB_ICONQUESTION \ + "Zap! installation has completed. Would you like to view the README file now?" \ + IDNO NoReadme + ExecShell open '$INSTDIR\README.txt' + NoReadme: +SectionEnd ; end the section + +Section Uninstall + MessageBox MB_YESNO|MB_ICONQUESTION \ + "Are you sure you wish to uninstall Zap!?" \ + IDNO Removed + + Delete $SMPROGRAMS\Zap\*.* + Delete "$DESKTOP\Zap!.lnk" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Zap" + DeleteRegKey HKLM SOFTWARE\Zap + RMDir $SMPROGRAMS\Zap + RMDir /r $INSTDIR + IfFileExists $INSTDIR 0 Removed + MessageBox MB_OK|MB_ICONEXCLAMATION \ + "Note: $INSTDIR could not be removed." +Removed: +SectionEnd + + + +; eof diff --git a/tnl-1.5.0/tnl/exe/levels/ctf1.txt b/tnl-1.5.0/tnl/exe/levels/ctf1.txt new file mode 100644 index 0000000000000000000000000000000000000000..dcfc87f6c3b67b37a3fa52cc8cad76d761a8f587 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/ctf1.txt @@ -0,0 +1,70 @@ +CTFGameType 10 8 +LevelName "Kompressor's Gambit" +Team Blue 0 0 1 +Team Red 1 0 0 +GridSize 300 +Ship 0.5 1 0 1 0 +Ship 1.5 0.5 0 1 1 +Ship 1 1 1 1 0 +FlagItem 0 8 2 +FlagItem 1 8 14 +LoadoutZone 0 11.2 2 11.8 2 11.7 1.7 11.3 1.7 +LoadoutZone 1 4.2 14 4.8 14 4.7 14.3 4.3 14.3 +Spawn 0 1 6 +Spawn 0 4.5 1.5 +Spawn 0 6.5 6.5 +Spawn 0 7 2 +Spawn 0 9 2 +Spawn 0 8 1 +Spawn 0 14.5 0.5 +Spawn 0 15.5 0.5 +Spawn 0 14.5 1.5 +Spawn 1 15 10 +Spawn 1 11.5 14.5 +Spawn 1 9.5 9.5 +Spawn 1 7 14 +Spawn 1 9 14 +Spawn 1 8 15 +Spawn 1 1.5 15.5 +Spawn 1 0.5 15.5 +Spawn 1 1.5 14.5 +RepairItem 4.5 0.88 +RepairItem 11.5 3.12 +RepairItem 11.5 15.12 +RepairItem 4.5 12.88 +BarrierMaker 50 1 0 2 0 3 1 4 1 4.2 0.5 4.8 0.5 5 1 6 1 7 0 9 0 10 1 10 2 11 2 11.2 1.5 11.8 1.5 12 2 13 2 14 1 14 0 16 0 16 2 15 3 16 4 16 11 15 12 15 13 16 14 16 15 15 16 14 16 13 15 12 15 11.8 15.5 11.2 15.5 11 15 10 15 9 16 7 16 6 15 6 14 5 14 4.8 14.5 4.2 14.5 4 14 3 14 2 15 2 16 0 16 0 14 1 13 0 12 0 5 1 4 1 3 0 2 0 1 1 0 +BarrierMaker 50 3 2 4 2 4.2 2.5 4.8 2.5 5 2 6 2 6 3 7 4 7 5 6 6 4 7 4 8.5 3.5 8.5 3.5 6 4 6 5 5 5 4 3 4 3 8.5 1 8.5 1 7 2 6 2 3 3 2 +BarrierMaker 50 1 9 3 9 3 10 1 10 1 9 +BarrierMaker 50 8 4 8 5 +BarrierMaker 50 8 5 8.5 6 7.5 6 8 5 +BarrierMaker 50 7 7 9 7 9 9 7 9 7 7 +BarrierMaker 50 5 8 6 7.5 6 8.5 5 8 +BarrierMaker 50 11 8 10 8.5 10 7.5 11 8 +BarrierMaker 50 8 11 7.5 10 8.5 10 8 11 +BarrierMaker 50 8 11 8 12 +TestItem 8 6.5 +TestItem 8 9.5 +TestItem 6.5 8 +TestItem 9.5 8 +BarrierMaker 50 1 10.5 1 11 2 12 2 13 4 13 4.2 12.5 4.8 12.5 5 13 6 13 7 12 7 11 6 10 4 9 3.5 9 3.5 10.5 1 10.5 +BarrierMaker 50 9 4 10 3 11 3 11.2 3.5 11.8 3.5 12 3 14 3 14 4 15 5 15 5.5 12.5 5.5 12.5 7 12 7 10 6 9 5 9 4 +BarrierMaker 50 10 14 10 13 9 12 9 11 10 10 12 9 12 7.5 12.5 7.5 12.5 10 12 10 11 11 11 12 13 12 13 7.5 15 7.5 15 9 14 10 14 13 13 14 12 14 11.8 13.5 11.2 13.5 11 14 10 14 +BarrierMaker 50 13 6 15 6 15 7 13 7 13 6 +BarrierMaker 50 7 1.7 7 1.5 7.5 1 7.7 1 +BarrierMaker 50 8.3 1 8.5 1 9 1.5 9 1.7 +BarrierMaker 50 7 2.3 7 2.5 7.5 3 8.5 3 9 2.5 9 2.3 +BarrierMaker 50 7 14.3 7 14.5 7.5 15 7.7 15 +BarrierMaker 50 8.3 15 8.5 15 9 14.5 9 14.3 +BarrierMaker 50 7 13.7 7 13.5 7.5 13 8.5 13 9 13.5 9 13.7 +Teleporter 11.5 11.5 1.5 1.5 +Teleporter 4.5 4.5 14.5 14.5 +LoadoutZone 1 11.2 14 11.8 14 11.7 13.7 11.3 13.7 +LoadoutZone 0 4.2 2 4.8 2 4.7 2.3 4.3 2.3 +ForceFieldProjector 0 8.9 4.2 +ForceFieldProjector 0 7.1 4.2 +Turret 0 6.9 1.6 +Turret 0 9.1 1.6 +ForceFieldProjector 1 8.9 11.8 +ForceFieldProjector 1 7.1 11.8 +Turret 1 6.9 14.4 +Turret 1 9.1 14.4 diff --git a/tnl-1.5.0/tnl/exe/levels/ctf2.txt b/tnl-1.5.0/tnl/exe/levels/ctf2.txt new file mode 100644 index 0000000000000000000000000000000000000000..b9031f76b7b8634c084e0997d1a50705ca299472 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/ctf2.txt @@ -0,0 +1,62 @@ +CTFGameType 10 8 +LevelName "Monki's Dash" + +Team Blue 0 0 1 +Team Red 1 0 0 +GridSize 300 +FlagItem 0 6 2 +FlagItem 1 6 14 +LoadoutZone 0 5.6 2.8 6.4 2.8 6.2 2.4 5.8 2.4 +LoadoutZone 1 5.6 13.2 6.4 13.2 6.2 13.6 5.8 13.6 +BarrierMaker 50 0 1 5 1 5.5 0.8 6.5 0.8 7 1 12 1 12 15 7 15 6.5 15.2 5.5 15.2 5 15 0 15 0 1 +BarrierMaker 50 6 6 7 7 7 7.5 9 7.5 9 8.5 7 8.5 7 9 6 10 5 9 5 8.5 3 8.5 3 7.5 5 7.5 5 7 6 6 +BarrierMaker 50 5 3 5 3.5 4 3.5 4 3.4 4.9 3 5 3 +BarrierMaker 50 4 4 5 4 5 5 5.5 5 +BarrierMaker 50 8 3 7 3 7 5 +BarrierMaker 50 4 2.5 4.5 2.5 4.5 2 5 2 +BarrierMaker 50 5.9 5 5.5 3.1 5.5 3 6.5 3 6.5 3.1 6.1 5 5.9 5 +BarrierMaker 50 3.5 4.5 3.5 6 4 6 +BarrierMaker 50 4.5 6 4.5 4.5 4 4.5 +BarrierMaker 50 3.5 2 4 2 +BarrierMaker 50 1.5 2 3 2 3 3.5 2.9 3.5 1.5 2.1 1.5 2 +BarrierMaker 50 0.8 2 0.9 2 2.3 3.9 2.3 4 2.2 4 0.8 3 0.8 2 +BarrierMaker 50 7 2 7.5 2 7.5 2.1 7.1 2.5 7 2.5 7 2 +BarrierMaker 50 7.5 4 8 4 8 5 7.5 5 7.5 4 +BarrierMaker 50 8 6 8.1 6 11 4 11 2 10.9 2 8 5.9 8 6 +BarrierMaker 50 8 2.5 9 2.5 9 3 8.5 3.5 +BarrierMaker 50 8 12 7 12 7 11 6.5 11 +BarrierMaker 50 4 13 5 13 5 11 +BarrierMaker 50 8 13.5 7.5 13.5 7.5 14 7 14 +BarrierMaker 50 8.5 11.5 8.5 10 8 10 +BarrierMaker 50 7.5 10 7.5 11.5 8 11.5 +BarrierMaker 50 8.5 14 8 14 +BarrierMaker 50 4.5 12 4 12 4 11 4.5 11 4.5 12 +BarrierMaker 50 4 13.5 3 13.5 3 13 3.5 12.5 +Spawn 0 3.5 4 +Spawn 0 11 1.5 +Spawn 0 0.5 1.5 +Spawn 0 4.5 7 +Spawn 0 8.7 2.8 +Spawn 0 11 4.5 +Spawn 0 6 1.2 +Spawn 1 8.5 12 +Spawn 1 1 14.5 +Spawn 1 11.5 14.5 +Spawn 1 7.5 9 +Spawn 1 3.3 13.2 +Spawn 1 1 11.5 +Spawn 1 6 14.8 +BarrierMaker 50 7 13 7 12.5 8 12.5 8 12.6 7.1 13 7 13 +BarrierMaker 50 6.1 11 6.5 12.9 6.5 13 5.5 13 5.5 12.9 5.9 11 6.1 11 +BarrierMaker 50 10.5 14 9 14 9 12.5 9.1 12.5 10.5 13.9 10.5 14 +BarrierMaker 50 11.2 14 11.1 14 9.7 12.1 9.7 12 9.8 12 11.2 13 11.2 14 +BarrierMaker 50 5 14 4.5 14 4.5 13.9 4.9 13.5 5 13.5 5 14 +BarrierMaker 50 4 10 3.9 10 1 12 1 14 1.1 14 4 10.1 4 10 +Turret 0 5.1 2 +ForceFieldProjector 0 4.2 2.6 +ForceFieldProjector 0 7 2.9 +Turret -1 2.9 8 +Turret 1 6.9 14 +ForceFieldProjector 1 7.8 13.4 +ForceFieldProjector 1 5 13.1 +Turret -1 9.1 8 diff --git a/tnl-1.5.0/tnl/exe/levels/ctf3.txt b/tnl-1.5.0/tnl/exe/levels/ctf3.txt new file mode 100644 index 0000000000000000000000000000000000000000..b27d3bceadbe97b7210e030c3332c3faae8e7567 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/ctf3.txt @@ -0,0 +1,148 @@ +CTFGameType 10 8 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName "Galaxy Crossover" +GridSize 300 +TestItem 13.5 5 +FlagItem 0 4 -1 +Spawn 0 7.1 3.1 +Spawn 0 6 2 +Spawn 0 3 4.8 +Spawn 0 1 4 +Spawn 0 4 -3.9 +Spawn 0 9.2 0.9 +Spawn 0 10.9 0 +Spawn 0 7.3 -1.5 +RepairItem 13.8 -0.6 +RepairItem 4.4 2.5 +Teleporter 2 1 11.5 6 +LoadoutZone 0 3.6 -4.1 4.4 -4.1 4.2 -3.7 3.8 -3.7 +BarrierMaker 50 2.5 -1 2.5 -1.5 3.5 -2.5 4.5 -2.5 5.5 -1.5 5.5 -1 +BarrierMaker 50 1.5 -1.5 1.5 0 1.5 0 1.5 0 3 1.5 3.5 1.5 +BarrierMaker 50 4.5 1.5 5 1.5 6.5 0 6.5 -1.5 +BarrierMaker 50 3.5 0.5 4.5 0.5 +BarrierMaker 50 3 -0.5 3 0 +BarrierMaker 50 5 -0.5 5 0 +BarrierMaker 50 5 -1 4.5 -1.5 +BarrierMaker 50 3.5 -1.5 3 -1 +BarrierMaker 50 2.5 -2.7 3.5 -3.7 3.6 -3.7 3.7 -3.5 4.3 -3.5 4.4 -3.7 4.5 -3.7 5.5 -2.8 +BarrierMaker 50 1.5 0 1.5 2 0.5 3 0.5 4.6 2 4.6 +BarrierMaker 50 16 5.5 16 4.5 14.4 3 14.3 3 14.3 5.5 16 5.5 +BarrierMaker 50 16 3.4 15.9 3.4 15.4 3 15.4 2.9 16 2.9 16 3.4 +BarrierMaker 50 16 1.2 16 2.2 12.6 2.2 +BarrierMaker 50 15.3 1.2 15.3 1.5 12.6 1.5 +BarrierMaker 50 12.5 0.5 11.5 1.5 +BarrierMaker 50 11.5 0.5 12.5 -0.5 +BarrierMaker 50 12.5 -1.5 11.5 -1.5 11.5 -0.5 10.5 -0.5 10.5 1.5 9.5 2.5 9.5 3.5 +BarrierMaker 50 8.5 4.5 7.5 5.5 6.5 5.5 5.5 4.5 4.5 4.5 3.5 5.5 2.2 5.5 +BarrierMaker 50 7.5 1.5 7.5 3.5 5.5 3.5 +BarrierMaker 50 5.5 3 6.5 2.5 7 1.5 +BarrierMaker 50 7 -2 7 -1 +BarrierMaker 50 7.5 -0.5 7.5 -1 7.6 -1 8 -0.6 8 -0.5 7.5 -0.5 +BarrierMaker 50 8 0.1 7.5 0.1 7.5 0.6 7.6 0.6 8 0.2 8 0.1 +BarrierMaker 50 8.6 -0.5 8.6 -0.6 9 -1 9.1 -1 9.1 -0.5 8.6 -0.5 +BarrierMaker 50 8.6 0.1 8.6 0.2 9 0.6 9.1 0.6 9.1 0.1 9.1 0.1 8.6 0.1 +BarrierMaker 50 9.6 -1.4 9.5 -0.3 9.6 0.7 9.8 0.7 10 -0.3 9.8 -1.4 9.6 -1.4 +BarrierMaker 50 8.2 -1.1 8 -1.9 8 -2 8.6 -2 8.6 -1.9 8.4 -1.1 8.2 -1.1 +BarrierMaker 50 9.1 -2 10 -2 10.7 -1.6 10.9 -1.2 +BarrierMaker 50 8.5 1.4 8.5 2 9 2 9.5 1.7 9.5 1.6 8.6 1.4 8.5 1.4 +BarrierMaker 50 8 2.7 8.6 2.7 +BarrierMaker 50 8 3.3 8.7 3.6 9 3.2 +BarrierMaker 50 6.5 1.2 7 0.7 7 0 +BarrierMaker 50 6.2 1.6 5.6 1.6 5 2.1 5 2.2 5.6 2.2 5.6 2.3 4.4 2.8 3.6 2.4 3.7 2.1 4 2 +BarrierMaker 50 1.5 3 1.5 3.1 1.9 4 2 4 2 3 1.5 3 +BarrierMaker 50 2.6 3.4 2.6 4 4 4 4 3.9 2.7 3.4 2.6 3.4 +BarrierMaker 50 11 3.1 11 4 12 5 12.9 5 12.9 4.9 11.1 3.1 11 3.1 +BarrierMaker 50 12 3 12 3.1 12.9 4 13.5 4 13.5 3.9 12.6 3 12 3 +BarrierMaker 50 13.5 3.3 13.6 3.3 13.6 2.7 13.5 2.7 13.2 3 13.5 3.3 +BarrierMaker 50 14.2 1 14.6 0.5 +BarrierMaker 50 14 -1.5 13.2 -1.5 13.2 0.3 14 0.3 14 0 13.5 -0.3 13.5 -0.9 14 -1.2 14 -1.5 +BarrierMaker 50 10.5 4 10.5 5 10.4 5 10 3.3 +TestItem 3 6 +FlagItem 1 12.5 12 +Spawn 1 9.4 7.9 +Spawn 1 10.5 9 +Spawn 1 13.5 6.2 +Spawn 1 15.5 7 +Spawn 1 12.5 14.9 +Spawn 1 7.3 10.1 +Spawn 1 5.6 11 +Spawn 1 9.2 12.5 +RepairItem 2.7 11.6 +RepairItem 12.1 8.5 +Teleporter 14.5 10 5 5 +BarrierMaker 50 14 12 14 12.5 13 13.5 12 13.5 11 12.5 11 12 +BarrierMaker 50 15 12.5 15 11 15 11 15 11 13.5 9.5 13 9.5 +BarrierMaker 50 12 9.5 11.5 9.5 10 11 10 12.5 +BarrierMaker 50 13 10.5 12 10.5 +BarrierMaker 50 13.5 11.5 13.5 11 +BarrierMaker 50 11.5 11.5 11.5 11 +BarrierMaker 50 11.5 12 12 12.5 +BarrierMaker 50 13 12.5 13.5 12 +BarrierMaker 50 14 13.7 13 14.7 12.9 14.7 12.8 14.5 12.2 14.5 12.1 14.7 12 14.7 11 13.8 +BarrierMaker 50 15 11 15 9 16 8 16 6.4 14.5 6.4 +BarrierMaker 50 0.5 5.5 0.5 6.5 2.1 8 2.2 8 2.2 5.5 0.5 5.5 +BarrierMaker 50 0.5 7.6 0.6 7.6 1.1 8 1.1 8.1 0.5 8.1 0.5 7.6 +BarrierMaker 50 0.5 9.8 0.5 8.8 3.9 8.8 +BarrierMaker 50 1.2 9.8 1.2 9.5 3.9 9.5 +BarrierMaker 50 4 10.5 5 9.5 +BarrierMaker 50 5 10.5 4 11.5 +BarrierMaker 50 4 12.5 5 12.5 5 11.5 6 11.5 6 9.5 7 8.5 7 7.5 +BarrierMaker 50 8 6.5 9 5.5 10 5.5 11 6.5 12 6.5 13 5.5 14.3 5.5 +BarrierMaker 50 9 9.5 9 7.5 11 7.5 +BarrierMaker 50 11 8 10 8.5 9.5 9.5 +BarrierMaker 50 9.5 13 9.5 12 +BarrierMaker 50 9 11.5 9 12 8.9 12 8.5 11.6 8.5 11.5 9 11.5 +BarrierMaker 50 8.5 10.9 9 10.9 9 10.4 8.9 10.4 8.5 10.8 8.5 10.9 +BarrierMaker 50 7.9 11.5 7.9 11.6 7.5 12 7.4 12 7.4 11.5 7.9 11.5 +BarrierMaker 50 7.9 10.9 7.9 10.8 7.5 10.4 7.4 10.4 7.4 10.9 7.4 10.9 7.9 10.9 +BarrierMaker 50 6.9 12.4 7 11.3 6.9 10.3 6.7 10.3 6.5 11.3 6.7 12.4 6.9 12.4 +BarrierMaker 50 8.3 12.1 8.5 12.9 8.5 13 7.9 13 7.9 12.9 8.1 12.1 8.3 12.1 +BarrierMaker 50 7.4 13 6.5 13 5.8 12.6 5.6 12.2 +BarrierMaker 50 8 9.6 8 9 7.5 9 7 9.3 7 9.4 7.9 9.6 8 9.6 +BarrierMaker 50 8.5 8.3 7.9 8.3 +BarrierMaker 50 8.5 7.7 7.8 7.4 7.5 7.8 +BarrierMaker 50 10 9.8 9.5 10.3 9.5 11 +BarrierMaker 50 10.3 9.4 10.9 9.4 11.5 8.9 11.5 8.8 10.9 8.8 10.9 8.7 12.1 8.2 12.9 8.6 12.8 8.9 12.5 9 +BarrierMaker 50 15 8 15 7.9 14.6 7 14.5 7 14.5 8 15 8 +BarrierMaker 50 13.9 7.6 13.9 7 12.5 7 12.5 7.1 13.8 7.6 13.9 7.6 +BarrierMaker 50 5.5 7.9 5.5 7 4.5 6 3.6 6 3.6 6.1 5.4 7.9 5.5 7.9 +BarrierMaker 50 4.5 8 4.5 7.9 3.6 7 3 7 3 7.1 3.9 8 4.5 8 +BarrierMaker 50 3 7.7 2.9 7.7 2.9 8.3 3 8.3 3.3 8 3 7.7 +BarrierMaker 50 2.3 10 1.9 10.5 +BarrierMaker 50 2.5 12.5 3.3 12.5 3.3 10.7 2.5 10.7 2.5 11 3 11.3 3 11.9 2.5 12.2 2.5 12.5 +BarrierMaker 50 6 7 6 6 6.1 6 6.5 7.7 +BarrierMaker 50 -0.1 10.5 -0.1 2.1 0.5 1.5 0.5 -2.5 2.5 -4.5 5.5 -4.5 7.5 -2.5 14.6 -2.5 14.6 0.5 16.6 0.5 16.6 8.9 16 9.5 16 13.5 14 15.5 11 15.5 9 13.5 1.9 13.5 1.9 10.5 -0.1 10.5 +LoadoutZone 0 11.7 -1.3 12.3 -1.3 12.3 -1 11.7 -1 +LoadoutZone 0 1.3 4.1 0.700001 4.1 0.7 4.4 1.3 4.4 +LoadoutZone 1 12.9 15.1 12.1 15.1 12.3 14.7 12.7 14.7 +LoadoutZone 1 4.8 12.3 4.2 12.3 4.2 12 4.8 12 +LoadoutZone 1 15.2 6.9 15.8 6.9 15.8 6.6 15.2 6.6 +Turret 0 2.7 -2.7 +Turret 0 5.3 -2.8 +ForceFieldProjector 0 2.3 -1.1 +ForceFieldProjector 0 5.7 -1.1 +Turret 0 3.6 0.7 +Turret 0 4.4 0.7 +ForceFieldProjector 0 2.4 1.2 +ForceFieldProjector -1 8.5 4.7 +ForceFieldProjector -1 14.1 1.1 +Turret 0 7.5 0.7 +Turret 0 7.5 -1.1 +Turret -1 14.3 2.9 +Turret 0 9.1 0.7 +Turret 0 9.1 -1.1 +Turret 1 13.8 13.7 +Turret 1 11.2 13.8 +ForceFieldProjector 1 14.2 12.1 +ForceFieldProjector 1 10.8 12.1 +Turret 1 12.9 10.3 +Turret 1 12.1 10.3 +ForceFieldProjector 1 14.1 9.8 +ForceFieldProjector -1 8 6.3 +ForceFieldProjector -1 2.4 9.9 +Turret 1 9 10.3 +Turret 1 9 12.1 +Turret -1 2.2 8.1 +Turret 1 7.4 10.3 +Turret 1 7.4 12.1 diff --git a/tnl-1.5.0/tnl/exe/levels/ctf4.txt b/tnl-1.5.0/tnl/exe/levels/ctf4.txt new file mode 100644 index 0000000000000000000000000000000000000000..5a1fd659392da2f9c92dabca2899d4f27969bc28 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/ctf4.txt @@ -0,0 +1,95 @@ +CTFGameType 10 8 +LevelName "Arcturus Triple Gakk" +LevelDescription "Hint: Make sure to keep your flag out of enemy hands." + +Team Blue 0 0 1 +Team Red 1 0 0 +GridSize 300 +Spawn 0 12 5 +Spawn 0 9.5 4 +BarrierMaker 50 2.5 8 2 6.5 1 5.5 1 4 5 0 6 -2 10 -3.5 12.5 -2.5 14.5 0 13 5 10.5 6.5 10 8 10 8.5 +BarrierMaker 50 8 -0.5 7.1 -1.3 7.2 -1.7 8.3 -2.3 9.5 -2.7 9.6 -2.7 9.7 -2.6 9.7 -1.6 8.9 -1.3 8.6 -0.8 8.7 -0.4 8.8 -0.3 8.8 0.2 8.7 0.3 8 0.3 7.9 0.2 7.9 -0.1 8.1 -0.2 8 -0.5 +BarrierMaker 50 10.5 -2.6 11.2 -2.5 11.6 -2.3 12.3 -1.8 12.5 -0.7 11.9 -0.6 11.7 -0.7 11.5 -1 11.5 -1.6 11.2 -1.9 10.6 -1.8 10.3 -1.9 10.3 -2.5 10.5 -2.6 +BarrierMaker 50 13.3 0.6 13 0 12 0.2 11.5 0 11.2 -0.3 10.5 0 10.2 0 10.2 0.7 10.8 1 11.3 0.8 12.1 0.8 12.6 1.1 13.3 0.9 13.3 0.6 +BarrierMaker 50 9.4 0.6 8.9 1.1 7.8 1 7.2 1.4 7.2 2 7.7 2.4 8.5 2.1 9.3 2.3 9.8 1.9 10.4 1.7 10.4 1.6 9.7 1.3 9.6 0.7 9.4 0.6 +BarrierMaker 50 6.7 -0.7 7.5 -0.3 7.5 0 +BarrierMaker 50 6.9 -0.1 5.9 -0.2 5.5 0.3 +BarrierMaker 50 5.7 0.9 6.2 0.3 7 0.5 +BarrierMaker 50 7.5 0.7 6.8 1.1 6.3 0.9 5.9 1.7 +BarrierMaker 50 5.1 0.9 4.9 1.6 4 2.3 4 3 +BarrierMaker 50 4.6 3.8 4.8 3.2 5.2 2.9 6 2.7 6.9 2.8 7.4 3.1 8 3.8 8 4.2 +BarrierMaker 50 12.1 2.1 11.5 3 10.6 3.2 9.7 3 9 3.3 8.7 4 8.7 4.6 +BarrierMaker 50 12.8 1.7 13.2 2 12.9 2.7 12.7 2.9 +BarrierMaker 50 12.3 3.3 11.7 3.8 +BarrierMaker 50 11.1 4.2 10.1 4.5 +BarrierMaker 50 6 4 6.5 4 6.5 4.5 6 4.5 6 4 +BarrierMaker 50 7.2 4.1 7.1 4.9 6.6 5.2 5.6 5.4 4.8 4.9 4.8 4.5 5.3 3.9 +BarrierMaker 50 7.7 6 7.5 5.4 7.9 5 8.5 5.1 9.3 5.7 9.2 6.3 8.7 6.8 8.2 6.7 8.1 6.5 8.6 6 8.5 5.7 8.1 5.5 7.9 5.7 7.9 6 7.7 6 +Spawn 0 11 2 +Spawn 0 6.5 2 +Spawn 0 6.5 -1.5 +Spawn 0 13.5 -0.5 +Spawn 0 8.5 3 +Spawn 0 4 4.5 +ForceFieldProjector 0 8.4 0.4 +ForceFieldProjector 0 10.3 0.9 +Turret 0 9.2 -1.3 +Turret 0 7.1 2.8 +Turret 0 7.5 5.9 +Turret 0 11.7 -0.5 +ForceFieldProjector 0 13.2 2.4 +ForceFieldProjector 0 11.8 3.5 +ForceFieldProjector 0 4.1 2.1 +RepairItem 5.5 5 +RepairItem 8.2 5.9 +Spawn 1 0.5 11.5 +Spawn 1 3 12.5 +BarrierMaker 50 10 8.5 10.5 10 11.5 11 11.5 12.5 7.5 16.5 6.5 18.5 2.5 20 0 19 -2 16.5 -0.5 11.5 2 10 2.5 8.5 2.5 8 +BarrierMaker 50 4.5 17 5.4 17.8 5.3 18.2 4.2 18.8 3 19.2 2.9 19.2 2.8 19.1 2.8 18.1 3.6 17.8 3.9 17.3 3.8 16.9 3.7 16.8 3.7 16.3 3.8 16.2 4.5 16.2 4.6 16.3 4.6 16.6 4.4 16.7 4.5 17 +BarrierMaker 50 2 19.1 1.3 19 0.9 18.8 0.199999 18.3 0 17.2 0.6 17.1 0.799999 17.2 1 17.5 1 18.1 1.3 18.4 1.9 18.3 2.2 18.4 2.2 19 2 19.1 +BarrierMaker 50 -0.799999 15.9 -0.5 16.5 0.5 16.3 1 16.5 1.3 16.8 2 16.5 2.3 16.5 2.3 15.8 1.7 15.5 1.2 15.7 0.4 15.7 -0.1 15.4 -0.799999 15.6 -0.799999 15.9 +BarrierMaker 50 3.1 15.9 3.6 15.4 4.7 15.5 5.3 15.1 5.3 14.5 4.8 14.1 4 14.4 3.2 14.2 2.7 14.6 2.1 14.8 2.1 14.9 2.8 15.2 2.9 15.8 3.1 15.9 +BarrierMaker 50 5.8 17.2 5 16.8 5 16.5 +BarrierMaker 50 5.6 16.6 6.6 16.7 7 16.2 +BarrierMaker 50 6.8 15.6 6.3 16.2 5.5 16 +BarrierMaker 50 5 15.8 5.7 15.4 6.2 15.6 6.6 14.8 +BarrierMaker 50 7.4 15.6 7.6 14.9 8.5 14.2 8.5 13.5 +BarrierMaker 50 7.9 12.7 7.7 13.3 7.3 13.6 6.5 13.8 5.6 13.7 5.1 13.4 4.5 12.7 4.5 12.3 +BarrierMaker 50 0.4 14.4 1 13.5 1.9 13.3 2.8 13.5 3.5 13.2 3.8 12.5 3.8 11.9 +BarrierMaker 50 -0.300001 14.8 -0.700001 14.5 -0.4 13.8 -0.200001 13.6 +BarrierMaker 50 0.199999 13.2 0.799999 12.7 +BarrierMaker 50 1.4 12.3 2.4 12 +BarrierMaker 50 6.5 12.5 6 12.5 6 12 6.5 12 6.5 12.5 +BarrierMaker 50 5.3 12.4 5.4 11.6 5.9 11.3 6.9 11.1 7.7 11.6 7.7 12 7.2 12.6 +BarrierMaker 50 4.8 10.5 5 11.1 4.6 11.5 4 11.4 3.2 10.8 3.3 10.2 3.8 9.7 4.3 9.8 4.4 10 3.9 10.5 4 10.8 4.4 11 4.6 10.8 4.6 10.5 4.8 10.5 +Spawn 1 1.5 14.5 +Spawn 1 6 14.5 +Spawn 1 6 18 +Spawn 1 -1 17 +Spawn 1 4 13.5 +Spawn 1 8.5 12 +ForceFieldProjector 1 4.1 16.1 +ForceFieldProjector 1 2.2 15.6 +Turret 1 3.3 17.8 +Turret 1 5.4 13.7 +Turret 1 5 10.6 +Turret 1 0.8 17 +ForceFieldProjector 1 -0.700001 14.1 +ForceFieldProjector 1 0.7 13 +ForceFieldProjector 1 8.4 14.4 +RepairItem 7 11.5 +RepairItem 4.3 10.6 +LoadoutZone 0 6 3.2 6 3.6 6.9 3.6 6.9 3.2 6.7 3 6.2 3 6 3.2 +LoadoutZone 0 10.4 -1 11.3 -1 11.3 -1.6 10.4 -1.6 +Teleporter 8.5 2.5 10 -3 +LoadoutZone 1 6.5 13.2 6.5 12.8 5.6 12.8 5.6 13.2 5.8 13.4 6.3 13.4 6.5 13.2 +LoadoutZone 1 2.1 17.4 1.2 17.4 1.2 18 2.1 18 +Teleporter 4 14 2.5 19.5 +Teleporter 6.1 10.1 8.3 4.4 +Teleporter 6.3 6.4 4.1 12.1 +FlagItem 0 9.9 -0.9 +FlagItem 1 2.6 17.3 +BarrierMaker 50 3.4 3.8 2.3 4.7 2.4 5.3 3.6 6.2 4.8 6.4 6.6 6.9 6.9 6.2 6.8 6.1 6 6 +BarrierMaker 50 9.1 12.7 10.2 11.8 10.1 11.2 8.9 10.3 7.7 10.1 5.9 9.6 5.6 10.3 5.7 10.4 6.5 10.5 +ForceFieldProjector 1 6.6 9.9 +ForceFieldProjector 0 5.9 6.6 diff --git a/tnl-1.5.0/tnl/exe/levels/football1.txt b/tnl-1.5.0/tnl/exe/levels/football1.txt new file mode 100644 index 0000000000000000000000000000000000000000..66a63899644f6dfd4a4ddcb446dbd791e6ef84d1 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/football1.txt @@ -0,0 +1,71 @@ +ZoneControlGameType 10 32 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName Diamond +GridSize 300 +GoalZone -1 -1.9 2.1 -1.1 2.1 -1.1 2.9 -1.9 2.9 +GoalZone -1 3.1 7.1 3.9 7.1 3.9 7.9 3.1 7.9 +GoalZone -1 8.1 2.1 8.9 2.1 8.9 2.9 8.1 2.9 +GoalZone -1 3.1 -2.9 3.9 -2.9 3.9 -2.1 3.1 -2.1 +LoadoutZone 0 9.9 -2.4 11.1 -2.4 10.9 -2 10.1 -2 +BarrierMaker 50 -2.5 4.5 -2.5 0.5 1.5 -3.5 5.5 -3.5 9.5 0.5 9.5 4.5 5.5 8.5 1.5 8.5 -2.5 4.5 +FlagItem -1 3.5 2.5 +Spawn 0 10.3 -2.6 +Spawn 0 9.9 -2.8 +Spawn 0 10.5 -3 +Spawn 0 11.1 -2.8 +Spawn 0 10.7 -2.6 +Spawn 0 11.6 -3 +Spawn 0 11.1 -3.3 +Spawn 0 10.5 -3.3 +Spawn 0 9.9 -3.3 +Spawn 0 9.4 -3 +Turret -1 9.4 2.5 +Turret -1 -2.4 2.5 +BarrierMaker 50 3 -2 4 -0.5 4 -0.4 2.5 0.5 1.5 0 1.5 -0.1 2.9 -2 3 -2 +BarrierMaker 50 4.5 -1 5 0.5 6 1.5 7.5 1 7.5 -1 7.4 -1.1 7.3 -1.1 6.5 0 6.4 0 5.5 -1.5 4.5 -1 +BarrierMaker 60 5.5 2.5 5.5 4 5 4.5 5.5 5 6.5 4 7 4.5 8 4 8 3.9 7.5 3.5 7 2.5 7 2 6.9 2 6.5 3 6 3 6 2.5 5.5 2.5 +BarrierMaker 165 4.1 5 3.5 5.7 3.7 5.9 4.4 5.7 4.5 6 4.4 6.2 3.9 6.3 3 6.1 3 6 3.3 5.5 3.7 5.1 4 4.9 4.1 5 +BarrierMaker 115 6.2 6 6.2 6.3 6.4 6.3 6.8 5.6 6.6 5.4 6.5 5.4 6.2 6 +BarrierMaker 50 0.5 3 1.5 4.5 1.5 5.5 1 5.5 1 5 0.5 4.5 0 4.5 0 5 -0.5 5 -0.5 4.5 -1 4 -1 3.5 0.5 3 +BarrierMaker 50 2 6.5 2 7 1 7 +BarrierMaker 50 -1 2 -0.5 1 +BarrierMaker 50 0 1 -0.5 2 +BarrierMaker 50 0.5 2 0.5 1 0 0 +ForceFieldProjector -1 6.4 1.5 +ForceFieldProjector -1 4 -0.7 +Turret -1 1.2 5.6 +Turret -1 1.6 5 +ForceFieldProjector -1 5.2 4.9 +BarrierMaker 50 10 -1.5 10.2 -1.5 10.3 -1.3 10.7 -1.3 10.8 -1.5 11 -1.5 11.5 -2.5 12 -2.5 12 -3.5 9 -3.5 9 -2.5 9.5 -2.5 10 -1.5 +Teleporter 10.5 -1.7 3.5 1.7 +LoadoutZone 1 -2.9 7.4 -4.1 7.4 -3.9 7 -3.1 7 +Spawn 1 -3.3 7.6 +Spawn 1 -2.9 7.8 +Spawn 1 -3.5 8 +Spawn 1 -4.1 7.8 +Spawn 1 -3.7 7.6 +Spawn 1 -4.6 8 +Spawn 1 -4.1 8.3 +Spawn 1 -3.5 8.3 +Spawn 1 -2.9 8.3 +Spawn 1 -2.4 8 +BarrierMaker 50 -3 6.5 -3.2 6.5 -3.3 6.3 -3.7 6.3 -3.8 6.5 -4 6.5 -4.5 7.5 -5 7.5 -5 8.5 -2 8.5 -2 7.5 -2.5 7.5 -3 6.5 +Teleporter -3.5 6.7 3.5 3.3 +LoadoutZone 1 2.5 2.1 2.7 2 2.7 3 2.5 2.9 +BarrierMaker 50 2.7 1.8 2.3 2 2.3 3 2.7 3.2 +LoadoutZone 0 4.5 2.1 4.3 2 4.3 3 4.5 2.9 +BarrierMaker 50 4.3 1.8 4.7 2 4.7 3 4.3 3.2 +BarrierMaker 205 5.3 4.7 6.3 3.6 6.7 3.6 7.1 4.1 7.4 3.9 7.4 3.8 7 3.4 6.8 2.9 +BarrierMaker 75 5.7 2.6 5.8 2.6 5.8 3.2 6.5 3.2 6.5 3.3 5.9 3.4 5.7 3.9 5.7 2.6 +BarrierMaker 85 6.7 3.1 6.9 2.2 6.9 2.7 7 2.9 6.8 2.8 6.8 2.7 +BarrierMaker 50 7.7 3.8 7.7 4 7.9 3.9 7.7 3.8 +BarrierMaker 320 5 -1.2 5.6 0.4 5.9 0.2 5.1 -1.3 +BarrierMaker 75 7.3 -1 7.3 0.8 6.2 0.8 7.4 -1 +BarrierMaker 125 7.2 -0.4 7.2 0.6 6.7 0.6 7.2 -0.5 +BarrierMaker 235 5.3 0.2 6.1 1 7 0.7 6.5 0 +BarrierMaker 145 6.9 0.9 7.4 0.7 +BarrierMaker 130 2.9 -1.7 3 -1.7 3.7 -0.6 3.7 -0.5 2.5 0.3 1.8 -0.1 1.8 -0.2 2.9 -1.7 +BarrierMaker 285 2.2 0 3.3 -1.1 +BarrierMaker 130 -0.3 4.8 -0.2 4.8 -0.2 4.2 0.6 4.2 1.2 4.8 1.2 5.3 1.3 5.3 1.3 4.6 0.4 3.3 -0.8 3.7 -0.8 3.9 -0.3 4.4 -0.3 4.8 +BarrierMaker 170 -0.6 4 0.6 3.7 diff --git a/tnl-1.5.0/tnl/exe/levels/football2.txt b/tnl-1.5.0/tnl/exe/levels/football2.txt new file mode 100644 index 0000000000000000000000000000000000000000..9bf7972b4b14a3f713b76ee8c99c0c343405840c --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/football2.txt @@ -0,0 +1,107 @@ +ZoneControlGameType 10 35 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName "Thank You, Drive Thru" +GridSize 300 +GoalZone -1 11.7 -7.3 12.3 -7.3 12.3 -6.7 11.7 -6.7 +LoadoutZone 0 16.4 -6.4 17.6 -6.4 17.4 -6 16.6 -6 +FlagItem -1 6 -3 +Spawn 0 16.8 -6.6 +Spawn 0 16.4 -6.8 +Spawn 0 17 -7 +Spawn 0 17.6 -6.8 +Spawn 0 17.2 -6.6 +Spawn 0 18.1 -7 +Spawn 0 17.6 -7.3 +Spawn 0 17 -7.3 +Spawn 0 16.4 -7.3 +Spawn 0 15.9 -7 +BarrierMaker 50 16.5 -5.5 16.7 -5.5 16.8 -5.3 17.2 -5.3 17.3 -5.5 17.5 -5.5 18 -6.5 18.5 -6.5 18.5 -7.5 15.5 -7.5 15.5 -6.5 16 -6.5 16.5 -5.5 +Teleporter 17 -5.7 6 -3.8 +LoadoutZone 1 -1.4 7.4 -2.6 7.4 -2.4 7 -1.6 7 +Spawn 1 -1.8 7.6 +Spawn 1 -1.4 7.8 +Spawn 1 -2 8 +Spawn 1 -2.6 7.8 +Spawn 1 -2.2 7.6 +Spawn 1 -3.1 8 +Spawn 1 -2.6 8.3 +Spawn 1 -2 8.3 +Spawn 1 -1.4 8.3 +Spawn 1 -0.9 8 +BarrierMaker 50 -1.5 6.5 -1.7 6.5 -1.8 6.3 -2.2 6.3 -2.3 6.5 -2.5 6.5 -3 7.5 -3.5 7.5 -3.5 8.5 -0.5 8.5 -0.5 7.5 -1 7.5 -1.5 6.5 +Teleporter -2 6.7 6 -2.2 +LoadoutZone 0 7.4 -4.2 6.6 -4.2 6.6 -3.8 7.4 -3.8 +BarrierMaker 50 4.5 -7.5 1.5 -7.5 1.5 -5.5 2.5 -4.5 1.5 -2.5 -0.5 -1.5 -1.5 -2.5 -3.5 -2.5 -3.5 0.5 -1.5 0.5 -0.5 -0.5 2.5 -0.5 5.5 2.5 5.5 5.5 4.5 6.5 4.5 8.5 7.5 8.5 7.5 6.5 6.5 5.5 7.5 3.5 9.5 2.5 10.5 3.5 12.5 3.5 12.5 0.5 11.5 -0.5 11.5 -4.5 12.5 -5.5 12.5 -7.5 10.5 -7.5 9.5 -6.5 5.5 -6.5 4.5 -7.5 +BarrierMaker 50 9.5 -5.5 7.5 -5.5 7.5 -4.5 8.5 -3.5 9.5 -3.5 9.5 -2.5 10.5 -2.5 10.5 -4.5 11.5 -5.5 10.5 -6.5 9.5 -5.5 +GoalZone -1 11.7 2.7 12.3 2.7 12.3 3.3 11.7 3.3 +GoalZone -1 1.7 -7.3 2.3 -7.3 2.3 -6.7 1.7 -6.7 +GoalZone -1 -3.3 -1.3 -2.7 -1.3 -2.7 -0.700001 -3.3 -0.700001 +GoalZone -1 5.7 7.7 6.3 7.7 6.3 8.3 5.7 8.3 +BarrierMaker 50 6.1 4.5 6.1 2.5 6.8 2.5 6.9 2.6 6.2 4.5 6.1 4.5 +BarrierMaker 50 7.2 2.1 7.3 2.2 8.5 2.2 9.5 1.7 9.5 1.5 10.5 1.5 11.5 0.5 10.5 -0.5 9.2 -0.5 8.2 -1.5 7.5 -1.5 6.5 -0.5 6.5 0.5 7.5 0.5 7.5 1.5 7.3 1.5 7.2 1.6 7.2 2.1 +BarrierMaker 15 3.7 -6.8 3.2 -6.3 +BarrierMaker 15 2.5 -6 2 -5.5 +BarrierMaker 15 3.7 -6.3 4.2 -5.8 +BarrierMaker 15 3.6 -5.8 3.2 -5.4 +BarrierMaker 15 2.7 -5.3 3.2 -4.8 +BarrierMaker 15 3.5 -5.2 4.1 -4.6 +BarrierMaker 15 4.9 -6.4 4.2 -6.4 3.9 -6.1 +BarrierMaker 15 4.5 -6.8 4.5 -6.4 +BarrierMaker 15 4.1 -5.2 4.9 -6 +BarrierMaker 15 2.9 -4 3.8 -4.9 +BarrierMaker 50 -2.8 -1.9 -2.4 -1.5 -2.4 -0.5 -2.8 -0.1 +BarrierMaker 50 -2.2 0.5 -1.8 0.1 -1.8 -0.199999 +BarrierMaker 50 -2.2 -2.5 -1.8 -2.1 -1.8 -1.8 +BarrierMaker 50 -1.8 -1.3 -1.8 -0.700001 -1.7 -0.699999 -1 -0.9 -1 -1.1 -1.7 -1.3 -1.8 -1.3 +BarrierMaker 50 1.1 -1.4 1.1 -1.1 3.5 -1.1 5.1 0.5 5.5 0.5 5.5 -0.5 4.5 -1.5 4.5 -2.5 3.5 -2.5 1.1 -1.4 +BarrierMaker 50 6.5 1.5 6.1 1.1 6 1.1 5.6 1.5 5.6 1.6 5.7 1.7 6.4 1.7 6.5 1.6 6.5 1.5 +BarrierMaker 50 6.5 6.5 6.5 7.2 6.2 7.5 5.8 7.5 5.5 7.2 5.5 6.5 5.8 6.2 6.2 6.2 6.5 6.5 +BarrierMaker 50 7 7.5 7 8.1 +BarrierMaker 50 5 7.5 5 8.1 +BarrierMaker 50 3.5 -3.1 4.5 -3.1 4.5 -4.1 4.4 -4.1 3.5 -3.2 3.5 -3.1 +BarrierMaker 50 6.5 -5.5 5.5 -5.5 5.5 -4.5 5.6 -4.5 6.5 -5.4 6.5 -5.5 +BarrierMaker 50 6.8 -3.5 6.8 -3 7.5 -3 7.5 -3.5 6.8 -3.5 +BarrierMaker 50 6.8 -2.5 6.8 -2 7.5 -2 7.5 -2.5 6.8 -2.5 +BarrierMaker 50 5.7 -1.8 5.7 -1.3 6.4 -1.3 6.4 -1.8 5.7 -1.8 +LoadoutZone 1 5.4 -2.2 4.6 -2.2 4.6 -1.8 5.4 -1.8 +BarrierMaker 50 9 -2.5 8.5 -2.5 8.5 -2 +BarrierMaker 50 8.5 -3.5 8.5 -3 +BarrierMaker 50 9.5 -2 9 -2 9 -1.5 +BarrierMaker 50 10 -1.5 9.5 -1.5 9.5 -1 +Turret -1 6.1 4.6 +ForceFieldProjector -1 5.2 5.9 +ForceFieldProjector -1 6.8 5.9 +Turret -1 -1.9 -1 +ForceFieldProjector -1 4.8 -5.8 +Turret -1 2.2 -5.8 +Turret -1 9.6 -1.1 +ForceFieldProjector -1 8.9 2.1 +ForceFieldProjector -1 11.4 0.3 +Turret -1 11.4 -5.3 +Turret -1 10.3 -6.4 +BarrierMaker 190 7.2 1.8 8.5 1.8 9.2 1.5 9.2 1.2 10.3 1.2 11.2 0.3 +BarrierMaker 225 7.9 1.5 7.9 -1.5 +BarrierMaker 215 6.5 -0.1 10.5 -0.1 10.7 0.1 10.7 0.2 10.2 0.6 8.6 0.6 8.6 1.5 +BarrierMaker 320 7 0.5 7 -0.3 7.8 -1 8 -1 8.9 -0.1 +BarrierMaker 200 7.1 -2.5 7.1 -2 +BarrierMaker 200 7.1 -3.5 7.1 -3 +BarrierMaker 200 6 -1.8 6 -1.3 +BarrierMaker 100 3.9 -3.3 3.9 -3.2 4.3 -3.2 4.3 -3.7 4.2 -3.7 3.9 -3.3 +BarrierMaker 75 4.4 -3.8 4.4 -4 +BarrierMaker 75 3.7 -3.1 3.8 -3.3 +BarrierMaker 100 6.1 -5.3 6.1 -5.4 5.7 -5.4 5.7 -4.9 5.8 -4.9 6.1 -5.3 +BarrierMaker 75 5.6 -4.8 5.6 -4.6 +BarrierMaker 75 6.3 -5.5 6.2 -5.3 +BarrierMaker 255 10 -2.5 10 -4.7 10.9 -5.6 10.5 -6 9.6 -5.1 7.9 -5.1 7.9 -4.7 8.7 -3.9 10 -3.9 +BarrierMaker 115 9.6 -4.5 8.5 -4.5 +BarrierMaker 65 -1 -1 -1.6 -1.2 -1.7 -1.2 -1.7 -0.8 -1.7 -0.8 -1.1 -1 -1.7 -1 +BarrierMaker 190 5.2 0.1 5.2 -0.4 4.1 -1.5 4.1 -2.2 3.6 -2.2 1.7 -1.4 3.8 -1.4 3.8 -1.3 5.1 0.1 5.2 0.1 +BarrierMaker 60 3.2 -1.8 3.9 -1.8 +BarrierMaker 75 1.7 -1.5 1.3 -1.3 1.3 -1.2 1.4 -1.2 1.8 -1.3 +BarrierMaker 95 6.1 1.3 6 1.3 5.8 1.5 5.8 1.6 6.3 1.6 6.3 1.5 6.1 1.3 +BarrierMaker 65 6.2 4.3 6.2 2.6 6.7 2.6 6.7 2.8 6.2 4 +BarrierMaker 85 6.5 2.8 6.3 2.8 6.3 3.5 6.6 2.9 6.5 2.8 +BarrierMaker 145 5.8 6.6 5.9 6.5 6.1 6.5 6.2 6.6 6.2 7.1 6.1 7.2 5.9 7.2 5.8 7.1 5.8 6.6 +BarrierMaker 15 4.1 -7.1 4.1 -6.8 +BarrierMaker 15 2.8 -6.5 2.8 -6.8 3.1 -7.1 3.3 -7.1 diff --git a/tnl-1.5.0/tnl/exe/levels/football3.txt b/tnl-1.5.0/tnl/exe/levels/football3.txt new file mode 100644 index 0000000000000000000000000000000000000000..4c9ededdff2784007efe4aa2b294a80e600cb59e --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/football3.txt @@ -0,0 +1,124 @@ +ZoneControlGameType 10 32 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName Gridiron +GridSize 300 +GoalZone -1 -4.4 -0.9 -3.6 -0.9 -3.6 -0.0999999 -4.4 -0.0999999 +GoalZone -1 3.6 8.6 4.4 8.6 4.4 9.4 3.6 9.4 +GoalZone -1 9.1 -0.4 9.9 -0.4 9.9 0.4 9.1 0.4 +GoalZone -1 -1.9 -3.9 -1.1 -3.9 -1.1 -3.1 -1.9 -3.1 +LoadoutZone 0 12.9 -4.9 14.1 -4.9 13.9 -4.5 13.1 -4.5 +FlagItem -1 3.5 2.5 +Spawn 0 13.3 -5.1 +Spawn 0 12.9 -5.3 +Spawn 0 13.5 -5.5 +Spawn 0 14.1 -5.3 +Spawn 0 13.7 -5.1 +Spawn 0 14.6 -5.5 +Spawn 0 14.1 -5.8 +Spawn 0 13.5 -5.8 +Spawn 0 12.9 -5.8 +Spawn 0 12.4 -5.5 +BarrierMaker 50 13 -4 13.2 -4 13.3 -3.8 13.7 -3.8 13.8 -4 14 -4 14.5 -5 15 -5 15 -6 12 -6 12 -5 12.5 -5 13 -4 +Teleporter 13.5 -4.2 3.5 1.7 +LoadoutZone 1 -7.9 8.9 -9.1 8.9 -8.9 8.5 -8.1 8.5 +Spawn 1 -8.3 9.1 +Spawn 1 -7.9 9.3 +Spawn 1 -8.5 9.5 +Spawn 1 -9.1 9.3 +Spawn 1 -8.7 9.1 +Spawn 1 -9.6 9.5 +Spawn 1 -9.1 9.8 +Spawn 1 -8.5 9.8 +Spawn 1 -7.9 9.8 +Spawn 1 -7.4 9.5 +BarrierMaker 50 -8 8 -8.2 8 -8.3 7.8 -8.7 7.8 -8.8 8 -9 8 -9.5 9 -10 9 -10 10 -7 10 -7 9 -7.5 9 -8 8 +Teleporter -8.5 8.2 3.5 3.3 +LoadoutZone 1 2.5 2.1 2.7 2 2.7 3 2.5 2.9 +BarrierMaker 50 2.7 1.8 2.3 2 2.3 3 2.7 3.2 +LoadoutZone 0 4.5 2.1 4.3 2 4.3 3 4.5 2.9 +BarrierMaker 50 4.3 1.8 4.7 2 4.7 3 4.3 3.2 +BarrierMaker 50 -5.5 3.5 -5.5 -1.5 -2 -5 2.5 -5 3.5 -6 7.5 -6 11 -2.5 11 1 10 2 10 7 7 10 3 10 1 8 -1 8 -3 10 -4 10 -6 8 -6 4 -5.5 3.5 +GoalZone -1 7.6 6.6 8.4 6.6 8.4 7.4 7.6 7.4 +GoalZone -1 7.6 -3.9 8.4 -3.9 8.4 -3.1 7.6 -3.1 +GoalZone -1 -4.4 3.6 -3.6 3.6 -3.6 4.4 -4.4 4.4 +GoalZone -1 -3.9 8.2 -3.1 8.2 -3.1 9 -3.9 9 +BarrierMaker 50 7.4 8.2 6.4 7.2 6.1 7.2 6 7.3 6 7.6 5.7 7.9 5.7 8.5 6.2 9 6.5 9 7 8.5 7.4 8.5 7.4 8.2 +BarrierMaker 50 9 6 4.4 6 +BarrierMaker 50 5.3 6.6 4.6 7.3 +BarrierMaker 50 3.4 7.7 2.1 6.4 +BarrierMaker 50 3.4 6.5 4 6.8 +BarrierMaker 50 2.6 5.8 3.8 5.2 +BarrierMaker 50 4.1 4.2 5.5 5 +BarrierMaker 50 5.2 3.6 4.8 4.6 +BarrierMaker 50 7.1 3.7 6.1 2.7 +BarrierMaker 50 6.3 4.8 7.9 4.3 +BarrierMaker 50 8.1 5.4 9.3 4 +BarrierMaker 50 8.2 3.3 6.7 2.3 7.1 1.4 9.2 1.8 9.1 2.8 8.2 3.3 +BarrierMaker 50 8.2 0.6 10.7 1.3 +BarrierMaker 50 8.2 -0.8 11 -1.3 +BarrierMaker 50 9.3 -2.7 8.6 -1.6 8.7 -1.5 10.1 -1.9 10.2 -2.2 9.4 -2.8 9.3 -2.7 +BarrierMaker 50 2.2 7.8 1.9 8.1 +BarrierMaker 50 1.3 6.9 1.6 7.3 1.8 7.3 1.8 7 1.3 6.1 1 6.1 1 6.9 1.3 6.9 +BarrierMaker 50 0 6.7 0 8 +BarrierMaker 50 0.5 6.4 -0.5 5.4 +BarrierMaker 50 0.8 5 0 5.9 +BarrierMaker 50 2.1 4.6 1.2 5.4 +BarrierMaker 50 2.3 5.2 1.9 4.8 +BarrierMaker 50 2.6 4 3.2 4.8 +BarrierMaker 50 6 -2.5 4 -3.5 1.5 -3.5 0 -2.5 -1 -1 -1 -0.5 -0.5 0 0 0 0.5 -0.5 0.5 -1.5 1 -2 2 -2.5 4 -2.5 5.5 -1.5 5.5 -0.5 6 0 7 -0.5 7 -1 6 -2.5 +BarrierMaker 50 -3.3 -2.8 -3.8 -3.2 +BarrierMaker 50 -2.8 -2.5 -2.3 -2.1 -2.7 -1.4 +BarrierMaker 50 -1.6 -1.6 -0.8 -1.3 +BarrierMaker 50 -3.9 -2.3 -3.2 -1.7 +BarrierMaker 50 -3.1 -0.5 -2 -0.5 -2 -1 +BarrierMaker 50 -1.4 0 -2.4 0.6 -2.8 0.1 +BarrierMaker 50 -2.4 7.5 -2.4 8.3 -2.3 8.3 -1.6 7.6 -1.6 7.5 -2.4 7.5 +BarrierMaker 50 -4.4 7.5 -4.4 8.3 -4.5 8.3 -5.2 7.6 -5.2 7.5 -4.4 7.5 +BarrierMaker 50 -4.4 6.8 -4.4 6 -4.5 6 -5.2 6.7 -5.2 6.8 -4.4 6.8 +BarrierMaker 50 -2.4 6.8 -2.4 6 -2.3 6 -1.6 6.7 -1.6 6.8 -2.4 6.8 +BarrierMaker 50 -3.8 5.9 -3.8 8 -3.2 8 -3.2 5.9 -3.8 5.9 +BarrierMaker 50 -5 5.4 -6 6.4 +BarrierMaker 50 -4.3 5.3 -3.3 5.1 -2.8 5.1 +BarrierMaker 50 -2 5.3 -1 6.2 -0.7 7.2 +BarrierMaker 50 -5.1 4.1 -5.1 4.8 -4.5 4.8 +BarrierMaker 50 -2.9 3.8 -2.9 3.1 -3.5 3.1 +BarrierMaker 50 -1.2 1.5 -2.3 3 -2 4.3 -1.1 4.6 -0.1 4.5 0.7 4 1.6 3.9 1.8 3.5 1.1 2.6 1 1.7 1.9 0.8 1.8 0.4 1.2 0.4 -1.2 1.5 +BarrierMaker 50 7.6 -4.5 7 -3.8 7 -3 7.7 -2.2 +BarrierMaker 50 6.7 -4.5 5.9 -5 +BarrierMaker 50 6 -4.5 5.7 -4 +BarrierMaker 50 5.4 -4.2 4.6 -4.4 +BarrierMaker 50 4.1 -4.5 3.5 -3.9 +BarrierMaker 50 3.2 -4.3 2.3 -4.3 0.9 -4.1 -0.2 -3.9 -1 -4.2 -1.8 -4.2 +BarrierMaker 50 -4.9 2.8 -3.7 2 -3.2 2.4 -2.7 2.3 -2.2 1.5 +Turret -1 -3.2 -0.5 +Turret -1 -0.4 -2.1 +ForceFieldProjector -1 2.3 -4.2 +ForceFieldProjector -1 2.4 -4.4 +Turret -1 4.9 -4.2 +Turret -1 8.1 -0.8 +Turret -1 8.1 0.6 +Teleporter 1.5 -2 -3.5 5.5 +Teleporter 4.5 -1.5 9.5 5 +Teleporter 3 -2 2.5 8.5 +Turret -1 -3.5 9.8 +ForceFieldProjector -1 -5.2 4.5 +BarrierMaker 95 7.2 8.3 7.2 8.2 6.4 7.4 6.2 7.4 6.2 7.7 5.9 8 5.9 8.4 6.3 8.8 6.4 8.8 6.9 8.3 7.2 8.3 +BarrierMaker 200 6.4 8.4 6.2 8.2 6.5 7.9 6.7 8.1 6.4 8.4 +BarrierMaker 90 1.7 7.3 1.2 6.3 1.1 6.3 1.1 6.7 1.3 6.7 1.3 6.6 +BarrierMaker 85 -2.3 8.2 -2.3 7.6 -1.7 7.6 -2.2 7.8 -2 8 +BarrierMaker 85 -2.3 6.1 -2.3 6.7 -1.7 6.7 -2.2 6.5 -2 6.3 +BarrierMaker 85 -4.5 6.1 -4.5 6.7 -5.1 6.7 -4.6 6.5 -4.8 6.3 +BarrierMaker 85 -4.5 8.2 -4.5 7.6 -5.1 7.6 -4.6 7.8 -4.8 8 +BarrierMaker 80 -3.4 7.8 -3.6 7.8 -3.6 6.1 -3.4 6.1 -3.4 7.8 +BarrierMaker 235 7.3 1.8 8.8 2.1 8.7 2.6 8.2 2.8 7.2 2.1 7.3 1.8 +BarrierMaker 95 8.7 -1.6 9.5 -2.6 10 -2.2 9.9 -2 8.9 -1.8 +BarrierMaker 125 9.3 -1.9 9.7 -2.3 +BarrierMaker 295 6.5 -0.5 6.5 -0.8 6.4 -1.1 5.8 -2 4 -3 1.7 -3 0.4 -2.2 -0.5 -0.8 +BarrierMaker 195 0.2 -1.4 0.2 -0.6 -0.1 -0.4 -0.4 -0.4 -0.7 -0.7 -0.7 -1.1 +BarrierMaker 175 5.8 -1.5 5.8 -0.7 6.1 -0.4 6.8 -0.8 +BarrierMaker 235 1.2 3.4 1.2 3.5 0.5 3.6 -0.3 4.1 -1.1 4.2 -1.7 4 -1.9 3 -0.9 1.8 0.9 1 1 1.1 0.6 1.7 0.7 2.8 1.2 3.4 +BarrierMaker 90 1.4 3.2 1.7 3.7 +BarrierMaker 90 1.3 1.1 1.7 0.7 1.7 0.6 1.6 0.5 1 0.7 +BarrierMaker 50 1.2 0.9 1.5 0.6 +BarrierMaker 510 -1.6 3.4 0.6 2.3 diff --git a/tnl-1.5.0/tnl/exe/levels/football4.txt b/tnl-1.5.0/tnl/exe/levels/football4.txt new file mode 100644 index 0000000000000000000000000000000000000000..187670e7eaacca0f25eb9f382a86c87de81a4e45 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/football4.txt @@ -0,0 +1,124 @@ +ZoneControlGameType 10 32 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName War +GridSize 270 +FlagItem -1 0 0 +LoadoutZone 0 -0.6 6.8 0.6 6.8 0.4 6.4 -0.4 6.4 +Spawn 0 -0.200001 7.3 +Spawn 0 -0.6 7.5 +Spawn 0 0 7.7 +Spawn 0 0.6 7.5 +Spawn 0 0.200001 7.3 +Spawn 0 1.1 7.7 +Spawn 0 0.6 8 +Spawn 0 0 8 +Spawn 0 -0.6 8 +Spawn 0 -1.1 7.7 +BarrierMaker 50 0 9.1 -0.2 9.1 -0.3 9 -1 9 -3 8 -5 8 -6 9 -8 9 -9 8 -9 6 -7 5 -6 3 -3 1 -3 0 +BarrierMaker 50 0 9.1 0.2 9.1 0.3 9 1 9 3 8 5 8 6 9 8 9 9 8 9 6 7 5 6 3 3 1 3 0 +GoalZone -1 -7.4 7.4 -6.6 7.4 -6.6 6.6 -7.4 6.6 +GoalZone -1 -0.4 5.4 0.4 5.4 0.4 4.6 -0.4 4.6 +GoalZone -1 6.6 7.4 7.4 7.4 7.4 6.6 6.6 6.6 +GoalZone -1 -0.4 2.4 0.4 2.4 0.4 1.6 -0.4 1.6 +BarrierMaker 50 -2 7 -1 6 -0.5 6 +BarrierMaker 50 0.5 6 1 6 2 7 +BarrierMaker 50 3 7 3 6.5 3.4 6.1 4 6.1 4.5 5.6 4.5 5.1 5 4.6 5.6 4.6 +BarrierMaker 50 3.9 7.3 4.3 6.9 5.2 6.9 +BarrierMaker 50 6 6.3 6 5.5 6.2 5.3 +BarrierMaker 50 8.2 6.7 8.2 7.5 7.8 7.9 7.4 7.9 +BarrierMaker 50 5.9 7.6 6.6 8.3 +Turret 0 6.1 6.1 +Turret 0 1.6 6.5 +Turret 0 0.6 5.9 +Turret 0 -0.6 5.9 +Turret 0 -1.6 6.5 +BarrierMaker 50 2.2 5.1 2.8 5.1 2.9 5.2 2.9 5.4 3 5.5 3.2 5.5 3.9 4.8 3.9 4.6 3.8 4.5 2.5 4.5 2.3 4.4 2.1 4.4 2 4.5 2 4.9 2.2 5.1 +BarrierMaker 50 4 3.6 4 3.7 4.3 4 4.5 4 4.8 3.7 4.8 3.6 4.7 3.5 4.1 3.5 4 3.6 +BarrierMaker 50 3.4 3.5 3.4 3.7 3.3 3.8 2.8 3.8 2.7 3.9 2 3.9 1.8 3.7 1.6 3.7 1 3.1 +BarrierMaker 50 0.6 4 0.1 3.5 -1.9 3.5 -2.9 2.5 -3.4 2.5 -3.7 2.8 -3.7 3.7 -4.2 4.2 -4.2 4.3 +BarrierMaker 50 -0.5 -0.8 -0.5 0.8 +BarrierMaker 50 0.5 -0.8 0.5 0.8 +BarrierMaker 50 -2.1 0.5 -1.3 0.8 -1 0.8 +BarrierMaker 50 1.3 0.8 2 0.8 2 1.4 3 2 3 2.6 2 2.6 1.8 2.4 1.8 2 1 1.6 1 1.4 1.3 0.8 +Turret -1 1.5 0.7 +Turret 0 -0.4 3.4 +ForceFieldProjector 0 1 3.2 +ForceFieldProjector 0 2.2 4.3 +BarrierMaker 50 -0.699999 4.4 -0.699999 4.8 +BarrierMaker 50 0.6 4.6 0.6 5 0.700001 5.1 1.2 5.1 1.3 5 1.3 4.9 0.9 4.5 0.700001 4.5 0.6 4.6 +BarrierMaker 50 1.9 5.7 2.3 5.7 2.6 6 +BarrierMaker 50 -3 5.9 -3 7 -3.5 7 +BarrierMaker 50 -4 6.5 -3.5 6 -3.5 5 +BarrierMaker 50 -4.2 5.5 -5.2 5.5 +BarrierMaker 50 -4.8 6.6 -4.8 5.5 +BarrierMaker 50 -4.7 7.2 -4 7.2 +BarrierMaker 50 -6.4 5.9 -6 6.3 -6 6.7 -5.7 7 -5.3 7 +BarrierMaker 50 -6.1 5.2 -5.6 4.2 -5.2 3.8 -4.8 3.6 -4.7 3.6 -4.7 3.7 -4.4 3.7 +BarrierMaker 50 -6 7.7 -6.4 8.1 +BarrierMaker 50 -6.9 8.2 -7.5 8.2 +BarrierMaker 50 -6.5 8.6 -6.5 9 +BarrierMaker 50 -8.6 7.4 -8.2 7 -8.1 7 -8 7.8 -8.1 7.9 -8.6 7.6 -8.6 7.4 +BarrierMaker 50 -8.3 6.5 -7.5 6.1 -7 6.1 -6.9 6 -6.9 5.6 -6.6 5.4 +BarrierMaker 50 -0.4 8.3 -0.4 9 +BarrierMaker 50 0.4 8.3 0.4 9 +Teleporter 0 8.7 1 0 +ForceFieldProjector 0 -0.299999 8.4 +LoadoutZone 1 0.6 -6.8 -0.6 -6.8 -0.4 -6.4 0.4 -6.4 +Spawn 1 0.200001 -7.3 +Spawn 1 0.6 -7.5 +Spawn 1 0 -7.7 +Spawn 1 -0.6 -7.5 +Spawn 1 -0.200001 -7.3 +Spawn 1 -1.1 -7.7 +Spawn 1 -0.6 -8 +Spawn 1 0 -8 +Spawn 1 0.6 -8 +Spawn 1 1.1 -7.7 +BarrierMaker 50 0 -9.1 0.2 -9.1 0.3 -9 1 -9 3 -8 5 -8 6 -9 8 -9 9 -8 9 -6 7 -5 6 -3 3 -1 3 0 +BarrierMaker 50 0 -9.1 -0.2 -9.1 -0.3 -9 -1 -9 -3 -8 -5 -8 -6 -9 -8 -9 -9 -8 -9 -6 -7 -5 -6 -3 -3 -1 -3 0 +GoalZone -1 7.4 -7.4 6.6 -7.4 6.6 -6.6 7.4 -6.6 +GoalZone -1 0.4 -5.4 -0.4 -5.4 -0.4 -4.6 0.4 -4.6 +GoalZone -1 -6.6 -7.4 -7.4 -7.4 -7.4 -6.6 -6.6 -6.6 +GoalZone -1 0.4 -2.4 -0.4 -2.4 -0.4 -1.6 0.4 -1.6 +BarrierMaker 50 2 -7 1 -6 0.5 -6 +BarrierMaker 50 -0.5 -6 -1 -6 -2 -7 +BarrierMaker 50 -3 -7 -3 -6.5 -3.4 -6.1 -4 -6.1 -4.5 -5.6 -4.5 -5.1 -5 -4.6 -5.6 -4.6 +BarrierMaker 50 -3.9 -7.3 -4.3 -6.9 -5.2 -6.9 +BarrierMaker 50 -6 -6.3 -6 -5.5 -6.2 -5.3 +BarrierMaker 50 -8.2 -6.7 -8.2 -7.5 -7.8 -7.9 -7.4 -7.9 +BarrierMaker 50 -5.9 -7.6 -6.6 -8.3 +Turret 1 -6.1 -6.1 +Turret 1 -1.6 -6.5 +Turret 1 -0.6 -5.9 +Turret 1 0.6 -5.9 +Turret 1 1.6 -6.5 +BarrierMaker 50 -2.2 -5.1 -2.8 -5.1 -2.9 -5.2 -2.9 -5.4 -3 -5.5 -3.2 -5.5 -3.9 -4.8 -3.9 -4.6 -3.8 -4.5 -2.5 -4.5 -2.3 -4.4 -2.1 -4.4 -2 -4.5 -2 -4.9 -2.2 -5.1 +BarrierMaker 50 -4 -3.6 -4 -3.7 -4.3 -4 -4.5 -4 -4.8 -3.7 -4.8 -3.6 -4.7 -3.5 -4.1 -3.5 -4 -3.6 +BarrierMaker 50 -3.4 -3.5 -3.4 -3.7 -3.3 -3.8 -2.8 -3.8 -2.7 -3.9 -2 -3.9 -1.8 -3.7 -1.6 -3.7 -1 -3.1 +BarrierMaker 50 -0.6 -4 -0.1 -3.5 1.9 -3.5 2.9 -2.5 3.4 -2.5 3.7 -2.8 3.7 -3.7 4.2 -4.2 4.2 -4.3 +BarrierMaker 50 2.1 -0.5 1.3 -0.8 1 -0.8 +BarrierMaker 50 -1.3 -0.8 -2 -0.8 -2 -1.4 -3 -2 -3 -2.6 -2 -2.6 -1.8 -2.4 -1.8 -2 -1 -1.6 -1 -1.4 -1.3 -0.8 +Turret -1 -1.5 -0.7 +Turret 1 0.4 -3.4 +ForceFieldProjector 1 -1 -3.2 +ForceFieldProjector 1 -2.2 -4.3 +BarrierMaker 50 0.699999 -4.4 0.699999 -4.8 +BarrierMaker 50 -0.6 -4.6 -0.6 -5 -0.700001 -5.1 -1.2 -5.1 -1.3 -5 -1.3 -4.9 -0.9 -4.5 -0.700001 -4.5 -0.6 -4.6 +BarrierMaker 50 -1.9 -5.7 -2.3 -5.7 -2.6 -6 +BarrierMaker 50 3 -5.9 3 -7 3.5 -7 +BarrierMaker 50 4 -6.5 3.5 -6 3.5 -5 +BarrierMaker 50 4.2 -5.5 5.2 -5.5 +BarrierMaker 50 4.8 -6.6 4.8 -5.5 +BarrierMaker 50 4.7 -7.2 4 -7.2 +BarrierMaker 50 6.4 -5.9 6 -6.3 6 -6.7 5.7 -7 5.3 -7 +BarrierMaker 50 6.1 -5.2 5.6 -4.2 5.2 -3.8 4.8 -3.6 4.7 -3.6 4.7 -3.7 4.4 -3.7 +BarrierMaker 50 6 -7.7 6.4 -8.1 +BarrierMaker 50 6.9 -8.2 7.5 -8.2 +BarrierMaker 50 6.5 -8.6 6.5 -9 +BarrierMaker 50 8.6 -7.4 8.2 -7 8.1 -7 8 -7.8 8.1 -7.9 8.6 -7.6 8.6 -7.4 +BarrierMaker 50 8.3 -6.5 7.5 -6.1 7 -6.1 6.9 -6 6.9 -5.6 6.6 -5.4 +BarrierMaker 50 0.4 -8.3 0.4 -9 +BarrierMaker 50 -0.4 -8.3 -0.4 -9 +Teleporter 0 -8.7 -1 0 +ForceFieldProjector 1 0.299999 -8.4 diff --git a/tnl-1.5.0/tnl/exe/levels/football5.txt b/tnl-1.5.0/tnl/exe/levels/football5.txt new file mode 100644 index 0000000000000000000000000000000000000000..0871baa6ba9aa10902162d9e630cb9eb5ba8559c --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/football5.txt @@ -0,0 +1,116 @@ +ZoneControlGameType 10 32 +Team Blue 0 0 1 +Team Red 1 0 0 +Team Yellow 1 1 0 +LevelName "Home Turf" +GridSize 300 +GoalZone -1 -0.9 -5.9 -0.0999999 -5.9 -0.0999999 -5.1 -0.9 -5.1 +LoadoutZone 0 -5.1 -8.4 -3.9 -8.4 -4.1 -8 -4.9 -8 +FlagItem -1 0.6 -1.7 +Spawn 0 -4.7 -8.6 +Spawn 0 -5.1 -8.8 +Spawn 0 -4.5 -9 +Spawn 0 -3.9 -8.8 +Spawn 0 -4.3 -8.6 +Spawn 0 -3.4 -9 +Spawn 0 -3.9 -9.3 +Spawn 0 -4.5 -9.3 +Spawn 0 -5.1 -9.3 +Spawn 0 -5.6 -9 +BarrierMaker 50 -5 -7.5 -4.8 -7.5 -4.7 -7.3 -4.3 -7.3 -4.2 -7.5 -4 -7.5 -3.5 -8.5 -3 -8.5 -3 -9.5 -6 -9.5 -6 -8.5 -5.5 -8.5 -5 -7.5 +Teleporter -4.5 -7.7 0 -8 +BarrierMaker 50 -1.7 -5.1 -1.5 -5.5 -1.5 -6.5 -0.5 -7.5 -0.5 -8.5 1.5 -8.5 2.5 -9.5 4.5 -9.5 5 -9 5 -7.8 4.5 -7.3 4.5 -6.5 3.5 -5.5 3.5 -3.5 5.4 -1.6 +GoalZone -1 3.1 -8.9 3.9 -8.9 3.9 -8.1 3.1 -8.1 +BarrierMaker 50 -1 -4.5 -0.3 -4.5 0.2 -4 +BarrierMaker 50 -0.5 -3.9 -0.5 -3.2 0.9 -3.2 +BarrierMaker 50 1 -3.8 1.9 -4.7 +BarrierMaker 50 0.6 -5 1.4 -4.2 +BarrierMaker 50 0.1 -6.8 0.9 -6.8 1.3 -6.4 2.3 -6.4 2.9 -5.8 +BarrierMaker 50 2.8 -8.5 2.8 -7.9 +BarrierMaker 50 2.5 -7.2 3.2 -7.2 3.8 -7.8 3.9 -7.8 +BarrierMaker 50 0.5 -7.5 1 -7.5 1.3 -7.8 1.9 -7.8 +BarrierMaker 50 1.5 -5.5 1.8 -5.5 1.8 -5.8 +BarrierMaker 50 2.3 -4.2 1.8 -3.7 1.8 -3.4 1.9 -3.3 2.5 -3.3 2.9 -3.7 +Turret 0 0.2 -6.7 +Turret 0 3.6 -9.4 +BarrierMaker 50 4.4 -8.7 4.2 -8.7 4.1 -8.6 4.1 -8.3 +ForceFieldProjector 0 0.1 -4.2 +ForceFieldProjector 0 0.7 -7.4 +LoadoutZone 0 -0.4 -3.7 0.4 -3.7 0.4 -3.3 -0.4 -3.3 +ForceFieldProjector -1 3.4 -3.7 +GoalZone -1 5.55955 -0.629423 5.15955 0.0633973 4.46673 -0.336603 4.86673 -1.02942 +LoadoutZone 1 9.82461 -3.01673 9.22461 -1.9775 8.9782 -2.3507 9.3782 -3.04352 +Spawn 1 9.79782 -2.57032 +Spawn 1 10.171 -2.81673 +Spawn 1 10.0442 -2.19711 +Spawn 1 9.57102 -1.7775 +Spawn 1 9.59782 -2.22391 +Spawn 1 9.49423 -1.24449 +Spawn 1 10.004 -1.5275 +Spawn 1 10.304 -2.04711 +Spawn 1 10.604 -2.56673 +Spawn 1 10.5942 -3.14974 +BarrierMaker 50 8.99519 -3.38013 8.89519 -3.20692 8.67198 -3.22032 8.47199 -2.87391 8.59519 -2.68731 8.49519 -2.5141 9.11121 -1.58109 8.86121 -1.14808 9.72724 -0.648077 11.2272 -3.24615 10.3612 -3.74615 10.1112 -3.31314 8.99519 -3.38013 +Teleporter 8.9184 -2.84711 6.9282 1.2 +BarrierMaker 50 5.4 -1.6 6.37916 -0.849038 6.74519 0.516987 7.61121 1.01699 6.61121 2.74904 6.97724 4.11506 5.97724 5.84711 5.29423 6.03012 4.255 5.43013 4.07199 4.74711 3.37916 4.34711 3.01314 2.98109 1.28109 1.98109 -1.3 2.7 +GoalZone -1 6.15763 4.33468 5.75763 5.0275 5.06481 4.6275 5.46481 3.93468 +BarrierMaker 50 4.39711 -1.41603 4.04711 -0.809808 3.3641 -0.626795 +BarrierMaker 50 3.6275 -1.28301 3.02128 -1.63301 2.32128 -0.420578 +BarrierMaker 50 2.7909 -0.0339749 3.12032 1.19545 +BarrierMaker 50 4.03013 0.219615 2.93731 0.512435 +BarrierMaker 50 5.83897 0.686602 5.43897 1.37942 4.89256 1.52583 4.39256 2.39186 3.57295 2.61147 +BarrierMaker 50 5.96122 3.87487 5.4416 3.57487 +BarrierMaker 50 4.98538 2.96506 4.63538 3.57128 4.855 4.3909 4.805 4.4775 +BarrierMaker 50 6.24519 1.38301 5.99519 1.81603 6.105 2.22583 5.805 2.74545 +BarrierMaker 50 4.01314 1.24904 3.86314 1.50885 4.12295 1.65885 +BarrierMaker 50 2.48731 1.29186 2.30429 0.608846 2.04449 0.458845 1.90788 0.495448 1.60788 1.01506 1.75429 1.56147 +Turret 1 5.70237 0.723205 +Turret 1 6.34064 5.01769 +BarrierMaker 50 5.33442 5.36051 5.43442 5.1873 5.39782 5.0507 5.13801 4.9007 +ForceFieldProjector 1 3.58731 -0.613398 +ForceFieldProjector 1 6.05859 1.50622 +LoadoutZone 1 3.40429 -1.29641 3.00429 -0.60359 2.65788 -0.80359 3.05788 -1.49641 +ForceFieldProjector -1 1.50429 1.99449 +GoalZone -1 -2.15955 2.22942 -2.55955 1.5366 -1.86673 1.1366 -1.46673 1.82942 +LoadoutZone 2 -2.22461 7.11673 -2.82461 6.0775 -2.3782 6.0507 -1.9782 6.74352 +Spawn 2 -2.59782 6.87032 +Spawn 2 -2.57102 7.31673 +Spawn 2 -3.04423 6.89711 +Spawn 2 -3.17102 6.2775 +Spawn 2 -2.79782 6.52391 +Spawn 2 -3.59423 5.94448 +Spawn 2 -3.60403 6.5275 +Spawn 2 -3.30404 7.04711 +Spawn 2 -3.00404 7.56673 +Spawn 2 -2.49423 7.84974 +BarrierMaker 50 -1.49519 6.58012 -1.59519 6.40692 -1.47198 6.22031 -1.67199 5.87391 -1.89519 5.8873 -1.99519 5.7141 -3.11121 5.78109 -3.36121 5.34807 -4.22724 5.84807 -2.72724 8.44615 -1.86121 7.94615 -2.11122 7.51314 -1.49519 6.58012 +Teleporter -1.9184 6.24711 -4.4282 2.5 +BarrierMaker 50 -1.3 2.7 -2.37916 3.04904 -3.74519 2.68301 -4.61121 3.18301 -5.61121 1.45096 -6.97724 1.08493 -7.97724 -0.647115 -7.79422 -1.33013 -6.755 -1.93013 -6.07199 -1.74711 -5.37916 -2.14711 -4.01314 -1.78109 -2.28109 -2.78109 -1.7 -5.1 +GoalZone -1 -6.75763 0.265321 -7.15763 -0.427499 -6.4648 -0.827499 -6.0648 -0.134678 +BarrierMaker 50 -0.897113 1.61602 -1.24711 1.00981 -1.0641 0.326794 +BarrierMaker 50 -0.627498 0.883012 -0.0212805 0.533012 -0.72128 -0.679423 +BarrierMaker 50 -1.2909 -0.466026 -2.52032 -0.79545 +BarrierMaker 50 -2.13013 0.480385 -1.83731 -0.612436 +BarrierMaker 50 -3.43897 1.8134 -3.83897 1.12058 -3.69256 0.574166 -4.19256 -0.291859 -3.97295 -1.11147 +BarrierMaker 50 -6.26121 0.325129 -5.7416 0.0251285 +BarrierMaker 50 -4.98538 -0.0650647 -5.33538 -0.671283 -6.155 -0.890896 -6.205 -0.977499 +BarrierMaker 50 -4.24519 1.81699 -4.49519 1.38397 -4.905 1.27417 -5.205 0.75455 +BarrierMaker 50 -3.01314 -0.0490381 -3.16314 -0.308846 -3.42295 -0.158846 +BarrierMaker 50 -2.28731 -1.39186 -1.60429 -1.20885 -1.34448 -1.35885 -1.30788 -1.49545 -1.60788 -2.01506 -2.15429 -2.16147 +Turret 2 -3.40237 1.6768 +Turret 2 -7.44064 0.0823084 +BarrierMaker 50 -7.23442 -0.960512 -7.13442 -0.787307 -6.99782 -0.750704 -6.73801 -0.900704 +ForceFieldProjector 2 -1.18731 0.513397 +ForceFieldProjector 2 -4.25859 1.59378 +LoadoutZone 2 -0.504293 0.696409 -0.904293 0.00358891 -0.557883 -0.196411 -0.157883 0.496409 +ForceFieldProjector -1 -2.40429 -2.59449 +BarrierMaker 50 -0.5 -1.8 0.1 -0.7 0.4 -0.7 +BarrierMaker 50 1.4364 -2.33934 0.234315 -2.69289 0.0221825 -2.48076 +BarrierMaker 50 1.01924 -0.959441 2.11924 -1.55944 2.11924 -1.85944 +BarrierMaker 50 2.7 -2.7 2.7 -2.2 2.9 -2.2 3.1 -2.1 +BarrierMaker 50 3.4 -2.6 3.8 -2.3 3.8 -1.9 4.1 -1.9 +BarrierMaker 50 0.6 1.3 0.6 0.9 1.1 0.7 1.4 0.3 1.6 -0.1 +BarrierMaker 50 0.9 0.3 0.5 -0.2 0.2 -0.1 0.1 -0.2 +Turret -1 -0.3 -1.2 +Turret -1 1.7 -1.2 +Turret -1 0.9 -2.6 diff --git a/tnl-1.5.0/tnl/exe/levels/hunters1.txt b/tnl-1.5.0/tnl/exe/levels/hunters1.txt new file mode 100644 index 0000000000000000000000000000000000000000..52d10fbe961f17f5214ce2cd94c28a07a7ba39aa --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/hunters1.txt @@ -0,0 +1,45 @@ +HuntersGameType 10 1 15 5000 +LevelName "Tin Man's Reprise" +Team Hunters 1 1 0 +GridSize 380 +HuntersNexusObject 4.4 2.5 50 50 +Teleporter -0.5 5.5 0 11.5 +Teleporter 2 12.1 8.8 2.7 +BarrierMaker 50 0.5 9 1.2 8.6 1.2 8.5 0.6 8.5 -0.2 8.8 -0.5 9.8 -0.3 10.2 0.4 9.9 0.5 9.8 0.3 9.4 0.5 9 +RepairItem -0.5 8.9 +Spawn 0 2.6 1.7 +Spawn 0 9.1 4.1 +Spawn 0 5.9 6.7 +Spawn 0 6.2 3.2 +Spawn 0 0.5 4.5 +BarrierMaker 50 4.2 2 3.9 2.4 +BarrierMaker 50 3.9 2.7 4.3 3 +BarrierMaker 50 4.5 2 4.9 2.3 +BarrierMaker 50 4.9 2.6 4.6 3 +BarrierMaker 50 2 1.6 1 2 -1 5 -1 6 -0.1 6 -0.1 5.6 0.1 5.6 1 6.5 1.2 6.5 2.3 5 2.5 5 3.5 6 3.9 6.5 3.9 6.9 4 7.5 4.4 7.7 5.1 7.5 5.5 7.2 5.9 7.1 6.6 7.3 7.2 7.4 7.8 7.4 8.4 6.9 8.6 6 8.6 5.5 8.9 4.9 9.6 4.5 10 3.8 10 3.5 9.4 3.2 9.3 2.9 9.3 2.4 8.8 2.1 8.2 2.4 8 3.2 7.5 4.2 7.3 4.3 7.2 4.2 7.2 4 7.4 2.9 7.2 2 6.7 1.6 6.2 1.6 6 1 6 0.2 5.5 -0.3 5 -0.5 4.2 -0.4 3.3 0.3 2.7 1.1 2 1.6 +BarrierMaker 50 0.7 4.8 0.4 5.1 0.5 5.4 1.1 5.2 1.9 4.6 1.8 4.4 0.7 4.8 +BarrierMaker 50 1.1 4.1 0.7 4 0.7 3.4 1.6 2.8 2.3 3.3 2.3 3.4 1.1 4.1 +BarrierMaker 50 3.5 4.4 3.1 4 3.2 3.5 +BarrierMaker 50 8.7 4 8 4.2 7.9 4.4 8 5 8.1 5 8.8 4.2 8.7 4 +BarrierMaker 50 6.8 4.5 6.3 3.6 6.1 3.7 6.3 5.2 6.4 5.3 6.8 5.2 6.8 4.5 +BarrierMaker 50 4.5 5.2 4.4 5.3 4.9 6.2 5.1 6.2 5.8 5.7 5.8 5.6 4.5 5.2 +BarrierMaker 50 5.2 4.8 4.6 4.8 4.6 4.5 +BarrierMaker 50 5 4.4 5 4 4.3 4 4 4.4 +BarrierMaker 50 4.2 0.7 5.2 1 5.3 0.9 5.4 0.3 5.3 0.2 4.2 0.5 4.2 0.7 +BarrierMaker 50 5.7 1.8 5.7 2.8 6.3 2.8 +BarrierMaker 50 6.3 2.2 6.8 2.2 6.8 3.4 +BarrierMaker 50 7.4 5.3 7.4 6.2 6.7 6.6 6.7 6.8 7.3 7 7.8 6.4 +Teleporter 4.8 -4.76837e-007 3.9 9.3 +Teleporter 4.7 7.1 1.8 10.6 +RepairItem 6 2.5 +RepairItem 7.3 6.6 +BarrierMaker 50 3.3 4.9 3.9 4.9 3.9 5.5 +BarrierMaker 50 5 3.5 5.2 3.5 5.5 4.2 5.7 4.2 +BarrierMaker 50 5.5 5.1 5.9 4.7 +BarrierMaker 50 5.7 6.3 6.3 6 +BarrierMaker 50 6.7 5.8 7 5.7 +BarrierMaker 50 -0.2 11.9 -0.5 10.9 -1 9.9 -0.8 8.7 0.1 7.9 1.2 8 1.8 8.3 1.8 8.8 0.9 9.3 0.9 9.4 1.1 9.6 1.2 9.6 2.7 9 3.5 9.2 4 9 4.1 9 4.3 9.4 4.3 9.5 3.7 9.7 3.2 11 2.7 11.8 2.7 11.9 3.2 12.1 3.2 12.2 2.8 12.6 1.7 12.5 1.4 11.5 1.8 11.2 2.2 11.5 2.3 11.5 2.8 10.4 3.1 9.9 2.9 9.6 2.3 9.7 1.4 10 1.4 10.1 1.6 10.3 1.7 10.3 1.9 10.1 2.5 9.9 2.6 9.9 2.7 10.1 2.2 11.1 2.1 11.1 1.8 10.9 1.2 11.3 1.1 11.2 0.8 10.3 0.5 10.3 0.1 10.7 0.5 11.6 0.4 11.7 -0.1 11.9 -0.2 11.9 +BarrierMaker 50 8.4 3 8.8 3.2 +BarrierMaker 50 8.4 3.6 8 3.8 +BarrierMaker 50 8.7 3.6 9.2 3.7 +BarrierMaker 50 2.1 2.5 2.2 2.7 2.6 2.9 3 2.8 3.1 2.4 3.1 2 3.3 1.6 3.8 1.5 4.4 1.5 4.5 1.4 4.4 1.2 3.9 1.1 3.7 0.9 3.5 0.9 3.3 1 3 1.5 2.7 2.1 2.5 2.1 2.3 2.2 2.1 2.4 2.1 2.5 diff --git a/tnl-1.5.0/tnl/exe/levels/hunters2.txt b/tnl-1.5.0/tnl/exe/levels/hunters2.txt new file mode 100644 index 0000000000000000000000000000000000000000..8ae78d34f6995e1e8ecab071eb35179858cfcb95 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/hunters2.txt @@ -0,0 +1,80 @@ +HuntersGameType 10 1 15 5000 +Team Hunters 1 1 0 +LevelName Colosseum +GridSize 300 +HuntersNexusObject 0 0 60 60 +Spawn 0 0 -7 +Spawn 0 1 7 +Spawn 0 9.90927e-007 7 +Spawn 0 -1 7 +BarrierMaker 50 -0.3 0.7 -0.2 0.6 0.2 0.6 0.3 0.7 +BarrierMaker 50 -0.7 -0.299999 -0.6 -0.2 -0.6 0.200001 -0.7 0.3 +BarrierMaker 50 -0.3 -0.7 -0.2 -0.6 0.2 -0.6 0.3 -0.7 +BarrierMaker 50 0.700001 -0.299999 0.600001 -0.2 0.600001 0.200001 0.700001 0.3 +BarrierMaker 50 1.8 -6.3 1.8 -5.5 +Teleporter 0.3 -5.2 0.3 3.4 +Teleporter -0.3 5.2 -0.3 -3.4 +BarrierMaker 50 0 -4.9 0 -5.4 0.1 -5.5 0.5 -5.5 0.6 -5.4 0.6 -4.4 0.5 -4.3 -1.1 -4.3 +BarrierMaker 50 -2.4 -4.3 -1.9 -4.3 -1.8 -4.4 -1.8 -4.8 -1.7 -4.9 -0.599999 -4.9 +BarrierMaker 50 -2.4 -3.7 -1.9 -3.7 -1.8 -3.6 -1.8 -2.6 -1.9 -2.5 -2.4 -2.5 +BarrierMaker 50 -1.2 -2.5 -1.2 -3.6 -1.1 -3.7 -0.0999994 -3.7 0 -3.6 0 -3.2 -0.0999994 -3.1 -0.599999 -3.1 +BarrierMaker 50 0.6 -3.7 0.6 -3.2 0.7 -3.1 1.1 -3.1 1.2 -3 1.2 -2.5 +BarrierMaker 50 1.2 -3.7 1.7 -3.7 1.8 -3.6 1.8 -2.6 1.9 -2.5 2.4 -2.5 +BarrierMaker 50 2.4 -3.7 2.4 -4.2 2.3 -4.3 1.2 -4.3 +BarrierMaker 50 1.8 -4.9 1.3 -4.9 1.2 -5 1.2 -6.2 1.1 -6.3 0.6 -6.3 +BarrierMaker 50 -0.599999 -6.3 -0.599999 -5.6 -0.7 -5.5 -1.7 -5.5 -1.8 -5.6 -1.8 -6.3 +BarrierMaker 50 -1.8 6.3 -1.8 5.5 +BarrierMaker 50 0 4.9 0 5.4 -0.1 5.5 -0.5 5.5 -0.6 5.4 -0.6 4.4 -0.5 4.3 1.1 4.3 +BarrierMaker 50 2.4 4.3 1.9 4.3 1.8 4.4 1.8 4.8 1.7 4.9 0.6 4.9 +BarrierMaker 50 2.4 3.7 1.9 3.7 1.8 3.6 1.8 2.6 1.9 2.5 2.4 2.5 +BarrierMaker 50 1.2 2.5 1.2 3.6 1.1 3.7 0.1 3.7 0 3.6 0 3.2 0.1 3.1 0.6 3.1 +BarrierMaker 50 -0.6 3.7 -0.6 3.2 -0.699999 3.1 -1.1 3.1 -1.2 3 -1.2 2.5 +BarrierMaker 50 -1.2 3.7 -1.7 3.7 -1.8 3.6 -1.8 2.6 -1.9 2.5 -2.4 2.5 +BarrierMaker 50 -2.4 3.7 -2.4 4.2 -2.3 4.3 -1.2 4.3 +BarrierMaker 50 -1.8 4.9 -1.3 4.9 -1.2 5 -1.2 6.2 -1.1 6.3 -0.6 6.3 +BarrierMaker 50 0.6 6.3 0.6 5.6 0.700001 5.5 1.7 5.5 1.8 5.6 1.8 6.3 +ForceFieldProjector 0 0.3 0.6 +ForceFieldProjector 0 -0.299999 -0.6 +ForceFieldProjector 0 -0.299999 0.6 +ForceFieldProjector 0 0.3 -0.6 +BarrierMaker 50 2.4 3.1 2.9 3.1 3 3 3 -3 2.9 -3.1 2.4 -3.1 +BarrierMaker 50 -2.4 3.1 -2.9 3.1 -3 3 -3 -3.1 -2.9 -3.2 -2.4 -3.2 +BarrierMaker 50 -5 -8 5 -8 7 -6 7 6 5 8 -5 8 -7 6 -7 -6 -5 -8 +Spawn 0 -3.5 4.5 +Spawn 0 3.5 4.5 +Spawn 0 3.5 -4.5 +Spawn 0 -3.5 -4.5 +BarrierMaker 50 -5 -4.5 -5 -5 -4 -6 -3.5 -6 +BarrierMaker 50 -4 -3 -4 -0.5 +BarrierMaker 50 -4 0 -4 1 +BarrierMaker 50 -4 1.5 -4 3 +BarrierMaker 50 -5 4 -5 0.5 +BarrierMaker 50 -5 0 -5 -1 +BarrierMaker 50 -5 -1.5 -5 -4 +BarrierMaker 50 -6 -5 -6 -3 +BarrierMaker 50 -6 -2.5 -6 1.5 +BarrierMaker 50 -6 2 -6 5 +BarrierMaker 50 5 -4.5 5 -5 4 -6 3.5 -6 +BarrierMaker 50 5 4.5 5 5 4 6 3.5 6 +BarrierMaker 50 -5 4.5 -5 5 -4 6 -3.5 6 +BarrierMaker 50 4 3 4 0.5 +BarrierMaker 50 4 0 4 -1 +BarrierMaker 50 4 -1.5 4 -3 +BarrierMaker 50 5 -4 5 -0.5 +BarrierMaker 50 5 0 5 1 +BarrierMaker 50 5 1.5 5 4 +BarrierMaker 50 6 5 6 3 +BarrierMaker 50 6 2.5 6 -1.5 +BarrierMaker 50 6 -2 6 -5 +BarrierMaker 50 -4 7 -2.5 7 +BarrierMaker 50 4 7 2.5 7 +BarrierMaker 50 4 -7 2.5 -7 +BarrierMaker 50 -4 -7 -2.5 -7 +Teleporter 6.5 0.5 1.2 6 +Teleporter -6.5 0.5 -1.2 -6 +Spawn 0 -1 -7 +Spawn 0 1 -7 +RepairItem 5.5 -6.5 +RepairItem -5.5 -6.5 +RepairItem 5.5 6.5 +RepairItem -5.5 6.5 diff --git a/tnl-1.5.0/tnl/exe/levels/level9.txt b/tnl-1.5.0/tnl/exe/levels/level9.txt new file mode 100644 index 0000000000000000000000000000000000000000..623220a37fa2d08879a2cba754c9b5b5966feda5 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/level9.txt @@ -0,0 +1,108 @@ +CTFGameType 10 8 +Team Blue 0 0 1 +Team Red 1 0 0 +GridSize 300 +BarrierMaker 25 10 +LoadoutZone 0 0.2 3.2 0.8 3.2 0.8 3.8 0.2 3.8 +ResourceItem 8.2 4.5 +ResourceItem 4 10 +ResourceItem 11 10 +ResourceItem 7.5 19 +ResourceItem 7.5 1 +CTFFlagItem 0 7.5 4.5 +Teleporter 14 1 14.8 8.2 +CTFFlagItem 1 7.5 15.5 +BarrierMaker 5 5 6 6 9 6 10 5 +BarrierMaker 6.5 3.5 6 4 6 5 6.5 5.5 +BarrierMaker 8.5 3.5 9 4 9 5 8.5 5.5 +BarrierMaker 5 4 6.5 2.5 +BarrierMaker 10 4 8.5 2.5 +BarrierMaker 7.5 2.5 7 3 8 3 7.5 2.5 +BarrierMaker 6 2 6.5 1.5 8.5 1.5 9 2 +BarrierMaker 6 1 5.5 0.5 5.5 1.5 6 1 +BarrierMaker 9 1 9.5 0.5 9.5 1.5 9 1 +BarrierMaker 4 4.5 3 4 3 5 4 4.5 +BarrierMaker 11 4.5 12 4 12 5 11 4.5 +BarrierMaker 13 4 12 3 11 3 11 2 10 1 10.5 1 11.5 2 11.5 2.5 12 2.5 13 3.5 13 4 +BarrierMaker 2 4 3 3 4 3 4 2 5 1 4.5 1 3.5 2 3.5 2.5 3 2.5 2 3.5 2 4 +BarrierMaker 1 5 0 4 1 4 1 5 +BarrierMaker 14 5 15 4 14 4 14 5 +BarrierMaker 2 2 1 3 1 2 2 1 2 2 +BarrierMaker 13 2 14 3 14 2 13 1 13 2 +BarrierMaker 0 7 0 1 1 0 6.5 0 7.5 0.5 8.5 0 14 0 15 1 15 7 11 6 10 7 8.5 7 7.5 6.5 6.5 7 5 7 4 6 0 7 +Teleporter 7 9 1 6 +Teleporter 8 9 14 6 +Teleporter 1 1 0.200001 8.2 +BarrierMaker 2 8 1 8.5 2 8.5 2 8 +BarrierMaker 2 8.9 2 9.1 2.9 9 2 8.9 +BarrierMaker 3 8 2.6 8.4 3.4 8.8 3 8 +BarrierMaker 4 8 4 9.5 4.5 8 4 8 +BarrierMaker 5 10 5 9.5 6 10 7 10 7.5 9 7 8.4 7.5 8.4 +BarrierMaker 2 12 1 11.5 2 11.5 2 12 +BarrierMaker 2 11.1 2 10.9 2.9 11 2 11.1 +BarrierMaker 3 12 2.6 11.6 3.4 11.2 3 12 +BarrierMaker 4 12 4 10.5 4.5 12 4 12 +BarrierMaker 5 10 5 10.5 6 10 7 10 7.5 11 7 11.6 7.5 11.6 +BarrierMaker 13 8 14 8.5 13 8.5 13 8 +BarrierMaker 13 8.9 13 9.1 12.1 9 13 8.9 +BarrierMaker 12 8 12.4 8.4 11.6 8.8 12 8 +BarrierMaker 11 8 11 9.5 10.5 8 11 8 +BarrierMaker 10 10 10 9.5 9 10 8 10 7.5 9 8 8.4 7.5 8.4 +BarrierMaker 13 12 14 11.5 13 11.5 13 12 +BarrierMaker 13 11.1 13 10.9 12.2 11 13 11.1 +BarrierMaker 12 12 12.4 11.6 11.6 11.2 12 12 +BarrierMaker 11 12 11 10.5 10.5 12 11 12 +BarrierMaker 9 12 10 11.5 10 12 +BarrierMaker 10 10 10 10.5 9 10 8 10 7.5 11 8 11.6 7.5 11.6 +BarrierMaker 5 15 6 14 9 14 10 15 +BarrierMaker 6.5 16.5 6 16 6 15 6.5 14.5 +BarrierMaker 8.5 16.5 9 16 9 15 8.5 14.5 +BarrierMaker 5 16 6.5 17.5 +BarrierMaker 10 16 8.5 17.5 +BarrierMaker 7.5 17.5 7 17 8 17 7.5 17.5 +BarrierMaker 6 18 6.5 18.5 8.5 18.5 9 18 +BarrierMaker 6 19 5.5 19.5 5.5 18.5 6 19 +BarrierMaker 9 19 9.5 19.5 9.5 18.5 9 19 +BarrierMaker 4 15.5 3 16 3 15 4 15.5 +BarrierMaker 11 15.5 12 16 12 15 11 15.5 +BarrierMaker 13 16 12 17 11 17 11 18 10 19 10.5 19 11.5 18 11.5 17.5 12 17.5 13 16.5 13 16 +BarrierMaker 2 16 3 17 4 17 4 18 5 19 4.5 19 3.5 18 3.5 17.5 3 17.5 2 16.5 2 16 +BarrierMaker 1 15 0 16 1 16 1 15 +BarrierMaker 14 15 15 16 14 16 14 15 +BarrierMaker 2 18 1 17 1 18 2 19 2 18 +BarrierMaker 13 18 14 17 14 18 13 19 13 18 +BarrierMaker 0 13 0 19 1 20 6.5 20 7.5 19.5 8.5 20 14 20 15 19 15 13 11 14 10 13 8.5 13 7.5 13.5 6.5 13 5 13 4 14 0 13 +Teleporter 14 19 14.8 11.8 +Teleporter 7 11 1 14 +Teleporter 8 11 14 14 +Teleporter 1 19 0.200001 11.8 +RepairItem 3.3 17.7 +RepairItem 11.7 17.7 +RepairItem 3.3 2.3 +RepairItem 11.7 2.3 +Spawn 1 6.1 13.5 +Spawn 1 2.7 15.5 +Spawn 1 8.9 13.5 +Spawn 1 12.3 15.5 +Spawn 1 0.200001 13.3 +Spawn 1 14.8 13.3 +Spawn 1 4.2 12.3 +Spawn 1 10.8 12.3 +Spawn 0 4.2 7.7 +Spawn 0 0.200001 6.7 +Spawn 0 6.1 6.5 +Spawn 0 2.7 4.5 +Spawn 0 10.8 7.7 +Spawn 0 14.8 6.7 +Spawn 0 8.9 6.5 +Spawn 0 12.3 4.5 +BarrierMaker 0 8 0 8.6 0.4 8.6 0.6 9 0.6 10 0.6 11 0.4 11.4 0 11.4 0 12 4 13 5 12 5 11.5 6 12 6.5 12 7.5 12.5 8.5 12 9 12 10 11.5 10 12 11 13 15 12 15 11.4 14.6 11.4 14.4 11 14.4 10 14.4 9 14.6 8.6 15 8.6 15 8 11 7 10 8 10 8.5 9 8 8.5 8 7.5 7.5 6.5 8 6 8 5 8.5 5 8 4 7 0 8 +BarrierMaker 3 10 1 11 1 9 3 10 +BarrierMaker 12 10 14 11 14 9 12 10 +LoadoutZone 0 14.2 3.2 14.8 3.2 14.8 3.8 14.2 3.8 +LoadoutZone 0 7.2 1.7 7.8 1.7 7.8 2.3 7.2 2.3 +LoadoutZone 0 8.2 10.2 8.8 10.2 8.8 10.8 8.2 10.8 +LoadoutZone 1 14.8 16.8 14.2 16.8 14.2 16.2 14.8 16.2 +LoadoutZone 1 0.8 16.8 0.2 16.8 0.2 16.2 0.8 16.2 +LoadoutZone 1 7.8 18.3 7.2 18.3 7.2 17.7 7.8 17.7 +LoadoutZone 1 6.8 9.8 6.2 9.8 6.2 9.2 6.8 9.2 diff --git a/tnl-1.5.0/tnl/exe/levels/rabbit1.txt b/tnl-1.5.0/tnl/exe/levels/rabbit1.txt new file mode 100644 index 0000000000000000000000000000000000000000..15055c961cd7ef4f857c377243622dded0738ee3 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/rabbit1.txt @@ -0,0 +1,37 @@ +RabbitGameType 8 100 10 30 +LevelName "Elmer's Revenge" + +Team Orange 1 0.5 0 +FlagItem -1 4.7 4.7 +GridSize 300 +BarrierMaker 50 4 -0.6 2.3 -0.3 0.7 0.7 -0.3 2.3 -0.6 4 -0.3 5.7 0.7 7.3 2.3 8.3 4 8.6 5.7 8.3 7.3 7.3 8.3 5.7 8.6 4 8.3 2.3 7.3 0.7 5.7 -0.3 4 -0.6 +BarrierMaker 50 -0.5 4.4 1 4 1 3.9 -0.5 3.5 +BarrierMaker 50 3.3 3.7 3.4 3.7 3.7 3.4 3.7 3.3 3.3 3.2 3.2 3.2 3.2 3.3 3.3 3.7 +BarrierMaker 50 2.3 4 2.3 3.9 1.4 3.4 1.3 3.4 1.3 3.5 1.7 3.9 1.7 4 1.3 4.4 1.3 4.5 1.4 4.5 2.3 4 +BarrierMaker 50 2.6 3.5 2.6 3.4 2.5 2.9 1.4 1.7 1.3 1.7 1.3 1.8 1.7 2.9 2.5 3.5 2.6 3.5 +BarrierMaker 50 3.6 2.6 3.6 2.5 3 1.7 1.9 1.3 1.8 1.3 1.8 1.4 3 2.5 3.5 2.6 3.6 2.6 +BarrierMaker 50 0.9 2.3 1.1 2.8 0.7 3.3 0.299999 3.2 0.2 2.6 0.8 2.3 0.9 2.3 +BarrierMaker 50 2.9 1.1 2.4 0.9 2.4 0.8 2.7 0.2 3.3 0.3 3.4 0.7 2.9 1.1 +Spawn 0 0.9 1.3 +Spawn 0 1.3 0.9 +BarrierMaker 50 8.5 4.4 7 4 7 3.9 8.5 3.5 +BarrierMaker 50 4.7 3.7 4.6 3.7 4.3 3.4 4.3 3.3 4.7 3.2 4.8 3.2 4.8 3.3 4.7 3.7 +BarrierMaker 50 5.7 4 5.7 3.9 6.6 3.4 6.7 3.4 6.7 3.5 6.3 3.9 6.3 4 6.7 4.4 6.7 4.5 6.6 4.5 5.7 4 +BarrierMaker 50 5.4 3.5 5.4 3.4 5.5 2.9 6.6 1.7 6.7 1.7 6.7 1.8 6.3 2.9 5.5 3.5 5.4 3.5 +BarrierMaker 50 4.4 2.6 4.4 2.5 5 1.7 6.1 1.3 6.2 1.3 6.2 1.4 5 2.5 4.5 2.6 4.4 2.6 +BarrierMaker 50 7.1 2.3 6.9 2.8 7.3 3.3 7.7 3.2 7.8 2.6 7.2 2.3 7.1 2.3 +BarrierMaker 50 5.1 1.1 5.6 0.9 5.6 0.8 5.3 0.2 4.7 0.3 4.6 0.7 5.1 1.1 +Spawn 0 7.1 1.3 +Spawn 0 6.7 0.9 +BarrierMaker 50 4.7 4.2 4.6 4.2 4.3 4.5 4.3 4.6 4.7 4.7 4.8 4.7 4.8 4.6 4.7 4.2 +BarrierMaker 50 5.4 4.4 5.4 4.5 5.5 5 6.6 6.2 6.7 6.2 6.7 6.1 6.3 5 5.5 4.4 5.4 4.4 +BarrierMaker 50 4.4 5.3 4.4 5.4 5 6.2 6.1 6.6 6.2 6.6 6.2 6.5 5 5.4 4.5 5.3 4.4 5.3 +BarrierMaker 50 7.1 5.6 6.9 5.1 7.3 4.6 7.7 4.7 7.8 5.3 7.2 5.6 7.1 5.6 +BarrierMaker 50 5.1 6.8 5.6 7 5.6 7.1 5.3 7.7 4.7 7.6 4.6 7.2 5.1 6.8 +Spawn 0 7.1 6.6 +Spawn 0 6.7 7 +BarrierMaker 50 3.3 4.2 3.4 4.2 3.7 4.5 3.7 4.6 3.3 4.7 3.2 4.7 3.2 4.6 3.3 4.2 +BarrierMaker 50 2.6 4.4 2.6 4.5 2.5 5 1.4 6.2 1.3 6.2 1.3 6.1 1.7 5 2.5 4.4 2.6 4.4 +BarrierMaker 50 3.6 5.3 3.6 5.4 3 6.2 1.9 6.6 1.8 6.6 1.8 6.5 3 5.4 3.5 5.3 3.6 5.3 +BarrierMaker 50 0.900001 5.6 1.1 5.1 0.7 4.6 0.3 4.7 0.2 5.3 0.800001 5.6 0.900001 5.6 +BarrierMaker 50 2.9 6.8 2.4 7 2.4 7.1 2.7 7.7 3.3 7.6 3.4 7.2 2.9 6.8 diff --git a/tnl-1.5.0/tnl/exe/levels/rabbit2.txt b/tnl-1.5.0/tnl/exe/levels/rabbit2.txt new file mode 100644 index 0000000000000000000000000000000000000000..06c33cf0fff64d3486649b103a230d8319ea8a3b --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/rabbit2.txt @@ -0,0 +1,30 @@ +RabbitGameType 100 8 10 30 +LevelName "Carrot Crazy" +Team Orange 1 0.5 0 +FlagItem 4.7 4.7 +GridSize 300 +BarrierMaker 50 1 1 3 3 +BarrierMaker 50 5 3 7 1 +BarrierMaker 50 5 5 7 7 +BarrierMaker 50 3 5 1 7 +BarrierMaker 50 3 1 4 0.3 5 1 +BarrierMaker 50 7 3 8.3 4 7 5 +BarrierMaker 50 5 7 4 7.7 3 7 +BarrierMaker 50 1 5 -0.3 4 1 3 +Spawn 0 1 6 +Spawn 0 1 2 +Spawn 0 6 1 +Spawn 0 2 1 +BarrierMaker 50 5 9 4 10 3 9 1 9 0 8 -1 6 -3 5 -4 4 -3 3 -1 2 0 0 1 -1 3 -1 4 -2 5 -1 7 -1 8 0 9 2 11 3 12 4 11 5 9 6 8 8 7 9 5 9 +Teleporter -3 4 10 4 +Teleporter 11 4 -2 4 +Teleporter 4 -1 4 8.5 +Teleporter 4 9 4 -0.500001 +RepairItem 4 0.8 +RepairItem 4 7.2 +RepairItem 0.7 4 +RepairItem 7.3 4 +Spawn 0 7 2 +Spawn 0 7 6 +Spawn 0 6 7 +Spawn 0 2 7 diff --git a/tnl-1.5.0/tnl/exe/levels/retrieve1.txt b/tnl-1.5.0/tnl/exe/levels/retrieve1.txt new file mode 100644 index 0000000000000000000000000000000000000000..5289a4ea47e8e2c141f6f0d1ab7be27d77b3cd26 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/retrieve1.txt @@ -0,0 +1,94 @@ +RetrieveGameType 10 15 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName "Triple Threat" +GridSize 300 +FlagItem -1 -1.5 1.5 +LoadoutZone 1 4.3 9.2 3.9 9.2 3.9 7.8 4.3 7.8 +Spawn 1 3.5 8.4 +Spawn 1 3.5 8.8 +Spawn 1 0.5 8 +Spawn 1 3.5 8 +Spawn 1 3.5 9.2 +FlagItem -1 6.5 5 +GoalZone 1 2.5 7.5 2.7 7.5 2.7 7.7 2.5 7.7 +GoalZone 1 0.9 7.5 1.1 7.5 1.1 7.7 0.9 7.7 +GoalZone 1 1.7 7.5 1.9 7.5 1.9 7.7 1.7 7.7 +BarrierMaker 50 0.5 10.5 3.5 10.5 4.5 9.5 4.5 7.5 3.5 6.5 3 6.5 3 5 5 5 6 6 7 6 8 5 8 -2 7 -3 6 -3 5 -2 3 -2 3 -3.5 3.5 -3.5 4.5 -4.5 4.5 -6.5 3.5 -7.5 0.5 -7.5 -0.5 -6.5 -0.5 -4.5 0.5 -3.5 0.5 -2 -0.5 -2 -2.5 0 -2.5 3 -0.5 5 0.5 5 0.5 6.5 -0.5 7.5 -0.5 9.5 0.5 10.5 +LoadoutZone 1 0.1 9.2 -0.299999 9.2 -0.299999 7.8 0.1 7.8 +BarrierMaker 50 -0.5 7.6 0.3 7.6 +BarrierMaker 50 1.1 7 2.3 7 2.3 6.9 1.9 6.5 1.9 5 1.5 5 1.5 6.5 1.1 6.9 1.1 7 +BarrierMaker 50 1.3 8.1 1.3 8.2 1.7 8.6 2.3 8.6 2.3 8.5 1.9 8.1 1.3 8.1 +BarrierMaker 50 0.8 8.9 0.8 8.1 +BarrierMaker 50 3 8.1 3 8.9 +Spawn 1 0.5 8.8 +Spawn 1 0.5 9.2 +Spawn 1 0.5 8.4 +BarrierMaker 50 0.7 9.8 1.4 9.1 2 9.1 2.6 9.7 2.6 9.8 2.5 9.9 0.7 9.9 0.7 9.8 +BarrierMaker 50 5.5 4.4 6.1 3.8 +BarrierMaker 50 6.8 3.8 7.4 4.4 +BarrierMaker 50 -0.5 1.5 2.5 1.5 +BarrierMaker 50 4.4 5 4.4 3.6 +BarrierMaker 50 3.3 2.5 3.3 4 +BarrierMaker 50 2.4 3.7 2.4 4.3 2.2 4.3 1.3 3.4 1.3 3.1 1.8 3.1 2.4 3.7 +BarrierMaker 50 2.4 2.6 2 2.6 1.6 2.2 0.6 2.2 0.2 2.6 +BarrierMaker 50 0.5 4.2 0.5 3.6 +BarrierMaker 50 -0.8 2.8 -0.8 3.7 +BarrierMaker 50 0.9 4.5 1.5 4.5 +BarrierMaker 50 3.5 1.5 6 1.5 +BarrierMaker 50 7 1.5 8 1.5 +BarrierMaker 50 6 3.2 6.8 3.2 +BarrierMaker 50 6.4 2.8 6.4 3.2 +BarrierMaker 50 5.5 2.8 6.1 2.2 +BarrierMaker 50 6.8 2.2 7.4 2.8 +BarrierMaker 50 4 3 4.7 2.3 5.3 2.3 +BarrierMaker 50 5.3 3.8 4.4 3.8 +Turret -1 2.3 1.6 +Turret -1 -0.7 3.3 +Turret 1 1.6 8 +Turret 1 0.1 7.5 +ForceFieldProjector 1 2 6.3 +BarrierMaker 50 -1.6 2.7 -1.6 2.2 -0.5 2.2 +BarrierMaker 50 -0.6 4.2 0 4.2 0 3.2 +LoadoutZone 0 4.3 -6.2 3.9 -6.2 3.9 -4.8 4.3 -4.8 +Spawn 0 3.5 -5.4 +Spawn 0 3.5 -5.8 +Spawn 0 0.5 -5 +Spawn 0 3.5 -5 +Spawn 0 3.5 -6.2 +FlagItem -1 6.5 -2 +GoalZone 0 2.5 -4.5 2.7 -4.5 2.7 -4.7 2.5 -4.7 +GoalZone 0 0.9 -4.5 1.1 -4.5 1.1 -4.7 0.9 -4.7 +GoalZone 0 1.7 -4.5 1.9 -4.5 1.9 -4.7 1.7 -4.7 +LoadoutZone 0 0.1 -6.2 -0.299999 -6.2 -0.299999 -4.8 0.1 -4.8 +BarrierMaker 50 -0.5 -4.6 0.3 -4.6 +BarrierMaker 50 1.1 -4 2.3 -4 2.3 -3.9 1.9 -3.5 1.9 -2 1.5 -2 1.5 -3.5 1.1 -3.9 1.1 -4 +BarrierMaker 50 1.3 -5.1 1.3 -5.2 1.7 -5.6 2.3 -5.6 2.3 -5.5 1.9 -5.1 1.3 -5.1 +BarrierMaker 50 0.8 -5.9 0.8 -5.1 +BarrierMaker 50 3 -5.1 3 -5.9 +Spawn 0 0.5 -5.8 +Spawn 0 0.5 -6.2 +Spawn 0 0.5 -5.4 +BarrierMaker 50 0.7 -6.8 1.4 -6.1 2 -6.1 2.6 -6.7 2.6 -6.8 2.5 -6.9 0.7 -6.9 0.7 -6.8 +BarrierMaker 50 5.5 -1.4 6.1 -0.8 +BarrierMaker 50 6.8 -0.8 7.4 -1.4 +BarrierMaker 50 4.4 -2 4.4 -0.6 +BarrierMaker 50 3.3 0.5 3.3 -1 +BarrierMaker 50 2.4 -0.699999 2.4 -1.3 2.2 -1.3 1.3 -0.4 1.3 -0.1 1.8 -0.1 2.4 -0.699999 +BarrierMaker 50 2.4 0.4 2 0.4 1.6 0.800001 0.6 0.800001 0.2 0.4 +BarrierMaker 50 0.5 -1.2 0.5 -0.6 +BarrierMaker 50 -0.8 0.2 -0.8 -0.699999 +BarrierMaker 50 0.9 -1.5 1.5 -1.5 +BarrierMaker 50 6 -0.199999 6.8 -0.199999 +BarrierMaker 50 6.4 0.2 6.4 -0.199999 +BarrierMaker 50 5.5 0.2 6.1 0.800001 +BarrierMaker 50 6.8 0.800001 7.4 0.2 +BarrierMaker 50 4 3.7998e-007 4.7 0.7 5.3 0.7 +BarrierMaker 50 5.3 -0.8 4.4 -0.8 +Turret -1 -0.7 -0.3 +Turret 0 1.6 -5 +Turret 0 0.1 -4.5 +ForceFieldProjector 0 2 -3.3 +BarrierMaker 50 -1.6 0.300001 -1.6 0.800001 -0.5 0.800001 +BarrierMaker 50 -0.6 -1.2 0 -1.2 0 -0.199999 +Turret -1 2.3 1.4 diff --git a/tnl-1.5.0/tnl/exe/levels/retrieve2.txt b/tnl-1.5.0/tnl/exe/levels/retrieve2.txt new file mode 100644 index 0000000000000000000000000000000000000000..54e0006901a142407bf8789b5bf47b316701a3af --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/retrieve2.txt @@ -0,0 +1,113 @@ +RetrieveGameType 10 16 +Team Blue 0 0 1 +Team Red 1 0 0 +Team Yellow 1 1 0 +LevelName "Mad Cow" +GridSize 300 +LoadoutZone 1 7.8 9.2 7.4 9.2 7.4 7.8 7.8 7.8 +Spawn 1 7 8.4 +Spawn 1 7 8.8 +Spawn 1 4 8 +Spawn 1 7 8 +Spawn 1 7 9.2 +FlagItem -1 4.8 1.7 +GoalZone 1 4.9 6.4 5.1 6.4 5.1 6.6 4.9 6.6 +GoalZone 1 5.9 6.4 6.1 6.4 6.1 6.6 5.9 6.6 +LoadoutZone 1 3.6 9.2 3.2 9.2 3.2 7.8 3.6 7.8 +BarrierMaker 50 4.3 8.9 4.3 8.1 +BarrierMaker 50 6.5 8.1 6.5 8.9 +Spawn 1 4 8.8 +Spawn 1 4 9.2 +Spawn 1 4 8.4 +FlagItem -1 6.5 2.5 +BarrierMaker 50 1.5 4 3.5 6 3.5 7 2.5 8 2.5 9 4.5 10 6.5 10 8.5 9 8.5 8 7.5 7 7.5 6 9.5 4 +BarrierMaker 50 4 6.5 3.5 6.5 +BarrierMaker 50 7 6.5 7.5 6.5 +BarrierMaker 50 5.5 5.5 5.5 6.5 +BarrierMaker 50 5.5 7 5.5 7.5 +BarrierMaker 50 4.9 8.1 6.1 8.1 6.1 8.4 5.8 8.7 5.2 8.7 4.9 8.4 4.9 8.1 +BarrierMaker 50 3.3 4.6 4 5.3 4.4 5.3 4.8 4.9 4.8 4.6 4.2 4 3.4 4 3.3 4.1 3.3 4.6 +BarrierMaker 50 5.1 4 5.6 4.5 6 4.7 +BarrierMaker 50 6.2 4.1 6.6 4.3 7.1 4.7 7.2 4.9 7.5 4.9 7.9 4.5 +BarrierMaker 50 6.2 5.5 6.2 5.4 6.5 5 6.6 5 6.9 5.4 6.9 5.5 6.7 5.9 6.6 5.9 6.2 5.5 +ForceFieldProjector 1 8.1 5.3 +BarrierMaker 50 4.7 9.2 5 9.4 6 9.4 6.3 9.2 +ForceFieldProjector 1 3.1 5.3 +Turret 1 6.9 6.5 +Turret 1 5.5 8 +LoadoutZone 2 10.7743 -4.07175 10.9743 -3.72534 9.76191 -3.02534 9.5619 -3.37175 +Spawn 2 10.4815 -2.97893 +Spawn 2 10.8279 -3.17893 +Spawn 2 11.6351 -0.180851 +Spawn 2 10.1351 -2.77893 +Spawn 2 11.1743 -3.37893 +GoalZone 2 9.79947 -0.160273 9.69947 -0.33348 9.87267 -0.43348 9.97267 -0.260275 +GoalZone 2 9.29947 -1.0263 9.19947 -1.1995 9.37268 -1.29951 9.47268 -1.1263 +LoadoutZone 2 12.8743 -0.434441 13.0743 -0.0880313 11.8619 0.611967 11.6619 0.26556 +BarrierMaker 50 12.2645 -0.890658 11.5717 -0.490659 +BarrierMaker 50 10.4717 -2.39592 11.1645 -2.79592 +Spawn 2 12.3279 -0.580852 +Spawn 2 12.6743 -0.780854 +Spawn 2 11.9815 -0.380853 +BarrierMaker 50 9.5 4 10.1531 1.25216 11.0191 0.752162 12.3851 1.11819 13.2511 0.618185 13.1172 -1.61386 12.1172 -3.34591 10.2511 -4.57797 9.38511 -4.07797 9.01908 -2.71194 8.15306 -2.21194 5.4 -3 +BarrierMaker 50 10.3361 0.569148 10.5861 1.00216 +BarrierMaker 50 8.83607 -2.02893 8.58607 -2.46194 +BarrierMaker 50 8.72005 -0.229891 9.58607 -0.72989 +BarrierMaker 50 10.0191 -0.979889 10.4521 -1.22989 +BarrierMaker 50 11.2717 -1.01027 10.6717 -2.04951 10.9315 -2.19951 11.3413 -2.0897 11.6413 -1.57008 11.5315 -1.16028 11.2717 -1.01027 +BarrierMaker 50 9.04062 2.12537 9.29684 1.16915 9.09684 0.822739 8.55043 0.676331 8.29062 0.826327 8.07101 1.64594 8.47101 2.33876 8.60761 2.37536 9.04062 2.12537 +BarrierMaker 50 7.62101 0.866518 7.80402 0.183506 7.77723 -0.262901 +BarrierMaker 50 7.15761 -0.136106 7.13082 -0.582516 7.22722 -1.21553 7.35043 -1.40213 7.20043 -1.66194 6.65402 -1.80835 +BarrierMaker 50 8.37004 -0.836107 8.28344 -0.78611 7.78703 -0.845917 7.73703 -0.932518 7.93344 -1.39233 8.02005 -1.44233 8.46646 -1.46912 8.51646 -1.38252 8.37004 -0.836107 +ForceFieldProjector 2 7.24684 -2.38155 +BarrierMaker 50 12.3243 -1.38707 12.3475 -1.74688 11.8475 -2.6129 11.5243 -2.77271 +ForceFieldProjector 2 9.74684 1.94857 +Turret 2 8.88607 -1.94233 +Turret 2 10.8851 -1.47989 +LoadoutZone 0 -2.15676 -0.120346 -1.95676 -0.466754 -0.744329 0.233245 -0.944324 0.579656 +Spawn 0 -1.06394 -0.413167 +Spawn 0 -1.41035 -0.613165 +Spawn 0 0.78247 -2.81124 +Spawn 0 -0.717533 -0.213165 +Spawn 0 -1.75676 -0.813164 +GoalZone 0 1.71811 -1.23182 1.61811 -1.05861 1.44491 -1.15861 1.5449 -1.33182 +GoalZone 0 1.21811 -0.365793 1.11811 -0.192588 0.944902 -0.292589 1.0449 -0.465794 +LoadoutZone 0 -0.0567617 -3.75765 0.14324 -4.10406 1.35567 -3.40406 1.15567 -3.05765 +BarrierMaker 50 -0.146954 -3.00143 0.545867 -2.60143 +BarrierMaker 50 -0.554137 -0.696176 -1.24695 -1.09618 +Spawn 0 0.0896502 -3.21124 +Spawn 0 -0.256763 -3.41124 +Spawn 0 0.436058 -3.01124 +BarrierMaker 50 5.4 -3 2.76452 -2.24425 1.89849 -2.74426 1.53247 -4.11028 0.666444 -4.61028 -1.19958 -3.37823 -2.19958 -1.64618 -2.33356 0.585871 -1.46753 1.08587 -0.101507 0.719848 0.764518 1.21985 1.5 4 +BarrierMaker 50 2.08151 -2.06124 2.33151 -2.49425 +BarrierMaker 50 0.581508 0.536836 0.331509 0.969848 +BarrierMaker 50 2.19753 -0.262203 1.33151 -0.762203 +BarrierMaker 50 0.898495 -1.0122 0.465481 -1.2622 +BarrierMaker 50 0.245867 -2.08182 -0.354134 -1.04259 -0.613945 -1.19259 -0.723751 -1.6024 -0.42375 -2.12201 -0.0139427 -2.23182 0.245867 -2.08182 +BarrierMaker 50 4.07695 -1.71746 3.12074 -1.46124 2.92074 -1.11483 3.06715 -0.568422 3.32695 -0.418421 4.14657 -0.638035 4.54657 -1.33086 4.50996 -1.46746 4.07695 -1.71746 +BarrierMaker 50 3.69657 0.141389 3.01356 0.3244 2.64035 0.570809 +BarrierMaker 50 3.05997 1.04401 2.68676 1.29042 2.09035 1.52344 1.86715 1.51004 1.71715 1.76985 1.86356 2.31626 +BarrierMaker 50 1.84753 0.344017 1.93413 0.394016 2.13054 0.853821 2.08055 0.940425 1.58413 1.00023 1.49753 0.950233 1.25112 0.577027 1.30112 0.490426 1.84753 0.344017 +ForceFieldProjector 0 1.07074 2.08946 +BarrierMaker 50 -0.60676 -2.80502 -0.929967 -2.64522 -1.42996 -1.77919 -1.40676 -1.41938 +ForceFieldProjector 0 3.57073 -2.24066 +Turret 0 0.631507 0.450234 +Turret 0 0.0324669 -1.5122 +BarrierMaker 50 4 2.5 4.5 3 +BarrierMaker 50 5.2 2.2 5.5 1.6 5.1 1.2 4.5 1.2 4 1.6 4 2.1 +BarrierMaker 50 6.1 2 5.7 2.3 5.7 3 6.4 3.3 +BarrierMaker 50 5.7 0.2 6.3 0.8 6.3 1.1 6.1 1.2 +BarrierMaker 50 6.5 1.5 6.9 1.5 7.3 1.9 7.2 2.2 7.3 2.3 +BarrierMaker 50 8.1 2.7 8.4 3.3 8.9 3.5 9.6 3.6 +BarrierMaker 50 5.4 -1.3 5.5 -1.9 5.2 -2.3 4.8 -2.7 4.8 -2.8 +BarrierMaker 50 5.1 -0.5 5.8 -0.5 6.3 -0.8 6.5 -1.1 +BarrierMaker 50 3 3.5 2.5 3.5 2.3 3.4 2.1 3.4 2 3.5 2 3.8 1.7 4.2 +BarrierMaker 50 3.6 3.2 4.3 2.8 +BarrierMaker 50 2.6 2.7 3.4 2.3 +BarrierMaker 50 4.6 0.2 4.6 0.6 4.9 0.6 5 0.5 4.8 0.2 4.6 0.2 +Turret -1 8.2 3.1 +Turret -1 4 3.1 +Turret -1 4.7 0.1 +ForceFieldProjector -1 5.5 -1.3 +ForceFieldProjector -1 2.3 1.5 +ForceFieldProjector -1 6.4 0.8 diff --git a/tnl-1.5.0/tnl/exe/levels/retrieve3.txt b/tnl-1.5.0/tnl/exe/levels/retrieve3.txt new file mode 100644 index 0000000000000000000000000000000000000000..01401616995be4113443a2e08316de6d895bb525 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/retrieve3.txt @@ -0,0 +1,108 @@ +RetrieveGameType 10 25 +Team Blue 0 0 1 +Team Red 1 0 0 +LevelName "The Law of Fives" +GridSize 350 +LoadoutZone 0 8 -4.6 7.7 -4.6 7.7 -3.4 8 -3.4 +Spawn 0 8.2 -4 +Spawn 0 8.2 -4.3 +Spawn 0 8.2 -4.6 +GoalZone 0 4.5 -5.9 4.7 -5.9 4.7 -6.1 4.5 -6.1 +FlagItem -1 -3.9 -3.4 +BarrierMaker 50 -6.5 0 -6.5 -2 -4.5 -4 -2.5 -4 -1.5 -3 0.5 -3 1.5 -5 3.5 -7 6.5 -7 8.5 -5 8.5 -3 6.5 -1 6.5 0 +BarrierMaker 50 4.5 -6.3 5.5 -6.3 5.8 -6 5.8 -5.6 +GoalZone 0 5.3 -5.9 5.5 -5.9 5.5 -6.1 5.3 -6.1 +GoalZone 0 4.9 -5.5 5.1 -5.5 5.1 -5.7 4.9 -5.7 +GoalZone 0 5.3 -5.1 5.5 -5.1 5.5 -5.3 5.3 -5.3 +GoalZone 0 4.5 -5.1 4.7 -5.1 4.7 -5.3 4.5 -5.3 +BarrierMaker 50 3.9 -5.7 3.9 -5 4.3 -4.6 4.5 -4.6 +BarrierMaker 50 6.6 -6 6.6 -5.4 6 -4.8 5.6 -4.8 +BarrierMaker 50 4.4 -4.2 6.2 -4.2 6.5 -4.5 +BarrierMaker 50 6.1 -6.3 6.1 -6.6 5.9 -6.8 5.6 -6.8 5.4 -7 +BarrierMaker 50 3.8 -6.5 3.2 -5.9 3.2 -5.3 2.7 -4.9 2.7 -4.5 3.2 -4 +BarrierMaker 50 3.4 -4.6 3.8 -4.2 3.8 -3.7 +Spawn 0 8.2 -3.7 +Spawn 0 8.2 -3.4 +BarrierMaker 50 7.8 -5 7.6 -4.8 7.6 -3.2 7.8 -3 +BarrierMaker 50 7.1 -4.7 7.1 -4 6.5 -3.4 5.9 -3.4 +BarrierMaker 50 4.6 -3.6 4.4 -3.6 4 -3.1 4 -2.9 4.1 -2.8 4.8 -2.8 5 -3 5 -3.1 4.6 -3.6 +BarrierMaker 50 5.5 -3.6 5.5 -3 6 -2.5 6.5 -2.5 6.6 -2.6 6.9 -2.6 7.1 -2.8 +BarrierMaker 50 -4.2 -2.7 -4.5 -2.7 -4.8 -2.4 -4.8 -1.9 -4.5 -1.6 -4.2 -1.6 -3.9 -1.9 -3.9 -2.4 -4.2 -2.7 +BarrierMaker 50 -2.7 -1.9 -3 -1.9 -3.3 -1.6 -3.3 -1.1 -3 -0.8 -2.7 -0.8 -2.4 -1.1 -2.4 -1.6 -2.7 -1.9 +BarrierMaker 50 -2.8 -3.5 -3.1 -3.5 -3.4 -3.2 -3.4 -2.7 -3.1 -2.4 -2.8 -2.4 -2.5 -2.7 -2.5 -3.2 -2.8 -3.5 +BarrierMaker 50 -1.2 -2.3 -1.5 -2.3 -1.8 -2 -1.8 -1.5 -1.5 -1.2 -1.2 -1.2 -0.9 -1.5 -0.9 -2 -1.2 -2.3 +BarrierMaker 50 -4 -1.1 -4.3 -1.1 -4.6 -0.8 -4.6 -0.3 -4.3 -5.96046e-008 -4 -5.96046e-008 -3.7 -0.3 -3.7 -0.8 -4 -1.1 +BarrierMaker 50 -5.5 -1.7 -5.8 -1.7 -6.1 -1.4 -6.1 -0.9 -5.8 -0.6 -5.5 -0.6 -5.2 -0.9 -5.2 -1.4 -5.5 -1.7 +FlagItem -1 0 -9.68575e-008 +BarrierMaker 50 2 -4 3 -3 3 -2.6 3.6 -2 5 -2 5.8 -1.3 5.8 -1 +BarrierMaker 50 1.7 -3 1.5 -3 1.1 -2.4 1.1 -2.2 1.2 -2.1 1.9 -2.1 2 -2.2 2 -2.4 1.7 -3 +BarrierMaker 50 1.4 -0.8 1.6 -0.8 2 -1.4 2 -1.6 1.9 -1.7 1.2 -1.7 1.1 -1.6 1.1 -1.4 1.4 -0.8 +BarrierMaker 50 3.4 -1.6 3.4 -1.4 2.8 -1 2.6 -1 2.5 -1.1 2.5 -1.8 2.6 -1.9 2.8 -1.9 3.4 -1.6 +BarrierMaker 50 3.6 -1 3.1 -0.5 2.6 -0.5 +BarrierMaker 50 4 0 3.3 -0.7 +BarrierMaker 50 4 -0.6 4.5 -1.1 4.9 -0.7 +BarrierMaker 50 4 -1.2 4 -1.6 4.4 -1.6 +BarrierMaker 50 4.5 -0.4 4.9 0 5.1 0 5.5 -0.4 +BarrierMaker 50 -0.4 -2.3 -0.4 -0.6 -0.2 -0.6 -0.2 -2.3 -0.4 -2.3 +BarrierMaker 50 0.6 -2.3 0.5 -2.3 0.3 -2.1 0.3 -1.7 0.7 -1.3 0.7 -0.8 0.3 -0.4 0.3 -0.2 0.5 0 1.1 0 1.4 -0.3 1.8 -0.3 2.1 0 2.5 0 +FlagItem -1 6 0 +Turret 0 5.1 -4.1 +Turret 0 2.6 -4.7 +ForceFieldProjector 0 2.5 -3.6 +Turret 0 4.2 -4.9 +ForceFieldProjector 0 5.6 -4.3 +Turret -1 -2.5 -1.8 +Turret -1 -4.7 -1.6 +ForceFieldProjector -1 0.5 -2.4 +RepairItem 4.2 -1.4 +LoadoutZone 1 -8 4.6 -7.7 4.6 -7.7 3.4 -8 3.4 +Spawn 1 -8.2 4 +Spawn 1 -8.2 4.3 +Spawn 1 -8.2 4.6 +GoalZone 1 -4.5 5.9 -4.7 5.9 -4.7 6.1 -4.5 6.1 +FlagItem -1 3.9 3.4 +BarrierMaker 50 6.5 0 6.5 2 4.5 4 2.5 4 1.5 3 -0.5 3 -1.5 5 -3.5 7 -6.5 7 -8.5 5 -8.5 3 -6.5 1 -6.5 0 +BarrierMaker 50 -4.5 6.3 -5.5 6.3 -5.8 6 -5.8 5.6 +GoalZone 1 -5.3 5.9 -5.5 5.9 -5.5 6.1 -5.3 6.1 +GoalZone 1 -4.9 5.5 -5.1 5.5 -5.1 5.7 -4.9 5.7 +GoalZone 1 -5.3 5.1 -5.5 5.1 -5.5 5.3 -5.3 5.3 +GoalZone 1 -4.5 5.1 -4.7 5.1 -4.7 5.3 -4.5 5.3 +BarrierMaker 50 -3.9 5.7 -3.9 5 -4.3 4.6 -4.5 4.6 +BarrierMaker 50 -6.6 6 -6.6 5.4 -6 4.8 -5.6 4.8 +BarrierMaker 50 -4.4 4.2 -6.2 4.2 -6.5 4.5 +BarrierMaker 50 -6.1 6.3 -6.1 6.6 -5.9 6.8 -5.6 6.8 -5.4 7 +BarrierMaker 50 -3.8 6.5 -3.2 5.9 -3.2 5.3 -2.7 4.9 -2.7 4.5 -3.2 4 +BarrierMaker 50 -3.4 4.6 -3.8 4.2 -3.8 3.7 +Spawn 1 -8.2 3.7 +Spawn 1 -8.2 3.4 +BarrierMaker 50 -7.8 5 -7.6 4.8 -7.6 3.2 -7.8 3 +BarrierMaker 50 -7.1 4.7 -7.1 4 -6.5 3.4 -5.9 3.4 +BarrierMaker 50 -4.6 3.6 -4.4 3.6 -4 3.1 -4 2.9 -4.1 2.8 -4.8 2.8 -5 3 -5 3.1 -4.6 3.6 +BarrierMaker 50 -5.5 3.6 -5.5 3 -6 2.5 -6.5 2.5 -6.6 2.6 -6.9 2.6 -7.1 2.8 +BarrierMaker 50 4.2 2.7 4.5 2.7 4.8 2.4 4.8 1.9 4.5 1.6 4.2 1.6 3.9 1.9 3.9 2.4 4.2 2.7 +BarrierMaker 50 2.7 1.9 3 1.9 3.3 1.6 3.3 1.1 3 0.8 2.7 0.8 2.4 1.1 2.4 1.6 2.7 1.9 +BarrierMaker 50 2.8 3.5 3.1 3.5 3.4 3.2 3.4 2.7 3.1 2.4 2.8 2.4 2.5 2.7 2.5 3.2 2.8 3.5 +BarrierMaker 50 1.2 2.3 1.5 2.3 1.8 2 1.8 1.5 1.5 1.2 1.2 1.2 0.9 1.5 0.9 2 1.2 2.3 +BarrierMaker 50 4 1.1 4.3 1.1 4.6 0.8 4.6 0.3 4.3 0 4 0 3.7 0.3 3.7 0.8 4 1.1 +BarrierMaker 50 5.5 1.7 5.8 1.7 6.1 1.4 6.1 0.9 5.8 0.6 5.5 0.6 5.2 0.9 5.2 1.4 5.5 1.7 +BarrierMaker 50 -2 4 -3 3 -3 2.6 -3.6 2 -5 2 -5.8 1.3 -5.8 1 +BarrierMaker 50 -1.7 3 -1.5 3 -1.1 2.4 -1.1 2.2 -1.2 2.1 -1.9 2.1 -2 2.2 -2 2.4 -1.7 3 +BarrierMaker 50 -1.4 0.8 -1.6 0.8 -2 1.4 -2 1.6 -1.9 1.7 -1.2 1.7 -1.1 1.6 -1.1 1.4 -1.4 0.8 +BarrierMaker 50 -3.4 1.6 -3.4 1.4 -2.8 1 -2.6 1 -2.5 1.1 -2.5 1.8 -2.6 1.9 -2.8 1.9 -3.4 1.6 +BarrierMaker 50 -3.6 1 -3.1 0.5 -2.6 0.5 +BarrierMaker 50 -4 0 -3.3 0.7 +BarrierMaker 50 -4 0.6 -4.5 1.1 -4.9 0.7 +BarrierMaker 50 -4 1.2 -4 1.6 -4.4 1.6 +BarrierMaker 50 -4.5 0.4 -4.9 0 -5.1 0 -5.5 0.4 +BarrierMaker 50 0.4 2.3 0.4 0.6 0.2 0.6 0.2 2.3 0.4 2.3 +BarrierMaker 50 -0.6 2.3 -0.5 2.3 -0.3 2.1 -0.3 1.7 -0.7 1.3 -0.7 0.8 -0.3 0.4 -0.3 0.2 -0.5 0 -1.1 0 -1.4 0.3 -1.8 0.3 -2.1 0 -2.5 0 +FlagItem -1 -6 0 +Turret 1 -5.1 4.1 +Turret 1 -2.6 4.7 +ForceFieldProjector 1 -2.5 3.6 +Turret 1 -4.2 4.9 +ForceFieldProjector 1 -5.6 4.3 +Turret -1 2.5 1.8 +Turret -1 4.7 1.6 +ForceFieldProjector -1 -0.5 2.4 +RepairItem -4.2 1.4 diff --git a/tnl-1.5.0/tnl/exe/levels/soccer1.txt b/tnl-1.5.0/tnl/exe/levels/soccer1.txt new file mode 100644 index 0000000000000000000000000000000000000000..f86ca92f0a6b7b6efc119c9f830b9f7cf761cfd0 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/soccer1.txt @@ -0,0 +1,64 @@ +SoccerGameType 10 8 +LevelName "Hat Trick" + +GridSize 280 + +Team Blue 0 0 1 +Team Red 1 0 0 + +BarrierMaker 50 0 1 5 1 5.5 0 6.5 0 7 1 12 1 12 4 9 6 9 10 12 12 12 15 7 15 6.5 16 5.5 16 5 15 0 15 0 12 3 10 3 6 0 4 0 1 + +BarrierMaker 50 6 6 7 7 5 7 6 6 + +BarrierMaker 50 5 3 5 3.5 4 3.5 5 3 +BarrierMaker 50 4 4 5 4 5 5 5.5 5 +BarrierMaker 50 8 3 7 3 7 5 +BarrierMaker 50 4 2.5 4.5 2.5 4.5 2 5 2 +BarrierMaker 50 6 5 5.5 3 6.5 3 6 5 +BarrierMaker 50 3.5 4.5 3.5 6 4 6 +BarrierMaker 50 4.5 6 4.5 4.5 4 4.5 +BarrierMaker 50 3.5 2 4 2 +BarrierMaker 50 1.5 2 3 2 3 3.5 1.5 2 +BarrierMaker 50 1 2 2.5 4 1 3 1 2 +BarrierMaker 50 7 2 7.5 2 7 2.5 7 2 +BarrierMaker 50 7.5 4 8 4 8 5 7.5 5 7.5 4 +BarrierMaker 50 8 6 11 4 11 2 8 6 +BarrierMaker 50 8 2.5 9 2.5 9 3 8.5 3.5 + +BarrierMaker 50 6 10 7 9 5 9 6 10 + +BarrierMaker 50 5 13 5 12.5 4 12.5 5 13 +BarrierMaker 50 4 12 5 12 5 11 5.5 11 +BarrierMaker 50 8 13 7 13 7 11 +BarrierMaker 50 4 13.5 4.5 13.5 4.5 14 5 14 +BarrierMaker 50 6 11 5.5 13 6.5 13 6 11 +BarrierMaker 50 3.5 11.5 3.5 10 4 10 +BarrierMaker 50 4.5 10 4.5 11.5 4 11.5 +BarrierMaker 50 3.5 14 4 14 +BarrierMaker 50 1.5 14 3 14 3 12.5 1.5 14 +BarrierMaker 50 1 14 2.5 12 1 13 1 14 +BarrierMaker 50 7 14 7.5 14 7 13.5 7 14 +BarrierMaker 50 7.5 12 8 12 8 11 7.5 11 7.5 12 +BarrierMaker 50 8 10 11 12 11 14 8 10 +BarrierMaker 50 8 13.5 9 13.5 9 13 8.5 12.5 + +Spawn 0 4 9 +Spawn 0 4 8.5 +Spawn 0 5 8.5 +Spawn 0 6 8.5 +Spawn 0 7 8.5 +Spawn 0 8 8.5 +Spawn 0 8 9 + +Spawn 1 4 7 +Spawn 1 4 7.5 +Spawn 1 5 7.5 +Spawn 1 6 7.5 +Spawn 1 7 7.5 +Spawn 1 8 7.5 +Spawn 1 8 7 + +SoccerBallItem 6 8 + +GoalZone 1 5.2 1 5.6 0.2 6.4 0.2 6.8 1 +GoalZone 0 5.2 15 6.8 15 6.4 15.8 5.6 15.8 diff --git a/tnl-1.5.0/tnl/exe/levels/soccer2.txt b/tnl-1.5.0/tnl/exe/levels/soccer2.txt new file mode 100644 index 0000000000000000000000000000000000000000..9a9bfabe5efaad3f7db5f36ebc0df150a595eb26 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/soccer2.txt @@ -0,0 +1,71 @@ +SoccerGameType 10 8 +LevelName "Got Milk?'s Gambit" +Team Blue 0 0 1 +Team Red 1 0 0 +GridSize 280 +BarrierMaker 50 0 1 5 1 5.5 0 6.5 0 7 1 12 1 12 4 9 6 9 10 12 12 12 15 7 15 6.5 16 5.5 16 5 15 0 15 0 12 3 10 3 6 0 4 0 1 +BarrierMaker 50 5 13 5 12.5 4 12.5 4 12.6 4.9 13 5 13 +BarrierMaker 50 4 12 5 12 5 10.7 5.1 10.7 5.5 11 +BarrierMaker 50 8 13 7 13 7 11 +BarrierMaker 50 3.5 11.5 3.5 10.5 3.8 10.2 +BarrierMaker 50 4.5 10.2 4.5 11 4 11.5 +BarrierMaker 50 3.5 14 4 14 +BarrierMaker 50 1.5 14 3 14 3 12.5 2.9 12.5 1.5 13.9 1.5 14 +BarrierMaker 50 1 13.5 1.1 13.6 2.5 12.2 2.5 11.8 2.3 11.8 1 12.8 1 13.5 +BarrierMaker 50 7 14 7.5 14 7.5 13.9 7.1 13.5 7 13.5 7 14 +BarrierMaker 50 7.5 12 8 12 8 11 7.5 11 7.5 12 +Spawn 1 -0.5 8.6 +Spawn 1 -0.5 8 +Spawn 1 -0.8 8.3 +Spawn 1 -0.5 7.4 +Spawn 1 -0.8 7.7 +Spawn 1 -0.2 7.7 +Spawn 1 -0.2 8.3 +SoccerBallItem 6 8 +GoalZone 0 5.2 15 6.8 15 6.4 15.8 5.6 15.8 +BarrierMaker 50 1 7.4 0 7.4 -0.2 7 -0.8 7 -1 7.4 -2 7.4 -2 7.6 -2.4 7.8 -2.4 8.2 -2 8.4 -2 8.6 -1 8.6 -0.8 9 -0.2 9 0 8.6 1 8.6 1 8.4 1.4 8.2 1.4 7.8 1 7.6 1 7.4 +Teleporter -2 8 4.3 6.3 +Teleporter 1 8 7.7 6.3 +LoadoutZone 1 -1.6 8.5 -1.6 7.5 -1.2 7.5 -1.2 8.5 +LoadoutZone 1 0.2 8.5 0.2 7.5 0.6 7.5 0.6 8.5 +Spawn 0 12.5 8.6 +Spawn 0 12.5 8 +Spawn 0 12.2 8.3 +Spawn 0 12.5 7.4 +Spawn 0 12.2 7.7 +Spawn 0 12.8 7.7 +Spawn 0 12.8 8.3 +BarrierMaker 50 14 7.4 13 7.4 12.8 7 12.2 7 12 7.4 11 7.4 11 7.6 10.6 7.8 10.6 8.2 11 8.4 11 8.6 12 8.6 12.2 9 12.8 9 13 8.6 14 8.6 14 8.4 14.4 8.2 14.4 7.8 14 7.6 14 7.4 +LoadoutZone 0 11.4 8.5 11.4 7.5 11.8 7.5 11.8 8.5 +LoadoutZone 0 13.2 8.5 13.2 7.5 13.6 7.5 13.6 8.5 +Teleporter 11 8 4.3 9.7 +Teleporter 14 8 7.7 9.7 +BarrierMaker 50 5.2 6.5 5 6.5 4.5 7 4 7 +BarrierMaker 50 5.2 9.5 5 9.5 4.5 9 4 9 +BarrierMaker 50 7 10 7 9.5 7.5 9 8 9 +BarrierMaker 50 7 6 7 6.5 7.5 7 8 7 +Turret 0 5.2 15 +Turret 0 6.8 15 +BarrierMaker 50 9.7 11.5 9.1 12.1 9.6 12.6 10.6 12.6 10.6 12.1 9.7 11.5 +BarrierMaker 50 11.3 12.5 11.3 13 9.9 14.4 9.3 14.4 +BarrierMaker 50 11.2 13.9 11.3 13.9 11.6 14.3 11.6 14.4 11 14.5 10.9 14.5 10.9 14.4 11.2 13.9 +Turret -1 5.1 9.7 +ForceFieldProjector 0 5.6 11.1 +BarrierMaker 50 5 3 5 3.5 4 3.5 4 3.4 4.9 3 5 3 +BarrierMaker 50 4 4 5 4 5 5.3 5.1 5.3 5.5 5 +BarrierMaker 50 8 3 7 3 7 5 +BarrierMaker 50 3.5 4.5 3.5 5.5 3.8 5.8 +BarrierMaker 50 4.5 5.8 4.5 5 4 4.5 +BarrierMaker 50 3.5 2 4 2 +BarrierMaker 50 1.5 2 3 2 3 3.5 2.9 3.5 1.5 2.1 1.5 2 +BarrierMaker 50 1 2.5 1.1 2.4 2.5 3.8 2.5 4.2 2.3 4.2 1 3.2 1 2.5 +BarrierMaker 50 7 2 7.5 2 7.5 2.1 7.1 2.5 7 2.5 7 2 +BarrierMaker 50 7.5 4 8 4 8 5 7.5 5 7.5 4 +GoalZone 1 5.2 0.999999 6.8 0.999999 6.4 0.2 5.6 0.2 +Turret 1 5.2 0.999998 +Turret 1 6.8 0.999998 +BarrierMaker 50 9.7 4.5 9.1 3.9 9.6 3.4 10.6 3.4 10.6 3.9 9.7 4.5 +BarrierMaker 50 11.3 3.5 11.3 3 9.9 1.6 9.3 1.6 +BarrierMaker 50 11.2 2.1 11.3 2.1 11.6 1.7 11.6 1.6 11 1.5 10.9 1.5 10.9 1.6 11.2 2.1 +Turret -1 5.1 6.3 +ForceFieldProjector 1 5.6 4.9 diff --git a/tnl-1.5.0/tnl/exe/levels/zm1.txt b/tnl-1.5.0/tnl/exe/levels/zm1.txt new file mode 100644 index 0000000000000000000000000000000000000000..0fb12b697f7e95cab62569aa9cbf768c97c0db53 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/levels/zm1.txt @@ -0,0 +1,33 @@ +# World definition - BJG + +GridSize 128 + +GameType 0.33 +LevelName Intermission +LevelDescription "Hint: Use the bouncy balls for defensive relief!" + +Team Blue 0 0 1 + +BarrierMaker 50 0 0 5 0 6 1 7 0 10 0 10 10 0 10 0 0 +BarrierMaker 50 8 4 8 4.5 +BarrierMaker 50 8 5 8.5 6 7.5 6 8 5 +BarrierMaker 50 7 7 9 7 9 9 7 9 7 7 +BarrierMaker 50 5 8 6 7.5 6 8.5 5 8 +BarrierMaker 50 11 8 10 8.5 10 7.5 11 8 +BarrierMaker 50 8 11 7.5 10 8.5 10 8 11 +BarrierMaker 50 8 11.5 8 12 + +Spawn 0 1 6 +Spawn 0 4.5 1.5 +Spawn 0 6.5 6.5 +Spawn 0 7 2 +Spawn 0 9 2 +Spawn 0 8 1 + +TestItem 1 2 +TestItem 8 2 +TestItem 3 2 +TestItem 7 2 +TestItem 4 2 +TestItem 5 2 +TestItem 6 2 diff --git a/tnl-1.5.0/tnl/exe/master.cfg b/tnl-1.5.0/tnl/exe/master.cfg new file mode 100644 index 0000000000000000000000000000000000000000..0aea246172036ffc888dc4d6a1988ce9feebfcf0 --- /dev/null +++ b/tnl-1.5.0/tnl/exe/master.cfg @@ -0,0 +1,4 @@ +port 29001 +motd "ZAP 1.4.0 rc " "A new version of Zap is available... get it at http://www.opentnl.org/download.php" +motd "ZAP 1.4.0 rc 8" "Welcome to Zap! Scheduled games Monday, Wednesday, and Friday at 6:00 PM PST" + diff --git a/tnl-1.5.0/tnl/exe/sfx/boop.wav b/tnl-1.5.0/tnl/exe/sfx/boop.wav new file mode 100644 index 0000000000000000000000000000000000000000..10d89410f3cfc0f8e2f02fe21926f3fc4bbc6e4e Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/boop.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce.wav b/tnl-1.5.0/tnl/exe/sfx/bounce.wav new file mode 100644 index 0000000000000000000000000000000000000000..a19c513190f10b674e45d6ac80e672ffd2741d3f Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/bounce.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav new file mode 100644 index 0000000000000000000000000000000000000000..db18f37a68c33a0f424827d8739a2cc0b078d298 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav new file mode 100644 index 0000000000000000000000000000000000000000..e7b425a3c9652bf9b63c4941dd5b12761efc71d2 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_shield.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_shield.wav new file mode 100644 index 0000000000000000000000000000000000000000..cf7f4ff41aca1157580b0c89b3914ca8bb6abcd7 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/bounce_shield.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav new file mode 100644 index 0000000000000000000000000000000000000000..d5c1bfd5cd47353fee486f505d894b189b456093 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/comm_down.wav b/tnl-1.5.0/tnl/exe/sfx/comm_down.wav new file mode 100644 index 0000000000000000000000000000000000000000..f1a97022e71b14ad5609740a203b4e70eb13a40f Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/comm_down.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/comm_up.wav b/tnl-1.5.0/tnl/exe/sfx/comm_up.wav new file mode 100644 index 0000000000000000000000000000000000000000..8d824232e2555e0160c14bb4d3a903a30ceac93b Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/comm_up.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_capture.wav b/tnl-1.5.0/tnl/exe/sfx/flag_capture.wav new file mode 100644 index 0000000000000000000000000000000000000000..fe7241351a85e64fa3593728f1db17b04bc9f0f0 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/flag_capture.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_drop.wav b/tnl-1.5.0/tnl/exe/sfx/flag_drop.wav new file mode 100644 index 0000000000000000000000000000000000000000..e400d53c5a0fc3237386ce8c73fc07bb0ec7fdc5 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/flag_drop.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_return.wav b/tnl-1.5.0/tnl/exe/sfx/flag_return.wav new file mode 100644 index 0000000000000000000000000000000000000000..77eea838c14140ffe406c7f37c71d7ff18c9ab03 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/flag_return.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav b/tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav new file mode 100644 index 0000000000000000000000000000000000000000..036b718037c88a7968d109c9e293b65be3210a8c Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav b/tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav new file mode 100644 index 0000000000000000000000000000000000000000..e4ab84c5183b33ea5f0e37e5b718cf7b969380e4 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/forcefield_up.wav b/tnl-1.5.0/tnl/exe/sfx/forcefield_up.wav new file mode 100644 index 0000000000000000000000000000000000000000..ccb6b8abfbfbe9d0badf779012e0d5482480c4a3 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/forcefield_up.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/grenade.wav b/tnl-1.5.0/tnl/exe/sfx/grenade.wav new file mode 100644 index 0000000000000000000000000000000000000000..7a92218886900f0e18106ff9260861a54daec5c3 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/grenade.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/mine_arm.wav b/tnl-1.5.0/tnl/exe/sfx/mine_arm.wav new file mode 100644 index 0000000000000000000000000000000000000000..78dac9518755995c19cc0e057ac29de1ce6e8c02 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/mine_arm.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav b/tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav new file mode 100644 index 0000000000000000000000000000000000000000..383d496fbbc7316da121a0badad180e825c61371 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/mine_explode.wav b/tnl-1.5.0/tnl/exe/sfx/mine_explode.wav new file mode 100644 index 0000000000000000000000000000000000000000..b9d9ba48865e5e9c974d643cfc3f7c6a3857a26c Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/mine_explode.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/phaser.wav b/tnl-1.5.0/tnl/exe/sfx/phaser.wav new file mode 100644 index 0000000000000000000000000000000000000000..41f67be23dbb5f674a1793955c0e5cdd02968115 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/phaser.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav b/tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav new file mode 100644 index 0000000000000000000000000000000000000000..db18f37a68c33a0f424827d8739a2cc0b078d298 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav b/tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav new file mode 100644 index 0000000000000000000000000000000000000000..5a170ee4328e056367d7410f6c9e87faaaf8b83f Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_explode.wav b/tnl-1.5.0/tnl/exe/sfx/ship_explode.wav new file mode 100644 index 0000000000000000000000000000000000000000..acca79c5717e35ecf16e2e5cf8faa205c5378a23 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_explode.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_heal.wav b/tnl-1.5.0/tnl/exe/sfx/ship_heal.wav new file mode 100644 index 0000000000000000000000000000000000000000..d6971d62238920293a82b6c04b13cd07ec595b7f Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_heal.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_repair.wav b/tnl-1.5.0/tnl/exe/sfx/ship_repair.wav new file mode 100644 index 0000000000000000000000000000000000000000..a33f50c4bc40165e1c5e4307289b5a98c6269ed1 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_repair.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_sensor.wav b/tnl-1.5.0/tnl/exe/sfx/ship_sensor.wav new file mode 100644 index 0000000000000000000000000000000000000000..480c48b91163db347a475eee008fb3f41f77defa Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_sensor.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_shield.wav b/tnl-1.5.0/tnl/exe/sfx/ship_shield.wav new file mode 100644 index 0000000000000000000000000000000000000000..ed6bde537bab7256a8bb2e6f5c90d6e31aa1b13b Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_shield.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_turbo.wav b/tnl-1.5.0/tnl/exe/sfx/ship_turbo.wav new file mode 100644 index 0000000000000000000000000000000000000000..e76a822cb72ff597fb753dd736fa7ae3828a74ea Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/ship_turbo.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/teleport_in.wav b/tnl-1.5.0/tnl/exe/sfx/teleport_in.wav new file mode 100644 index 0000000000000000000000000000000000000000..64fd19af7b002a8298c64ebfb938f303a160c43b Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/teleport_in.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/teleport_out.wav b/tnl-1.5.0/tnl/exe/sfx/teleport_out.wav new file mode 100644 index 0000000000000000000000000000000000000000..ea4231bdc1ae6eb3ddf70b8b9b8dd2d8161b4dbc Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/teleport_out.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/triple.wav b/tnl-1.5.0/tnl/exe/sfx/triple.wav new file mode 100644 index 0000000000000000000000000000000000000000..41f67be23dbb5f674a1793955c0e5cdd02968115 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/triple.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/triple_impact.wav b/tnl-1.5.0/tnl/exe/sfx/triple_impact.wav new file mode 100644 index 0000000000000000000000000000000000000000..db18f37a68c33a0f424827d8739a2cc0b078d298 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/triple_impact.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/turret.wav b/tnl-1.5.0/tnl/exe/sfx/turret.wav new file mode 100644 index 0000000000000000000000000000000000000000..a5cdf4f50ff3a10eee1efe6480c45cf6b5ad2a86 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/turret.wav differ diff --git a/tnl-1.5.0/tnl/exe/sfx/turret_impact.wav b/tnl-1.5.0/tnl/exe/sfx/turret_impact.wav new file mode 100644 index 0000000000000000000000000000000000000000..41f67be23dbb5f674a1793955c0e5cdd02968115 Binary files /dev/null and b/tnl-1.5.0/tnl/exe/sfx/turret_impact.wav differ diff --git a/tnl-1.5.0/tnl/glut/glDedicated.h b/tnl-1.5.0/tnl/glut/glDedicated.h new file mode 100644 index 0000000000000000000000000000000000000000..0707c2376e83dbf60f567b477f70c2017ae2de0d --- /dev/null +++ b/tnl-1.5.0/tnl/glut/glDedicated.h @@ -0,0 +1,2126 @@ +//----------------------------------------------------------------------------- +// ZAP Dedicated server OpenGL stubs +//----------------------------------------------------------------------------- + +// Most of this is from... +/* + * Mesa 3-D graphics library + * Version: 3.4 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// portions of this file are: +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + + + +#define ZAP_GL_FUNCTION(returnType, func, args, returnstmt) inline returnType func args { returnstmt } + +// GL Constants + +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + +#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 +#define GL_FOG_COORDINATE_EXT 0x8451 +#define GL_FRAGMENT_DEPTH_EXT 0x8452 +#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 +#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 +#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 +#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 +#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + +#ifndef GL_EXT_packed_pixels +#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 +#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 +#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 +#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif + +#ifndef GL_EXT_paletted_texture +#define GL_COLOR_INDEX1_EXT 0x80E2 +#define GL_COLOR_INDEX2_EXT 0x80E3 +#define GL_COLOR_INDEX4_EXT 0x80E4 +#define GL_COLOR_INDEX8_EXT 0x80E5 +#define GL_COLOR_INDEX12_EXT 0x80E6 +#define GL_COLOR_INDEX16_EXT 0x80E7 +#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED +#endif + +#define GL_CLAMP_TO_EDGE_EXT 0x812F + +#define GL_V12MTVFMT_EXT 0x8702 +#define GL_V12MTNVFMT_EXT 0x8703 +#define GL_V12FTVFMT_EXT 0x8704 +#define GL_V12FMTVFMT_EXT 0x8705 + +#ifndef GL_EXT_texture_env_combine +#define GL_COMBINE_EXT 0x8570 +#define GL_COMBINE_RGB_EXT 0x8571 +#define GL_COMBINE_ALPHA_EXT 0x8572 +#define GL_RGB_SCALE_EXT 0x8573 +#define GL_ADD_SIGNED_EXT 0x8574 +#define GL_INTERPOLATE_EXT 0x8575 +#define GL_CONSTANT_EXT 0x8576 +#define GL_PRIMARY_COLOR_EXT 0x8577 +#define GL_PREVIOUS_EXT 0x8578 +#define GL_SOURCE0_RGB_EXT 0x8580 +#define GL_SOURCE1_RGB_EXT 0x8581 +#define GL_SOURCE2_RGB_EXT 0x8582 +#define GL_SOURCE3_RGB_EXT 0x8583 +#define GL_SOURCE4_RGB_EXT 0x8584 +#define GL_SOURCE5_RGB_EXT 0x8585 +#define GL_SOURCE6_RGB_EXT 0x8586 +#define GL_SOURCE7_RGB_EXT 0x8587 +#define GL_SOURCE0_ALPHA_EXT 0x8588 +#define GL_SOURCE1_ALPHA_EXT 0x8589 +#define GL_SOURCE2_ALPHA_EXT 0x858A +#define GL_SOURCE3_ALPHA_EXT 0x858B +#define GL_SOURCE4_ALPHA_EXT 0x858C +#define GL_SOURCE5_ALPHA_EXT 0x858D +#define GL_SOURCE6_ALPHA_EXT 0x858E +#define GL_SOURCE7_ALPHA_EXT 0x858F +#define GL_OPERAND0_RGB_EXT 0x8590 +#define GL_OPERAND1_RGB_EXT 0x8591 +#define GL_OPERAND2_RGB_EXT 0x8592 +#define GL_OPERAND3_RGB_EXT 0x8593 +#define GL_OPERAND4_RGB_EXT 0x8594 +#define GL_OPERAND5_RGB_EXT 0x8595 +#define GL_OPERAND6_RGB_EXT 0x8596 +#define GL_OPERAND7_RGB_EXT 0x8597 +#define GL_OPERAND0_ALPHA_EXT 0x8598 +#define GL_OPERAND1_ALPHA_EXT 0x8599 +#define GL_OPERAND2_ALPHA_EXT 0x859A +#define GL_OPERAND3_ALPHA_EXT 0x859B +#define GL_OPERAND4_ALPHA_EXT 0x859C +#define GL_OPERAND5_ALPHA_EXT 0x859D +#define GL_OPERAND6_ALPHA_EXT 0x859E +#define GL_OPERAND7_ALPHA_EXT 0x859F +#endif + +/* + * Mesa 3-D graphics library + * Version: 3.4 + * + * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + +#define GL_VERSION_1_1 1 +#define GL_VERSION_1_2 1 + +/* + * + * Datatypes + * + */ +#ifdef CENTERLINE_CLPP +#define signed +#endif +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef void GLvoid; +typedef signed char GLbyte; /* 1-byte signed */ +typedef short GLshort; /* 2-byte signed */ +typedef int GLint; /* 4-byte signed */ +typedef unsigned char GLubyte; /* 1-byte unsigned */ +typedef unsigned short GLushort; /* 2-byte unsigned */ +typedef unsigned int GLuint; /* 4-byte unsigned */ +typedef int GLsizei; /* 4-byte signed */ +typedef float GLfloat; /* single precision float */ +typedef float GLclampf; /* single precision float in [0,1] */ +typedef double GLdouble; /* double precision float */ +typedef double GLclampd; /* double precision float in [0,1] */ + + + +/* + * + * Constants + * + */ + +/* Boolean values */ +#define GL_FALSE 0x0 +#define GL_TRUE 0x1 + +/* Data types */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_DOUBLE 0x140A +#define GL_2_BYTES 0x1407 +#define GL_3_BYTES 0x1408 +#define GL_4_BYTES 0x1409 + +/* Primitives */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_QUADS 0x0007 +#define GL_QUAD_STRIP 0x0008 +#define GL_POLYGON 0x0009 + +/* Vertex Arrays */ +#define GL_VERTEX_ARRAY 0x8074 +#define GL_NORMAL_ARRAY 0x8075 +#define GL_COLOR_ARRAY 0x8076 +#define GL_INDEX_ARRAY 0x8077 +#define GL_TEXTURE_COORD_ARRAY 0x8078 +#define GL_EDGE_FLAG_ARRAY 0x8079 +#define GL_VERTEX_ARRAY_SIZE 0x807A +#define GL_VERTEX_ARRAY_TYPE 0x807B +#define GL_VERTEX_ARRAY_STRIDE 0x807C +#define GL_NORMAL_ARRAY_TYPE 0x807E +#define GL_NORMAL_ARRAY_STRIDE 0x807F +#define GL_COLOR_ARRAY_SIZE 0x8081 +#define GL_COLOR_ARRAY_TYPE 0x8082 +#define GL_COLOR_ARRAY_STRIDE 0x8083 +#define GL_INDEX_ARRAY_TYPE 0x8085 +#define GL_INDEX_ARRAY_STRIDE 0x8086 +#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 +#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 +#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A +#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C +#define GL_VERTEX_ARRAY_POINTER 0x808E +#define GL_NORMAL_ARRAY_POINTER 0x808F +#define GL_COLOR_ARRAY_POINTER 0x8090 +#define GL_INDEX_ARRAY_POINTER 0x8091 +#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 +#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 +#define GL_V2F 0x2A20 +#define GL_V3F 0x2A21 +#define GL_C4UB_V2F 0x2A22 +#define GL_C4UB_V3F 0x2A23 +#define GL_C3F_V3F 0x2A24 +#define GL_N3F_V3F 0x2A25 +#define GL_C4F_N3F_V3F 0x2A26 +#define GL_T2F_V3F 0x2A27 +#define GL_T4F_V4F 0x2A28 +#define GL_T2F_C4UB_V3F 0x2A29 +#define GL_T2F_C3F_V3F 0x2A2A +#define GL_T2F_N3F_V3F 0x2A2B +#define GL_T2F_C4F_N3F_V3F 0x2A2C +#define GL_T4F_C4F_N3F_V4F 0x2A2D + +/* Matrix Mode */ +#define GL_MATRIX_MODE 0x0BA0 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 + +/* Points */ +#define GL_POINT_SMOOTH 0x0B10 +#define GL_POINT_SIZE 0x0B11 +#define GL_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_POINT_SIZE_RANGE 0x0B12 + +/* Lines */ +#define GL_LINE_SMOOTH 0x0B20 +#define GL_LINE_STIPPLE 0x0B24 +#define GL_LINE_STIPPLE_PATTERN 0x0B25 +#define GL_LINE_STIPPLE_REPEAT 0x0B26 +#define GL_LINE_WIDTH 0x0B21 +#define GL_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_LINE_WIDTH_RANGE 0x0B22 + +/* Polygons */ +#define GL_POINT 0x1B00 +#define GL_LINE 0x1B01 +#define GL_FILL 0x1B02 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_POLYGON_MODE 0x0B40 +#define GL_POLYGON_SMOOTH 0x0B41 +#define GL_POLYGON_STIPPLE 0x0B42 +#define GL_EDGE_FLAG 0x0B43 +#define GL_CULL_FACE 0x0B44 +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_POINT 0x2A01 +#define GL_POLYGON_OFFSET_LINE 0x2A02 +#define GL_POLYGON_OFFSET_FILL 0x8037 + +/* Display Lists */ +#define GL_COMPILE 0x1300 +#define GL_COMPILE_AND_EXECUTE 0x1301 +#define GL_LIST_BASE 0x0B32 +#define GL_LIST_INDEX 0x0B33 +#define GL_LIST_MODE 0x0B30 + +/* Depth buffer */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_DEPTH_TEST 0x0B71 +#define GL_DEPTH_BITS 0x0D56 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_COMPONENT 0x1902 + +/* Lighting */ +#define GL_LIGHTING 0x0B50 +#define GL_LIGHT0 0x4000 +#define GL_LIGHT1 0x4001 +#define GL_LIGHT2 0x4002 +#define GL_LIGHT3 0x4003 +#define GL_LIGHT4 0x4004 +#define GL_LIGHT5 0x4005 +#define GL_LIGHT6 0x4006 +#define GL_LIGHT7 0x4007 +#define GL_SPOT_EXPONENT 0x1205 +#define GL_SPOT_CUTOFF 0x1206 +#define GL_CONSTANT_ATTENUATION 0x1207 +#define GL_LINEAR_ATTENUATION 0x1208 +#define GL_QUADRATIC_ATTENUATION 0x1209 +#define GL_AMBIENT 0x1200 +#define GL_DIFFUSE 0x1201 +#define GL_SPECULAR 0x1202 +#define GL_SHININESS 0x1601 +#define GL_EMISSION 0x1600 +#define GL_POSITION 0x1203 +#define GL_SPOT_DIRECTION 0x1204 +#define GL_AMBIENT_AND_DIFFUSE 0x1602 +#define GL_COLOR_INDEXES 0x1603 +#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 +#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 +#define GL_LIGHT_MODEL_AMBIENT 0x0B53 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_SHADE_MODEL 0x0B54 +#define GL_FLAT 0x1D00 +#define GL_SMOOTH 0x1D01 +#define GL_COLOR_MATERIAL 0x0B57 +#define GL_COLOR_MATERIAL_FACE 0x0B55 +#define GL_COLOR_MATERIAL_PARAMETER 0x0B56 +#define GL_NORMALIZE 0x0BA1 + +/* User clipping planes */ +#define GL_CLIP_PLANE0 0x3000 +#define GL_CLIP_PLANE1 0x3001 +#define GL_CLIP_PLANE2 0x3002 +#define GL_CLIP_PLANE3 0x3003 +#define GL_CLIP_PLANE4 0x3004 +#define GL_CLIP_PLANE5 0x3005 + +/* Accumulation buffer */ +#define GL_ACCUM_RED_BITS 0x0D58 +#define GL_ACCUM_GREEN_BITS 0x0D59 +#define GL_ACCUM_BLUE_BITS 0x0D5A +#define GL_ACCUM_ALPHA_BITS 0x0D5B +#define GL_ACCUM_CLEAR_VALUE 0x0B80 +#define GL_ACCUM 0x0100 +#define GL_ADD 0x0104 +#define GL_LOAD 0x0101 +#define GL_MULT 0x0103 +#define GL_RETURN 0x0102 + +/* Alpha testing */ +#define GL_ALPHA_TEST 0x0BC0 +#define GL_ALPHA_TEST_REF 0x0BC2 +#define GL_ALPHA_TEST_FUNC 0x0BC1 + +/* Blending */ +#define GL_BLEND 0x0BE2 +#define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND_DST 0x0BE0 +#define GL_ZERO 0x0 +#define GL_ONE 0x1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 + +/* Render Mode */ +#define GL_FEEDBACK 0x1C01 +#define GL_RENDER 0x1C00 +#define GL_SELECT 0x1C02 + +/* Feedback */ +#define GL_2D 0x0600 +#define GL_3D 0x0601 +#define GL_3D_COLOR 0x0602 +#define GL_3D_COLOR_TEXTURE 0x0603 +#define GL_4D_COLOR_TEXTURE 0x0604 +#define GL_POINT_TOKEN 0x0701 +#define GL_LINE_TOKEN 0x0702 +#define GL_LINE_RESET_TOKEN 0x0707 +#define GL_POLYGON_TOKEN 0x0703 +#define GL_BITMAP_TOKEN 0x0704 +#define GL_DRAW_PIXEL_TOKEN 0x0705 +#define GL_COPY_PIXEL_TOKEN 0x0706 +#define GL_PASS_THROUGH_TOKEN 0x0700 +#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 +#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 +#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 + +/* Selection */ +#define GL_SELECTION_BUFFER_POINTER 0x0DF3 +#define GL_SELECTION_BUFFER_SIZE 0x0DF4 + +/* Fog */ +#define GL_FOG 0x0B60 +#define GL_FOG_MODE 0x0B65 +#define GL_FOG_DENSITY 0x0B62 +#define GL_FOG_COLOR 0x0B66 +#define GL_FOG_INDEX 0x0B61 +#define GL_FOG_START 0x0B63 +#define GL_FOG_END 0x0B64 +#define GL_LINEAR 0x2601 +#define GL_EXP 0x0800 +#define GL_EXP2 0x0801 + +/* Logic Ops */ +#define GL_LOGIC_OP 0x0BF1 +#define GL_INDEX_LOGIC_OP 0x0BF1 +#define GL_COLOR_LOGIC_OP 0x0BF2 +#define GL_LOGIC_OP_MODE 0x0BF0 +#define GL_CLEAR 0x1500 +#define GL_SET 0x150F +#define GL_COPY 0x1503 +#define GL_COPY_INVERTED 0x150C +#define GL_NOOP 0x1505 +#define GL_INVERT 0x150A +#define GL_AND 0x1501 +#define GL_NAND 0x150E +#define GL_OR 0x1507 +#define GL_NOR 0x1508 +#define GL_XOR 0x1506 +#define GL_EQUIV 0x1509 +#define GL_AND_REVERSE 0x1502 +#define GL_AND_INVERTED 0x1504 +#define GL_OR_REVERSE 0x150B +#define GL_OR_INVERTED 0x150D + +/* Stencil */ +#define GL_STENCIL_TEST 0x0B90 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BITS 0x0D57 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_INDEX 0x1901 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 + +/* Buffers, Pixel Drawing/Reading */ +#define GL_NONE 0x0 +#define GL_LEFT 0x0406 +#define GL_RIGHT 0x0407 +/*GL_FRONT 0x0404 */ +/*GL_BACK 0x0405 */ +/*GL_FRONT_AND_BACK 0x0408 */ +#define GL_FRONT_LEFT 0x0400 +#define GL_FRONT_RIGHT 0x0401 +#define GL_BACK_LEFT 0x0402 +#define GL_BACK_RIGHT 0x0403 +#define GL_AUX0 0x0409 +#define GL_AUX1 0x040A +#define GL_AUX2 0x040B +#define GL_AUX3 0x040C +#define GL_COLOR_INDEX 0x1900 +#define GL_RED 0x1903 +#define GL_GREEN 0x1904 +#define GL_BLUE 0x1905 +#define GL_ALPHA 0x1906 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_ALPHA_BITS 0x0D55 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_INDEX_BITS 0x0D51 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_AUX_BUFFERS 0x0C00 +#define GL_READ_BUFFER 0x0C02 +#define GL_DRAW_BUFFER 0x0C01 +#define GL_DOUBLEBUFFER 0x0C32 +#define GL_STEREO 0x0C33 +#define GL_BITMAP 0x1A00 +#define GL_COLOR 0x1800 +#define GL_DEPTH 0x1801 +#define GL_STENCIL 0x1802 +#define GL_DITHER 0x0BD0 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 + +/* Implementation limits */ +#define GL_MAX_LIST_NESTING 0x0B31 +#define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_NAME_STACK_DEPTH 0x0D37 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_EVAL_ORDER 0x0D30 +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_CLIP_PLANES 0x0D32 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_PIXEL_MAP_TABLE 0x0D34 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B + +/* Gets */ +#define GL_ATTRIB_STACK_DEPTH 0x0BB0 +#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_CURRENT_INDEX 0x0B01 +#define GL_CURRENT_COLOR 0x0B00 +#define GL_CURRENT_NORMAL 0x0B02 +#define GL_CURRENT_RASTER_COLOR 0x0B04 +#define GL_CURRENT_RASTER_DISTANCE 0x0B09 +#define GL_CURRENT_RASTER_INDEX 0x0B05 +#define GL_CURRENT_RASTER_POSITION 0x0B07 +#define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 +#define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 +#define GL_CURRENT_TEXTURE_COORDS 0x0B03 +#define GL_INDEX_CLEAR_VALUE 0x0C20 +#define GL_INDEX_MODE 0x0C30 +#define GL_INDEX_WRITEMASK 0x0C21 +#define GL_MODELVIEW_MATRIX 0x0BA6 +#define GL_MODELVIEW_STACK_DEPTH 0x0BA3 +#define GL_NAME_STACK_DEPTH 0x0D70 +#define GL_PROJECTION_MATRIX 0x0BA7 +#define GL_PROJECTION_STACK_DEPTH 0x0BA4 +#define GL_RENDER_MODE 0x0C40 +#define GL_RGBA_MODE 0x0C31 +#define GL_TEXTURE_MATRIX 0x0BA8 +#define GL_TEXTURE_STACK_DEPTH 0x0BA5 +#define GL_VIEWPORT 0x0BA2 + +/* Evaluators */ +#define GL_AUTO_NORMAL 0x0D80 +#define GL_MAP1_COLOR_4 0x0D90 +#define GL_MAP1_GRID_DOMAIN 0x0DD0 +#define GL_MAP1_GRID_SEGMENTS 0x0DD1 +#define GL_MAP1_INDEX 0x0D91 +#define GL_MAP1_NORMAL 0x0D92 +#define GL_MAP1_TEXTURE_COORD_1 0x0D93 +#define GL_MAP1_TEXTURE_COORD_2 0x0D94 +#define GL_MAP1_TEXTURE_COORD_3 0x0D95 +#define GL_MAP1_TEXTURE_COORD_4 0x0D96 +#define GL_MAP1_VERTEX_3 0x0D97 +#define GL_MAP1_VERTEX_4 0x0D98 +#define GL_MAP2_COLOR_4 0x0DB0 +#define GL_MAP2_GRID_DOMAIN 0x0DD2 +#define GL_MAP2_GRID_SEGMENTS 0x0DD3 +#define GL_MAP2_INDEX 0x0DB1 +#define GL_MAP2_NORMAL 0x0DB2 +#define GL_MAP2_TEXTURE_COORD_1 0x0DB3 +#define GL_MAP2_TEXTURE_COORD_2 0x0DB4 +#define GL_MAP2_TEXTURE_COORD_3 0x0DB5 +#define GL_MAP2_TEXTURE_COORD_4 0x0DB6 +#define GL_MAP2_VERTEX_3 0x0DB7 +#define GL_MAP2_VERTEX_4 0x0DB8 +#define GL_COEFF 0x0A00 +#define GL_DOMAIN 0x0A02 +#define GL_ORDER 0x0A01 + +/* Hints */ +#define GL_FOG_HINT 0x0C54 +#define GL_LINE_SMOOTH_HINT 0x0C52 +#define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 +#define GL_POINT_SMOOTH_HINT 0x0C51 +#define GL_POLYGON_SMOOTH_HINT 0x0C53 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* Scissor box */ +#define GL_SCISSOR_TEST 0x0C11 +#define GL_SCISSOR_BOX 0x0C10 + +/* Pixel Mode / Transfer */ +#define GL_MAP_COLOR 0x0D10 +#define GL_MAP_STENCIL 0x0D11 +#define GL_INDEX_SHIFT 0x0D12 +#define GL_INDEX_OFFSET 0x0D13 +#define GL_RED_SCALE 0x0D14 +#define GL_RED_BIAS 0x0D15 +#define GL_GREEN_SCALE 0x0D18 +#define GL_GREEN_BIAS 0x0D19 +#define GL_BLUE_SCALE 0x0D1A +#define GL_BLUE_BIAS 0x0D1B +#define GL_ALPHA_SCALE 0x0D1C +#define GL_ALPHA_BIAS 0x0D1D +#define GL_DEPTH_SCALE 0x0D1E +#define GL_DEPTH_BIAS 0x0D1F +#define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 +#define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 +#define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 +#define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 +#define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 +#define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 +#define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 +#define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 +#define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 +#define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 +#define GL_PIXEL_MAP_S_TO_S 0x0C71 +#define GL_PIXEL_MAP_I_TO_I 0x0C70 +#define GL_PIXEL_MAP_I_TO_R 0x0C72 +#define GL_PIXEL_MAP_I_TO_G 0x0C73 +#define GL_PIXEL_MAP_I_TO_B 0x0C74 +#define GL_PIXEL_MAP_I_TO_A 0x0C75 +#define GL_PIXEL_MAP_R_TO_R 0x0C76 +#define GL_PIXEL_MAP_G_TO_G 0x0C77 +#define GL_PIXEL_MAP_B_TO_B 0x0C78 +#define GL_PIXEL_MAP_A_TO_A 0x0C79 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_PACK_LSB_FIRST 0x0D01 +#define GL_PACK_ROW_LENGTH 0x0D02 +#define GL_PACK_SKIP_PIXELS 0x0D04 +#define GL_PACK_SKIP_ROWS 0x0D03 +#define GL_PACK_SWAP_BYTES 0x0D00 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_UNPACK_LSB_FIRST 0x0CF1 +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SWAP_BYTES 0x0CF0 +#define GL_ZOOM_X 0x0D16 +#define GL_ZOOM_Y 0x0D17 + +/* Texture mapping */ +#define GL_TEXTURE_ENV 0x2300 +#define GL_TEXTURE_ENV_MODE 0x2200 +#define GL_TEXTURE_1D 0x0DE0 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_ENV_COLOR 0x2201 +#define GL_TEXTURE_GEN_S 0x0C60 +#define GL_TEXTURE_GEN_T 0x0C61 +#define GL_TEXTURE_GEN_MODE 0x2500 +#define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_WIDTH 0x1000 +#define GL_TEXTURE_HEIGHT 0x1001 +#define GL_TEXTURE_BORDER 0x1005 +#define GL_TEXTURE_COMPONENTS 0x1003 +#define GL_TEXTURE_RED_SIZE 0x805C +#define GL_TEXTURE_GREEN_SIZE 0x805D +#define GL_TEXTURE_BLUE_SIZE 0x805E +#define GL_TEXTURE_ALPHA_SIZE 0x805F +#define GL_TEXTURE_LUMINANCE_SIZE 0x8060 +#define GL_TEXTURE_INTENSITY_SIZE 0x8061 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_OBJECT_LINEAR 0x2401 +#define GL_OBJECT_PLANE 0x2501 +#define GL_EYE_LINEAR 0x2400 +#define GL_EYE_PLANE 0x2502 +#define GL_SPHERE_MAP 0x2402 +#define GL_DECAL 0x2101 +#define GL_MODULATE 0x2100 +#define GL_NEAREST 0x2600 +#define GL_REPEAT 0x2901 +#define GL_CLAMP 0x2900 +#define GL_S 0x2000 +#define GL_T 0x2001 +#define GL_R 0x2002 +#define GL_Q 0x2003 +#define GL_TEXTURE_GEN_R 0x0C62 +#define GL_TEXTURE_GEN_Q 0x0C63 + +/* GL 1.1 texturing */ +#define GL_PROXY_TEXTURE_1D 0x8063 +#define GL_PROXY_TEXTURE_2D 0x8064 +#define GL_TEXTURE_PRIORITY 0x8066 +#define GL_TEXTURE_RESIDENT 0x8067 +#define GL_TEXTURE_BINDING_1D 0x8068 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_TEXTURE_INTERNAL_FORMAT 0x1003 + +/* GL 1.2 texturing */ +#define GL_PACK_SKIP_IMAGES 0x806B +#define GL_PACK_IMAGE_HEIGHT 0x806C +#define GL_UNPACK_SKIP_IMAGES 0x806D +#define GL_UNPACK_IMAGE_HEIGHT 0x806E +#define GL_TEXTURE_3D 0x806F +#define GL_PROXY_TEXTURE_3D 0x8070 +#define GL_TEXTURE_DEPTH 0x8071 +#define GL_TEXTURE_WRAP_R 0x8072 +#define GL_MAX_3D_TEXTURE_SIZE 0x8073 +#define GL_TEXTURE_BINDING_3D 0x806A + +/* Internal texture formats (GL 1.1) */ +#define GL_ALPHA4 0x803B +#define GL_ALPHA8 0x803C +#define GL_ALPHA12 0x803D +#define GL_ALPHA16 0x803E +#define GL_LUMINANCE4 0x803F +#define GL_LUMINANCE8 0x8040 +#define GL_LUMINANCE12 0x8041 +#define GL_LUMINANCE16 0x8042 +#define GL_LUMINANCE4_ALPHA4 0x8043 +#define GL_LUMINANCE6_ALPHA2 0x8044 +#define GL_LUMINANCE8_ALPHA8 0x8045 +#define GL_LUMINANCE12_ALPHA4 0x8046 +#define GL_LUMINANCE12_ALPHA12 0x8047 +#define GL_LUMINANCE16_ALPHA16 0x8048 +#define GL_INTENSITY 0x8049 +#define GL_INTENSITY4 0x804A +#define GL_INTENSITY8 0x804B +#define GL_INTENSITY12 0x804C +#define GL_INTENSITY16 0x804D +#define GL_R3_G3_B2 0x2A10 +#define GL_RGB4 0x804F +#define GL_RGB5 0x8050 +#define GL_RGB8 0x8051 +#define GL_RGB10 0x8052 +#define GL_RGB12 0x8053 +#define GL_RGB16 0x8054 +#define GL_RGBA2 0x8055 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGBA8 0x8058 +#define GL_RGB10_A2 0x8059 +#define GL_RGBA12 0x805A +#define GL_RGBA16 0x805B + +/* Utility */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* Errors */ +#define GL_NO_ERROR 0x0 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_OPERATION 0x0502 +#define GL_STACK_OVERFLOW 0x0503 +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_OUT_OF_MEMORY 0x0505 + + +/* OpenGL 1.2 */ +#define GL_RESCALE_NORMAL 0x803A +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_BGR 0x80E0 +#define GL_BGRA 0x80E1 +#define GL_UNSIGNED_BYTE_3_3_2 0x8032 +#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 +#define GL_UNSIGNED_INT_8_8_8_8 0x8035 +#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 +#define GL_UNSIGNED_INT_10_10_10_2 0x8036 +#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA +#define GL_TEXTURE_MIN_LOD 0x813A +#define GL_TEXTURE_MAX_LOD 0x813B +#define GL_TEXTURE_BASE_LEVEL 0x813C +#define GL_TEXTURE_MAX_LEVEL 0x813D +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + + + +/* + * OpenGL 1.2 imaging subset (NOT IMPLEMENTED BY MESA) + */ +/* GL_EXT_color_table */ +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_COLOR_TABLE_SCALE 0x80D6 +#define GL_COLOR_TABLE_BIAS 0x80D7 +#define GL_COLOR_TABLE_FORMAT 0x80D8 +#define GL_COLOR_TABLE_WIDTH 0x80D9 +#define GL_COLOR_TABLE_RED_SIZE 0x80DA +#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB +#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC +#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD +#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE +#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF +/* GL_EXT_convolution and GL_HP_convolution_border_modes */ +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_CONVOLUTION_BORDER_MODE 0x8013 +#define GL_CONVOLUTION_FILTER_SCALE 0x8014 +#define GL_CONVOLUTION_FILTER_BIAS 0x8015 +#define GL_REDUCE 0x8016 +#define GL_CONVOLUTION_FORMAT 0x8017 +#define GL_CONVOLUTION_WIDTH 0x8018 +#define GL_CONVOLUTION_HEIGHT 0x8019 +#define GL_MAX_CONVOLUTION_WIDTH 0x801A +#define GL_MAX_CONVOLUTION_HEIGHT 0x801B +#define GL_POST_CONVOLUTION_RED_SCALE 0x801C +#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D +#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E +#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F +#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 +#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 +#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 +#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 +#define GL_CONSTANT_BORDER 0x8151 +#define GL_REPLICATE_BORDER 0x8153 +#define GL_CONVOLUTION_BORDER_COLOR 0x8154 +/* GL_SGI_color_matrix */ +#define GL_COLOR_MATRIX 0x80B1 +#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 +#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 +#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 +#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 +#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 +#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 +#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 +#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 +#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA +#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB +/* GL_EXT_histogram */ +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_HISTOGRAM_WIDTH 0x8026 +#define GL_HISTOGRAM_FORMAT 0x8027 +#define GL_HISTOGRAM_RED_SIZE 0x8028 +#define GL_HISTOGRAM_GREEN_SIZE 0x8029 +#define GL_HISTOGRAM_BLUE_SIZE 0x802A +#define GL_HISTOGRAM_ALPHA_SIZE 0x802B +#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C +#define GL_HISTOGRAM_SINK 0x802D +#define GL_MINMAX 0x802E +#define GL_MINMAX_FORMAT 0x802F +#define GL_MINMAX_SINK 0x8030 +#define GL_TABLE_TOO_LARGE 0x8031 +/* GL_EXT_blend_color, GL_EXT_blend_minmax */ +#define GL_BLEND_EQUATION 0x8009 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_COLOR 0x8005 + + +/* glPush/PopAttrib bits */ +#define GL_CURRENT_BIT 0x00000001 +#define GL_POINT_BIT 0x00000002 +#define GL_LINE_BIT 0x00000004 +#define GL_POLYGON_BIT 0x00000008 +#define GL_POLYGON_STIPPLE_BIT 0x00000010 +#define GL_PIXEL_MODE_BIT 0x00000020 +#define GL_LIGHTING_BIT 0x00000040 +#define GL_FOG_BIT 0x00000080 +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_ACCUM_BUFFER_BIT 0x00000200 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_VIEWPORT_BIT 0x00000800 +#define GL_TRANSFORM_BIT 0x00001000 +#define GL_ENABLE_BIT 0x00002000 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_HINT_BIT 0x00008000 +#define GL_EVAL_BIT 0x00010000 +#define GL_LIST_BIT 0x00020000 +#define GL_TEXTURE_BIT 0x00040000 +#define GL_SCISSOR_BIT 0x00080000 +#define GL_ALL_ATTRIB_BITS 0x000FFFFF + + +#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 +#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 +#define GL_ALL_CLIENT_ATTRIB_BITS 0xFFFFFFFF + +/* + * GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1) + */ +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + + +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 15 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +extern void *glutStrokeRoman; +extern void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +extern void *glutBitmap9By15; +extern void *glutBitmap8By13; +extern void *glutBitmapTimesRoman10; +extern void *glutBitmapTimesRoman24; +extern void *glutBitmapHelvetica10; +extern void *glutBitmapHelvetica12; +extern void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X ((GLenum) 100) +#define GLUT_WINDOW_Y ((GLenum) 101) +#define GLUT_WINDOW_WIDTH ((GLenum) 102) +#define GLUT_WINDOW_HEIGHT ((GLenum) 103) +#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) +#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) +#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) +#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) +#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) +#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) +#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) +#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) +#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) +#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) +#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) +#define GLUT_WINDOW_RGBA ((GLenum) 116) +#define GLUT_WINDOW_PARENT ((GLenum) 117) +#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) +#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) +#define GLUT_WINDOW_STEREO ((GLenum) 121) +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR ((GLenum) 122) +#endif +#define GLUT_SCREEN_WIDTH ((GLenum) 200) +#define GLUT_SCREEN_HEIGHT ((GLenum) 201) +#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) +#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) +#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) +#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) +#define GLUT_INIT_WINDOW_X ((GLenum) 500) +#define GLUT_INIT_WINDOW_Y ((GLenum) 501) +#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) +#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) +#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME ((GLenum) 700) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD ((GLenum) 600) +#define GLUT_HAS_MOUSE ((GLenum) 601) +#define GLUT_HAS_SPACEBALL ((GLenum) 602) +#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) +#define GLUT_HAS_TABLET ((GLenum) 604) +#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) +#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) +#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) +#define GLUT_NUM_DIALS ((GLenum) 608) +#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) +#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) +#define GLUT_HAS_JOYSTICK ((GLenum) 612) +#define GLUT_OWNS_JOYSTICK ((GLenum) 613) +#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) +#define GLUT_JOYSTICK_AXES ((GLenum) 615) +#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) +#define GLUT_LAYER_IN_USE ((GLenum) 801) +#define GLUT_HAS_OVERLAY ((GLenum) 802) +#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) +#define GLUT_NORMAL_DAMAGED ((GLenum) 804) +#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) +#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) +#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) +#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) +#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) +#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) +#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) +#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL ((GLenum) 0) +#define GLUT_OVERLAY ((GLenum) 1) + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + +#define GLUT_DISABLE_ATEXIT_HACK +#define GLUT_BUILDING_LIB + +/* GLUT initialization sub-API. */ +inline void APIENTRY glutInit(int *argcp, char **argv) {} +inline void APIENTRY glutInitDisplayMode(unsigned int mode) {} +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +inline void APIENTRY glutInitDisplayString(const char *string) {} +#endif +inline void APIENTRY glutInitWindowPosition(int x, int y) {} +inline void APIENTRY glutInitWindowSize(int width, int height) {} +inline void APIENTRY glutMainLoop(void) {} + +/* GLUT window sub-API. */ +inline int APIENTRY glutCreateWindow(const char *title){ return 0; } +inline int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height) { return 0; } +inline void APIENTRY glutDestroyWindow(int win) {} +inline void APIENTRY glutPostRedisplay(void) {} +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +inline void APIENTRY glutPostWindowRedisplay(int win) {} +#endif +inline void APIENTRY glutSwapBuffers(void) {} +inline int APIENTRY glutGetWindow(void) { return 0; } +inline void APIENTRY glutSetWindow(int win) {} +inline void APIENTRY glutSetWindowTitle(const char *title) {} +inline void APIENTRY glutSetIconTitle(const char *title) {} +inline void APIENTRY glutPositionWindow(int x, int y) {} +inline void APIENTRY glutReshapeWindow(int width, int height) {} +inline void APIENTRY glutPopWindow(void) {} +inline void APIENTRY glutPushWindow(void) {} +inline void APIENTRY glutIconifyWindow(void) {} +inline void APIENTRY glutShowWindow(void) {} +inline void APIENTRY glutHideWindow(void) {} +#if (GLUT_API_VERSION >= 3) +inline void APIENTRY glutFullScreen(void) {} +inline void APIENTRY glutSetCursor(int cursor) {} +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +inline void APIENTRY glutWarpPointer(int x, int y) {} +#endif + +/* GLUT overlay sub-API. */ +inline void APIENTRY glutEstablishOverlay(void) {} +inline void APIENTRY glutRemoveOverlay(void) {} +inline void APIENTRY glutUseLayer(GLenum layer) {} +inline void APIENTRY glutPostOverlayRedisplay(void) {} +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +inline void APIENTRY glutPostWindowOverlayRedisplay(int win) {} +#endif +inline void APIENTRY glutShowOverlay(void) {} +inline void APIENTRY glutHideOverlay(void) {} +#endif + +#define GLUTCALLBACK +/* GLUT menu sub-API. */ +inline int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)) { return 0; } +inline void APIENTRY glutDestroyMenu(int menu) {} +inline int APIENTRY glutGetMenu(void) { return 0; } +inline void APIENTRY glutSetMenu(int menu) {} +inline void APIENTRY glutAddMenuEntry(const char *label, int value) {} +inline void APIENTRY glutAddSubMenu(const char *label, int submenu) {} +inline void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value) {} +inline void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu) {} +inline void APIENTRY glutRemoveMenuItem(int item) {} +inline void APIENTRY glutAttachMenu(int button) {} +inline void APIENTRY glutDetachMenu(int button) {} + +/* GLUT window callback sub-API. */ +inline void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)) {} +inline void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)) {} +inline void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)) {} +inline void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)) {} +inline void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)) {} +inline void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)) {} +inline void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)) {} +inline void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)) {} +inline void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)) {} +inline void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value) {} +inline void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)) {} +#if (GLUT_API_VERSION >= 2) +inline void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)) {} +inline void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)) {} +inline void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)) {} +inline void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)) {} +inline void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)) {} +inline void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)) {} +inline void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)) {} +inline void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)) {} +#if (GLUT_API_VERSION >= 3) +inline void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)) {} +inline void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)) {} +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +inline void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)) {} +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +inline void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)) {} +inline void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)){} +inline void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval) {} +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +inline void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue) {} +inline GLfloat APIENTRY glutGetColor(int ndx, int component) {} +inline void APIENTRY glutCopyColormap(int win) {} + +/* GLUT state retrieval sub-API. */ +inline int APIENTRY glutGet(GLenum type) { return 0; } +inline int APIENTRY glutDeviceGet(GLenum type) { return 0; } +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +inline int APIENTRY glutExtensionSupported(const char *name) { return 0; } +#endif +#if (GLUT_API_VERSION >= 3) +inline int APIENTRY glutGetModifiers(void) { return 0; } +inline int APIENTRY glutLayerGet(GLenum type) { return 0; } +#endif + +/* GLUT font sub-API */ +inline void APIENTRY glutBitmapCharacter(void *font, int character) { } +inline int APIENTRY glutBitmapWidth(void *font, int character) { return 0; } +inline void APIENTRY glutStrokeCharacter(void *font, int character) {} +inline int APIENTRY glutStrokeWidth(void *font, int character) { return 0; } + +//------------------------------------------------------------------------------ +// GL functions +//------------------------------------------------------------------------------ + +/* + * Miscellaneous + */ + +ZAP_GL_FUNCTION(void, glClearIndex, ( GLfloat c ), return; ) + +ZAP_GL_FUNCTION(void, glClearColor, ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ), return; ) + +ZAP_GL_FUNCTION(void, glClear, ( GLbitfield mask ), return; ) + +ZAP_GL_FUNCTION(void, glIndexMask, ( GLuint mask ), return; ) + +ZAP_GL_FUNCTION(void, glColorMask, ( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ), return; ) + +ZAP_GL_FUNCTION(void, glAlphaFunc, ( GLenum func, GLclampf ref ), return; ) + +ZAP_GL_FUNCTION(void, glBlendFunc, ( GLenum sfactor, GLenum dfactor ), return; ) + +ZAP_GL_FUNCTION(void, glLogicOp, ( GLenum opcode ), return; ) + +ZAP_GL_FUNCTION(void, glCullFace, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glFrontFace, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glPointSize, ( GLfloat size ), return; ) + +ZAP_GL_FUNCTION(void, glLineWidth, ( GLfloat width ), return; ) + +ZAP_GL_FUNCTION(void, glLineStipple, ( GLint factor, GLushort pattern ), return; ) + +ZAP_GL_FUNCTION(void, glPolygonMode, ( GLenum face, GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glPolygonOffset, ( GLfloat factor, GLfloat units ), return; ) + +ZAP_GL_FUNCTION(void, glPolygonStipple, ( const GLubyte *mask ), return; ) + +ZAP_GL_FUNCTION(void, glGetPolygonStipple, ( GLubyte *mask ), return; ) + +ZAP_GL_FUNCTION(void, glEdgeFlag, ( GLboolean flag ), return; ) + +ZAP_GL_FUNCTION(void, glEdgeFlagv, ( const GLboolean *flag ), return; ) + +ZAP_GL_FUNCTION(void, glScissor, ( GLint x, GLint y, GLsizei width, GLsizei height), return; ) + +ZAP_GL_FUNCTION(void, glClipPlane, ( GLenum plane, const GLdouble *equation ), return; ) + +ZAP_GL_FUNCTION(void, glGetClipPlane, ( GLenum plane, GLdouble *equation ), return; ) + +ZAP_GL_FUNCTION(void, glDrawBuffer, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glReadBuffer, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glEnable, ( GLenum cap ), return; ) + +ZAP_GL_FUNCTION(void, glDisable, ( GLenum cap ), return; ) + +ZAP_GL_FUNCTION(GLboolean, glIsEnabled, ( GLenum cap ), return GL_FALSE; ) + + +ZAP_GL_FUNCTION(void, glEnableClientState, ( GLenum cap ), return; ) /* 1.1 */ + +ZAP_GL_FUNCTION(void, glDisableClientState, ( GLenum cap ), return; ) /* 1.1 */ + + +ZAP_GL_FUNCTION(void, glGetBooleanv, ( GLenum pname, GLboolean *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetDoublev, ( GLenum pname, GLdouble *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetFloatv, ( GLenum pname, GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetIntegerv, ( GLenum pname, GLint *params ), return; ) + + +ZAP_GL_FUNCTION(void, glPushAttrib, ( GLbitfield mask ), return; ) + +ZAP_GL_FUNCTION(void, glPopAttrib, ( void ), return; ) + + +ZAP_GL_FUNCTION(void, glPushClientAttrib, ( GLbitfield mask ), return; ) /* 1.1 */ + +ZAP_GL_FUNCTION(void, glPopClientAttrib, ( void ), return; ) /* 1.1 */ + + +ZAP_GL_FUNCTION(GLint, glRenderMode, ( GLenum mode ), return 0; ) + +ZAP_GL_FUNCTION(GLenum, glGetError, ( void ), return 0; ) + +ZAP_GL_FUNCTION(const GLubyte*, glGetString, ( GLenum name ), return (const GLubyte*)""; ) + +ZAP_GL_FUNCTION(void, glFinish, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glFlush, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glHint, ( GLenum target, GLenum mode ), return; ) + + + +/* + * Depth Buffer + */ + +ZAP_GL_FUNCTION(void, glClearDepth, ( GLclampd depth ), return; ) + +ZAP_GL_FUNCTION(void, glDepthFunc, ( GLenum func ), return; ) + +ZAP_GL_FUNCTION(void, glDepthMask, ( GLboolean flag ), return; ) + +ZAP_GL_FUNCTION(void, glDepthRange, ( GLclampd near_val, GLclampd far_val ), return; ) + + +/* + * Accumulation Buffer + */ + +ZAP_GL_FUNCTION(void, glClearAccum, ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ), return; ) + +ZAP_GL_FUNCTION(void, glAccum, ( GLenum op, GLfloat value ), return; ) + + + +/* + * Transformation + */ + +ZAP_GL_FUNCTION(void, glMatrixMode, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glOrtho, ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ), return; ) + +ZAP_GL_FUNCTION(void, glFrustum, ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ), return; ) + +ZAP_GL_FUNCTION(void, glViewport, ( GLint x, GLint y, GLsizei width, GLsizei height ), return; ) + +ZAP_GL_FUNCTION(void, glPushMatrix, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glPopMatrix, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glLoadIdentity, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glLoadMatrixd, ( const GLdouble *m ), return; ) +ZAP_GL_FUNCTION(void, glLoadMatrixf, ( const GLfloat *m ), return; ) + +ZAP_GL_FUNCTION(void, glMultMatrixd, ( const GLdouble *m ), return; ) +ZAP_GL_FUNCTION(void, glMultMatrixf, ( const GLfloat *m ), return; ) + +ZAP_GL_FUNCTION(void, glRotated, ( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ), return; ) +ZAP_GL_FUNCTION(void, glRotatef, ( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ), return; ) + +ZAP_GL_FUNCTION(void, glScaled, ( GLdouble x, GLdouble y, GLdouble z ), return; ) +ZAP_GL_FUNCTION(void, glScalef, ( GLfloat x, GLfloat y, GLfloat z ), return; ) + +ZAP_GL_FUNCTION(void, glTranslated, ( GLdouble x, GLdouble y, GLdouble z ), return; ) +ZAP_GL_FUNCTION(void, glTranslatef, ( GLfloat x, GLfloat y, GLfloat z ), return; ) + + + +/* + * Display Lists + */ + +ZAP_GL_FUNCTION(GLboolean, glIsList, ( GLuint list ), return GL_FALSE; ) + +ZAP_GL_FUNCTION(void, glDeleteLists, ( GLuint list, GLsizei range ), return; ) + +ZAP_GL_FUNCTION(GLuint, glGenLists, ( GLsizei range ), return 0; ) + +ZAP_GL_FUNCTION(void, glNewList, ( GLuint list, GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glEndList, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glCallList, ( GLuint list ), return; ) + +ZAP_GL_FUNCTION(void, glCallLists, ( GLsizei n, GLenum type, const GLvoid *lists ), return; ) + +ZAP_GL_FUNCTION(void, glListBase, ( GLuint base ), return; ) + + + +/* + * Drawing Functions + */ + +ZAP_GL_FUNCTION(void, glBegin, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glEnd, ( void ), return; ) + + +ZAP_GL_FUNCTION(void, glVertex2d, ( GLdouble x, GLdouble y ), return; ) +ZAP_GL_FUNCTION(void, glVertex2f, ( GLfloat x, GLfloat y ), return; ) +ZAP_GL_FUNCTION(void, glVertex2i, ( GLint x, GLint y ), return; ) +ZAP_GL_FUNCTION(void, glVertex2s, ( GLshort x, GLshort y ), return; ) + +ZAP_GL_FUNCTION(void, glVertex3d, ( GLdouble x, GLdouble y, GLdouble z ), return; ) +ZAP_GL_FUNCTION(void, glVertex3f, ( GLfloat x, GLfloat y, GLfloat z ), return; ) +ZAP_GL_FUNCTION(void, glVertex3i, ( GLint x, GLint y, GLint z ), return; ) +ZAP_GL_FUNCTION(void, glVertex3s, ( GLshort x, GLshort y, GLshort z ), return; ) + +ZAP_GL_FUNCTION(void, glVertex4d, ( GLdouble x, GLdouble y, GLdouble z, GLdouble w ), return; ) +ZAP_GL_FUNCTION(void, glVertex4f, ( GLfloat x, GLfloat y, GLfloat z, GLfloat w ), return; ) +ZAP_GL_FUNCTION(void, glVertex4i, ( GLint x, GLint y, GLint z, GLint w ), return; ) +ZAP_GL_FUNCTION(void, glVertex4s, ( GLshort x, GLshort y, GLshort z, GLshort w ), return; ) + +ZAP_GL_FUNCTION(void, glVertex2dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex2fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex2iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex2sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glVertex3dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex3fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex3iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex3sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glVertex4dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex4fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex4iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glVertex4sv, ( const GLshort *v ), return; ) + + +ZAP_GL_FUNCTION(void, glNormal3b, ( GLbyte nx, GLbyte ny, GLbyte nz ), return; ) +ZAP_GL_FUNCTION(void, glNormal3d, ( GLdouble nx, GLdouble ny, GLdouble nz ), return; ) +ZAP_GL_FUNCTION(void, glNormal3f, ( GLfloat nx, GLfloat ny, GLfloat nz ), return; ) +ZAP_GL_FUNCTION(void, glNormal3i, ( GLint nx, GLint ny, GLint nz ), return; ) +ZAP_GL_FUNCTION(void, glNormal3s, ( GLshort nx, GLshort ny, GLshort nz ), return; ) + +ZAP_GL_FUNCTION(void, glNormal3bv, ( const GLbyte *v ), return; ) +ZAP_GL_FUNCTION(void, glNormal3dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glNormal3fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glNormal3iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glNormal3sv, ( const GLshort *v ), return; ) + + +ZAP_GL_FUNCTION(void, glIndexd, ( GLdouble c ), return; ) +ZAP_GL_FUNCTION(void, glIndexf, ( GLfloat c ), return; ) +ZAP_GL_FUNCTION(void, glIndexi, ( GLint c ), return; ) +ZAP_GL_FUNCTION(void, glIndexs, ( GLshort c ), return; ) +ZAP_GL_FUNCTION(void, glIndexub, ( GLubyte c ), return; ) /* 1.1 */ + +ZAP_GL_FUNCTION(void, glIndexdv, ( const GLdouble *c ), return; ) +ZAP_GL_FUNCTION(void, glIndexfv, ( const GLfloat *c ), return; ) +ZAP_GL_FUNCTION(void, glIndexiv, ( const GLint *c ), return; ) +ZAP_GL_FUNCTION(void, glIndexsv, ( const GLshort *c ), return; ) +ZAP_GL_FUNCTION(void, glIndexubv, ( const GLubyte *c ), return; ) /* 1.1 */ + +ZAP_GL_FUNCTION(void, glColor3b, ( GLbyte red, GLbyte green, GLbyte blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3d, ( GLdouble red, GLdouble green, GLdouble blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3f, ( GLfloat red, GLfloat green, GLfloat blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3i, ( GLint red, GLint green, GLint blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3s, ( GLshort red, GLshort green, GLshort blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3ub, ( GLubyte red, GLubyte green, GLubyte blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3ui, ( GLuint red, GLuint green, GLuint blue ), return; ) +ZAP_GL_FUNCTION(void, glColor3us, ( GLushort red, GLushort green, GLushort blue ), return; ) + +ZAP_GL_FUNCTION(void, glColor4b, ( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4d, ( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4f, ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4i, ( GLint red, GLint green, GLint blue, GLint alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4s, ( GLshort red, GLshort green, GLshort blue, GLshort alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4ub, ( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4ui, ( GLuint red, GLuint green, GLuint blue, GLuint alpha ), return; ) +ZAP_GL_FUNCTION(void, glColor4us, ( GLushort red, GLushort green, GLushort blue, GLushort alpha ), return; ) + + +ZAP_GL_FUNCTION(void, glColor3bv, ( const GLbyte *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3sv, ( const GLshort *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3ubv, ( const GLubyte *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3uiv, ( const GLuint *v ), return; ) +ZAP_GL_FUNCTION(void, glColor3usv, ( const GLushort *v ), return; ) + +ZAP_GL_FUNCTION(void, glColor4bv, ( const GLbyte *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4sv, ( const GLshort *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4ubv, ( const GLubyte *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4uiv, ( const GLuint *v ), return; ) +ZAP_GL_FUNCTION(void, glColor4usv, ( const GLushort *v ), return; ) + + +ZAP_GL_FUNCTION(void, glTexCoord1d, ( GLdouble s ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord1f, ( GLfloat s ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord1i, ( GLint s ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord1s, ( GLshort s ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord2d, ( GLdouble s, GLdouble t ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord2f, ( GLfloat s, GLfloat t ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord2i, ( GLint s, GLint t ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord2s, ( GLshort s, GLshort t ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord3d, ( GLdouble s, GLdouble t, GLdouble r ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord3f, ( GLfloat s, GLfloat t, GLfloat r ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord3i, ( GLint s, GLint t, GLint r ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord3s, ( GLshort s, GLshort t, GLshort r ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord4d, ( GLdouble s, GLdouble t, GLdouble r, GLdouble q ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord4f, ( GLfloat s, GLfloat t, GLfloat r, GLfloat q ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord4i, ( GLint s, GLint t, GLint r, GLint q ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord4s, ( GLshort s, GLshort t, GLshort r, GLshort q ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord1dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord1fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord1iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord1sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord2dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord2fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord2iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord2sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord3dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord3fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord3iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord3sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoord4dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord4fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord4iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glTexCoord4sv, ( const GLshort *v ), return; ) + + +ZAP_GL_FUNCTION(void, glRasterPos2d, ( GLdouble x, GLdouble y ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos2f, ( GLfloat x, GLfloat y ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos2i, ( GLint x, GLint y ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos2s, ( GLshort x, GLshort y ), return; ) + +ZAP_GL_FUNCTION(void, glRasterPos3d, ( GLdouble x, GLdouble y, GLdouble z ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos3f, ( GLfloat x, GLfloat y, GLfloat z ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos3i, ( GLint x, GLint y, GLint z ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos3s, ( GLshort x, GLshort y, GLshort z ), return; ) + +ZAP_GL_FUNCTION(void, glRasterPos4d, ( GLdouble x, GLdouble y, GLdouble z, GLdouble w ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos4f, ( GLfloat x, GLfloat y, GLfloat z, GLfloat w ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos4i, ( GLint x, GLint y, GLint z, GLint w ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos4s, ( GLshort x, GLshort y, GLshort z, GLshort w ), return; ) + +ZAP_GL_FUNCTION(void, glRasterPos2dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos2fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos2iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos2sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glRasterPos3dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos3fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos3iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos3sv, ( const GLshort *v ), return; ) + +ZAP_GL_FUNCTION(void, glRasterPos4dv, ( const GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos4fv, ( const GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos4iv, ( const GLint *v ), return; ) +ZAP_GL_FUNCTION(void, glRasterPos4sv, ( const GLshort *v ), return; ) + + +ZAP_GL_FUNCTION(void, glRectd, ( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ), return; ) +ZAP_GL_FUNCTION(void, glRectf, ( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ), return; ) +ZAP_GL_FUNCTION(void, glRecti, ( GLint x1, GLint y1, GLint x2, GLint y2 ), return; ) +ZAP_GL_FUNCTION(void, glRects, ( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ), return; ) + + +ZAP_GL_FUNCTION(void, glRectdv, ( const GLdouble *v1, const GLdouble *v2 ), return; ) +ZAP_GL_FUNCTION(void, glRectfv, ( const GLfloat *v1, const GLfloat *v2 ), return; ) +ZAP_GL_FUNCTION(void, glRectiv, ( const GLint *v1, const GLint *v2 ), return; ) +ZAP_GL_FUNCTION(void, glRectsv, ( const GLshort *v1, const GLshort *v2 ), return; ) + + + +/* + * Vertex Arrays (1.1) + */ + +ZAP_GL_FUNCTION(void, glVertexPointer, ( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ), return; ) + +ZAP_GL_FUNCTION(void, glNormalPointer, ( GLenum type, GLsizei stride, const GLvoid *ptr ), return; ) + +ZAP_GL_FUNCTION(void, glColorPointer, ( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ), return; ) + +ZAP_GL_FUNCTION(void, glIndexPointer, ( GLenum type, GLsizei stride, const GLvoid *ptr ), return; ) + +ZAP_GL_FUNCTION(void, glTexCoordPointer, ( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr ), return; ) + +ZAP_GL_FUNCTION(void, glEdgeFlagPointer, ( GLsizei stride, const GLvoid *ptr ), return; ) + +ZAP_GL_FUNCTION(void, glGetPointerv, ( GLenum pname, void **params ), return; ) + +ZAP_GL_FUNCTION(void, glArrayElement, ( GLint i ), return; ) + +ZAP_GL_FUNCTION(void, glDrawArrays, ( GLenum mode, GLint first, GLsizei count ), return; ) + +ZAP_GL_FUNCTION(void, glDrawElements, ( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices ), return; ) + +ZAP_GL_FUNCTION(void, glInterleavedArrays, ( GLenum format, GLsizei stride, const GLvoid *pointer ), return; ) + + +/* + * Lighting + */ + +ZAP_GL_FUNCTION(void, glShadeModel, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glLightf, ( GLenum light, GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glLighti, ( GLenum light, GLenum pname, GLint param ), return; ) +ZAP_GL_FUNCTION(void, glLightfv, ( GLenum light, GLenum pname, const GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glLightiv, ( GLenum light, GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetLightfv, ( GLenum light, GLenum pname, GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glGetLightiv, ( GLenum light, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glLightModelf, ( GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glLightModeli, ( GLenum pname, GLint param ), return; ) +ZAP_GL_FUNCTION(void, glLightModelfv, ( GLenum pname, const GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glLightModeliv, ( GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glMaterialf, ( GLenum face, GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glMateriali, ( GLenum face, GLenum pname, GLint param ), return; ) +ZAP_GL_FUNCTION(void, glMaterialfv, ( GLenum face, GLenum pname, const GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glMaterialiv, ( GLenum face, GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetMaterialfv, ( GLenum face, GLenum pname, GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glGetMaterialiv, ( GLenum face, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glColorMaterial, ( GLenum face, GLenum mode ), return; ) + + + + +/* + * Raster functions + */ + +ZAP_GL_FUNCTION(void, glPixelZoom, ( GLfloat xfactor, GLfloat yfactor ), return; ) + +ZAP_GL_FUNCTION(void, glPixelStoref, ( GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glPixelStorei, ( GLenum pname, GLint param ), return; ) + +ZAP_GL_FUNCTION(void, glPixelTransferf, ( GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glPixelTransferi, ( GLenum pname, GLint param ), return; ) + +ZAP_GL_FUNCTION(void, glPixelMapfv, ( GLenum map, GLint mapsize, const GLfloat *values ), return; ) +ZAP_GL_FUNCTION(void, glPixelMapuiv, ( GLenum map, GLint mapsize, const GLuint *values ), return; ) +ZAP_GL_FUNCTION(void, glPixelMapusv, ( GLenum map, GLint mapsize, const GLushort *values ), return; ) + +ZAP_GL_FUNCTION(void, glGetPixelMapfv, ( GLenum map, GLfloat *values ), return; ) +ZAP_GL_FUNCTION(void, glGetPixelMapuiv, ( GLenum map, GLuint *values ), return; ) +ZAP_GL_FUNCTION(void, glGetPixelMapusv, ( GLenum map, GLushort *values ), return; ) + +ZAP_GL_FUNCTION(void, glBitmap, ( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap ), return; ) + +ZAP_GL_FUNCTION(void, glReadPixels, ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ), return; ) + +ZAP_GL_FUNCTION(void, glDrawPixels, ( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ), return; ) + +ZAP_GL_FUNCTION(void, glCopyPixels, ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type ), return; ) + + + +/* + * Stenciling + */ + +ZAP_GL_FUNCTION(void, glStencilFunc, ( GLenum func, GLint ref, GLuint mask ), return; ) + +ZAP_GL_FUNCTION(void, glStencilMask, ( GLuint mask ), return; ) + +ZAP_GL_FUNCTION(void, glStencilOp, ( GLenum fail, GLenum zfail, GLenum zpass ), return; ) + +ZAP_GL_FUNCTION(void, glClearStencil, ( GLint s ), return; ) + + + +/* + * Texture mapping + */ + +ZAP_GL_FUNCTION(void, glTexGend, ( GLenum coord, GLenum pname, GLdouble param ), return; ) +ZAP_GL_FUNCTION(void, glTexGenf, ( GLenum coord, GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glTexGeni, ( GLenum coord, GLenum pname, GLint param ), return; ) + +ZAP_GL_FUNCTION(void, glTexGendv, ( GLenum coord, GLenum pname, const GLdouble *params ), return; ) +ZAP_GL_FUNCTION(void, glTexGenfv, ( GLenum coord, GLenum pname, const GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glTexGeniv, ( GLenum coord, GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetTexGendv, ( GLenum coord, GLenum pname, GLdouble *params ), return; ) +ZAP_GL_FUNCTION(void, glGetTexGenfv, ( GLenum coord, GLenum pname, GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glGetTexGeniv, ( GLenum coord, GLenum pname, GLint *params ), return; ) + + +ZAP_GL_FUNCTION(void, glTexEnvf, ( GLenum target, GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glTexEnvi, ( GLenum target, GLenum pname, GLint param ), return; ) + +ZAP_GL_FUNCTION(void, glTexEnvfv, ( GLenum target, GLenum pname, const GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glTexEnviv, ( GLenum target, GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetTexEnvfv, ( GLenum target, GLenum pname, GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glGetTexEnviv, ( GLenum target, GLenum pname, GLint *params ), return; ) + + +ZAP_GL_FUNCTION(void, glTexParameterf, ( GLenum target, GLenum pname, GLfloat param ), return; ) +ZAP_GL_FUNCTION(void, glTexParameteri, ( GLenum target, GLenum pname, GLint param ), return; ) + +ZAP_GL_FUNCTION(void, glTexParameterfv, ( GLenum target, GLenum pname, const GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glTexParameteriv, ( GLenum target, GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetTexParameterfv, ( GLenum target, GLenum pname, GLfloat *params), return; ) +ZAP_GL_FUNCTION(void, glGetTexParameteriv, ( GLenum target, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetTexLevelParameterfv, ( GLenum target, GLint level, GLenum pname, GLfloat *params ), return; ) +ZAP_GL_FUNCTION(void, glGetTexLevelParameteriv, ( GLenum target, GLint level, GLenum pname, GLint *params ), return; ) + + +ZAP_GL_FUNCTION(void, glTexImage1D, ( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels ), return; ) + +ZAP_GL_FUNCTION(void, glTexImage2D, ( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ), return; ) + +ZAP_GL_FUNCTION(void, glGetTexImage, ( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ), return; ) + + + +/* 1.1 functions */ + +ZAP_GL_FUNCTION(void, glGenTextures, ( GLsizei n, GLuint *textures ), return; ) + +ZAP_GL_FUNCTION(void, glDeleteTextures, ( GLsizei n, const GLuint *textures), return; ) + +ZAP_GL_FUNCTION(void, glBindTexture, ( GLenum target, GLuint texture ), return; ) + +ZAP_GL_FUNCTION(void, glPrioritizeTextures, ( GLsizei n, const GLuint *textures, const GLclampf *priorities ), return; ) + +ZAP_GL_FUNCTION(GLboolean, glAreTexturesResident, ( GLsizei n, const GLuint *textures, GLboolean *residences ), return GL_FALSE; ) + +ZAP_GL_FUNCTION(GLboolean, glIsTexture, ( GLuint texture ), return GL_FALSE; ) + + +ZAP_GL_FUNCTION(void, glTexSubImage1D, ( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels ), return; ) + + +ZAP_GL_FUNCTION(void, glTexSubImage2D, ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ), return; ) + + +ZAP_GL_FUNCTION(void, glCopyTexImage1D, ( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border ), return; ) + + +ZAP_GL_FUNCTION(void, glCopyTexImage2D, ( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border ), return; ) + + +ZAP_GL_FUNCTION(void, glCopyTexSubImage1D, ( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ), return; ) + + +ZAP_GL_FUNCTION(void, glCopyTexSubImage2D, ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ), return; ) + + + + +/* + * Evaluators + */ + +ZAP_GL_FUNCTION(void, glMap1d, ( GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points ), return; ) +ZAP_GL_FUNCTION(void, glMap1f, ( GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points ), return; ) + +ZAP_GL_FUNCTION(void, glMap2d, ( GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points ), return; ) +ZAP_GL_FUNCTION(void, glMap2f, ( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points ), return; ) + +ZAP_GL_FUNCTION(void, glGetMapdv, ( GLenum target, GLenum query, GLdouble *v ), return; ) +ZAP_GL_FUNCTION(void, glGetMapfv, ( GLenum target, GLenum query, GLfloat *v ), return; ) +ZAP_GL_FUNCTION(void, glGetMapiv, ( GLenum target, GLenum query, GLint *v ), return; ) + +ZAP_GL_FUNCTION(void, glEvalCoord1d, ( GLdouble u ), return; ) +ZAP_GL_FUNCTION(void, glEvalCoord1f, ( GLfloat u ), return; ) + +ZAP_GL_FUNCTION(void, glEvalCoord1dv, ( const GLdouble *u ), return; ) +ZAP_GL_FUNCTION(void, glEvalCoord1fv, ( const GLfloat *u ), return; ) + +ZAP_GL_FUNCTION(void, glEvalCoord2d, ( GLdouble u, GLdouble v ), return; ) +ZAP_GL_FUNCTION(void, glEvalCoord2f, ( GLfloat u, GLfloat v ), return; ) + +ZAP_GL_FUNCTION(void, glEvalCoord2dv, ( const GLdouble *u ), return; ) +ZAP_GL_FUNCTION(void, glEvalCoord2fv, ( const GLfloat *u ), return; ) + +ZAP_GL_FUNCTION(void, glMapGrid1d, ( GLint un, GLdouble u1, GLdouble u2 ), return; ) +ZAP_GL_FUNCTION(void, glMapGrid1f, ( GLint un, GLfloat u1, GLfloat u2 ), return; ) + +ZAP_GL_FUNCTION(void, glMapGrid2d, ( GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2 ), return; ) +ZAP_GL_FUNCTION(void, glMapGrid2f, ( GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2 ), return; ) + +ZAP_GL_FUNCTION(void, glEvalPoint1, ( GLint i ), return; ) + +ZAP_GL_FUNCTION(void, glEvalPoint2, ( GLint i, GLint j ), return; ) + +ZAP_GL_FUNCTION(void, glEvalMesh1, ( GLenum mode, GLint i1, GLint i2 ), return; ) + +ZAP_GL_FUNCTION(void, glEvalMesh2, ( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ), return; ) + + + +/* + * Fog + */ + +ZAP_GL_FUNCTION(void, glFogf, ( GLenum pname, GLfloat param ), return; ) + +ZAP_GL_FUNCTION(void, glFogi, ( GLenum pname, GLint param ), return; ) + +ZAP_GL_FUNCTION(void, glFogfv, ( GLenum pname, const GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glFogiv, ( GLenum pname, const GLint *params ), return; ) + + + +/* + * Selection and Feedback + */ + +ZAP_GL_FUNCTION(void, glFeedbackBuffer, ( GLsizei size, GLenum type, GLfloat *buffer ), return; ) + +ZAP_GL_FUNCTION(void, glPassThrough, ( GLfloat token ), return; ) + +ZAP_GL_FUNCTION(void, glSelectBuffer, ( GLsizei size, GLuint *buffer ), return; ) + +ZAP_GL_FUNCTION(void, glInitNames, ( void ), return; ) + +ZAP_GL_FUNCTION(void, glLoadName, ( GLuint name ), return; ) + +ZAP_GL_FUNCTION(void, glPushName, ( GLuint name ), return; ) + +ZAP_GL_FUNCTION(void, glPopName, ( void ), return; ) + + + +/* 1.2 functions */ +ZAP_GL_FUNCTION(void, glDrawRangeElements, ( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices ), return; ) + +ZAP_GL_FUNCTION(void, glTexImage3D, ( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels ), return; ) + +ZAP_GL_FUNCTION(void, glTexSubImage3D, ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels), return; ) + +ZAP_GL_FUNCTION(void, glCopyTexSubImage3D, ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height ), return; ) + + +/* 1.2 imaging extension functions */ + +ZAP_GL_FUNCTION(void, glColorTable, ( GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table ), return; ) + +ZAP_GL_FUNCTION(void, glColorSubTable, ( GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data ), return; ) + +ZAP_GL_FUNCTION(void, glColorTableParameteriv, (GLenum target, GLenum pname, const GLint *params), return; ) + +ZAP_GL_FUNCTION(void, glColorTableParameterfv, (GLenum target, GLenum pname, const GLfloat *params), return; ) + +ZAP_GL_FUNCTION(void, glCopyColorSubTable, ( GLenum target, GLsizei start, GLint x, GLint y, GLsizei width ), return; ) + +ZAP_GL_FUNCTION(void, glCopyColorTable, ( GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width ), return; ) + +ZAP_GL_FUNCTION(void, glGetColorTable, ( GLenum target, GLenum format, GLenum type, GLvoid *table ), return; ) + +ZAP_GL_FUNCTION(void, glGetColorTableParameterfv, ( GLenum target, GLenum pname, GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetColorTableParameteriv, ( GLenum target, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glBlendEquation, ( GLenum mode ), return; ) + +ZAP_GL_FUNCTION(void, glBlendColor, ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ), return; ) + +ZAP_GL_FUNCTION(void, glHistogram, ( GLenum target, GLsizei width, GLenum internalformat, GLboolean sink ), return; ) + +ZAP_GL_FUNCTION(void, glResetHistogram, ( GLenum target ), return; ) + +ZAP_GL_FUNCTION(void, glGetHistogram, ( GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values ), return; ) + +ZAP_GL_FUNCTION(void, glGetHistogramParameterfv, ( GLenum target, GLenum pname, GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetHistogramParameteriv, ( GLenum target, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glMinmax, ( GLenum target, GLenum internalformat, GLboolean sink ), return; ) + +ZAP_GL_FUNCTION(void, glResetMinmax, ( GLenum target ), return; ) + +ZAP_GL_FUNCTION(void, glGetMinmax, ( GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values ), return; ) + +ZAP_GL_FUNCTION(void, glGetMinmaxParameterfv, ( GLenum target, GLenum pname, GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetMinmaxParameteriv, ( GLenum target, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glConvolutionFilter1D, ( GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image ), return; ) + +ZAP_GL_FUNCTION(void, glConvolutionFilter2D, ( GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image ), return; ) + +ZAP_GL_FUNCTION(void, glConvolutionParameterf, ( GLenum target, GLenum pname, GLfloat params ), return; ) + +ZAP_GL_FUNCTION(void, glConvolutionParameterfv, ( GLenum target, GLenum pname, const GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glConvolutionParameteri, ( GLenum target, GLenum pname, GLint params ), return; ) + +ZAP_GL_FUNCTION(void, glConvolutionParameteriv, ( GLenum target, GLenum pname, const GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glCopyConvolutionFilter1D, ( GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width ), return; ) + +ZAP_GL_FUNCTION(void, glCopyConvolutionFilter2D, ( GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height), return; ) + +ZAP_GL_FUNCTION(void, glGetConvolutionFilter, ( GLenum target, GLenum format, GLenum type, GLvoid *image ), return; ) + +ZAP_GL_FUNCTION(void, glGetConvolutionParameterfv, ( GLenum target, GLenum pname, GLfloat *params ), return; ) + +ZAP_GL_FUNCTION(void, glGetConvolutionParameteriv, ( GLenum target, GLenum pname, GLint *params ), return; ) + +ZAP_GL_FUNCTION(void, glSeparableFilter2D, ( GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column ), return; ) +ZAP_GL_FUNCTION(void, glGetSeparableFilter, ( GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span ), return; ) + +ZAP_GL_FUNCTION(void, glActiveTextureARB, (GLenum texture), return; ) +ZAP_GL_FUNCTION(void, glClientActiveTextureARB, (GLenum texture), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1dARB, (GLenum target, GLdouble s), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1dvARB, (GLenum target, const GLdouble *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1fARB, (GLenum target, GLfloat s), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1fvARB, (GLenum target, const GLfloat *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1iARB, (GLenum target, GLint s), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1ivARB, (GLenum target, const GLint *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1sARB, (GLenum target, GLshort s), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord1svARB, (GLenum target, const GLshort *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2dARB, (GLenum target, GLdouble s, GLdouble t), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2dvARB, (GLenum target, const GLdouble *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2fARB, (GLenum target, GLfloat s, GLfloat t), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2fvARB, (GLenum target, const GLfloat *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2iARB, (GLenum target, GLint s, GLint t), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2ivARB, (GLenum target, const GLint *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2sARB, (GLenum target, GLshort s, GLshort t), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord2svARB, (GLenum target, const GLshort *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3dARB, (GLenum target, GLdouble s, GLdouble t, GLdouble r), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3dvARB, (GLenum target, const GLdouble *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3fARB, (GLenum target, GLfloat s, GLfloat t, GLfloat r), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3fvARB, (GLenum target, const GLfloat *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3iARB, (GLenum target, GLint s, GLint t, GLint r), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3ivARB, (GLenum target, const GLint *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3sARB, (GLenum target, GLshort s, GLshort t, GLshort r), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord3svARB, (GLenum target, const GLshort *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4dARB, (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4dvARB, (GLenum target, const GLdouble *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4fARB, (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4fvARB, (GLenum target, const GLfloat *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4iARB, (GLenum target, GLint s, GLint t, GLint r, GLint q), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4ivARB, (GLenum target, const GLint *v), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4sARB, (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q), return; ) +ZAP_GL_FUNCTION(void, glMultiTexCoord4svARB, (GLenum target, const GLshort *v), return; ) + +/* EXT_paletted_texture */ +ZAP_GL_FUNCTION(void, glColorTableEXT, (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const void* data), return; ) + +/* EXT_compiled_vertex_array */ +ZAP_GL_FUNCTION(void, glLockArraysEXT, (GLint first, GLsizei count), return; ) +ZAP_GL_FUNCTION(void, glUnlockArraysEXT, (void), return; ) + +/* EXT_fog_coord */ +ZAP_GL_FUNCTION(void, glFogCoordfEXT, (GLfloat coord), return; ) +ZAP_GL_FUNCTION(void, glFogCoordPointerEXT, (GLenum type, GLsizei stride, void *pointer), return; ) + +/* EXT_vertex_buffer */ +ZAP_GL_FUNCTION(GLboolean, glAvailableVertexBufferEXT, (void), return GL_FALSE; ) +ZAP_GL_FUNCTION(GLint, glAllocateVertexBufferEXT, (GLsizei size, GLint format, GLboolean preserve), return 0; ) +ZAP_GL_FUNCTION(void*, glLockVertexBufferEXT, (GLint handle, GLsizei size), return NULL; ) +ZAP_GL_FUNCTION(void, glUnlockVertexBufferEXT, (GLint handle), return; ) +ZAP_GL_FUNCTION(void, glSetVertexBufferEXT, (GLint handle), return; ) +ZAP_GL_FUNCTION(void, glOffsetVertexBufferEXT, (GLint handle, GLuint offset), return; ) +ZAP_GL_FUNCTION(void, glFillVertexBufferEXT, (GLint handle, GLint first, GLsizei count), return; ) +ZAP_GL_FUNCTION(void, glFreeVertexBufferEXT, (GLint handle), return; ) diff --git a/tnl-1.5.0/tnl/glut/glut.h b/tnl-1.5.0/tnl/glut/glut.h new file mode 100644 index 0000000000000000000000000000000000000000..5d549e05a3cd4e6d4e67ea4802e570dcadfd63ea --- /dev/null +++ b/tnl-1.5.0/tnl/glut/glut.h @@ -0,0 +1,724 @@ +#ifndef __glut_h__ +#define __glut_h__ + +/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998. */ + +/* This program is freely distributable without licensing fees and is + provided without guarantee or warrantee expressed or implied. This + program is -not- in the public domain. */ + +#if defined(_WIN32) + +/* GLUT 3.7 now tries to avoid including + to avoid name space pollution, but Win32's + needs APIENTRY and WINGDIAPI defined properly. */ +# if 0 + /* This would put tons of macros and crap in our clean name space. */ +# define WIN32_LEAN_AND_MEAN +# include +# else + /* XXX This is from Win32's */ +# ifndef APIENTRY +# define GLUT_APIENTRY_DEFINED +# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) || defined(__BORLANDC__) || defined(__LCC__) +# define APIENTRY __stdcall +# else +# define APIENTRY +# endif +# endif + /* XXX This is from Win32's */ +# ifndef CALLBACK +# if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC)) && !defined(MIDL_PASS) || defined(__LCC__) +# define CALLBACK __stdcall +# else +# define CALLBACK +# endif +# endif + /* XXX Hack for lcc compiler. It doesn't support __declspec(dllimport), just __stdcall. */ +# if defined( __LCC__ ) +# undef WINGDIAPI +# define WINGDIAPI __stdcall +# else + /* XXX This is from Win32's and */ +# ifndef WINGDIAPI +# define GLUT_WINGDIAPI_DEFINED +# define WINGDIAPI __declspec(dllimport) +# endif +# endif + /* XXX This is from Win32's */ +# ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; +# define _WCHAR_T_DEFINED +# endif +# endif + +/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA + in your compile preprocessor options. */ +# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA) +# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */ +/* To enable automatic SGI OpenGL for Windows library usage for GLUT, + define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */ +# ifdef GLUT_USE_SGI_OPENGL +# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */ +# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */ +# pragma comment (lib, "glut.lib") /* link with Win32 GLUT for SGI OpenGL lib */ +# else +# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */ +# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */ +# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */ +# endif +# endif + +/* To disable supression of annoying warnings about floats being promoted + to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor + options. */ +# ifndef GLUT_NO_WARNING_DISABLE +# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */ +# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */ +# endif + +/* Win32 has an annoying issue where there are multiple C run-time + libraries (CRTs). If the executable is linked with a different CRT + from the GLUT DLL, the GLUT DLL will not share the same CRT static + data seen by the executable. In particular, atexit callbacks registered + in the executable will not be called if GLUT calls its (different) + exit routine). GLUT is typically built with the + "/MD" option (the CRT with multithreading DLL support), but the Visual + C++ linker default is "/ML" (the single threaded CRT). + + One workaround to this issue is requiring users to always link with + the same CRT as GLUT is compiled with. That requires users supply a + non-standard option. GLUT 3.7 has its own built-in workaround where + the executable's "exit" function pointer is covertly passed to GLUT. + GLUT then calls the executable's exit function pointer to ensure that + any "atexit" calls registered by the application are called if GLUT + needs to exit. + + Note that the __glut*WithExit routines should NEVER be called directly. + To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */ + +/* XXX This is from Win32's */ +# if !defined(_MSC_VER) && !defined(__cdecl) + /* Define __cdecl for non-Microsoft compilers. */ +# define __cdecl +# define GLUT_DEFINED___CDECL +# endif +# ifndef _CRTIMP +# ifdef _NTSDK + /* Definition compatible with NT SDK */ +# define _CRTIMP +# else + /* Current definition */ +# ifdef _DLL +# define _CRTIMP __declspec(dllimport) +# else +# define _CRTIMP +# endif +# endif +# define GLUT_DEFINED__CRTIMP +# endif + +/* GLUT API entry point declarations for Win32. */ +# ifdef GLUT_BUILDING_LIB +# define GLUTAPI __declspec(dllexport) +# else +# ifdef _DLL +# define GLUTAPI __declspec(dllimport) +# else +# define GLUTAPI extern +# endif +# endif + +/* GLUT callback calling convention for Win32. */ +# define GLUTCALLBACK __cdecl + +#endif /* _WIN32 */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) +# ifndef GLUT_BUILDING_LIB +/* CodeWarrior for Win32 does a "using std::exit;" in stdlib.h. + So declaring ::exit(int) would cause an ambiguous error if + someone would include stdlib.h before glut.h. */ +# if defined(__MWERKS__) && defined(__cplusplus) + extern _CRTIMP void __cdecl std::exit(int); +# else + extern _CRTIMP void __cdecl exit(int); +# endif +# endif +#else +/* non-Win32 case. */ +/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */ +# define APIENTRY +# define GLUT_APIENTRY_DEFINED +# define CALLBACK +/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */ +# define GLUTAPI extern +# define GLUTCALLBACK +/* Prototype exit for the non-Win32 case (see above). */ +extern void exit(int); +#endif + +/** + GLUT API revision history: + + GLUT_API_VERSION is updated to reflect incompatible GLUT + API changes (interface changes, semantic changes, deletions, + or additions). + + GLUT_API_VERSION=1 First public release of GLUT. 11/29/94 + + GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling, + extension. Supports new input devices like tablet, dial and button + box, and Spaceball. Easy to query OpenGL extensions. + + GLUT_API_VERSION=3 glutMenuStatus added. + + GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer, + glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic + video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc, + glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat, + glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). +**/ +#ifndef GLUT_API_VERSION /* allow this to be overriden */ +#define GLUT_API_VERSION 3 +#endif + +/** + GLUT implementation revision history: + + GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT + API revisions and implementation revisions (ie, bug fixes). + + GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of + GLUT Xlib-based implementation. 11/29/94 + + GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of + GLUT Xlib-based implementation providing GLUT version 2 + interfaces. + + GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95 + + GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95 + + GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95 + + GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96 + + GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner + and video resize. 1/3/97 + + GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines. + + GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release. + + GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling. + + GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support. + + GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface. + + GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa +**/ +#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */ +#define GLUT_XLIB_IMPLEMENTATION 15 +#endif + +/* Display mode bit masks. */ +#define GLUT_RGB 0 +#define GLUT_RGBA GLUT_RGB +#define GLUT_INDEX 1 +#define GLUT_SINGLE 0 +#define GLUT_DOUBLE 2 +#define GLUT_ACCUM 4 +#define GLUT_ALPHA 8 +#define GLUT_DEPTH 16 +#define GLUT_STENCIL 32 +#if (GLUT_API_VERSION >= 2) +#define GLUT_MULTISAMPLE 128 +#define GLUT_STEREO 256 +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_LUMINANCE 512 +#endif + +/* Mouse buttons. */ +#define GLUT_LEFT_BUTTON 0 +#define GLUT_MIDDLE_BUTTON 1 +#define GLUT_RIGHT_BUTTON 2 + +/* Mouse button state. */ +#define GLUT_DOWN 0 +#define GLUT_UP 1 + +#if (GLUT_API_VERSION >= 2) +/* function keys */ +#define GLUT_KEY_F1 1 +#define GLUT_KEY_F2 2 +#define GLUT_KEY_F3 3 +#define GLUT_KEY_F4 4 +#define GLUT_KEY_F5 5 +#define GLUT_KEY_F6 6 +#define GLUT_KEY_F7 7 +#define GLUT_KEY_F8 8 +#define GLUT_KEY_F9 9 +#define GLUT_KEY_F10 10 +#define GLUT_KEY_F11 11 +#define GLUT_KEY_F12 12 +/* directional keys */ +#define GLUT_KEY_LEFT 100 +#define GLUT_KEY_UP 101 +#define GLUT_KEY_RIGHT 102 +#define GLUT_KEY_DOWN 103 +#define GLUT_KEY_PAGE_UP 104 +#define GLUT_KEY_PAGE_DOWN 105 +#define GLUT_KEY_HOME 106 +#define GLUT_KEY_END 107 +#define GLUT_KEY_INSERT 108 +#endif + +/* Entry/exit state. */ +#define GLUT_LEFT 0 +#define GLUT_ENTERED 1 + +/* Menu usage state. */ +#define GLUT_MENU_NOT_IN_USE 0 +#define GLUT_MENU_IN_USE 1 + +/* Visibility state. */ +#define GLUT_NOT_VISIBLE 0 +#define GLUT_VISIBLE 1 + +/* Window status state. */ +#define GLUT_HIDDEN 0 +#define GLUT_FULLY_RETAINED 1 +#define GLUT_PARTIALLY_RETAINED 2 +#define GLUT_FULLY_COVERED 3 + +/* Color index component selection values. */ +#define GLUT_RED 0 +#define GLUT_GREEN 1 +#define GLUT_BLUE 2 + +#if defined(_WIN32) +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN ((void*)0) +#define GLUT_STROKE_MONO_ROMAN ((void*)1) + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 ((void*)2) +#define GLUT_BITMAP_8_BY_13 ((void*)3) +#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4) +#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 ((void*)6) +#define GLUT_BITMAP_HELVETICA_12 ((void*)7) +#define GLUT_BITMAP_HELVETICA_18 ((void*)8) +#endif +#else +/* Stroke font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutStrokeRoman; +GLUTAPI void *glutStrokeMonoRoman; + +/* Stroke font constants (use these in GLUT program). */ +#define GLUT_STROKE_ROMAN (&glutStrokeRoman) +#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman) + +/* Bitmap font opaque addresses (use constants instead in source code). */ +GLUTAPI void *glutBitmap9By15; +GLUTAPI void *glutBitmap8By13; +GLUTAPI void *glutBitmapTimesRoman10; +GLUTAPI void *glutBitmapTimesRoman24; +GLUTAPI void *glutBitmapHelvetica10; +GLUTAPI void *glutBitmapHelvetica12; +GLUTAPI void *glutBitmapHelvetica18; + +/* Bitmap font constants (use these in GLUT program). */ +#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15) +#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13) +#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10) +#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24) +#if (GLUT_API_VERSION >= 3) +#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10) +#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12) +#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18) +#endif +#endif + +/* glutGet parameters. */ +#define GLUT_WINDOW_X ((GLenum) 100) +#define GLUT_WINDOW_Y ((GLenum) 101) +#define GLUT_WINDOW_WIDTH ((GLenum) 102) +#define GLUT_WINDOW_HEIGHT ((GLenum) 103) +#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104) +#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105) +#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106) +#define GLUT_WINDOW_RED_SIZE ((GLenum) 107) +#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108) +#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109) +#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110) +#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111) +#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112) +#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113) +#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114) +#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115) +#define GLUT_WINDOW_RGBA ((GLenum) 116) +#define GLUT_WINDOW_PARENT ((GLenum) 117) +#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118) +#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119) +#if (GLUT_API_VERSION >= 2) +#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120) +#define GLUT_WINDOW_STEREO ((GLenum) 121) +#endif +#if (GLUT_API_VERSION >= 3) +#define GLUT_WINDOW_CURSOR ((GLenum) 122) +#endif +#define GLUT_SCREEN_WIDTH ((GLenum) 200) +#define GLUT_SCREEN_HEIGHT ((GLenum) 201) +#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202) +#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203) +#define GLUT_MENU_NUM_ITEMS ((GLenum) 300) +#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400) +#define GLUT_INIT_WINDOW_X ((GLenum) 500) +#define GLUT_INIT_WINDOW_Y ((GLenum) 501) +#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502) +#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503) +#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504) +#if (GLUT_API_VERSION >= 2) +#define GLUT_ELAPSED_TIME ((GLenum) 700) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123) +#endif + +#if (GLUT_API_VERSION >= 2) +/* glutDeviceGet parameters. */ +#define GLUT_HAS_KEYBOARD ((GLenum) 600) +#define GLUT_HAS_MOUSE ((GLenum) 601) +#define GLUT_HAS_SPACEBALL ((GLenum) 602) +#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603) +#define GLUT_HAS_TABLET ((GLenum) 604) +#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605) +#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606) +#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607) +#define GLUT_NUM_DIALS ((GLenum) 608) +#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609) +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610) +#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611) +#define GLUT_HAS_JOYSTICK ((GLenum) 612) +#define GLUT_OWNS_JOYSTICK ((GLenum) 613) +#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614) +#define GLUT_JOYSTICK_AXES ((GLenum) 615) +#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616) +#endif + +#if (GLUT_API_VERSION >= 3) +/* glutLayerGet parameters. */ +#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800) +#define GLUT_LAYER_IN_USE ((GLenum) 801) +#define GLUT_HAS_OVERLAY ((GLenum) 802) +#define GLUT_TRANSPARENT_INDEX ((GLenum) 803) +#define GLUT_NORMAL_DAMAGED ((GLenum) 804) +#define GLUT_OVERLAY_DAMAGED ((GLenum) 805) + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* glutVideoResizeGet parameters. */ +#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900) +#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901) +#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902) +#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903) +#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904) +#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905) +#define GLUT_VIDEO_RESIZE_X ((GLenum) 906) +#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907) +#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908) +#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909) +#endif + +/* glutUseLayer parameters. */ +#define GLUT_NORMAL ((GLenum) 0) +#define GLUT_OVERLAY ((GLenum) 1) + +/* glutGetModifiers return mask. */ +#define GLUT_ACTIVE_SHIFT 1 +#define GLUT_ACTIVE_CTRL 2 +#define GLUT_ACTIVE_ALT 4 + +/* glutSetCursor parameters. */ +/* Basic arrows. */ +#define GLUT_CURSOR_RIGHT_ARROW 0 +#define GLUT_CURSOR_LEFT_ARROW 1 +/* Symbolic cursor shapes. */ +#define GLUT_CURSOR_INFO 2 +#define GLUT_CURSOR_DESTROY 3 +#define GLUT_CURSOR_HELP 4 +#define GLUT_CURSOR_CYCLE 5 +#define GLUT_CURSOR_SPRAY 6 +#define GLUT_CURSOR_WAIT 7 +#define GLUT_CURSOR_TEXT 8 +#define GLUT_CURSOR_CROSSHAIR 9 +/* Directional cursors. */ +#define GLUT_CURSOR_UP_DOWN 10 +#define GLUT_CURSOR_LEFT_RIGHT 11 +/* Sizing cursors. */ +#define GLUT_CURSOR_TOP_SIDE 12 +#define GLUT_CURSOR_BOTTOM_SIDE 13 +#define GLUT_CURSOR_LEFT_SIDE 14 +#define GLUT_CURSOR_RIGHT_SIDE 15 +#define GLUT_CURSOR_TOP_LEFT_CORNER 16 +#define GLUT_CURSOR_TOP_RIGHT_CORNER 17 +#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18 +#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19 +/* Inherit from parent window. */ +#define GLUT_CURSOR_INHERIT 100 +/* Blank cursor. */ +#define GLUT_CURSOR_NONE 101 +/* Fullscreen crosshair (if available). */ +#define GLUT_CURSOR_FULL_CROSSHAIR 102 +#endif + +/* GLUT initialization sub-API. */ +GLUTAPI void APIENTRY glutInit(int *argcp, char **argv); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI void APIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static void APIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); } +#define glutInit glutInit_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutInitDisplayMode(unsigned int mode); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutInitDisplayString(const char *string); +#endif +GLUTAPI void APIENTRY glutInitWindowPosition(int x, int y); +GLUTAPI void APIENTRY glutInitWindowSize(int width, int height); +GLUTAPI void APIENTRY glutMainLoop(void); + +/* GLUT window sub-API. */ +GLUTAPI int APIENTRY glutCreateWindow(const char *title); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); } +#define glutCreateWindow glutCreateWindow_ATEXIT_HACK +#endif +#endif +GLUTAPI int APIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height); +GLUTAPI void APIENTRY glutDestroyWindow(int win); +GLUTAPI void APIENTRY glutPostRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutSwapBuffers(void); +GLUTAPI int APIENTRY glutGetWindow(void); +GLUTAPI void APIENTRY glutSetWindow(int win); +GLUTAPI void APIENTRY glutSetWindowTitle(const char *title); +GLUTAPI void APIENTRY glutSetIconTitle(const char *title); +GLUTAPI void APIENTRY glutPositionWindow(int x, int y); +GLUTAPI void APIENTRY glutReshapeWindow(int width, int height); +GLUTAPI void APIENTRY glutPopWindow(void); +GLUTAPI void APIENTRY glutPushWindow(void); +GLUTAPI void APIENTRY glutIconifyWindow(void); +GLUTAPI void APIENTRY glutShowWindow(void); +GLUTAPI void APIENTRY glutHideWindow(void); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutFullScreen(void); +GLUTAPI void APIENTRY glutSetCursor(int cursor); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWarpPointer(int x, int y); +#endif + +/* GLUT overlay sub-API. */ +GLUTAPI void APIENTRY glutEstablishOverlay(void); +GLUTAPI void APIENTRY glutRemoveOverlay(void); +GLUTAPI void APIENTRY glutUseLayer(GLenum layer); +GLUTAPI void APIENTRY glutPostOverlayRedisplay(void); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11) +GLUTAPI void APIENTRY glutPostWindowOverlayRedisplay(int win); +#endif +GLUTAPI void APIENTRY glutShowOverlay(void); +GLUTAPI void APIENTRY glutHideOverlay(void); +#endif + +/* GLUT menu sub-API. */ +GLUTAPI int APIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int)); +#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) +GLUTAPI int APIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int)); +#ifndef GLUT_BUILDING_LIB +static int APIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); } +#define glutCreateMenu glutCreateMenu_ATEXIT_HACK +#endif +#endif +GLUTAPI void APIENTRY glutDestroyMenu(int menu); +GLUTAPI int APIENTRY glutGetMenu(void); +GLUTAPI void APIENTRY glutSetMenu(int menu); +GLUTAPI void APIENTRY glutAddMenuEntry(const char *label, int value); +GLUTAPI void APIENTRY glutAddSubMenu(const char *label, int submenu); +GLUTAPI void APIENTRY glutChangeToMenuEntry(int item, const char *label, int value); +GLUTAPI void APIENTRY glutChangeToSubMenu(int item, const char *label, int submenu); +GLUTAPI void APIENTRY glutRemoveMenuItem(int item); +GLUTAPI void APIENTRY glutAttachMenu(int button); +GLUTAPI void APIENTRY glutDetachMenu(int button); + +/* GLUT window callback sub-API. */ +GLUTAPI void APIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void APIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height)); +GLUTAPI void APIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +GLUTAPI void APIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void APIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state)); +GLUTAPI void APIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void)); +GLUTAPI void APIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value); +GLUTAPI void APIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state)); +#if (GLUT_API_VERSION >= 2) +GLUTAPI void APIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void APIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z)); +GLUTAPI void APIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void APIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state)); +GLUTAPI void APIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value)); +GLUTAPI void APIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y)); +GLUTAPI void APIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y)); +#if (GLUT_API_VERSION >= 3) +GLUTAPI void APIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y)); +GLUTAPI void APIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void)); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI void APIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state)); +#endif +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +GLUTAPI void APIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y)); +GLUTAPI void APIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y)); +GLUTAPI void APIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval); +#endif +#endif +#endif + +/* GLUT color index sub-API. */ +GLUTAPI void APIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue); +GLUTAPI GLfloat APIENTRY glutGetColor(int ndx, int component); +GLUTAPI void APIENTRY glutCopyColormap(int win); + +/* GLUT state retrieval sub-API. */ +GLUTAPI int APIENTRY glutGet(GLenum type); +GLUTAPI int APIENTRY glutDeviceGet(GLenum type); +#if (GLUT_API_VERSION >= 2) +/* GLUT extension support sub-API */ +GLUTAPI int APIENTRY glutExtensionSupported(const char *name); +#endif +#if (GLUT_API_VERSION >= 3) +GLUTAPI int APIENTRY glutGetModifiers(void); +GLUTAPI int APIENTRY glutLayerGet(GLenum type); +#endif + +/* GLUT font sub-API */ +GLUTAPI void APIENTRY glutBitmapCharacter(void *font, int character); +GLUTAPI int APIENTRY glutBitmapWidth(void *font, int character); +GLUTAPI void APIENTRY glutStrokeCharacter(void *font, int character); +GLUTAPI int APIENTRY glutStrokeWidth(void *font, int character); +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +GLUTAPI int APIENTRY glutBitmapLength(void *font, const unsigned char *string); +GLUTAPI int APIENTRY glutStrokeLength(void *font, const unsigned char *string); +#endif + +/* GLUT pre-built models sub-API */ +GLUTAPI void APIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); +GLUTAPI void APIENTRY glutWireCube(GLdouble size); +GLUTAPI void APIENTRY glutSolidCube(GLdouble size); +GLUTAPI void APIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void APIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings); +GLUTAPI void APIENTRY glutWireDodecahedron(void); +GLUTAPI void APIENTRY glutSolidDodecahedron(void); +GLUTAPI void APIENTRY glutWireTeapot(GLdouble size); +GLUTAPI void APIENTRY glutSolidTeapot(GLdouble size); +GLUTAPI void APIENTRY glutWireOctahedron(void); +GLUTAPI void APIENTRY glutSolidOctahedron(void); +GLUTAPI void APIENTRY glutWireTetrahedron(void); +GLUTAPI void APIENTRY glutSolidTetrahedron(void); +GLUTAPI void APIENTRY glutWireIcosahedron(void); +GLUTAPI void APIENTRY glutSolidIcosahedron(void); + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9) +/* GLUT video resize sub-API. */ +GLUTAPI int APIENTRY glutVideoResizeGet(GLenum param); +GLUTAPI void APIENTRY glutSetupVideoResizing(void); +GLUTAPI void APIENTRY glutStopVideoResizing(void); +GLUTAPI void APIENTRY glutVideoResize(int x, int y, int width, int height); +GLUTAPI void APIENTRY glutVideoPan(int x, int y, int width, int height); + +/* GLUT debugging sub-API. */ +GLUTAPI void APIENTRY glutReportErrors(void); +#endif + +#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13) +/* GLUT device control sub-API. */ +/* glutSetKeyRepeat modes. */ +#define GLUT_KEY_REPEAT_OFF 0 +#define GLUT_KEY_REPEAT_ON 1 +#define GLUT_KEY_REPEAT_DEFAULT 2 + +/* Joystick button masks. */ +#define GLUT_JOYSTICK_BUTTON_A 1 +#define GLUT_JOYSTICK_BUTTON_B 2 +#define GLUT_JOYSTICK_BUTTON_C 4 +#define GLUT_JOYSTICK_BUTTON_D 8 + +GLUTAPI void APIENTRY glutIgnoreKeyRepeat(int ignore); +GLUTAPI void APIENTRY glutSetKeyRepeat(int repeatMode); +GLUTAPI void APIENTRY glutForceJoystickFunc(void); + +/* GLUT game mode sub-API. */ +/* glutGameModeGet. */ +#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0) +#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1) +#define GLUT_GAME_MODE_WIDTH ((GLenum) 2) +#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3) +#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4) +#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5) +#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6) + +GLUTAPI void APIENTRY glutGameModeString(const char *string); +GLUTAPI int APIENTRY glutEnterGameMode(void); +GLUTAPI void APIENTRY glutLeaveGameMode(void); +GLUTAPI int APIENTRY glutGameModeGet(GLenum mode); +#endif + +#ifdef __cplusplus +} + +#endif + +#ifdef GLUT_APIENTRY_DEFINED +# undef GLUT_APIENTRY_DEFINED +# undef APIENTRY +#endif + +#ifdef GLUT_WINGDIAPI_DEFINED +# undef GLUT_WINGDIAPI_DEFINED +# undef WINGDIAPI +#endif + +#ifdef GLUT_DEFINED___CDECL +# undef GLUT_DEFINED___CDECL +# undef __cdecl +#endif + +#ifdef GLUT_DEFINED__CRTIMP +# undef GLUT_DEFINED__CRTIMP +# undef _CRTIMP +#endif + +#endif /* __glut_h__ */ + diff --git a/tnl-1.5.0/tnl/glut/glut32.lib b/tnl-1.5.0/tnl/glut/glut32.lib new file mode 100644 index 0000000000000000000000000000000000000000..c25583d44b72d67e32a8bb20bd542bef43d01161 Binary files /dev/null and b/tnl-1.5.0/tnl/glut/glut32.lib differ diff --git a/tnl-1.5.0/tnl/glut/glutInclude.h b/tnl-1.5.0/tnl/glut/glutInclude.h new file mode 100644 index 0000000000000000000000000000000000000000..a8d84d62720f4dbc797c9f0a17b46b716d14fc44 --- /dev/null +++ b/tnl-1.5.0/tnl/glut/glutInclude.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef GLUT_INCLUDE +#define GLUT_INCLUDE + +#if defined(TNL_OS_XBOX) + +#include "glXBox.h" + +#elif defined( ZAP_DEDICATED ) + +#include "glDedicated.h" + +#elif defined (TNL_OS_MAC_OSX ) + +#include + +#else + +#include "glut.h" + +#endif + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/aes.c b/tnl-1.5.0/tnl/libtomcrypt/aes.c new file mode 100644 index 0000000000000000000000000000000000000000..42ccf85221af3b314f5b5b5c632eecce7374a41b --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/aes.c @@ -0,0 +1,595 @@ +/* AES implementation by Tom St Denis + * + * Derived from the Public Domain source code by + +--- + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto +--- + */ + +#include "mycrypt.h" + +#ifdef RIJNDAEL + +const struct _cipher_descriptor rijndael_desc = +{ + "rijndael", + 6, + 16, 32, 16, 10, + &rijndael_setup, + &rijndael_ecb_encrypt, + &rijndael_ecb_decrypt, + &rijndael_test, + &rijndael_keysize +}; + +const struct _cipher_descriptor aes_desc = +{ + "aes", + 6, + 16, 32, 16, 10, + &rijndael_setup, + &rijndael_ecb_encrypt, + &rijndael_ecb_decrypt, + &rijndael_test, + &rijndael_keysize +}; + +#include "aes_tab.c" + +int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey) +{ + int i, j; + ulong32 temp, *rk, *rrk; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) { + return CRYPT_INVALID_ROUNDS; + } + + skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; + + /* setup the forward key */ + i = 0; + rk = skey->rijndael.eK; + LOAD32H(rk[0], key ); + LOAD32H(rk[1], key + 4); + LOAD32H(rk[2], key + 8); + LOAD32H(rk[3], key + 12); + if (keylen == 16) { + j = 44; + for (;;) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + break; + } + rk += 4; + } + } else if (keylen == 24) { + j = 52; + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; + #else + temp = rk[5]; + #endif + rk[ 6] = rk[ 0] ^ + (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + break; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } else if (keylen == 32) { + j = 60; + LOAD32H(rk[4], key + 16); + LOAD32H(rk[5], key + 20); + LOAD32H(rk[6], key + 24); + LOAD32H(rk[7], key + 28); + for (;;) { + #ifdef _MSC_VER + temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; + #else + temp = rk[7]; + #endif + rk[ 8] = rk[ 0] ^ + (Te4_3[byte(temp, 2)]) ^ + (Te4_2[byte(temp, 1)]) ^ + (Te4_1[byte(temp, 0)]) ^ + (Te4_0[byte(temp, 3)]) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + break; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te4_3[byte(temp, 3)]) ^ + (Te4_2[byte(temp, 2)]) ^ + (Te4_1[byte(temp, 1)]) ^ + (Te4_0[byte(temp, 0)]); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + rk += 8; + } + } else { + /* this can't happen */ + j = 4; + } + + /* setup the inverse key now */ + rk = skey->rijndael.dK; + rrk = skey->rijndael.eK + j - 4; + + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + /* copy first */ + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; + rk -= 3; rrk -= 3; + + for (i = 1; i < skey->rijndael.Nr; i++) { + rrk -= 4; + rk += 4; + #ifdef SMALL_CODE + temp = rrk[0]; + rk[0] = + Td0[255 & Te4[byte(temp, 3)]] ^ + Td1[255 & Te4[byte(temp, 2)]] ^ + Td2[255 & Te4[byte(temp, 1)]] ^ + Td3[255 & Te4[byte(temp, 0)]]; + temp = rrk[1]; + rk[1] = + Td0[255 & Te4[byte(temp, 3)]] ^ + Td1[255 & Te4[byte(temp, 2)]] ^ + Td2[255 & Te4[byte(temp, 1)]] ^ + Td3[255 & Te4[byte(temp, 0)]]; + temp = rrk[2]; + rk[2] = + Td0[255 & Te4[byte(temp, 3)]] ^ + Td1[255 & Te4[byte(temp, 2)]] ^ + Td2[255 & Te4[byte(temp, 1)]] ^ + Td3[255 & Te4[byte(temp, 0)]]; + temp = rrk[3]; + rk[3] = + Td0[255 & Te4[byte(temp, 3)]] ^ + Td1[255 & Te4[byte(temp, 2)]] ^ + Td2[255 & Te4[byte(temp, 1)]] ^ + Td3[255 & Te4[byte(temp, 0)]]; + #else + temp = rrk[0]; + rk[0] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[1]; + rk[1] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[2]; + rk[2] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + temp = rrk[3]; + rk[3] = + Tks0[byte(temp, 3)] ^ + Tks1[byte(temp, 2)] ^ + Tks2[byte(temp, 1)] ^ + Tks3[byte(temp, 0)]; + #endif + + } + + /* copy last */ + rrk -= 4; + rk += 4; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk++ = *rrk++; + *rk = *rrk; + + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#else +void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.eK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, pt ); s0 ^= rk[0]; + LOAD32H(s1, pt + 4); s1 ^= rk[1]; + LOAD32H(s2, pt + 8); s2 ^= rk[2]; + LOAD32H(s3, pt + 12); s3 ^= rk[3]; + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + t0 = + Te0[byte(s0, 3)] ^ + Te1[byte(s1, 2)] ^ + Te2[byte(s2, 1)] ^ + Te3[byte(s3, 0)] ^ + rk[4]; + t1 = + Te0[byte(s1, 3)] ^ + Te1[byte(s2, 2)] ^ + Te2[byte(s3, 1)] ^ + Te3[byte(s0, 0)] ^ + rk[5]; + t2 = + Te0[byte(s2, 3)] ^ + Te1[byte(s3, 2)] ^ + Te2[byte(s0, 1)] ^ + Te3[byte(s1, 0)] ^ + rk[6]; + t3 = + Te0[byte(s3, 3)] ^ + Te1[byte(s0, 2)] ^ + Te2[byte(s1, 1)] ^ + Te3[byte(s2, 0)] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0[byte(t0, 3)] ^ + Te1[byte(t1, 2)] ^ + Te2[byte(t2, 1)] ^ + Te3[byte(t3, 0)] ^ + rk[0]; + s1 = + Te0[byte(t1, 3)] ^ + Te1[byte(t2, 2)] ^ + Te2[byte(t3, 1)] ^ + Te3[byte(t0, 0)] ^ + rk[1]; + s2 = + Te0[byte(t2, 3)] ^ + Te1[byte(t3, 2)] ^ + Te2[byte(t0, 1)] ^ + Te3[byte(t1, 0)] ^ + rk[2]; + s3 = + Te0[byte(t3, 3)] ^ + Te1[byte(t0, 2)] ^ + Te2[byte(t1, 1)] ^ + Te3[byte(t2, 0)] ^ + rk[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te4_3[(t0 >> 24) ]) ^ + (Te4_2[(t1 >> 16) & 0xff]) ^ + (Te4_1[(t2 >> 8) & 0xff]) ^ + (Te4_0[(t3 ) & 0xff]) ^ + rk[0]; + STORE32H(s0, ct); + s1 = + (Te4_3[(t1 >> 24) ]) ^ + (Te4_2[(t2 >> 16) & 0xff]) ^ + (Te4_1[(t3 >> 8) & 0xff]) ^ + (Te4_0[(t0 ) & 0xff]) ^ + rk[1]; + STORE32H(s1, ct+4); + s2 = + (Te4_3[(t2 >> 24) ]) ^ + (Te4_2[(t3 >> 16) & 0xff]) ^ + (Te4_1[(t0 >> 8) & 0xff]) ^ + (Te4_0[(t1 ) & 0xff]) ^ + rk[2]; + STORE32H(s2, ct+8); + s3 = + (Te4_3[(t3 >> 24) ]) ^ + (Te4_2[(t0 >> 16) & 0xff]) ^ + (Te4_1[(t1 >> 8) & 0xff]) ^ + (Te4_0[(t2 ) & 0xff]) ^ + rk[3]; + STORE32H(s3, ct+12); +} + +#ifdef CLEAN_STACK +void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + _rijndael_ecb_encrypt(pt, ct, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); +} +#endif + +#ifdef CLEAN_STACK +static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#else +void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +#endif +{ + ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; + int Nr, r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + Nr = skey->rijndael.Nr; + rk = skey->rijndael.dK; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + LOAD32H(s0, ct ); s0 ^= rk[0]; + LOAD32H(s1, ct + 4); s1 ^= rk[1]; + LOAD32H(s2, ct + 8); s2 ^= rk[2]; + LOAD32H(s3, ct + 12); s3 ^= rk[3]; + + /* + * Nr - 1 full rounds: + */ + r = Nr >> 1; + for (;;) { + + t0 = + Td0[byte(s0, 3)] ^ + Td1[byte(s3, 2)] ^ + Td2[byte(s2, 1)] ^ + Td3[byte(s1, 0)] ^ + rk[4]; + t1 = + Td0[byte(s1, 3)] ^ + Td1[byte(s0, 2)] ^ + Td2[byte(s3, 1)] ^ + Td3[byte(s2, 0)] ^ + rk[5]; + t2 = + Td0[byte(s2, 3)] ^ + Td1[byte(s1, 2)] ^ + Td2[byte(s0, 1)] ^ + Td3[byte(s3, 0)] ^ + rk[6]; + t3 = + Td0[byte(s3, 3)] ^ + Td1[byte(s2, 2)] ^ + Td2[byte(s1, 1)] ^ + Td3[byte(s0, 0)] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + + s0 = + Td0[byte(t0, 3)] ^ + Td1[byte(t3, 2)] ^ + Td2[byte(t2, 1)] ^ + Td3[byte(t1, 0)] ^ + rk[0]; + s1 = + Td0[byte(t1, 3)] ^ + Td1[byte(t0, 2)] ^ + Td2[byte(t3, 1)] ^ + Td3[byte(t2, 0)] ^ + rk[1]; + s2 = + Td0[byte(t2, 3)] ^ + Td1[byte(t1, 2)] ^ + Td2[byte(t0, 1)] ^ + Td3[byte(t3, 0)] ^ + rk[2]; + s3 = + Td0[byte(t3, 3)] ^ + Td1[byte(t2, 2)] ^ + Td2[byte(t1, 1)] ^ + Td3[byte(t0, 0)] ^ + rk[3]; + } + + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Td4[(t0 >> 24) ] & 0xff000000) ^ + (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t1 ) & 0xff] & 0x000000ff) ^ + rk[0]; + STORE32H(s0, pt); + s1 = + (Td4[(t1 >> 24) ] & 0xff000000) ^ + (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t2 ) & 0xff] & 0x000000ff) ^ + rk[1]; + STORE32H(s1, pt+4); + s2 = + (Td4[(t2 >> 24) ] & 0xff000000) ^ + (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t3 ) & 0xff] & 0x000000ff) ^ + rk[2]; + STORE32H(s2, pt+8); + s3 = + (Td4[(t3 >> 24) ] & 0xff000000) ^ + (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Td4[(t0 ) & 0xff] & 0x000000ff) ^ + rk[3]; + STORE32H(s3, pt+12); +} + + +#ifdef CLEAN_STACK +void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + _rijndael_ecb_decrypt(ct, pt, skey); + burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); +} +#endif + +int rijndael_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } + }, { + 24, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, + 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } + }, { + 32, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, + 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } + } + }; + + symmetric_key key; + unsigned char tmp[2][16]; + int i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); + rijndael_ecb_decrypt(tmp[0], tmp[1], &key); + if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (memcmp(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rijndael_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize < 24) { + *desired_keysize = 16; + return CRYPT_OK; + } else if (*desired_keysize < 32) { + *desired_keysize = 24; + return CRYPT_OK; + } else { + *desired_keysize = 32; + return CRYPT_OK; + } +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/aes_tab.c b/tnl-1.5.0/tnl/libtomcrypt/aes_tab.c new file mode 100644 index 0000000000000000000000000000000000000000..03a81efa65b1e9c76214c537d80cdbc9a23a4da6 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/aes_tab.c @@ -0,0 +1,977 @@ +/* The precomputed tables for AES */ +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +Te4[x] = S [x].[01, 01, 01, 01]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01, 01, 01, 01]; +*/ + +static const ulong32 Te0[256] = { + 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, + 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, + 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, + 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, + 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, + 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, + 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, + 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, + 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, + 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, + 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, + 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, + 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, + 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, + 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, + 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, + 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, + 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, + 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, + 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, + 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, + 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, + 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, + 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, + 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, + 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, + 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, + 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, + 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, + 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, + 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, + 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, + 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, + 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, + 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, + 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, + 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, + 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, + 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, + 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, + 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, + 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, + 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, + 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, + 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, + 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, + 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, + 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, + 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, + 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, + 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, + 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, + 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, + 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, + 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, + 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, + 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, + 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, + 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, + 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, + 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, + 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, + 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, + 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, +}; +static const ulong32 Te1[256] = { + 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, + 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, + 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, + 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, + 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, + 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, + 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, + 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, + 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, + 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, + 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, + 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, + 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, + 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, + 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, + 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, + 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, + 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, + 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, + 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, + 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, + 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, + 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, + 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, + 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, + 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, + 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, + 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, + 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, + 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, + 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, + 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, + 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, + 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, + 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, + 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, + 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, + 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, + 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, + 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, + 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, + 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, + 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, + 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, + 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, + 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, + 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, + 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, + 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, + 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, + 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, + 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, + 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, + 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, + 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, + 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, + 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, + 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, + 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, + 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, + 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, + 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, + 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, + 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, +}; +static const ulong32 Te2[256] = { + 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, + 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, + 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, + 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, + 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, + 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, + 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, + 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, + 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, + 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, + 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, + 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, + 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, + 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, + 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, + 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, + 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, + 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, + 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, + 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, + 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, + 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, + 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, + 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, + 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, + 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, + 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, + 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, + 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, + 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, + 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, + 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, + 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, + 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, + 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, + 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, + 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, + 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, + 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, + 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, + 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, + 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, + 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, + 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, + 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, + 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, + 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, + 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, + 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, + 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, + 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, + 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, + 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, + 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, + 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, + 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, + 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, + 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, + 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, + 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, + 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, + 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, + 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, + 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, +}; +static const ulong32 Te3[256] = { + + 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, + 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, + 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, + 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, + 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, + 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, + 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, + 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, + 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, + 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, + 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, + 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, + 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, + 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, + 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, + 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, + 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, + 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, + 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, + 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, + 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, + 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, + 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, + 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, + 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, + 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, + 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, + 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, + 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, + 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, + 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, + 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, + 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, + 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, + 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, + 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, + 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, + 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, + 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, + 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, + 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, + 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, + 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, + 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, + 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, + 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, + 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, + 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, + 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, + 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, + 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, + 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, + 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, + 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, + 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, + 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, + 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, + 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, + 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, + 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, + 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, + 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, + 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, + 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, +}; +static const ulong32 Te4[256] = { + 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, + 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, + 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, + 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, + 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, + 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, + 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, + 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, + 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, + 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, + 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, + 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, + 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, + 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, + 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, + 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, + 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, + 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, + 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, + 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, + 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, + 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, + 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, + 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, + 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, + 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, + 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, + 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, + 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, + 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, + 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, + 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, + 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, + 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, + 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, + 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, + 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, + 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, + 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, + 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, + 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, + 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, + 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, + 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, + 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, + 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, + 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, + 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, + 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, + 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, + 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, + 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, + 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, + 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, + 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, + 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, + 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, + 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, + 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, + 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, + 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, + 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, + 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, + 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, +}; + +#ifdef SMALL_CODE + +#define Te4_0 0x000000FF & Te4 +#define Te4_1 0x0000FF00 & Te4 +#define Te4_2 0x00FF0000 & Te4 +#define Te4_3 0xFF000000 & Te4 + +#else + +static const ulong32 Te4_0[] = { +0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL, +0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL, +0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, +0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL, +0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL, +0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL, +0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL, +0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, +0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL, +0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL, +0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL, +0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL, +0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, +0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL, +0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL, +0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL, +0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL, +0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, +0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL, +0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL, +0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL, +0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL, +0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, +0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL, +0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL, +0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL, +0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL, +0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, +0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL, +0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL, +0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL, +0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL +}; + +static const ulong32 Te4_1[] = { +0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL, +0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL, +0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, +0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL, +0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL, +0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL, +0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL, +0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, +0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL, +0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL, +0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, +0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL, +0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, +0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL, +0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL, +0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, +0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL, +0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, +0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL, +0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL, +0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL, +0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL, +0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, +0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL, +0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL, +0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, +0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL, +0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, +0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL, +0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL, +0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL, +0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL +}; + +static const ulong32 Te4_2[] = { +0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL, +0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL, +0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, +0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL, +0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL, +0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL, +0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL, +0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, +0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL, +0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL, +0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, +0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL, +0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, +0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL, +0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL, +0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, +0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL, +0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, +0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL, +0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL, +0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL, +0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL, +0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, +0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL, +0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL, +0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, +0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL, +0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, +0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL, +0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL, +0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL, +0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL +}; + +static const ulong32 Te4_3[] = { +0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL, +0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL, +0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, +0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL, +0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL, +0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL, +0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL, +0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, +0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL, +0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL, +0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL, +0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL, +0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, +0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL, +0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL, +0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL, +0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL, +0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, +0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL, +0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL, +0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL, +0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL, +0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, +0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL, +0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL, +0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL, +0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL, +0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, +0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL, +0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL, +0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL, +0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL +}; + +#endif + +static const ulong32 Td0[256] = { + 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, + 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, + 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, + 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, + 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, + 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, + 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, + 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, + 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, + 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, + 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, + 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, + 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, + 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, + 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, + 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, + 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, + 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, + 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, + 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, + 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, + 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, + 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, + 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, + 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, + 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, + 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, + 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, + 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, + 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, + 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, + 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, + 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, + 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, + 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, + 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, + 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, + 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, + 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, + 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, + 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, + 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, + 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, + 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, + 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, + 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, + 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, + 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, + 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, + 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, + 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, + 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, + 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, + 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, + 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, + 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, + 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, + 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, + 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, + 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, + 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, + 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, + 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, + 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, +}; +static const ulong32 Td1[256] = { + 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, + 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, + 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, + 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, + 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, + 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, + 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, + 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, + 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, + 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, + 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, + 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, + 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, + 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, + 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, + 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, + 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, + 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, + 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, + 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, + 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, + 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, + 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, + 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, + 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, + 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, + 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, + 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, + 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, + 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, + 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, + 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, + 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, + 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, + 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, + 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, + 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, + 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, + 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, + 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, + 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, + 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, + 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, + 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, + 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, + 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, + 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, + 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, + 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, + 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, + 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, + 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, + 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, + 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, + 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, + 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, + 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, + 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, + 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, + 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, + 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, + 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, + 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, + 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, +}; +static const ulong32 Td2[256] = { + 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, + 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, + 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, + 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, + 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, + 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, + 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, + 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, + 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, + 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, + 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, + 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, + 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, + 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, + 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, + 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, + 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, + 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, + 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, + 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, + + 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, + 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, + 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, + 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, + 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, + 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, + 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, + 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, + 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, + 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, + 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, + 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, + 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, + 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, + 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, + 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, + 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, + 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, + 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, + 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, + 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, + 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, + 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, + 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, + 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, + 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, + 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, + 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, + 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, + 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, + 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, + 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, + 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, + 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, + 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, + 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, + 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, + 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, + 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, + 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, + 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, + 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, + 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, + 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, +}; +static const ulong32 Td3[256] = { + 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, + 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, + 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, + 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, + 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, + 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, + 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, + 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, + 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, + 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, + 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, + 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, + 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, + 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, + 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, + 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, + 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, + 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, + 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, + 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, + 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, + 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, + 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, + 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, + 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, + 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, + 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, + 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, + 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, + 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, + 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, + 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, + 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, + 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, + 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, + 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, + 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, + 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, + 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, + 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, + 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, + 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, + 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, + 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, + 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, + 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, + 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, + 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, + 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, + 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, + 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, + 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, + 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, + 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, + 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, + 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, + 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, + 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, + 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, + 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, + 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, + 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, + 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, + 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, +}; +static const ulong32 Td4[256] = { + 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, + 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, + 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, + 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, + 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, + 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, + 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, + 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, + 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, + 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, + 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, + 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, + 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, + 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, + 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, + 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, + 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, + 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, + 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, + 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, + 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, + 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, + 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, + 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, + 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, + 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, + 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, + 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, + 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, + 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, + 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, + 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, + 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, + 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, + 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, + 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, + 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, + 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, + 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, + 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, + 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, + 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, + 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, + 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, + 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, + 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, + 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, + 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, + 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, + 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, + 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, + 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, + 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, + 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, + 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, + 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, + 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, + 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, + 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, + 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, + 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, + 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, + 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, + 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, +}; +static const ulong32 rcon[] = { + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, + 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +#ifndef SMALL_CODE +static const ulong32 Tks0[] = { +0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL, +0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL, +0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL, +0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL, +0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL, +0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL, +0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL, +0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL, +0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL, +0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL, +0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL, +0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL, +0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL, +0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL, +0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL, +0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL, +0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL, +0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL, +0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL, +0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL, +0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL, +0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL, +0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL, +0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL, +0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL, +0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL, +0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL, +0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL, +0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL, +0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL, +0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL, +0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL +}; + +static const ulong32 Tks1[] = { +0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL, +0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL, +0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL, +0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL, +0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL, +0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL, +0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL, +0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL, +0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL, +0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL, +0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL, +0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL, +0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL, +0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL, +0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL, +0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL, +0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL, +0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL, +0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL, +0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL, +0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL, +0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL, +0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL, +0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL, +0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL, +0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL, +0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL, +0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL, +0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL, +0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL, +0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL, +0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL +}; + +static const ulong32 Tks2[] = { +0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL, +0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL, +0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL, +0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL, +0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL, +0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL, +0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL, +0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL, +0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL, +0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL, +0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL, +0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL, +0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL, +0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL, +0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL, +0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL, +0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL, +0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL, +0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL, +0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL, +0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL, +0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL, +0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL, +0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL, +0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL, +0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL, +0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL, +0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL, +0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL, +0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL, +0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL, +0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL +}; + +static const ulong32 Tks3[] = { +0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, +0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, +0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, +0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, +0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, +0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, +0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, +0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, +0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, +0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, +0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, +0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, +0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, +0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, +0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, +0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, +0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, +0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, +0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, +0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, +0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, +0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, +0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, +0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, +0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, +0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, +0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, +0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, +0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, +0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, +0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, +0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL +}; +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/authors b/tnl-1.5.0/tnl/libtomcrypt/authors new file mode 100644 index 0000000000000000000000000000000000000000..ba4ea6b3231329b3ee65af74061b01bbf8a029b5 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/authors @@ -0,0 +1,55 @@ +This is a list of people who have contributed [directly or indirectly] to the project +[in no partcular order]. If you have helped and your name is not here email me at +tomstdenis@yahoo.com. + + +1) Richard.van.de.Laarschot@ict.nl + + Gave help porting the lib to MSVC particularly pointed out various warnings and errors. + +2) Richard Heathfield + + Gave a lot of help concerning valid C portable code. + +3) Ajay K. Agrawal + + Helped port the library to MSVC and spotted a few bugs and errors. + +4) Brian Gladman + + Wrote the AES and Serpent code used. Found a bug in the hash code for certain types of inputs. + +5) Svante Seleborg + + Submitted the "ampi.c" code as well as many suggestions on improving the readability of the source code. + +6) Clay Culver + + Submitted a fix for "rsa.c" which cleaned up some code. Submited some other fixes too. :-) + Clay has helped find bugs in various pieces of code including the registry functions, base64 routines + and the make process. He is also now the primary author of the libtomcrypt reference manual and has plan + at making a HTML version. + +7) Jason Klapste + + Submitted fixes to the yarrow, hash, make process and test code as well as other subtle bug fixes. The +yarrow code can now default to any cipher/hash that is left after you remove them from a build. + +8) Dobes Vandermeer + + Submitted HMAC code that worked flawlessly out of the box... good job! Also submitted a MD4 routine. + Submitted some modified DES code that was merged into the code base [using the libtomcrypt API] + +9) Wayne Scott (wscott@bitmover.com) + + Submitted base64 that complies with the RFC standards. Submitted some ideas to improve the RSA key generation + as well. + +10) Sky Schulz (sky@ogn.com) + + Has submitted a set of ideas to improve the library and make it more attractive for professional users. + +11) Mike Frysinger + + Together with Clay came up with a more "unix friendly" makefile. Mike Frysinger has been keeping copies of + the library for the Gentoo linux distribution. \ No newline at end of file diff --git a/tnl-1.5.0/tnl/libtomcrypt/base64.c b/tnl-1.5.0/tnl/libtomcrypt/base64.c new file mode 100644 index 0000000000000000000000000000000000000000..a772b805e39a29af9ad4d63c85da21ec83c6ea77 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/base64.c @@ -0,0 +1,109 @@ +/* compliant base64 code donated by Wayne Scott (wscott@bitmover.com) */ +#include "mycrypt.h" + +#ifdef BASE64 + +static const char *codes = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static const unsigned char map[256] = { +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, +255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, +255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255 }; + +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, len2, leven; + unsigned char *p; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* valid output size ? */ + len2 = 4 * ((len + 2) / 3); + if (*outlen < len2 + 1) { + return CRYPT_BUFFER_OVERFLOW; + } + p = out; + leven = 3*(len / 3); + for (i = 0; i < leven; i += 3) { + *p++ = codes[in[0] >> 2]; + *p++ = codes[((in[0] & 3) << 4) + (in[1] >> 4)]; + *p++ = codes[((in[1] & 0xf) << 2) + (in[2] >> 6)]; + *p++ = codes[in[2] & 0x3f]; + in += 3; + } + /* Pad it if necessary... */ + if (i < len) { + unsigned a = in[0]; + unsigned b = (i+1 < len) ? in[1] : 0; + unsigned c = 0; + + *p++ = codes[a >> 2]; + *p++ = codes[((a & 3) << 4) + (b >> 4)]; + *p++ = (i+1 < len) ? codes[((b & 0xf) << 2) + (c >> 6)] : '='; + *p++ = '='; + } + + /* append a NULL byte */ + *p = '\0'; + + /* return ok */ + *outlen = p - out; + return CRYPT_OK; +} + +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen) +{ + unsigned long t, x, y, z; + unsigned char c; + int g = 3; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + for (x = y = z = t = 0; x < len; x++) { + c = map[in[x]]; + if (c == 255) continue; + if (c == 254) { c = 0; g--; } + t = (t<<6)|c; + if (++y == 4) { + if (z + g > *outlen) { return CRYPT_BUFFER_OVERFLOW; } + out[z++] = (unsigned char)((t>>16)&255); + if (g > 1) out[z++] = (unsigned char)((t>>8)&255); + if (g > 2) out[z++] = (unsigned char)(t&255); + y = t = 0; + } + } + if (y != 0) { + return CRYPT_INVALID_PACKET; + } + *outlen = z; + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/bits.c b/tnl-1.5.0/tnl/libtomcrypt/bits.c new file mode 100644 index 0000000000000000000000000000000000000000..60e3a438591a7b3085111e4b7ae7a4302c4f66b5 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/bits.c @@ -0,0 +1,199 @@ +/* portable way to get secure random bits to feed a PRNG */ +#include "mycrypt.h" + +#ifdef DEVRANDOM +/* on *NIX read /dev/random */ +static unsigned long rng_nix(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ +#ifdef NO_FILE + return 0; +#else + FILE *f; + unsigned long x; +#ifdef TRY_URANDOM_FIRST + f = fopen("/dev/urandom", "rb"); + if (f == NULL) +#endif /* TRY_URANDOM_FIRST */ + f = fopen("/dev/random", "rb"); + + if (f == NULL) { + return 0; + } + + /* disable buffering */ + if (setvbuf(f, NULL, _IONBF, 0) != 0) { + fclose(f); + return 0; + } + + x = (unsigned long)fread(buf, 1, (size_t)len, f); + fclose(f); + return x; +#endif /* NO_FILE */ +} + +#endif /* DEVRANDOM */ + +#ifdef SONY_PS2 +#include +#include +#define min(a,b) ((a) < (b) ? (a) : (b)) +// Very simple/stupid MD5-based RNG that samples "entropy" from various PS2 control registers +static unsigned long rng_ps2(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + static unsigned long lastx[2] = { 0xaab7cb4b2fd3b2b9, 0xcec58aff72afe49f }; // md5sum of bits.c + unsigned long j; + unsigned int samples[10]; // number of sample data sources + int l; + hash_state md; + + for (j = 0; j < len; j += sizeof(lastx)) { + md5_init(&md); + samples[0] = *T2_COUNT; + samples[1] = *T3_COUNT; + samples[2] = *IPU_TOP; + samples[3] = *GIF_TAG0; + samples[4] = *GIF_TAG1; + samples[5] = *GIF_TAG2; + samples[6] = *VIF1_CODE; + samples[7] = *VIF0_CODE; + samples[8] = *D0_MADR; + samples[9] = *D1_MADR; + md5_process(&md, (unsigned char *)(&samples[0]), sizeof(samples)); + // include previous round + md5_process(&md, (unsigned char *)(&lastx[0]), sizeof(lastx)); + md5_done(&md, (unsigned char *)(&lastx[0])); + l = min(sizeof(lastx), len-j); + memcpy(buf+j, &lastx[0], l); //min(sizeof(lastx), len-j)); + } + return len; +} +#endif /* SONY_PS2 */ + +/* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */ +#if !defined(SONY_PS2) && defined(CLOCKS_PER_SEC) + +#define ANSI_RNG + +static unsigned long rng_ansic(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + clock_t t1; + int l, acc, bits, a, b; + + if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) { + return 0; + } + + l = len; + bits = 8; + acc = a = b = 0; + while (len--) { + if (callback != NULL) callback(); + while (bits--) { + do { + t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; + t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; + } while (a == b); + acc = (acc << 1) | a; + } + *buf++ = acc; + acc = 0; + bits = 8; + } + acc = bits = a = b = 0; + return l; +} + +#endif + +/* Try the Microsoft CSP */ +#ifdef WIN32 +#define _WIN32_WINNT 0x0400 +#include +#include + +static unsigned long rng_win32(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + HCRYPTPROV hProv = 0; + if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) + return 0; + + if (CryptGenRandom(hProv, len, buf) == TRUE) { + CryptReleaseContext(hProv, 0); + return len; + } else { + CryptReleaseContext(hProv, 0); + return 0; + } +} + +#endif /* WIN32 */ + +unsigned long rng_get_bytes(unsigned char *buf, unsigned long len, + void (*callback)(void)) +{ + unsigned long x; + + _ARGCHK(buf != NULL); + +#ifdef SONY_PS2 + x = rng_ps2(buf, len, callback); if (x != 0) { return x; } +#elif defined(DEVRANDOM) + x = rng_nix(buf, len, callback); if (x != 0) { return x; } +#endif +#ifdef WIN32 + x = rng_win32(buf, len, callback); if (x != 0) { return x; } +#endif +#ifdef ANSI_RNG + x = rng_ansic(buf, len, callback); if (x != 0) { return x; } +#endif + return 0; +} + +int rng_make_prng(int bits, int wprng, prng_state *prng, + void (*callback)(void)) +{ + unsigned char buf[256]; + int err; + + _ARGCHK(prng != NULL); + + /* check parameter */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if (bits < 64 || bits > 1024) { + return CRYPT_INVALID_PRNGSIZE; + } + + if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { + return err; + } + + bits = ((bits/8)+((bits&7)!=0?1:0)) * 2; + if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { + return CRYPT_ERROR_READPRNG; + } + + if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { + return err; + } + + if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { + return err; + } + + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_OK; +} + diff --git a/tnl-1.5.0/tnl/libtomcrypt/blowfish.c b/tnl-1.5.0/tnl/libtomcrypt/blowfish.c new file mode 100644 index 0000000000000000000000000000000000000000..80284b8bfeacf8ca704c7826e395a3bb72bd99f0 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/blowfish.c @@ -0,0 +1,519 @@ +#include "mycrypt.h" + +#ifdef BLOWFISH + +const struct _cipher_descriptor blowfish_desc = +{ + "blowfish", + 0, + 8, 56, 8, 16, + &blowfish_setup, + &blowfish_ecb_encrypt, + &blowfish_ecb_decrypt, + &blowfish_test, + &blowfish_keysize +}; + +static const ulong32 ORIG_P[16 + 2] = { + 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL, + 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL, + 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL, + 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL, + 0x9216D5D9UL, 0x8979FB1BUL +}; + +static const ulong32 ORIG_S[4][256] = { + { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL, + 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL, + 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL, + 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL, + 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL, + 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL, + 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL, + 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL, + 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL, + 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL, + 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL, + 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL, + 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL, + 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL, + 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL, + 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL, + 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL, + 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL, + 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL, + 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL, + 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL, + 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL, + 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL, + 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL, + 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL, + 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL, + 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL, + 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL, + 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL, + 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL, + 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL, + 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL, + 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL, + 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL, + 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL, + 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL, + 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL, + 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL, + 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL, + 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL, + 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL, + 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL, + 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL, + 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL, + 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL, + 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL, + 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL, + 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL, + 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL, + 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL, + 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL, + 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL, + 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL, + 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL, + 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL, + 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL, + 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL, + 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL, + 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL, + 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL, + 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL, + 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL, + 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL, + 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL }, + { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL, + 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL, + 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL, + 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL, + 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL, + 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL, + 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL, + 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL, + 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL, + 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL, + 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL, + 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL, + 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL, + 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL, + 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL, + 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL, + 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL, + 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL, + 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL, + 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL, + 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL, + 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL, + 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL, + 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL, + 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL, + 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL, + 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL, + 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL, + 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL, + 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL, + 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL, + 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL, + 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL, + 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL, + 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL, + 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL, + 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL, + 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL, + 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL, + 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL, + 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL, + 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL, + 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL, + 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL, + 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL, + 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL, + 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL, + 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL, + 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL, + 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL, + 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL, + 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL, + 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL, + 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL, + 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL, + 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL, + 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL, + 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL, + 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL, + 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL, + 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL, + 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL, + 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL, + 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL }, + { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL, + 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL, + 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL, + 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL, + 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL, + 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL, + 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL, + 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL, + 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL, + 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL, + 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL, + 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL, + 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL, + 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL, + 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL, + 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL, + 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL, + 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL, + 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL, + 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL, + 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL, + 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL, + 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL, + 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL, + 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL, + 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL, + 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL, + 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL, + 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL, + 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL, + 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL, + 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL, + 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL, + 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL, + 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL, + 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL, + 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL, + 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL, + 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL, + 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL, + 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL, + 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL, + 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL, + 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL, + 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL, + 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL, + 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL, + 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL, + 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL, + 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL, + 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL, + 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL, + 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL, + 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL, + 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL, + 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL, + 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL, + 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL, + 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL, + 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL, + 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL, + 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL, + 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL, + 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL }, + { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL, + 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL, + 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL, + 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL, + 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL, + 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL, + 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL, + 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL, + 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL, + 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL, + 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL, + 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL, + 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL, + 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL, + 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL, + 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL, + 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL, + 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL, + 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL, + 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL, + 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL, + 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL, + 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL, + 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL, + 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL, + 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL, + 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL, + 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL, + 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL, + 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL, + 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL, + 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL, + 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL, + 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL, + 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL, + 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL, + 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL, + 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL, + 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL, + 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL, + 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL, + 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL, + 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL, + 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL, + 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL, + 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL, + 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL, + 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL, + 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL, + 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL, + 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL, + 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL, + 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL, + 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL, + 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL, + 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL, + 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL, + 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL, + 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL, + 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL, + 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL, + 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL, + 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL, + 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL } +}; + +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, + symmetric_key *skey) +{ + ulong32 x, y, z, A; + unsigned char B[8]; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check key length */ + if (keylen < 8 || keylen > 56) { + return CRYPT_INVALID_KEYSIZE; + } + + /* check rounds */ + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + /* load in key bytes (Supplied by David Hopwood) */ + for (x = y = 0; x < 18; x++) { + A = 0; + for (z = 0; z < 4; z++) { + A = (A << 8) | ((ulong32)key[y++] & 255); + if (y == (ulong32)keylen) { + y = 0; + } + } + skey->blowfish.K[x] = ORIG_P[x] ^ A; + } + + /* copy sboxes */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y++) { + skey->blowfish.S[x][y] = ORIG_S[x][y]; + } + } + + /* encrypt K array */ + for (x = 0; x < 8; x++) { + B[x] = 0; + } + + for (x = 0; x < 18; x += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.K[x], &B[0]); + LOAD32H(skey->blowfish.K[x+1], &B[4]); + } + + /* encrypt S array */ + for (x = 0; x < 4; x++) { + for (y = 0; y < 256; y += 2) { + /* encrypt it */ + blowfish_ecb_encrypt(B, B, skey); + /* copy it */ + LOAD32H(skey->blowfish.S[x][y], &B[0]); + LOAD32H(skey->blowfish.S[x][y+1], &B[4]); + } + } + +#ifdef CLEAN_STACK + zeromem(B, sizeof(B)); +#endif + + return CRYPT_OK; +} + +#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)] + +#ifdef CLEAN_STACK +static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 L, R; + int r; + ulong32 *S1, *S2, *S3, *S4; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + S1 = key->blowfish.S[0]; + S2 = key->blowfish.S[1]; + S3 = key->blowfish.S[2]; + S4 = key->blowfish.S[3]; + + /* load it */ + LOAD32H(L, &pt[0]); + LOAD32H(R, &pt[4]); + + /* do 16 rounds */ + for (r = 0; r < 16; ) { + L ^= key->blowfish.K[r++]; R ^= F(L); + R ^= key->blowfish.K[r++]; L ^= F(R); + L ^= key->blowfish.K[r++]; R ^= F(L); + R ^= key->blowfish.K[r++]; L ^= F(R); + } + + /* last keying */ + R ^= key->blowfish.K[17]; + L ^= key->blowfish.K[16]; + + /* store */ + STORE32H(R, &ct[0]); + STORE32H(L, &ct[4]); +} + +#ifdef CLEAN_STACK +void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _blowfish_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 L, R; + int r; + ulong32 *S1, *S2, *S3, *S4; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + S1 = key->blowfish.S[0]; + S2 = key->blowfish.S[1]; + S3 = key->blowfish.S[2]; + S4 = key->blowfish.S[3]; + + /* load it */ + LOAD32H(R, &ct[0]); + LOAD32H(L, &ct[4]); + + /* undo last keying */ + R ^= key->blowfish.K[17]; + L ^= key->blowfish.K[16]; + + /* do 16 rounds */ + for (r = 15; r > 0; ) { + L ^= F(R); R ^= key->blowfish.K[r--]; + R ^= F(L); L ^= key->blowfish.K[r--]; + L ^= F(R); R ^= key->blowfish.K[r--]; + R ^= F(L); L ^= key->blowfish.K[r--]; + } + + /* store */ + STORE32H(L, &pt[0]); + STORE32H(R, &pt[4]); +} + +#ifdef CLEAN_STACK +void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _blowfish_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + + +int blowfish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + symmetric_key key; + static const struct { + unsigned char key[8], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78} + }, + { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A} + }, + { + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2} + } + }; + unsigned char tmp[2][8]; + int x, y; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key); + blowfish_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if ((memcmp(tmp[0], tests[x].ct, 8) != 0) || (memcmp(tmp[1], tests[x].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int blowfish_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 56) { + *desired_keysize = 56; + } + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/cast5.c b/tnl-1.5.0/tnl/libtomcrypt/cast5.c new file mode 100644 index 0000000000000000000000000000000000000000..ab2ccc5b739e513bf8ae35cd9922b27dc78696d5 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/cast5.c @@ -0,0 +1,659 @@ +/* Implementation of CAST5 (RFC 2144) by Tom St Denis */ +#include "mycrypt.h" + +#ifdef CAST5 + +const struct _cipher_descriptor cast5_desc = { + "cast5", + 15, + 5, 16, 8, 16, + &cast5_setup, + &cast5_ecb_encrypt, + &cast5_ecb_decrypt, + &cast5_test, + &cast5_keysize +}; + +static const ulong32 S1[256] = { +0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL, +0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL, +0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL, +0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL, +0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL, +0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL, +0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL, +0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL, +0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL, +0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL, +0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL, +0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL, +0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL, +0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL, +0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL, +0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL, +0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL, +0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL, +0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL, +0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL, +0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL, +0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL, +0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL, +0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL, +0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL, +0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL, +0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL, +0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL, +0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL, +0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL, +0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL, +0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL, +0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL, +0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL, +0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL, +0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL, +0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL, +0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL, +0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL, +0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL, +0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL, +0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL, +0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL}; + +static const ulong32 S2[256] = { +0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL, +0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL, +0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL, +0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL, +0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL, +0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL, +0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL, +0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL, +0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL, +0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL, +0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL, +0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL, +0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL, +0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL, +0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL, +0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL, +0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL, +0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL, +0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL, +0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL, +0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL, +0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL, +0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL, +0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL, +0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL, +0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL, +0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL, +0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL, +0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL, +0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL, +0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL, +0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL, +0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL, +0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL, +0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL, +0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL, +0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL, +0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL, +0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL, +0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL, +0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL, +0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL, +0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL}; + +static const ulong32 S3[256] = { +0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL, +0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL, +0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL, +0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL, +0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL, +0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL, +0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL, +0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL, +0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL, +0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL, +0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL, +0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL, +0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL, +0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL, +0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL, +0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL, +0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL, +0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL, +0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL, +0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL, +0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL, +0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL, +0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL, +0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL, +0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL, +0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL, +0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL, +0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL, +0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL, +0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL, +0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL, +0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL, +0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL, +0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL, +0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL, +0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL, +0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL, +0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL, +0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL, +0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL, +0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL, +0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL, +0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL}; + +static const ulong32 S4[256] = { +0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL, +0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL, +0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL, +0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL, +0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL, +0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL, +0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL, +0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL, +0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL, +0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL, +0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL, +0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL, +0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL, +0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL, +0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL, +0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL, +0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL, +0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL, +0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL, +0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL, +0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL, +0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL, +0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL, +0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL, +0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL, +0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL, +0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL, +0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL, +0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL, +0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL, +0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL, +0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL, +0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL, +0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL, +0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL, +0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL, +0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL, +0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL, +0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL, +0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL, +0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL, +0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL, +0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL}; + +static const ulong32 S5[256] = { +0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL, +0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL, +0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL, +0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL, +0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL, +0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL, +0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL, +0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL, +0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL, +0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL, +0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL, +0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL, +0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL, +0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL, +0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL, +0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL, +0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL, +0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL, +0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL, +0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL, +0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL, +0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL, +0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL, +0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL, +0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL, +0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL, +0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL, +0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL, +0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL, +0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL, +0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL, +0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL, +0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL, +0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL, +0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL, +0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL, +0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL, +0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL, +0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL, +0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL, +0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL, +0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL, +0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL}; + +static const ulong32 S6[256] = { +0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL, +0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL, +0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL, +0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL, +0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL, +0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL, +0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL, +0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL, +0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL, +0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL, +0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL, +0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL, +0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL, +0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL, +0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL, +0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL, +0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL, +0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL, +0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL, +0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL, +0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL, +0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL, +0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL, +0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL, +0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL, +0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL, +0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL, +0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL, +0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL, +0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL, +0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL, +0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL, +0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL, +0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL, +0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL, +0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL, +0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL, +0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL, +0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL, +0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL, +0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL, +0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL, +0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL}; + +static const ulong32 S7[256] = { +0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL, +0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL, +0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL, +0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL, +0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL, +0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL, +0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL, +0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL, +0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL, +0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL, +0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL, +0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL, +0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL, +0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL, +0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL, +0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL, +0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL, +0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL, +0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL, +0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL, +0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL, +0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL, +0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL, +0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL, +0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL, +0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL, +0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL, +0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL, +0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL, +0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL, +0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL, +0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL, +0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL, +0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL, +0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL, +0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL, +0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL, +0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL, +0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL, +0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL, +0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL, +0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL, +0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL}; + +static const ulong32 S8[256] = { +0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL, +0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL, +0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL, +0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL, +0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL, +0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL, +0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL, +0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL, +0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL, +0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL, +0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL, +0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL, +0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL, +0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL, +0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL, +0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL, +0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL, +0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL, +0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL, +0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL, +0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL, +0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL, +0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL, +0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL, +0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL, +0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL, +0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL, +0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL, +0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL, +0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL, +0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL, +0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL, +0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL, +0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL, +0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL, +0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL, +0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL, +0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL, +0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL, +0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL, +0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL, +0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL, +0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL}; + +/* returns the i'th byte of a variable */ +#ifdef _MSC_VER + #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))) +#else + #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255) +#endif + +#ifdef CLEAN_STACK +static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 x[4], z[4]; + unsigned char buf[16]; + int y, i; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (num_rounds == 12 && keylen > 10) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen < 5 || keylen > 16) { + return CRYPT_INVALID_KEYSIZE; + } + + /* extend the key as required */ + zeromem(buf, sizeof(buf)); + memcpy(buf, key, (size_t)keylen); + + /* load and start the awful looking network */ + for (y = 0; y < 4; y++) { + LOAD32H(x[3-y],buf+4*y); + } + + for (i = y = 0; y < 2; y++) { + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)]; + skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)]; + skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)]; + + /* second half */ + z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; + z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; + z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; + z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; + skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)]; + skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)]; + skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)]; + skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)]; + + x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; + x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; + x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; + x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)]; + skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)]; + skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)]; + skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)]; + } + + skey->cast5.keylen = keylen; + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + zeromem(x, sizeof(x)); + zeromem(z, sizeof(z)); +#endif + + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int z; + z = _cast5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2); + return z; +} +#endif + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km + R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)]; +} + +INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km ^ R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)]; +} + +INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) +{ + ulong32 I; + I = (Km - R); + I = ROL(I, Kr); + return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)]; +} + +#ifdef CLEAN_STACK +static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 R, L; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32H(L,&pt[0]); + LOAD32H(R,&pt[4]); + L ^= FI(R, key->cast5.K[0], key->cast5.K[16]); + R ^= FII(L, key->cast5.K[1], key->cast5.K[17]); + L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]); + R ^= FI(L, key->cast5.K[3], key->cast5.K[19]); + L ^= FII(R, key->cast5.K[4], key->cast5.K[20]); + R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]); + L ^= FI(R, key->cast5.K[6], key->cast5.K[22]); + R ^= FII(L, key->cast5.K[7], key->cast5.K[23]); + L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]); + R ^= FI(L, key->cast5.K[9], key->cast5.K[25]); + L ^= FII(R, key->cast5.K[10], key->cast5.K[26]); + R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]); + if (key->cast5.keylen > 10) { + L ^= FI(R, key->cast5.K[12], key->cast5.K[28]); + R ^= FII(L, key->cast5.K[13], key->cast5.K[29]); + L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]); + R ^= FI(L, key->cast5.K[15], key->cast5.K[31]); + } + STORE32H(R,&ct[0]); + STORE32H(L,&ct[4]); +} + + +#ifdef CLEAN_STACK +void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _cast5_ecb_encrypt(pt,ct,key); + burn_stack(sizeof(ulong32)*3); +} +#endif + +#ifdef CLEAN_STACK +static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 R, L; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32H(R,&ct[0]); + LOAD32H(L,&ct[4]); + if (key->cast5.keylen > 10) { + R ^= FI(L, key->cast5.K[15], key->cast5.K[31]); + L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]); + R ^= FII(L, key->cast5.K[13], key->cast5.K[29]); + L ^= FI(R, key->cast5.K[12], key->cast5.K[28]); + } + R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]); + L ^= FII(R, key->cast5.K[10], key->cast5.K[26]); + R ^= FI(L, key->cast5.K[9], key->cast5.K[25]); + L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]); + R ^= FII(L, key->cast5.K[7], key->cast5.K[23]); + L ^= FI(R, key->cast5.K[6], key->cast5.K[22]); + R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]); + L ^= FII(R, key->cast5.K[4], key->cast5.K[20]); + R ^= FI(L, key->cast5.K[3], key->cast5.K[19]); + L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]); + R ^= FII(L, key->cast5.K[1], key->cast5.K[17]); + L ^= FI(R, key->cast5.K[0], key->cast5.K[16]); + STORE32H(L,&pt[0]); + STORE32H(R,&pt[4]); +} + +#ifdef CLEAN_STACK +void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _cast5_ecb_decrypt(ct,pt,key); + burn_stack(sizeof(ulong32)*3); +} +#endif + +int cast5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16]; + unsigned char pt[8]; + unsigned char ct[8]; + } tests[] = { + { 16, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2} + }, + { 10, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, + }, + { 5, + {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E} + } + }; + int i, y, err; + symmetric_key key; + unsigned char tmp[2][8]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + cast5_ecb_encrypt(tests[i].pt, tmp[0], &key); + cast5_ecb_decrypt(tmp[0], tmp[1], &key); + if ((memcmp(tmp[0], tests[i].ct, 8) != 0) || (memcmp(tmp[1], tests[i].pt, 8) != 0)) { + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + } + return CRYPT_OK; + #endif +} + +int cast5_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 5) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 16) { + *desired_keysize = 16; + } + return CRYPT_OK; +} + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/cbc.c b/tnl-1.5.0/tnl/libtomcrypt/cbc.c new file mode 100644 index 0000000000000000000000000000000000000000..bd08bee763680ba8f0182ed3652adb434023ab60 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/cbc.c @@ -0,0 +1,111 @@ +#include "mycrypt.h" + +#ifdef CBC + +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc) +{ + int x, err; + + _ARGCHK(IV != NULL); + _ARGCHK(key != NULL); + _ARGCHK(cbc != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) { + return err; + } + + /* copy IV */ + cbc->blocklen = cipher_descriptor[cipher].block_length; + cbc->cipher = cipher; + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = IV[x]; + } + return CRYPT_OK; +} + +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc) +{ + int x, err; + unsigned char tmp[MAXBLOCKSIZE]; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cbc != NULL); + + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen valid? */ + if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + /* xor IV against plaintext */ + for (x = 0; x < cbc->blocklen; x++) { + tmp[x] = pt[x] ^ cbc->IV[x]; + } + + /* encrypt */ + cipher_descriptor[cbc->cipher].ecb_encrypt(tmp, ct, &cbc->key); + + /* store IV [ciphertext] for a future block */ + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = ct[x]; + } + + #ifdef CLEAN_STACK + zeromem(tmp, sizeof(tmp)); + #endif + return CRYPT_OK; +} + +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc) +{ + int x, err; + unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE]; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cbc != NULL); + + /* decrypt the block from ct into tmp */ + if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key); + + /* is blocklen valid? */ + if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) { + return CRYPT_INVALID_ARG; + } + + /* xor IV against the plaintext of the previous step */ + for (x = 0; x < cbc->blocklen; x++) { + /* copy CT in case ct == pt */ + tmp2[x] = ct[x]; + + /* actually decrypt the byte */ + pt[x] = tmp[x] ^ cbc->IV[x]; + } + + /* replace IV with this current ciphertext */ + for (x = 0; x < cbc->blocklen; x++) { + cbc->IV[x] = tmp2[x]; + } + #ifdef CLEAN_STACK + zeromem(tmp, sizeof(tmp)); + zeromem(tmp2, sizeof(tmp2)); + #endif + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/cfb.c b/tnl-1.5.0/tnl/libtomcrypt/cfb.c new file mode 100644 index 0000000000000000000000000000000000000000..39c9105130c0ed2023d75b425136790d18663067 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/cfb.c @@ -0,0 +1,101 @@ +#include "mycrypt.h" + +#ifdef CFB + +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb) +{ + int x, err; + + _ARGCHK(IV != NULL); + _ARGCHK(key != NULL); + _ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + + /* copy data */ + cfb->cipher = cipher; + cfb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < cfb->blocklen; x++) + cfb->IV[x] = IV[x]; + + /* init the cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { + return err; + } + + /* encrypt the IV */ + cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); + cfb->padlen = 0; + + return CRYPT_OK; +} + +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); + ++pt; + ++ct; + ++cfb->padlen; + } + return CRYPT_OK; +} + +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb) +{ + int err; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(cfb != NULL); + + if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || + cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (cfb->padlen == cfb->blocklen) { + cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); + cfb->padlen = 0; + } + cfb->pad[cfb->padlen] = *ct; + *pt = *ct ^ cfb->IV[cfb->padlen]; + ++pt; + ++ct; + ++cfb->padlen; + } + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/crypt.c b/tnl-1.5.0/tnl/libtomcrypt/crypt.c new file mode 100644 index 0000000000000000000000000000000000000000..a64248f3aaccf51288bd624b03fa6501b297bbfb --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/crypt.c @@ -0,0 +1,541 @@ +#include "mycrypt.h" +#include + +#define TAB_SIZE 32 + +struct _cipher_descriptor cipher_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; + +struct _hash_descriptor hash_descriptor[TAB_SIZE] = { +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, +{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } }; + +struct _prng_descriptor prng_descriptor[TAB_SIZE] = { +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL }, +{ NULL, NULL, NULL, NULL, NULL } }; + +/* ch1-01-1 */ +#if (ARGTYPE == 0) +void crypt_argchk(char *v, char *s, int d) +{ +#ifdef SONY_PS2 + printf("_ARGCHK '%s' failure on line %d of file %s\n", + v, d, s); +#else + fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n", + v, d, s); +#endif + (void)raise(SIGABRT); +} +#endif +/* ch1-01-1 */ + +int find_cipher(const char *name) +{ + int x; + _ARGCHK(name != NULL); + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) { + return x; + } + } + return -1; +} + +int find_hash(const char *name) +{ + int x; + _ARGCHK(name != NULL); + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name != NULL && strcmp(hash_descriptor[x].name, name) == 0) { + return x; + } + } + return -1; +} + +int find_prng(const char *name) +{ + int x; + _ARGCHK(name != NULL); + for (x = 0; x < TAB_SIZE; x++) { + if ((prng_descriptor[x].name != NULL) && strcmp(prng_descriptor[x].name, name) == 0) { + return x; + } + } + return -1; +} + +int find_cipher_id(unsigned char ID) +{ + int x; + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].ID == ID) { + return (cipher_descriptor[x].name == NULL) ? -1 : x; + } + } + return -1; +} + +int find_hash_id(unsigned char ID) +{ + int x; + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].ID == ID) { + return (hash_descriptor[x].name == NULL) ? -1 : x; + } + } + return -1; +} + +/* idea from Wayne Scott */ +int find_cipher_any(const char *name, int blocklen, int keylen) +{ + int x; + + _ARGCHK(name != NULL); + + x = find_cipher(name); + if (x != -1) return x; + + for (x = 0; cipher_descriptor[x].name != NULL && x < TAB_SIZE; x++) { + if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) { + return x; + } + } + return -1; +} + +int register_cipher(const struct _cipher_descriptor *cipher) +{ + int x; + + _ARGCHK(cipher != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) { + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (cipher_descriptor[x].name == NULL) { + memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor)); + return x; + } + } + + /* no spot */ + return -1; +} + +int unregister_cipher(const struct _cipher_descriptor *cipher) +{ + int x; + + _ARGCHK(cipher != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor)) == 0) { + cipher_descriptor[x].name = NULL; + cipher_descriptor[x].ID = 255; + return CRYPT_OK; + } + } + return CRYPT_ERROR; +} + +int register_hash(const struct _hash_descriptor *hash) +{ + int x; + + _ARGCHK(hash != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)) == 0) { + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (hash_descriptor[x].name == NULL) { + memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)); + return x; + } + } + + /* no spot */ + return -1; +} + +int unregister_hash(const struct _hash_descriptor *hash) +{ + int x; + + _ARGCHK(hash != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)) == 0) { + hash_descriptor[x].name = NULL; + return CRYPT_OK; + } + } + return CRYPT_ERROR; +} + +int register_prng(const struct _prng_descriptor *prng) +{ + int x; + + _ARGCHK(prng != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)) == 0) { + return x; + } + } + + /* find a blank spot */ + for (x = 0; x < TAB_SIZE; x++) { + if (prng_descriptor[x].name == NULL) { + memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)); + return x; + } + } + + /* no spot */ + return -1; +} + +int unregister_prng(const struct _prng_descriptor *prng) +{ + int x; + + _ARGCHK(prng != NULL); + + /* is it already registered? */ + for (x = 0; x < TAB_SIZE; x++) { + if (memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)) != 0) { + prng_descriptor[x].name = NULL; + return CRYPT_OK; + } + } + return CRYPT_ERROR; +} + +int cipher_is_valid(int idx) +{ + if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) { + return CRYPT_INVALID_CIPHER; + } + return CRYPT_OK; +} + +int hash_is_valid(int idx) +{ + if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { + return CRYPT_INVALID_HASH; + } + return CRYPT_OK; +} + +int prng_is_valid(int idx) +{ + if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { + return CRYPT_INVALID_PRNG; + } + return CRYPT_OK; +} + +const char *crypt_build_settings = + "LibTomCrypt " SCRYPT "\n\n" + "Endianess: " +#if defined(ENDIAN_NEUTRAL) + "neutral\n" +#elif defined(ENDIAN_LITTLE) + "little" + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #else + " (64-bit words)\n" + #endif +#elif defined(ENDIAN_BIG) + "big" + #if defined(ENDIAN_32BITWORD) + " (32-bit words)\n" + #else + " (64-bit words)\n" + #endif +#endif + "Clean stack: " +#if defined(CLEAN_STACK) + "enabled\n" +#else + "disabled\n" +#endif + "Ciphers built-in:\n" +#if defined(BLOWFISH) + " Blowfish\n" +#endif +#if defined(RC2) + " RC2\n" +#endif +#if defined(RC5) + " RC5\n" +#endif +#if defined(RC6) + " RC6\n" +#endif +#if defined(SAFERP) + " Safer+\n" +#endif +#if defined(SAFER) + " Safer\n" +#endif +#if defined(RIJNDAEL) + " Rijndael\n" +#endif +#if defined(XTEA) + " XTEA\n" +#endif +#if defined(TWOFISH) + " Twofish " + #if defined(TWOFISH_SMALL) && defined(TWOFISH_TABLES) + "(small, tables)\n" + #elif defined(TWOFISH_SMALL) + "(small)\n" + #elif defined(TWOFISH_TABLES) + "(tables)\n" + #else + "\n" + #endif +#endif +#if defined(DES) + " DES\n" +#endif +#if defined(CAST5) + " CAST5\n" +#endif +#if defined(NOEKEON) + " Noekeon\n" +#endif +#if defined(SKIPJACK) + " Skipjack\n" +#endif + + "\nHashes built-in:\n" +#if defined(SHA512) + " SHA-512\n" +#endif +#if defined(SHA384) + " SHA-384\n" +#endif +#if defined(SHA256) + " SHA-256\n" +#endif +#if defined(SHA224) + " SHA-224\n" +#endif +#if defined(TIGER) + " TIGER\n" +#endif +#if defined(SHA1) + " SHA1\n" +#endif +#if defined(MD5) + " MD5\n" +#endif +#if defined(MD4) + " MD4\n" +#endif +#if defined(MD2) + " MD2\n" +#endif +#if defined(RIPEMD128) + " RIPEMD128\n" +#endif +#if defined(RIPEMD160) + " RIPEMD160\n" +#endif + + "\nBlock Chaining Modes:\n" +#if defined(CFB) + " CFB\n" +#endif +#if defined(OFB) + " OFB\n" +#endif +#if defined(ECB) + " ECB\n" +#endif +#if defined(CBC) + " CBC\n" +#endif +#if defined(CTR) + " CTR\n" +#endif + + "\nPRNG:\n" +#if defined(YARROW) + " Yarrow\n" +#endif +#if defined(SPRNG) + " SPRNG\n" +#endif +#if defined(RC4) + " RC4\n" +#endif + + "\nPK Algs:\n" +#if defined(MRSA) + " RSA\n" +#endif +#if defined(MDH) + " DH\n" +#endif +#if defined(MECC) + " ECC\n" +#endif +#if defined(KR) + " KR\n" +#endif + + "\nCompiler:\n" +#if defined(WIN32) + " WIN32 platform detected.\n" +#endif +#if defined(__CYGWIN__) + " CYGWIN Detected.\n" +#endif +#if defined(__DJGPP__) + " DJGPP Detected.\n" +#endif +#if defined(_MSC_VER) + " MSVC compiler detected.\n" +#endif +#if defined(__GNUC__) + " GCC compiler detected.\n" +#endif + + "\nVarious others: " +#if defined(GF) + " GF " +#endif +#if defined(BASE64) + " BASE64 " +#endif +#if defined(MPI) + " MPI " +#endif +#if defined(HMAC) + " HMAC " +#endif +#if defined(TRY_UNRANDOM_FIRST) + " TRY_UNRANDOM_FIRST " +#endif +#if defined(LTC_TEST) + " LTC_TEST " +#endif + "\n" + + "\n\n\n" + ; + diff --git a/tnl-1.5.0/tnl/libtomcrypt/crypt.pdf b/tnl-1.5.0/tnl/libtomcrypt/crypt.pdf new file mode 100644 index 0000000000000000000000000000000000000000..304e47803511d9e8a8b00e602ffb633e7d394ab6 Binary files /dev/null and b/tnl-1.5.0/tnl/libtomcrypt/crypt.pdf differ diff --git a/tnl-1.5.0/tnl/libtomcrypt/ctr.c b/tnl-1.5.0/tnl/libtomcrypt/ctr.c new file mode 100644 index 0000000000000000000000000000000000000000..c633a13262b03fbbb45acef889bb3b2e8c21838e --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/ctr.c @@ -0,0 +1,83 @@ +#include "mycrypt.h" + +#ifdef CTR + +int ctr_start(int cipher, const unsigned char *count, const unsigned char *key, int keylen, + int num_rounds, symmetric_CTR *ctr) +{ + int x, err; + + _ARGCHK(count != NULL); + _ARGCHK(key != NULL); + _ARGCHK(ctr != NULL); + + /* bad param? */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* setup cipher */ + if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) { + return err; + } + + /* copy ctr */ + ctr->blocklen = cipher_descriptor[cipher].block_length; + ctr->cipher = cipher; + ctr->padlen = 0; + for (x = 0; x < ctr->blocklen; x++) { + ctr->ctr[x] = count[x]; + } + cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); + return CRYPT_OK; +} + +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) +{ + int x, err; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ctr != NULL); + + if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ctr->blocklen < 0 || ctr->blocklen > (int)sizeof(ctr->ctr) || + ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + /* is the pad empty? */ + if (ctr->padlen == ctr->blocklen) { + /* increment counter */ + for (x = 0; x < ctr->blocklen; x++) { + ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; + if (ctr->ctr[x] != (unsigned char)0) { + break; + } + } + + /* encrypt it */ + cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); + ctr->padlen = 0; + } + *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; + } + return CRYPT_OK; +} + +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr) +{ + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ctr != NULL); + + return ctr_encrypt(ct, pt, len, ctr); +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/des.c b/tnl-1.5.0/tnl/libtomcrypt/des.c new file mode 100644 index 0000000000000000000000000000000000000000..2cbc5e07f12081a2bed2df9dd8dc2138c0c68962 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/des.c @@ -0,0 +1,1803 @@ +/* DES code submitted by Dobes Vandermeer */ +#include "mycrypt.h" + +#ifdef DES + +#define EN0 0 +#define DE1 1 + +const struct _cipher_descriptor des_desc = +{ + "des", + 13, + 8, 8, 8, 16, + &des_setup, + &des_ecb_encrypt, + &des_ecb_decrypt, + &des_test, + &des_keysize +}; + +const struct _cipher_descriptor des3_desc = +{ + "3des", + 14, + 24, 24, 8, 16, + &des3_setup, + &des3_ecb_encrypt, + &des3_ecb_decrypt, + &des3_test, + &des3_keysize +}; + +static const ulong32 bytebit[8] = +{ + 0200, 0100, 040, 020, 010, 04, 02, 01 +}; + +static const ulong32 bigbyte[24] = +{ + 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, + 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, + 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, + 0x800UL, 0x400UL, 0x200UL, 0x100UL, + 0x80UL, 0x40UL, 0x20UL, 0x10UL, + 0x8UL, 0x4UL, 0x2UL, 0x1L +}; + +/* Use the key schedule specific in the standard (ANSI X3.92-1981) */ + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 +}; + +static const unsigned char totrot[16] = { + 1, 2, 4, 6, + 8, 10, 12, 14, + 15, 17, 19, 21, + 23, 25, 27, 28 +}; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 +}; + + +static const ulong32 SP1[64] = +{ + 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, + 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, + 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, + 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, + 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, + 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, + 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, + 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, + 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, + 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, + 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, + 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, + 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, + 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, + 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL +}; + +static const ulong32 SP2[64] = +{ + 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, + 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, + 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, + 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, + 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, + 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, + 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, + 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, + 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, + 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, + 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, + 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, + 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, + 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, + 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, + 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL +}; + +static const ulong32 SP3[64] = +{ + 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, + 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, + 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, + 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, + 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, + 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, + 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, + 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, + 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, + 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, + 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, + 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, + 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, + 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, + 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, + 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL +}; + +static const ulong32 SP4[64] = +{ + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, + 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, + 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, + 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, + 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, + 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, + 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, + 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, + 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, + 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, + 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, + 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, + 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL +}; + +static const ulong32 SP5[64] = +{ + 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, + 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, + 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, + 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, + 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, + 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, + 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, + 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, + 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, + 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, + 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, + 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, + 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, + 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, + 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, + 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL +}; + +static const ulong32 SP6[64] = +{ + 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, + 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, + 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, + 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, + 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, + 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, + 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, + 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, + 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, + 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, + 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, + 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, + 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, + 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, + 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL +}; + +static const ulong32 SP7[64] = +{ + 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, + 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, + 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, + 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, + 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, + 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, + 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, + 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, + 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, + 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, + 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, + 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, + 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, + 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, + 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, + 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL +}; + +static const ulong32 SP8[64] = +{ + 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, + 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, + 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, + 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, + 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, + 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, + 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, + 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, + 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, + 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, + 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, + 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, + 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, + 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, + 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, + 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL +}; + +#ifndef SMALL_CODE + +static const ulong64 des_ip[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010), + CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010), + CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010), + CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010), + CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010), + CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010), + CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010), + CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010), + CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010), + CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010), + CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010), + CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010), + CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010), + CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010), + CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010), + CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010), + CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010), + CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010), + CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010), + CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010), + CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010), + CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010), + CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010), + CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010), + CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010), + CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010), + CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010), + CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010), + CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010), + CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010), + CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010), + CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010), + CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010), + CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010), + CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010), + CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010), + CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010), + CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010), + CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010), + CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010), + CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010), + CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010), + CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010), + CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010), + CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010), + CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010), + CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010), + CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010), + CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010), + CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010), + CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010), + CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010), + CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010), + CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010), + CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010), + CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010), + CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010), + CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010), + CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010), + CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010), + CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010), + CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010), + CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010), + CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008), + CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008), + CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808), + CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808), + CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008), + CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008), + CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808), + CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808), + CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008), + CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008), + CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808), + CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808), + CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008), + CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008), + CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808), + CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808), + CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008), + CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008), + CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808), + CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808), + CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008), + CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008), + CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808), + CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808), + CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008), + CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008), + CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808), + CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808), + CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008), + CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008), + CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808), + CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808), + CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008), + CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008), + CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808), + CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808), + CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008), + CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008), + CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808), + CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808), + CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008), + CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008), + CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808), + CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808), + CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008), + CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008), + CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808), + CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808), + CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008), + CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008), + CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808), + CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808), + CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008), + CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008), + CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808), + CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808), + CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008), + CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008), + CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808), + CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808), + CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008), + CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008), + CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808), + CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004), + CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004), + CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404), + CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404), + CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004), + CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004), + CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404), + CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404), + CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004), + CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004), + CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404), + CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404), + CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004), + CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004), + CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404), + CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404), + CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004), + CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004), + CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404), + CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404), + CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004), + CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004), + CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404), + CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404), + CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004), + CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004), + CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404), + CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404), + CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004), + CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004), + CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404), + CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404), + CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004), + CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004), + CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404), + CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404), + CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004), + CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004), + CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404), + CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404), + CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004), + CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004), + CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404), + CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404), + CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004), + CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004), + CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404), + CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404), + CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004), + CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004), + CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404), + CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404), + CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004), + CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004), + CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404), + CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404), + CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004), + CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004), + CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404), + CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404), + CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004), + CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004), + CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404), + CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002), + CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002), + CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202), + CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202), + CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002), + CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002), + CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202), + CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202), + CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002), + CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002), + CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202), + CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202), + CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002), + CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002), + CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202), + CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202), + CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002), + CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002), + CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202), + CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202), + CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002), + CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002), + CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202), + CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202), + CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002), + CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002), + CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202), + CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202), + CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002), + CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002), + CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202), + CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202), + CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002), + CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002), + CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202), + CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202), + CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002), + CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002), + CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202), + CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202), + CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002), + CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002), + CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202), + CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202), + CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002), + CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002), + CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202), + CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202), + CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002), + CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002), + CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202), + CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202), + CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002), + CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002), + CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202), + CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202), + CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002), + CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002), + CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202), + CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202), + CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002), + CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002), + CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202), + CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100), + CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100), + CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100), + CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100), + CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100), + CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100), + CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100), + CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100), + CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100), + CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100), + CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100), + CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100), + CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100), + CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100), + CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100), + CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100), + CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100), + CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100), + CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100), + CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100), + CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100), + CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100), + CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100), + CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100), + CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100), + CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100), + CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100), + CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100), + CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100), + CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100), + CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100), + CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100), + CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101), + CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101), + CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101), + CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101), + CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101), + CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101), + CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101), + CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101), + CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101), + CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101), + CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101), + CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101), + CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101), + CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101), + CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101), + CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101), + CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101), + CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101), + CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101), + CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101), + CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101), + CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101), + CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101), + CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101), + CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101), + CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101), + CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101), + CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101), + CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101), + CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101), + CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101), + CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080), + CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080), + CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080), + CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080), + CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080), + CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080), + CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080), + CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080), + CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080), + CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080), + CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080), + CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080), + CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080), + CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080), + CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080), + CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080), + CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080), + CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080), + CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080), + CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080), + CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080), + CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080), + CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080), + CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080), + CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080), + CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080), + CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080), + CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080), + CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080), + CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080), + CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080), + CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080), + CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080), + CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080), + CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080), + CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080), + CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080), + CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080), + CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080), + CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080), + CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080), + CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080), + CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080), + CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080), + CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080), + CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080), + CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080), + CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080), + CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080), + CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080), + CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080), + CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080), + CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080), + CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080), + CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080), + CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080), + CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080), + CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080), + CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080), + CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080), + CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080), + CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080), + CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080), + CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040), + CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040), + CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040), + CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040), + CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040), + CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040), + CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040), + CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040), + CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040), + CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040), + CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040), + CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040), + CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040), + CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040), + CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040), + CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040), + CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040), + CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040), + CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040), + CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040), + CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040), + CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040), + CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040), + CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040), + CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040), + CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040), + CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040), + CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040), + CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040), + CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040), + CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040), + CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040), + CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040), + CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040), + CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040), + CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040), + CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040), + CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040), + CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040), + CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040), + CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040), + CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040), + CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040), + CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040), + CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040), + CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040), + CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040), + CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040), + CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040), + CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040), + CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040), + CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040), + CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040), + CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040), + CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040), + CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040), + CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040), + CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040), + CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040), + CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040), + CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040), + CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040), + CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040), + CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020), + CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020), + CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020), + CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020), + CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020), + CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020), + CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020), + CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020), + CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020), + CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020), + CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020), + CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020), + CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020), + CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020), + CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020), + CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020), + CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020), + CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020), + CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020), + CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020), + CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020), + CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020), + CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020), + CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020), + CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020), + CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020), + CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020), + CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020), + CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020), + CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020), + CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020), + CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020), + CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020), + CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020), + CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020), + CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020), + CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020), + CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020), + CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020), + CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020), + CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020), + CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020), + CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020), + CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020), + CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020), + CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020), + CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020), + CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020), + CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020), + CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020), + CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020), + CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020), + CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020), + CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020), + CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020), + CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020), + CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020), + CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020), + CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020), + CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020), + CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020), + CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020), + CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020), + CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020) + }}; + +static const ulong64 des_fp[8][256] = { + +{ CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000), + CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000), + CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200), + CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200), + CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002), + CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002), + CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202), + CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202), + CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000), + CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000), + CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200), + CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200), + CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002), + CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002), + CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202), + CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202), + CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000), + CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000), + CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200), + CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200), + CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002), + CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002), + CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202), + CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202), + CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000), + CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000), + CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200), + CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200), + CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002), + CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002), + CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202), + CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202), + CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000), + CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000), + CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200), + CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200), + CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002), + CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002), + CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202), + CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202), + CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000), + CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000), + CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200), + CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200), + CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002), + CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002), + CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202), + CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202), + CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000), + CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000), + CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200), + CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200), + CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002), + CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002), + CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202), + CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202), + CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000), + CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000), + CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200), + CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200), + CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002), + CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002), + CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202), + CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000), + CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000), + CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800), + CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800), + CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008), + CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008), + CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808), + CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808), + CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000), + CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000), + CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800), + CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800), + CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008), + CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008), + CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808), + CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808), + CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000), + CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000), + CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800), + CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800), + CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008), + CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008), + CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808), + CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808), + CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000), + CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000), + CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800), + CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800), + CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008), + CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008), + CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808), + CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808), + CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000), + CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000), + CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800), + CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800), + CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008), + CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008), + CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808), + CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808), + CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000), + CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000), + CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800), + CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800), + CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008), + CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008), + CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808), + CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808), + CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000), + CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000), + CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800), + CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800), + CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008), + CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008), + CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808), + CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808), + CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000), + CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000), + CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800), + CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800), + CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008), + CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008), + CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808), + CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000), + CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000), + CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000), + CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000), + CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020), + CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020), + CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020), + CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020), + CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000), + CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000), + CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000), + CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000), + CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020), + CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020), + CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020), + CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020), + CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000), + CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000), + CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000), + CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000), + CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020), + CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020), + CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020), + CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020), + CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000), + CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000), + CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000), + CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000), + CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020), + CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020), + CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020), + CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020), + CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000), + CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000), + CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000), + CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000), + CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020), + CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020), + CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020), + CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020), + CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000), + CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000), + CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000), + CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000), + CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020), + CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020), + CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020), + CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020), + CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000), + CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000), + CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000), + CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000), + CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020), + CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020), + CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020), + CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020), + CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000), + CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000), + CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000), + CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000), + CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020), + CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020), + CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020), + CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000), + CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000), + CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000), + CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000), + CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080), + CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080), + CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080), + CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080), + CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000), + CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000), + CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000), + CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000), + CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080), + CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080), + CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080), + CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080), + CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000), + CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000), + CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000), + CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000), + CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080), + CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080), + CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080), + CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080), + CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000), + CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000), + CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000), + CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000), + CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080), + CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080), + CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080), + CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080), + CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000), + CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000), + CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000), + CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000), + CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080), + CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080), + CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080), + CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080), + CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000), + CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000), + CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000), + CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000), + CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080), + CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080), + CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080), + CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080), + CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000), + CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000), + CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000), + CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000), + CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080), + CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080), + CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080), + CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080), + CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000), + CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000), + CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000), + CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000), + CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080), + CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080), + CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080), + CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000), + CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000), + CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100), + CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100), + CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001), + CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001), + CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101), + CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101), + CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000), + CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000), + CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100), + CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100), + CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001), + CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001), + CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101), + CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101), + CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000), + CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000), + CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100), + CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100), + CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001), + CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001), + CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101), + CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101), + CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000), + CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000), + CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100), + CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100), + CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001), + CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001), + CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101), + CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101), + CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000), + CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000), + CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100), + CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100), + CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001), + CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001), + CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101), + CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101), + CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000), + CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000), + CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100), + CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100), + CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001), + CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001), + CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101), + CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101), + CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000), + CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000), + CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100), + CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100), + CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001), + CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001), + CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101), + CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101), + CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000), + CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000), + CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100), + CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100), + CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001), + CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001), + CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101), + CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000), + CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000), + CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400), + CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400), + CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004), + CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004), + CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404), + CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404), + CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000), + CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000), + CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400), + CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400), + CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004), + CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004), + CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404), + CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404), + CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000), + CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000), + CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400), + CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400), + CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004), + CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004), + CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404), + CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404), + CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000), + CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000), + CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400), + CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400), + CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004), + CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004), + CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404), + CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404), + CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000), + CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000), + CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400), + CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400), + CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004), + CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004), + CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404), + CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404), + CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000), + CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000), + CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400), + CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400), + CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004), + CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004), + CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404), + CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404), + CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000), + CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000), + CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400), + CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400), + CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004), + CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004), + CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404), + CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404), + CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000), + CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000), + CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400), + CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400), + CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004), + CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004), + CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404), + CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000), + CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000), + CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000), + CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000), + CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010), + CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010), + CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010), + CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010), + CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000), + CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000), + CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000), + CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000), + CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010), + CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010), + CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010), + CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010), + CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000), + CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000), + CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000), + CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000), + CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010), + CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010), + CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010), + CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010), + CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000), + CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000), + CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000), + CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000), + CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010), + CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010), + CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010), + CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010), + CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000), + CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000), + CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000), + CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000), + CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010), + CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010), + CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010), + CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010), + CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000), + CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000), + CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000), + CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000), + CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010), + CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010), + CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010), + CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010), + CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000), + CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000), + CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000), + CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000), + CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010), + CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010), + CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010), + CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010), + CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000), + CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000), + CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000), + CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000), + CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010), + CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010), + CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010), + CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010) + }, +{ CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000), + CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000), + CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000), + CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000), + CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040), + CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040), + CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040), + CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040), + CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000), + CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000), + CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000), + CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000), + CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040), + CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040), + CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040), + CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040), + CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000), + CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000), + CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000), + CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000), + CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040), + CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040), + CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040), + CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040), + CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000), + CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000), + CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000), + CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000), + CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040), + CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040), + CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040), + CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040), + CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000), + CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000), + CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000), + CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000), + CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040), + CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040), + CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040), + CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040), + CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000), + CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000), + CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000), + CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000), + CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040), + CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040), + CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040), + CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040), + CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000), + CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000), + CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000), + CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000), + CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040), + CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040), + CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040), + CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040), + CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000), + CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000), + CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000), + CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000), + CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040), + CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040), + CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040), + CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040) + }}; + +#endif + + +static void cookey(const ulong32 *raw1, ulong32 *keyout); + +#ifdef CLEAN_STACK +void _deskey(const unsigned char *key, short edf, ulong32 *keyout) +#else +void deskey(const unsigned char *key, short edf, ulong32 *keyout) +#endif +{ + ulong32 i, j, l, m, n, kn[32]; + unsigned char pc1m[56], pcr[56]; + + for (j=0; j < 56; j++) { + l = (ulong32)pc1[j]; + m = l & 7; + pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); + } + + for (i=0; i < 16; i++) { + if (edf == DE1) { + m = (15 - i) << 1; + } else { + m = i << 1; + } + n = m + 1; + kn[m] = kn[n] = 0L; + for (j=0; j < 28; j++) { + l = j + (ulong32)totrot[i]; + if (l < 28) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (/*j = 28*/; j < 56; j++) { + l = j + (ulong32)totrot[i]; + if (l < 56) { + pcr[j] = pc1m[l]; + } else { + pcr[j] = pc1m[l - 28]; + } + } + for (j=0; j < 24; j++) { + if ((int)pcr[(int)pc2[j]] != 0) { + kn[m] |= bigbyte[j]; + } + if ((int)pcr[(int)pc2[j+24]] != 0) { + kn[n] |= bigbyte[j]; + } + } + } + + cookey(kn, keyout); +} + +#ifdef CLEAN_STACK +void deskey(const unsigned char *key, short edf, ulong32 *keyout) +{ + _deskey(key, edf, keyout); + burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112); +} +#endif + +#ifdef CLEAN_STACK +static void _cookey(const ulong32 *raw1, ulong32 *keyout) +#else +static void cookey(const ulong32 *raw1, ulong32 *keyout) +#endif +{ + ulong32 *cook; + const ulong32 *raw0; + ulong32 dough[32]; + int i; + + cook = dough; + for(i=0; i < 16; i++, raw1++) + { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + + memcpy(keyout, dough, sizeof dough); +} + +#ifdef CLEAN_STACK +static void cookey(const ulong32 *raw1, ulong32 *keyout) +{ + _cookey(raw1, keyout); + burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int)); +} +#endif + +#ifndef CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +#else +static void _desfunc(ulong32 *block, const ulong32 *keys) +#endif +{ + ulong32 work, right, leftt; + int round; + + leftt = block[0]; + right = block[1]; + +#ifdef SMALL_CODE + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + + right = ROL(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + + leftt ^= work; + right ^= work; + leftt = ROL(leftt, 1); +#else + { + ulong64 tmp; + tmp = des_ip[0][byte(leftt, 0)] ^ + des_ip[1][byte(leftt, 1)] ^ + des_ip[2][byte(leftt, 2)] ^ + des_ip[3][byte(leftt, 3)] ^ + des_ip[4][byte(right, 0)] ^ + des_ip[5][byte(right, 1)] ^ + des_ip[6][byte(right, 2)] ^ + des_ip[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + for (round = 0; round < 8; round++) { + work = ROR(right, 4) ^ *keys++; + leftt ^= SP7[work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + leftt ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + + work = ROR(leftt, 4) ^ *keys++; + right ^= SP7[ work & 0x3fL] + ^ SP5[(work >> 8) & 0x3fL] + ^ SP3[(work >> 16) & 0x3fL] + ^ SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + right ^= SP8[ work & 0x3fL] + ^ SP6[(work >> 8) & 0x3fL] + ^ SP4[(work >> 16) & 0x3fL] + ^ SP2[(work >> 24) & 0x3fL]; + } + +#ifdef SMALL_CODE + right = ROR(right, 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ROR(leftt, 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + // -- + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); +#else + { + ulong64 tmp; + tmp = des_fp[0][byte(leftt, 0)] ^ + des_fp[1][byte(leftt, 1)] ^ + des_fp[2][byte(leftt, 2)] ^ + des_fp[3][byte(leftt, 3)] ^ + des_fp[4][byte(right, 0)] ^ + des_fp[5][byte(right, 1)] ^ + des_fp[6][byte(right, 2)] ^ + des_fp[7][byte(right, 3)]; + leftt = (ulong32)(tmp >> 32); + right = (ulong32)(tmp & 0xFFFFFFFFUL); + } +#endif + + block[0] = right; + block[1] = leftt; +} + +#ifdef CLEAN_STACK +static void desfunc(ulong32 *block, const ulong32 *keys) +{ + _desfunc(block, keys); + burn_stack(sizeof(ulong32) * 4 + sizeof(int)); +} +#endif + +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des.ek); + deskey(key, DE1, skey->des.dk); + + return CRYPT_OK; +} + +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if( num_rounds != 0 && num_rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 24) { + return CRYPT_INVALID_KEYSIZE; + } + + deskey(key, EN0, skey->des3.ek[0]); + deskey(key+8, DE1, skey->des3.ek[1]); + deskey(key+16, EN0, skey->des3.ek[2]); + + deskey(key, DE1, skey->des3.dk[2]); + deskey(key+8, EN0, skey->des3.dk[1]); + deskey(key+16, DE1, skey->des3.dk[0]); + + return CRYPT_OK; +} + +void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + ulong32 work[2]; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, key->des.ek); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); +} + +void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + ulong32 work[2]; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, key->des.dk); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); +} + +void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + ulong32 work[2]; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], pt+0); + LOAD32H(work[1], pt+4); + desfunc(work, key->des3.ek[0]); + desfunc(work, key->des3.ek[1]); + desfunc(work, key->des3.ek[2]); + STORE32H(work[0],ct+0); + STORE32H(work[1],ct+4); +} + +void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + ulong32 work[2]; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + LOAD32H(work[0], ct+0); + LOAD32H(work[1], ct+4); + desfunc(work, key->des3.dk[0]); + desfunc(work, key->des3.dk[1]); + desfunc(work, key->des3.dk[2]); + STORE32H(work[0],pt+0); + STORE32H(work[1],pt+4); +} + +int des_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + int err; + static const struct des_test_case { + int num, mode; // mode 1 = encrypt + unsigned char key[8], txt[8], out[8]; + } cases[] = { + { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } }, + { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + + { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, + { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } }, + { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } }, + { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } }, + { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } }, + { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } }, + { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } }, + { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } }, + { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, + {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } } + + /*** more test cases you could add if you are not convinced (the above test cases aren't really too good): + + key plaintext ciphertext + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58 + 3000000000000000 1000000000000001 958E6E627A05557B + 1111111111111111 1111111111111111 F40379AB9E0EC533 + 0123456789ABCDEF 1111111111111111 17668DFC7292532D + 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD + 0000000000000000 0000000000000000 8CA64DE9C1B123A7 + FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4 + 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B + 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 + 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A + 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A + 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 + 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B + 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 + 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A + 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F + 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 + 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 + 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A + 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 + 025816164629B007 480D39006EE762F2 A1F9915541020B56 + 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 + 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC + 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A + 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 + 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 + 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100 + 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606 + E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7 + 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451 + FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE + 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D + FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2 + + http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt + ***/ + }; + int i, y; + unsigned char tmp[8]; + symmetric_key des; + + for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) + { + if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) { + return err; + } + if (cases[i].mode != 0) { + des_ecb_encrypt(cases[i].txt, tmp, &des); + } else { + des_ecb_decrypt(cases[i].txt, tmp, &des); + } + + if (memcmp(cases[i].out, tmp, sizeof(tmp)) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[y] = 0; + for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); + for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); + for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int des3_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char key[24], pt[8], ct[8], tmp[8]; + symmetric_key skey; + int x, err; + + if ((err = des_test()) != CRYPT_OK) { + return err; + } + + for (x = 0; x < 8; x++) { + pt[x] = x; + } + + for (x = 0; x < 24; x++) { + key[x] = x; + } + + if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) { + return err; + } + + des3_ecb_encrypt(pt, ct, &skey); + des3_ecb_decrypt(ct, tmp, &skey); + + if (memcmp(pt, tmp, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int des_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if(*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } + *desired_keysize = 8; + return CRYPT_OK; +} + +int des3_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if(*desired_keysize < 24) { + return CRYPT_INVALID_KEYSIZE; + } + *desired_keysize = 24; + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/dh.c b/tnl-1.5.0/tnl/libtomcrypt/dh.c new file mode 100644 index 0000000000000000000000000000000000000000..78b99488a6dcdf808d03d72afb0fc2bff710f706 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/dh.c @@ -0,0 +1,491 @@ +#include "mycrypt.h" + +#ifdef MDH + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +static const struct { + int size; + char *name, *base, *prime; +} sets[] = { +#ifdef DH768 +{ + 96, + "DH-768", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////m3wvV" +}, +#endif +#ifdef DH1024 +{ + 128, + "DH-1024", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////m3C47" +}, +#endif +#ifdef DH1280 +{ + 160, + "DH-1280", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////m4kSN" +}, +#endif +#ifdef DH1536 +{ + 192, + "DH-1536", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////m5uqd" +}, +#endif +#ifdef DH1792 +{ + 224, + "DH-1792", + "4", + "F///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////mT/sd" +}, +#endif +#ifdef DH2048 +{ + 256, + "DH-2048", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////////////////m8MPh" +}, +#endif +#ifdef DH2560 +{ + 320, + "DH-2560", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////mKFpF" +}, +#endif +#ifdef DH3072 +{ + 384, + "DH-3072", + "4", + "3///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////////////m32nN" +}, +#endif +#ifdef DH4096 +{ + 512, + "DH-4096", + "4", + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////" + "/////////////////////m8pOF" +}, +#endif +{ + 0, + NULL, + NULL, + NULL +} +}; + +static int is_valid_idx(int n) +{ + int x; + + for (x = 0; sets[x].size; x++); + if ((n < 0) || (n >= x)) { + return 0; + } + return 1; +} + +int dh_test(void) +{ + mp_int p, g, tmp; + int x, res, primality; + + if ((res = mp_init_multi(&p, &g, &tmp, NULL)) != MP_OKAY) { goto error; } + + for (x = 0; sets[x].size != 0; x++) { +#if 0 + printf("dh_test():testing size %d-bits\n", sets[x].size * 8); +#endif + if ((res = mp_read_radix(&g,(char *)sets[x].base, 64)) != MP_OKAY) { goto error; } + if ((res = mp_read_radix(&p,(char *)sets[x].prime, 64)) != MP_OKAY) { goto error; } + + /* ensure p is prime */ + if ((res = is_prime(&p, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + res = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + if ((res = mp_sub_d(&p, 1, &tmp)) != MP_OKAY) { goto error; } + if ((res = mp_div_2(&tmp, &tmp)) != MP_OKAY) { goto error; } + + /* ensure (p-1)/2 is prime */ + if ((res = is_prime(&tmp, &primality)) != CRYPT_OK) { goto done; } + if (primality == 0) { + res = CRYPT_FAIL_TESTVECTOR; + goto done; + } + + /* now see if g^((p-1)/2) mod p is in fact 1 */ + if ((res = mp_exptmod(&g, &tmp, &p, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&tmp, 1)) { + res = CRYPT_FAIL_TESTVECTOR; + goto done; + } + } + res = CRYPT_OK; + goto done; +error: + res = mpi_to_ltc_error(res); +done: + mp_clear_multi(&tmp, &g, &p, NULL); + return res; +} + +void dh_sizes(int *low, int *high) +{ + int x; + _ARGCHK(low != NULL); + _ARGCHK(high != NULL); + *low = INT_MAX; + *high = 0; + for (x = 0; sets[x].size != 0; x++) { + if (*low > sets[x].size) *low = sets[x].size; + if (*high < sets[x].size) *high = sets[x].size; + } +} + +int dh_get_size(dh_key *key) +{ + _ARGCHK(key != NULL); + if (is_valid_idx(key->idx) == 1) { + return sets[key->idx].size; + } else { + return INT_MAX; /* large value that would cause dh_make_key() to fail */ + } +} + +int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) +{ + unsigned char buf[512]; + unsigned long x; + mp_int p, g; + int res, err; + + _ARGCHK(key != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* find key size */ + for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); +#ifdef FAST_PK + keysize = MIN(sets[x].size, 32); +#else + keysize = sets[x].size; +#endif + + if (sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + key->idx = x; + + /* make up random string */ + if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) { + return CRYPT_ERROR_READPRNG; + } + + /* init parameters */ + if ((res = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(res); + } + if ((res = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; } + if ((res = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + + /* load the x value */ + if ((res = mp_read_unsigned_bin(&key->x, buf, keysize)) != MP_OKAY) { goto error; } + if ((res = mp_exptmod(&g, &key->x, &p, &key->y)) != MP_OKAY) { goto error; } + key->type = PK_PRIVATE; + + if ((res = mp_shrink(&key->x)) != MP_OKAY) { goto error; } + if ((res = mp_shrink(&key->y)) != MP_OKAY) { goto error; } + + /* free up ram */ + res = CRYPT_OK; + goto done2; +error: + res = mpi_to_ltc_error(res); + mp_clear_multi(&key->x, &key->y, NULL); +done2: + mp_clear_multi(&p, &g, NULL); + zeromem(buf, sizeof(buf)); + return res; +} + +void dh_free(dh_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->x, &key->y, NULL); +} + +#define OUTPUT_BIGNUM(num, buf2, y, z) \ +{ \ + z = (unsigned long)mp_unsigned_bin_size(num); \ + STORE32L(z, buf2+y); \ + y += 4; \ + if ((err = mp_to_unsigned_bin(num, buf2+y)) != MP_OKAY) { return mpi_to_ltc_error(err); } \ + y += z; \ +} + + +#define INPUT_BIGNUM(num, in, x, y) \ +{ \ + /* load value */ \ + if (y + 4 > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + LOAD32L(x, in+y); \ + y += 4; \ + \ + /* sanity check... */ \ + if (x+y > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + \ + /* load it */ \ + if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != MP_OKAY) {\ + err = mpi_to_ltc_error(err); \ + goto error; \ + } \ + y += x; \ + if ((err = mp_shrink(num)) != MP_OKAY) { \ + err = mpi_to_ltc_error(err); \ + goto error; \ + } \ +} + + +int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key) +{ + unsigned char buf2[1536]; + unsigned long y, z; + int err; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* header */ + y = PACKET_SIZE; + + /* header */ + buf2[y++] = type; + buf2[y++] = (unsigned char)(sets[key->idx].size / 8); + + /* export y */ + OUTPUT_BIGNUM(&key->y, buf2, y, z); + + if (type == PK_PRIVATE) { + /* export x */ + OUTPUT_BIGNUM(&key->x, buf2, y, z); + } + + /* check for overflow */ + if (*outlen < y) { + #ifdef CLEAN_STACK + zeromem(buf2, sizeof(buf2)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY); + + /* output it */ + *outlen = y; + memcpy(out, buf2, (size_t)y); + + /* clear mem */ +#ifdef CLEAN_STACK + zeromem(buf2, sizeof(buf2)); +#endif + return CRYPT_OK; +} + +int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key) +{ + unsigned long x, y, s; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* make sure valid length */ + if (2+PACKET_SIZE > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type byte */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init */ + if ((err = mp_init_multi(&key->x, &key->y, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* advance past packet header */ + y = PACKET_SIZE; + + /* key type, e.g. private, public */ + key->type = (int)in[y++]; + + /* key size in bytes */ + s = (unsigned long)in[y++] * 8; + + for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++); + if (sets[x].size == 0) { + err = CRYPT_INVALID_KEYSIZE; + goto error; + } + key->idx = (int)x; + + /* type check both values */ + if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) { + err = CRYPT_PK_TYPE_MISMATCH; + goto error; + } + + /* is the key idx valid? */ + if (is_valid_idx(key->idx) != 1) { + err = CRYPT_PK_TYPE_MISMATCH; + goto error; + } + + /* load public value g^x mod p*/ + INPUT_BIGNUM(&key->y, in, x, y); + + if (key->type == PK_PRIVATE) { + INPUT_BIGNUM(&key->x, in, x, y); + } + + /* eliminate private key if public */ + if (key->type == PK_PUBLIC) { + mp_clear(&key->x); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->y, &key->x, NULL); + return err; +} + +int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + mp_int tmp, p; + unsigned long x; + int res; + + _ARGCHK(private_key != NULL); + _ARGCHK(public_key != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* types valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* same idx? */ + if (private_key->idx != public_key->idx) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* compute y^x mod p */ + if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + if (mp_read_radix(&p, (char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; } + if (mp_exptmod(&public_key->y, &private_key->x, &p, &tmp) != MP_OKAY) { goto error; } + + /* enough space for output? */ + x = (unsigned long)mp_unsigned_bin_size(&tmp); + if (*outlen < x) { + res = CRYPT_BUFFER_OVERFLOW; + goto done; + } + if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) { goto error; } + *outlen = x; + res = CRYPT_OK; + goto done; +error: + res = CRYPT_MEM; +done: + mp_clear_multi(&p, &tmp, NULL); + return res; +} + +#include "dh_sys.c" + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/dh_sys.c b/tnl-1.5.0/tnl/libtomcrypt/dh_sys.c new file mode 100644 index 0000000000000000000000000000000000000000..fb10a7e8e6f75c59c7d70bbdbad1298c9b02c4c8 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/dh_sys.c @@ -0,0 +1,406 @@ +int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + dh_key *key) +{ + unsigned char pub_expt[768], dh_shared[768], skey[MAXBLOCKSIZE]; + dh_key pubkey; + unsigned long x, y, z, hashsize, pubkeysize; + int err; + + _ARGCHK(inkey != NULL); + _ARGCHK(out != NULL); + _ARGCHK(len != NULL); + _ARGCHK(key != NULL); + + /* check that wprng/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (keylen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } + + pubkeysize = sizeof(pub_expt); + if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + dh_free(&pubkey); + return err; + } + + /* now check if the out buffer is big enough */ + if (*len < (9 + PACKET_SIZE + pubkeysize + keylen)) { + dh_free(&pubkey); + return CRYPT_BUFFER_OVERFLOW; + } + + /* make random key */ + hashsize = hash_descriptor[hash].hashsize; + + x = (unsigned long)sizeof(dh_shared); + if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) { + dh_free(&pubkey); + return err; + } + dh_free(&pubkey); + + z = sizeof(skey); + if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) { + return err; + } + + /* output header */ + y = PACKET_SIZE; + + /* size of hash name and the name itself */ + out[y++] = hash_descriptor[hash].ID; + + /* length of DH pubkey and the key itself */ + STORE32L(pubkeysize, out+y); + y += 4; + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = pub_expt[x]; + } + + /* Store the encrypted key */ + STORE32L(keylen, out+y); + y += 4; + + for (x = 0; x < keylen; x++, y++) { + out[y] = skey[x] ^ inkey[x]; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY); + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(pub_expt, sizeof(pub_expt)); + zeromem(dh_shared, sizeof(dh_shared)); + zeromem(skey, sizeof(skey)); +#endif + + *len = y; + return CRYPT_OK; +} + +int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + dh_key *key) +{ + unsigned char shared_secret[768], skey[MAXBLOCKSIZE]; + unsigned long x, y, z,hashsize, keysize; + int res, hash, err; + dh_key pubkey; + + _ARGCHK(in != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(keylen != NULL); + _ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check if initial header should fit */ + if (inlen < PACKET_SIZE+1+4+4) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= PACKET_SIZE+1+4+4; + } + + /* is header correct? */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + return err; + } + + /* now lets get the hash name */ + y = PACKET_SIZE; + hash = find_hash_id(in[y++]); + if (hash == -1) { + return CRYPT_INVALID_HASH; + } + + /* common values */ + hashsize = hash_descriptor[hash].hashsize; + + /* get public key */ + LOAD32L(x, in+y); + + /* now check if the imported key will fit */ + if (inlen < x) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= x; + } + + y += 4; + if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) { + return err; + } + y += x; + + /* make shared key */ + x = (unsigned long)sizeof(shared_secret); + if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { + dh_free(&pubkey); + return err; + } + dh_free(&pubkey); + + z = sizeof(skey); + if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { + return err; + } + + /* load in the encrypted key */ + LOAD32L(keysize, in+y); + + /* will the outkey fit as part of the input */ + if (inlen < keysize) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= keysize; + } + + if (keysize > *keylen) { + res = CRYPT_BUFFER_OVERFLOW; + goto done; + } + y += 4; + + *keylen = keysize; + + for (x = 0; x < keysize; x++, y++) { + outkey[x] = skey[x] ^ in[y]; + } + + res = CRYPT_OK; +done: +#ifdef CLEAN_STACK + zeromem(shared_secret, sizeof(shared_secret)); + zeromem(skey, sizeof(skey)); +#endif + return res; +} + +/* perform an ElGamal Signature of a hash + * + * The math works as follows. x is the private key, M is the message to sign + + 1. pick a random k + 2. compute a = g^k mod p + 3. compute b = (M - xa)/k mod p + 4. Send (a,b) + + Now to verify with y=g^x mod p, a and b + + 1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k) + = g^(xa + (M - xa)) + = g^M [all mod p] + + 2. Compare against g^M mod p [based on input hash]. + 3. If result of #2 == result of #1 then signature valid +*/ +int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key) +{ + mp_int a, b, k, m, g, p, p1, tmp; + unsigned char buf[1536]; + unsigned long x, y; + int res, err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* check parameters */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* is the IDX valid ? */ + if (is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + /* make up a random value k, + * since the order of the group is prime + * we need not check if gcd(k, r) is 1 + */ + if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) != + (unsigned long)(sets[key->idx].size)) { + return CRYPT_ERROR_READPRNG; + } + + /* init bignums */ + if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* load k and m */ + if ((err = mp_read_unsigned_bin(&m, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; } +#ifdef FAST_PK + if ((err = mp_read_unsigned_bin(&k, buf, MIN(32,sets[key->idx].size))) != MP_OKAY) { goto error; } +#else + if ((err = mp_read_unsigned_bin(&k, buf, sets[key->idx].size)) != MP_OKAY) { goto error; } +#endif + + /* load g, p and p1 */ + if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = mp_sub_d(&p, 1, &p1)) != MP_OKAY) { goto error; } + if ((err = mp_div_2(&p1, &p1)) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */ + + /* now get a = g^k mod p */ + if ((err = mp_exptmod(&g, &k, &p, &a)) != MP_OKAY) { goto error; } + + /* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */ + if ((err = mp_invmod(&k, &p1, &k)) != MP_OKAY) { goto error; } /* k = 1/k mod p1 */ + if ((err = mp_mulmod(&a, &key->x, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = xa */ + if ((err = mp_submod(&m, &tmp, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = M - xa */ + if ((err = mp_mulmod(&k, &tmp, &p1, &b)) != MP_OKAY) { goto error; } /* b = (M - xa)/k */ + + /* store header */ + y = PACKET_SIZE; + + /* now store them both (a,b) */ + x = (unsigned long)mp_unsigned_bin_size(&a); + STORE32L(x, buf+y); y += 4; + if ((err = mp_to_unsigned_bin(&a, buf+y)) != MP_OKAY) { goto error; } + y += x; + + x = (unsigned long)mp_unsigned_bin_size(&b); + STORE32L(x, buf+y); y += 4; + if ((err = mp_to_unsigned_bin(&b, buf+y)) != MP_OKAY) { goto error; } + y += x; + + /* check if size too big */ + if (*outlen < y) { + res = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* store header */ + packet_store_header(buf, PACKET_SECT_DH, PACKET_SUB_SIGNED); + + /* store it */ + memcpy(out, buf, (size_t)y); + *outlen = y; +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + res = CRYPT_OK; + goto done; +error: + res = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL); + return res; +} + +int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key) +{ + mp_int a, b, p, g, m, tmp; + unsigned long x, y; + int res, err; + + _ARGCHK(sig != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* default to invalid */ + *stat = 0; + + /* check initial input length */ + if (siglen < PACKET_SIZE+4+4) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= PACKET_SIZE + 4 + 4; + } + + /* header ok? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get hash out of packet */ + y = PACKET_SIZE; + + /* init all bignums */ + if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* load a and b */ + LOAD32L(x, sig+y); + if (siglen < x) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= x; + } + + y += 4; + if ((err = mp_read_unsigned_bin(&a, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; } + y += x; + + LOAD32L(x, sig+y); + if (siglen < x) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= x; + } + y += 4; + if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; } + y += x; + + /* load p and g */ + if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; } + + /* load m */ + if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error; } + + /* find g^m mod p */ + if ((err = mp_exptmod(&g, &m, &p, &m)) != MP_OKAY) { goto error; } /* m = g^m mod p */ + + /* find y^a * a^b */ + if ((err = mp_exptmod(&key->y, &a, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = y^a mod p */ + if ((err = mp_exptmod(&a, &b, &p, &a)) != MP_OKAY) { goto error; } /* a = a^b mod p */ + if ((err = mp_mulmod(&a, &tmp, &p, &a)) != MP_OKAY) { goto error; } /* a = y^a * a^b mod p */ + + /* y^a * a^b == g^m ??? */ + if (mp_cmp(&a, &m) == 0) { + *stat = 1; + } + + /* clean up */ + res = CRYPT_OK; + goto done; +error: + res = mpi_to_ltc_error(err); +done: + mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL); + return res; +} + diff --git a/tnl-1.5.0/tnl/libtomcrypt/dsa.c b/tnl-1.5.0/tnl/libtomcrypt/dsa.c new file mode 100644 index 0000000000000000000000000000000000000000..fe0e75a0cefc56d96cec6032a7c079e17544acfc --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/dsa.c @@ -0,0 +1,498 @@ +#include "mycrypt.h" + +#ifdef MDSA + +#define DRAW(x) { char __buf[1000]; mp_toradix(x, __buf, 16); printf("\n%s == %s\n", #x, __buf); } + +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) +{ + mp_int tmp, tmp2; + int err, res; + unsigned char buf[512]; + + _ARGCHK(prng != NULL); + _ARGCHK(key != NULL); + + /* check prng */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (group_size >= 1024 || group_size <= 15 || + group_size >= modulus_size || (modulus_size - group_size) >= (int)sizeof(buf)) { + return CRYPT_INVALID_ARG; + } + + /* init mp_ints */ + if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* make our prime q */ + if ((err = rand_prime(&key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error2; } + + /* double q */ + if ((err = mp_mul_2(&key->q, &tmp)) != MP_OKAY) { goto error; } + + /* now make a random string and multply it against q */ + if (prng_descriptor[wprng].read(buf, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { + err = CRYPT_ERROR_READPRNG; + goto error2; + } + + /* force magnitude */ + buf[0] |= 0x80; + + /* force even */ + buf[modulus_size - group_size - 1] &= ~1; + + if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY) { goto error; } + + /* now loop until p is prime */ + for (;;) { + if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { goto error2; } + if (res == MP_YES) break; + + /* add 2q to p and 2 to tmp2 */ + if ((err = mp_add(&tmp, &key->p, &key->p)) != MP_OKAY) { goto error; } + if ((err = mp_add_d(&tmp2, 2, &tmp2)) != MP_OKAY) { goto error; } + } + + /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ + mp_set(&key->g, 1); + + do { + if ((err = mp_add_d(&key->g, 1, &key->g)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != MP_OKAY) { goto error; } + } while (mp_cmp_d(&tmp, 1) == MP_EQ); + + /* at this point tmp generates a group of order q mod p */ + mp_exch(&tmp, &key->g); + + /* so now we have our DH structure, generator g, order q, modulus p + Now we need a random exponent [mod q] and it's power g^x mod p + */ + do { + if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { + err = CRYPT_ERROR_READPRNG; + goto error2; + } + if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY) { goto error; } + } while (mp_cmp_d(&key->x, 1) != MP_GT); + if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY) { goto error; } + + key->type = PK_PRIVATE; + key->qord = group_size; + + /* shrink the ram required */ + if ((err = mp_shrink(&key->g)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; } + if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; } + + err = CRYPT_OK; + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + + goto done; +error : err = mpi_to_ltc_error(err); +error2: mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); +done : mp_clear_multi(&tmp, &tmp2, NULL); + return err; +} + +void dsa_free(dsa_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL); +} + + +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key) +{ + mp_int k, kinv, tmp, r, s; + unsigned char buf[512]; + int err, y; + unsigned long len; + + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(prng != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* check group order size */ + if (key->qord >= (int)sizeof(buf)) { + return CRYPT_INVALID_ARG; + } + + /* Init our temps */ + if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY) { goto error; } + +retry: + /* gen random k */ + if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { + err = CRYPT_ERROR_READPRNG; + goto done; + } + + /* read k */ + if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY) { goto error; } + + /* now find 1/k mod q */ + if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY) { goto error; } + + /* now find r = g^k mod p mod q */ + if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY) { goto error; } + + if (mp_iszero(&r) == MP_YES) { goto retry; } + + /* now find s = (in + xr)/k mod q */ + if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY) { goto error; } + if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY) { goto error; } + + if (mp_iszero(&s) == MP_YES) { goto retry; } + + /* now store em both */ + + /* first check that we have enough room */ + if (*outlen < (unsigned long)(PACKET_SIZE + 4 + mp_unsigned_bin_size(&s) + mp_unsigned_bin_size(&r))) { + err = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* packet header */ + packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_SIGNED); + y = PACKET_SIZE; + + /* store length of r */ + len = mp_unsigned_bin_size(&r); + out[y++] = (len>>8)&255; + out[y++] = (len & 255); + + /* store r */ + mp_to_unsigned_bin(&r, out+y); + y += len; + + /* store length of s */ + len = mp_unsigned_bin_size(&s); + out[y++] = (len>>8)&255; + out[y++] = (len & 255); + + /* store s */ + mp_to_unsigned_bin(&s, out+y); + y += len; + + /* reset size */ + *outlen = y; + + err = CRYPT_OK; + goto done; + +error : err = mpi_to_ltc_error(err); +done : mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, dsa_key *key) +{ + mp_int r, s, w, v, u1, u2; + unsigned long x, y; + int err; + + _ARGCHK(sig != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + if (siglen < PACKET_SIZE+2+2) { + return CRYPT_INVALID_PACKET; + } + + /* is the message format correct? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DSA, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* skip over header */ + y = PACKET_SIZE; + + /* init our variables */ + if ((err = mp_init_multi(&r, &s, &w, &v, &u1, &u2, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* read in r followed by s */ + x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]); + y += 2; + if (y + x > siglen) { + err = CRYPT_INVALID_PACKET; + goto done; + } + if ((err = mp_read_unsigned_bin(&r, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; } + y += x; + + /* load s */ + x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]); + y += 2; + if (y + x > siglen) { + err = CRYPT_INVALID_PACKET; + goto done; + } + if ((err = mp_read_unsigned_bin(&s, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; } + + /* w = 1/s mod q */ + if ((err = mp_invmod(&s, &key->q, &w)) != MP_OKAY) { goto error; } + + /* u1 = m * w mod q */ + if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, inlen)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY) { goto error; } + + /* u2 = r*w mod q */ + if ((err = mp_mulmod(&r, &w, &key->q, &u2)) != MP_OKAY) { goto error; } + + /* v = g^u1 * y^u2 mod p mod q */ + if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY) { goto error; } + + /* if r = v then we're set */ + if (mp_cmp(&r, &v) == MP_EQ) { + *stat = 1; + } + + err = CRYPT_OK; + goto done; + +error : err = mpi_to_ltc_error(err); +done : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL); + return err; +} + +#define OUTPUT_BIGNUM(num, buf2, y, z) \ +{ \ + z = (unsigned long)mp_unsigned_bin_size(num); \ + if ((y + 4 + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \ + STORE32L(z, out+y); \ + y += 4; \ + if (mp_to_unsigned_bin(num, out+y) != MP_OKAY) { return CRYPT_MEM; } \ + y += z; \ +} + +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) +{ + unsigned long y, z; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + if (type == PK_PRIVATE && key->type != PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + if (type != PK_PUBLIC && type != PK_PRIVATE) { + return CRYPT_INVALID_ARG; + } + + /* can we store the static header? */ + if (*outlen < (PACKET_SIZE + 1 + 2)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY); + y = PACKET_SIZE; + + /* store g, p, q, qord */ + out[y++] = type; + out[y++] = (key->qord>>8)&255; + out[y++] = key->qord & 255; + + OUTPUT_BIGNUM(&key->g,out,y,z); + OUTPUT_BIGNUM(&key->p,out,y,z); + OUTPUT_BIGNUM(&key->q,out,y,z); + + /* public exponent */ + OUTPUT_BIGNUM(&key->y,out,y,z); + + if (type == PK_PRIVATE) { + OUTPUT_BIGNUM(&key->x,out,y,z); + } + + *outlen = y; + return CRYPT_OK; +} + +#define INPUT_BIGNUM(num, in, x, y) \ +{ \ + /* load value */ \ + if (y+4 > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + LOAD32L(x, in+y); \ + y += 4; \ + \ + /* sanity check... */ \ + if (y+x > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + \ + /* load it */ \ + if (mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x) != MP_OKAY) {\ + err = CRYPT_MEM; \ + goto error; \ + } \ + y += x; \ + if (mp_shrink(num) != MP_OKAY) { \ + err = CRYPT_MEM; \ + goto error; \ + } \ +} + +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) +{ + unsigned long x, y; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* check length */ + if ((1+2+PACKET_SIZE) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DSA, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + y = PACKET_SIZE; + + /* init key */ + if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + /* read type/qord */ + key->type = in[y++]; + key->qord = ((unsigned)in[y]<<8)|((unsigned)in[y+1]); + y += 2; + + /* input publics */ + INPUT_BIGNUM(&key->g,in,x,y); + INPUT_BIGNUM(&key->p,in,x,y); + INPUT_BIGNUM(&key->q,in,x,y); + INPUT_BIGNUM(&key->y,in,x,y); + if (key->type == PK_PRIVATE) { + INPUT_BIGNUM(&key->x,in,x,y); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); + return err; +} + +int dsa_verify_key(dsa_key *key, int *stat) +{ + mp_int tmp, tmp2; + int res, err; + + _ARGCHK(key != NULL); + _ARGCHK(stat != NULL); + + *stat = 0; + + /* first make sure key->q and key->p are prime */ + if ((err = is_prime(&key->q, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + + if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { + return err; + } + if (res == 0) { + return CRYPT_OK; + } + + /* now make sure that g is not -1, 0 or 1 and

g, 0) == MP_EQ || mp_cmp_d(&key->g, 1) == MP_EQ) { + return CRYPT_OK; + } + if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != MP_OKAY) { goto error; } + if ((err = mp_sub_d(&key->p, 1, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp(&tmp, &key->g) == MP_EQ || mp_cmp(&key->g, &key->p) != MP_LT) { + err = CRYPT_OK; + goto done; + } + + /* 1 < y < p-1 */ + if (!(mp_cmp_d(&key->y, 1) == MP_GT && mp_cmp(&key->y, &tmp) == MP_LT)) { + err = CRYPT_OK; + goto done; + } + + /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */ + if ((err = mp_div(&tmp, &key->q, &tmp, &tmp2)) != MP_OKAY) { goto error; } + if (mp_iszero(&tmp2) != MP_YES) { + err = CRYPT_OK; + goto done; + } + + if ((err = mp_exptmod(&key->g, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&tmp, 1) != MP_EQ) { + err = CRYPT_OK; + goto done; + } + + /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */ + if ((err = mp_exptmod(&key->y, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; } + if (mp_cmp_d(&tmp, 1) != MP_EQ) { + err = CRYPT_OK; + goto done; + } + + /* at this point we are out of tests ;-( */ + err = CRYPT_OK; + *stat = 1; + goto done; +error: err = mpi_to_ltc_error(err); +done : mp_clear_multi(&tmp, &tmp2, NULL); + return err; +} +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/ecb.c b/tnl-1.5.0/tnl/libtomcrypt/ecb.c new file mode 100644 index 0000000000000000000000000000000000000000..0c04881c952e5e34817abce4b0064024bf081e9c --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/ecb.c @@ -0,0 +1,49 @@ +#include "mycrypt.h" + +#ifdef ECB + +int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb) +{ + int err; + _ARGCHK(key != NULL); + _ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + ecb->cipher = cipher; + ecb->blocklen = cipher_descriptor[cipher].block_length; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key); +} + +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb) +{ + int err; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key); + return CRYPT_OK; +} + +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb) +{ + int err; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ecb != NULL); + + if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { + return err; + } + cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); + return CRYPT_OK; +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/ecc.c b/tnl-1.5.0/tnl/libtomcrypt/ecc.c new file mode 100644 index 0000000000000000000000000000000000000000..13c23da64fd7bd585785ef2913c937639eb0af0b --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/ecc.c @@ -0,0 +1,975 @@ +/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b + * + * All curves taken from NIST recommendation paper of July 1999 + * Available at http://csrc.nist.gov/cryptval/dss.htm + */ + +#include "mycrypt.h" + +#ifdef MECC + +/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ +static const struct { + int size; + char *name, *prime, *B, *order, *Gx, *Gy; +} sets[] = { +#ifdef ECC160 +{ + 20, + "ECC-160", + /* prime */ + "G00000000000000000000000007", + /* B */ + "1oUV2vOaSlWbxr6", + /* order */ + "G0000000000004sCQUtDxaqDUN5", + /* Gx */ + "jpqOf1BHus6Yd/pyhyVpP", + /* Gy */ + "D/wykuuIFfr+vPyx7kQEPu8MixO", +}, +#endif +#ifdef ECC192 +{ + 24, + "ECC-192", + /* prime */ + "/////////////////////l//////////", + + /* B */ + "P2456UMSWESFf+chSYGmIVwutkp1Hhcn", + + /* order */ + "////////////////cTxuDXHhoR6qqYWn", + + /* Gx */ + "68se3h0maFPylo3hGw680FJ/2ls2/n0I", + + /* Gy */ + "1nahbV/8sdXZ417jQoJDrNFvTw4UUKWH" +}, +#endif +#ifdef ECC224 +{ + 28, + "ECC-224", + + /* prime */ + "400000000000000000000000000000000000BV", + + /* B */ + "21HkWGL2CxJIp", + + /* order */ + "4000000000000000000Kxnixk9t8MLzMiV264/", + + /* Gx */ + "jpqOf1BHus6Yd/pyhyVpP", + + /* Gy */ + "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck", +}, +#endif +#ifdef ECC256 +{ + 32, + "ECC-256", + /* Prime */ + "F////y000010000000000000000////////////////", + + /* B */ + "5h6DTYgEfFdi+kzLNQOXhnb7GQmp5EmzZlEF3udqc1B", + + /* Order */ + "F////y00000//////////+yvlgjfnUUXFEvoiByOoLH", + + /* Gx */ + "6iNqVBXB497+BpcvMEaGF9t0ts1BUipeFIXEKNOcCAM", + + /* Gy */ + "4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r" +}, +#endif +#ifdef ECC384 +{ + 48, + "ECC-384", + /* prime */ + "//////////////////////////////////////////x/////00000000003/" + "////", + + /* B */ + "ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ" + "x2hl", + + /* Order */ + "////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC" + "nIbp", + + /* Gx and Gy */ + "geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo" + "TWgt", + + "DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG" + "wWvV" +}, +#endif +#ifdef ECC521 +{ + 65, + "ECC-521", + /* prime */ + "V///////////////////////////////////////////////////////////" + "///////////////////////////", + + /* B */ + "56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l" + "JknlmSrSz+8FImqyUz57zHhK3y0", + + /* Order */ + "V//////////////////////////////////////////+b66XuE/BvPhVym1I" + "FS9fT0xjScuYPn7hhjljnwHE6G9", + + /* Gx and Gy */ + "CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19" + "wB/gDupIBF1XMf2c/b+VZ72vRrc", + + "HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0" + "J+j1s4rF726edB2G8Y+b7QVqMPG", +}, +#endif +{ + 0, + NULL, NULL, NULL, NULL, NULL, NULL +} +}; + +#if 0 + +/* you plug in a prime and B value and it finds a pseudo-random base point */ +void ecc_find_base(void) +{ + static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951"; + static char *order = "26959946667150639794667015087019637467111563745054605861463538557247"; + static char *b = "9538957348957353489587"; + mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y; + char buf[4096]; + int i; + + mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL); + mp_read_radix(&p, prime, 10); + mp_read_radix(&r, order, 10); + mp_read_radix(&B, b, 10); + + /* get (p+1)/4 */ + mp_add_d(&p, 1, &pp); + mp_div_2(&pp, &pp); + mp_div_2(&pp, &pp); + + buf[0] = 0; + do { + printf("."); fflush(stdout); + /* make a random value of x */ + for (i = 0; i < 16; i++) buf[i+1] = rand() & 255; + mp_read_raw(&x, buf, 17); + mp_copy(&x, &tx); + + /* now compute x^3 - 3x + b */ + mp_expt_d(&x, 3, &tmp1); + mp_mul_d(&x, 3, &tmp2); + mp_sub(&tmp1, &tmp2, &tmp1); + mp_add(&tmp1, &B, &tmp1); + mp_mod(&tmp1, &p, &tmp1); + + /* now compute sqrt via x^((p+1)/4) */ + mp_exptmod(&tmp1, &pp, &p, &tmp2); + mp_copy(&tmp2, &ty); + + /* now square it */ + mp_sqrmod(&tmp2, &p, &tmp2); + + /* tmp2 should equal tmp1 */ + } while (mp_cmp(&tmp1, &tmp2)); + + /* now output values in way that libtomcrypt wants */ + mp_todecimal(&p, buf); + printf("\n\np==%s\n", buf); + mp_tohex(&B, buf); + printf("b==%s\n", buf); + mp_todecimal(&r, buf); + printf("r==%s\n", buf); + mp_tohex(&tx, buf); + printf("Gx==%s\n", buf); + mp_tohex(&ty, buf); + printf("Gy==%s\n", buf); + + mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL); +} + +#endif + +static int is_valid_idx(int n) +{ + int x; + + for (x = 0; sets[x].size != 0; x++); + if ((n < 0) || (n >= x)) { + return 0; + } + return 1; +} + +static ecc_point *new_point(void) +{ + ecc_point *p; + p = XMALLOC(sizeof(ecc_point)); + if (p == NULL) { + return NULL; + } + if (mp_init_multi(&p->x, &p->y, NULL) != MP_OKAY) { + XFREE(p); + return NULL; + } + return p; +} + +static void del_point(ecc_point *p) +{ + /* prevents free'ing null arguments */ + if (p == NULL) { + return; + } else { + mp_clear_multi(&p->x, &p->y, NULL); + XFREE(p); + } +} + +/* double a point R = 2P, R can be P*/ +static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) +{ + mp_int s, tmp, tmpx; + int res; + + if ((res = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(res); + } + + /* s = (3Xp^2 + a) / (2Yp) */ + if ((res = mp_mul_2(&P->y, &tmp)) != MP_OKAY) { goto error; } /* tmp = 2*y */ + if ((res = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ + if ((res = mp_sqr(&P->x, &s)) != MP_OKAY) { goto error; } /* s = x^2 */ + if ((res = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + if ((res = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) */ + if ((res = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */ + if (mp_cmp_d(&s, 0) == MP_LT) { /* if s < 0 add modulus */ + if ((res = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; } + } + if ((res = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */ + if ((res = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + + /* Xr = s^2 - 2Xp */ + if ((res = mp_sqr(&s, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = s^2 */ + if ((res = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY) { goto error; } /* tmpx = tmpx mod modulus */ + if ((res = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x */ + if ((res = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */ + + /* Yr = -Yp + s(Xp - Xr) */ + if ((res = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = x - tmpx */ + if ((res = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */ + if ((res = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* y = tmp - y mod modulus */ + if ((res = mp_copy(&tmpx, &R->x)) != MP_OKAY) { goto error; } /* x = tmpx */ + + res = CRYPT_OK; + goto done; +error: + res = mpi_to_ltc_error(res); +done: + mp_clear_multi(&tmpx, &tmp, &s, NULL); + return res; +} + +/* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */ +static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu) +{ + mp_int s, tmp, tmpx; + int res; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return mpi_to_ltc_error(res); + } + + /* is P==Q or P==-Q? */ + if (((res = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((res = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) { + mp_clear(&tmp); + return mpi_to_ltc_error(res); + } + + if (mp_cmp(&P->x, &Q->x) == MP_EQ) + if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) { + mp_clear(&tmp); + return dbl_point(P, R, modulus, mu); + } + + if ((res = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) { + mp_clear(&tmp); + return mpi_to_ltc_error(res); + } + + /* get s = (Yp - Yq)/(Xp-Xq) mod p */ + if ((res = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - Qx mod modulus */ + if (mp_cmp_d(&tmp, 0) == MP_LT) { /* if tmp<0 add modulus */ + if ((res = mp_add(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } + } + if ((res = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ + if ((res = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY) { goto error; } /* s = Py - Qy mod modulus */ + if (mp_cmp_d(&s, 0) == MP_LT) { /* if s<0 add modulus */ + if ((res = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; } + } + if ((res = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = s * tmp mod modulus */ + if ((res = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; } + + /* Xr = s^2 - Xp - Xq */ + if ((res = mp_sqr(&s, &tmp)) != MP_OKAY) { goto error; } /* tmp = s^2 mod modulus */ + if ((res = mp_reduce(&tmp, modulus, mu)) != MP_OKAY) { goto error; } + if ((res = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - Px */ + if ((res = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmp - Qx */ + + /* Yr = -Yp + s(Xp - Xr) */ + if ((res = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - tmpx */ + if ((res = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */ + if ((res = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* Ry = tmp - Py mod modulus */ + if ((res = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY) { goto error; } /* Rx = tmpx mod modulus */ + + res = CRYPT_OK; + goto done; +error: + res = mpi_to_ltc_error(res); +done: + mp_clear_multi(&s, &tmpx, &tmp, NULL); + return res; +} + +/* size of sliding window, don't change this! */ +#define WINSIZE 4 + +/* perform R = kG where k == integer and G == ecc_point */ +static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) +{ + ecc_point *tG, *M[8]; + int i, j, res; + mp_int mu; + mp_digit buf; + int first, bitbuf, bitcpy, bitcnt, mode, digidx; + + /* init barrett reduction */ + if ((res = mp_init(&mu)) != MP_OKAY) { + return mpi_to_ltc_error(res); + } + if ((res = mp_reduce_setup(&mu, modulus)) != MP_OKAY) { + mp_clear(&mu); + return mpi_to_ltc_error(res); + } + + /* alloc ram for window temps */ + for (i = 0; i < 8; i++) { + M[i] = new_point(); + if (M[i] == NULL) { + for (j = 0; j < i; j++) { + del_point(M[j]); + } + mp_clear(&mu); + return CRYPT_MEM; + } + } + + /* make a copy of G incase R==G */ + tG = new_point(); + if (tG == NULL) { goto error; } + + /* calc the M tab, which holds kG for k==8..15 */ + /* M[0] == 8G */ + if (dbl_point(G, M[0], modulus, &mu) != CRYPT_OK) { goto error; } + if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; } + if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; } + + /* now find (8+k)G for k=1..7 */ + for (j = 9; j < 16; j++) { + if (add_point(M[j-9], G, M[j-8], modulus, &mu) != CRYPT_OK) { goto error; } + } + + /* tG = G */ + if (mp_copy(&G->x, &tG->x) != MP_OKAY) { goto error; } + if (mp_copy(&G->y, &tG->y) != MP_OKAY) { goto error; } + + /* setup sliding window */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = k->used - 1; + bitcpy = bitbuf = 0; + first = 1; + + /* perform ops */ + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + if (digidx == -1) { + break; + } + buf = k->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the multiplicand */ + i = (buf >> (DIGIT_BIT - 1)) & 1; + buf <<= 1; + + /* skip leading zero bits */ + if (mode == 0 && i == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we double */ + if (mode == 1 && i == 0) { + if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; } + continue; + } + + /* else we add it to the window */ + bitbuf |= (i << (WINSIZE - ++bitcpy)); + mode = 2; + + if (bitcpy == WINSIZE) { + /* if this is the first window we do a simple copy */ + if (first == 1) { + /* R = kG [k = first window] */ + if (mp_copy(&M[bitbuf-8]->x, &R->x) != MP_OKAY) { goto error; } + if (mp_copy(&M[bitbuf-8]->y, &R->y) != MP_OKAY) { goto error; } + first = 0; + } else { + /* normal window */ + /* ok window is filled so double as required and add */ + /* double first */ + for (j = 0; j < WINSIZE; j++) { + if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; } + } + + /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ + if (add_point(R, M[bitbuf-8], R, modulus, &mu) != CRYPT_OK) { goto error; } + } + /* empty window and reset */ + bitcpy = bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then double/add */ + if (mode == 2 && bitcpy > 0) { + /* double then add */ + for (j = 0; j < bitcpy; j++) { + /* only double if we have had at least one add first */ + if (first == 0) { + if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; } + } + + bitbuf <<= 1; + if ((bitbuf & (1 << WINSIZE)) != 0) { + if (first == 1){ + /* first add, so copy */ + if (mp_copy(&tG->x, &R->x) != MP_OKAY) { goto error; } + if (mp_copy(&tG->y, &R->y) != MP_OKAY) { goto error; } + first = 0; + } else { + /* then add */ + if (add_point(R, tG, R, modulus, &mu) != CRYPT_OK) { goto error; } + } + } + } + } + res = CRYPT_OK; + goto done; +error: + res = CRYPT_MEM; +done: + del_point(tG); + for (i = 0; i < 8; i++) { + del_point(M[i]); + } + mp_clear(&mu); + return res; +} + +#undef WINSIZE + +int ecc_test(void) +{ + mp_int modulus, order; + ecc_point *G, *GG; + int i, res, primality; + + if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + G = new_point(); + if (G == NULL) { + mp_clear_multi(&modulus, &order, NULL); + return CRYPT_MEM; + } + + GG = new_point(); + if (GG == NULL) { + mp_clear_multi(&modulus, &order, NULL); + del_point(G); + return CRYPT_MEM; + } + + for (i = 0; sets[i].size; i++) { + #if 0 + printf("Testing %d\n", sets[i].size); + #endif + if (mp_read_radix(&modulus, (char *)sets[i].prime, 64) != MP_OKAY) { goto error; } + if (mp_read_radix(&order, (char *)sets[i].order, 64) != MP_OKAY) { goto error; } + + /* is prime actually prime? */ + if (is_prime(&modulus, &primality) != CRYPT_OK) { goto error; } + if (primality == 0) { + res = CRYPT_FAIL_TESTVECTOR; + goto done1; + } + + /* is order prime ? */ + if (is_prime(&order, &primality) != CRYPT_OK) { goto error; } + if (primality == 0) { + res = CRYPT_FAIL_TESTVECTOR; + goto done1; + } + + if (mp_read_radix(&G->x, (char *)sets[i].Gx, 64) != MP_OKAY) { goto error; } + if (mp_read_radix(&G->y, (char *)sets[i].Gy, 64) != MP_OKAY) { goto error; } + + /* then we should have G == (order + 1)G */ + if (mp_add_d(&order, 1, &order) != MP_OKAY) { goto error; } + if (ecc_mulmod(&order, G, GG, &modulus) != CRYPT_OK) { goto error; } + if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) { + res = CRYPT_FAIL_TESTVECTOR; + goto done1; + } + } + res = CRYPT_OK; + goto done1; +error: + res = CRYPT_MEM; +done1: + del_point(GG); + del_point(G); + mp_clear_multi(&order, &modulus, NULL); + return res; +} + +void ecc_sizes(int *low, int *high) +{ + int i; + _ARGCHK(low != NULL); + _ARGCHK(high != NULL); + + *low = INT_MAX; + *high = 0; + for (i = 0; sets[i].size != 0; i++) { + if (sets[i].size < *low) { + *low = sets[i].size; + } + if (sets[i].size > *high) { + *high = sets[i].size; + } + } +} + +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) +{ + int x, res, err; + ecc_point *base; + mp_int prime; + unsigned char buf[128]; + + _ARGCHK(key != NULL); + + /* good prng? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* find key size */ + for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); + keysize = sets[x].size; + + if (sets[x].size == 0) { + return CRYPT_INVALID_KEYSIZE; + } + key->idx = x; + + /* make up random string */ + if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { + return CRYPT_ERROR_READPRNG; + } + + /* setup the key variables */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + base = new_point(); + if (base == NULL) { + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL); + return CRYPT_MEM; + } + + /* read in the specs for this key */ + if (mp_read_radix(&prime, (char *)sets[key->idx].prime, 64) != MP_OKAY) { goto error; } + if (mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64) != MP_OKAY) { goto error; } + if (mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64) != MP_OKAY) { goto error; } + if (mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize) != MP_OKAY) { goto error; } + + /* make the public key */ + if (ecc_mulmod(&key->k, base, &key->pubkey, &prime) != CRYPT_OK) { goto error; } + key->type = PK_PRIVATE; + + /* shrink key */ + if (mp_shrink(&key->k) != MP_OKAY) { goto error; } + if (mp_shrink(&key->pubkey.x) != MP_OKAY) { goto error; } + if (mp_shrink(&key->pubkey.y) != MP_OKAY) { goto error; } + + /* free up ram */ + res = CRYPT_OK; + goto done; +error: + res = CRYPT_MEM; +done: + del_point(base); + mp_clear(&prime); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return res; +} + +void ecc_free(ecc_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); +} + +static int compress_y_point(ecc_point *pt, int idx, int *result) +{ + mp_int tmp, tmp2, p; + int res; + + _ARGCHK(pt != NULL); + _ARGCHK(result != NULL); + + if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + /* get x^3 - 3x + b */ + if (mp_read_radix(&p, (char *)sets[idx].B, 64) != MP_OKAY) { goto error; } /* p = B */ + if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */ + if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ + if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ + if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */ + if (mp_read_radix(&p, (char *)sets[idx].prime, 64) != MP_OKAY) { goto error; } /* p = prime */ + if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ + + /* now find square root */ + if (mp_add_d(&p, 1, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */ + if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = tmp2/2 */ + if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */ + if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ + + /* if tmp equals the y point give a 0, otherwise 1 */ + if (mp_cmp(&tmp, &pt->y) == 0) { + *result = 0; + } else { + *result = 1; + } + + res = CRYPT_OK; + goto done; +error: + res = CRYPT_MEM; +done: + mp_clear_multi(&p, &tmp, &tmp2, NULL); + return res; +} + +static int expand_y_point(ecc_point *pt, int idx, int result) +{ + mp_int tmp, tmp2, p; + int res; + + _ARGCHK(pt != NULL); + + if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + /* get x^3 - 3x + b */ + if (mp_read_radix(&p, (char *)sets[idx].B, 64) != MP_OKAY) { goto error; } /* p = B */ + if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */ + if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ + if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ + if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */ + if (mp_read_radix(&p, (char *)sets[idx].prime, 64) != MP_OKAY) { goto error; } /* p = prime */ + if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ + + /* now find square root */ + if (mp_add_d(&p, 1, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */ + if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = tmp2/2 */ + if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */ + if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ + + /* if result==0, then y==tmp, otherwise y==p-tmp */ + if (result == 0) { + if (mp_copy(&tmp, &pt->y) != MP_OKAY) { goto error; } + } else { + if (mp_sub(&p, &tmp, &pt->y) != MP_OKAY) { goto error; } + } + + res = CRYPT_OK; + goto done; +error: + res = CRYPT_MEM; +done: + mp_clear_multi(&p, &tmp, &tmp2, NULL); + return res; +} + +#define OUTPUT_BIGNUM(num, buf2, y, z) \ +{ \ + z = (unsigned long)mp_unsigned_bin_size(num); \ + STORE32L(z, buf2+y); \ + y += 4; \ + if (mp_to_unsigned_bin(num, buf2+y) != MP_OKAY) { return CRYPT_MEM; } \ + y += z; \ +} + + +#define INPUT_BIGNUM(num, in, x, y) \ +{ \ + /* load value */ \ + if (y+4 > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + LOAD32L(x, in+y); \ + y += 4; \ + \ + /* sanity check... */ \ + if (y+x > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error; \ + } \ + \ + /* load it */ \ + if (mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x) != MP_OKAY) {\ + err = CRYPT_MEM; \ + goto error; \ + } \ + y += x; \ + if (mp_shrink(num) != MP_OKAY) { \ + err = CRYPT_MEM; \ + goto error; \ + } \ +} + +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) +{ + unsigned long y, z; + int res, err; + unsigned char buf2[512]; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* type valid? */ + if (key->type != PK_PRIVATE && type == PK_PRIVATE) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* output type and magic byte */ + y = PACKET_SIZE; + buf2[y++] = (unsigned char)type; + buf2[y++] = (unsigned char)sets[key->idx].size; + + /* output x coordinate */ + OUTPUT_BIGNUM(&(key->pubkey.x), buf2, y, z); + + /* compress y and output it */ + if ((err = compress_y_point(&key->pubkey, key->idx, &res)) != CRYPT_OK) { + return err; + } + buf2[y++] = (unsigned char)res; + + if (type == PK_PRIVATE) { + OUTPUT_BIGNUM(&key->k, buf2, y, z); + } + + /* check size */ + if (*outlen < y) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header */ + packet_store_header(buf2, PACKET_SECT_ECC, PACKET_SUB_KEY); + + memcpy(out, buf2, (size_t)y); + *outlen = y; + + #ifdef CLEAN_STACK + zeromem(buf2, sizeof(buf2)); + #endif + return CRYPT_OK; +} + +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) +{ + unsigned long x, y, s; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* check length */ + if (2+PACKET_SIZE > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* check type */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init key */ + if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + y = PACKET_SIZE; + key->type = (int)in[y++]; + s = (unsigned long)in[y++]; + + for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++); + if (sets[x].size == 0) { + err = CRYPT_INVALID_KEYSIZE; + goto error; + } + key->idx = (int)x; + + /* type check both values */ + if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* is the key idx valid? */ + if (is_valid_idx(key->idx) != 1) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* load x coordinate */ + INPUT_BIGNUM(&key->pubkey.x, in, x, y); + + /* load y */ + x = (unsigned long)in[y++]; + if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) { + goto error; + } + + if (key->type == PK_PRIVATE) { + /* load private key */ + INPUT_BIGNUM(&key->k, in, x, y); + } + + /* eliminate private key if public */ + if (key->type == PK_PUBLIC) { + mp_clear(&key->k); + } + + return CRYPT_OK; +error: + mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); + return err; +} + +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y; + ecc_point *result; + mp_int prime; + int res; + + _ARGCHK(private_key != NULL); + _ARGCHK(public_key != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* type valid? */ + if (private_key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + if (private_key->idx != public_key->idx) { + return CRYPT_PK_TYPE_MISMATCH; + } + + /* make new point */ + result = new_point(); + if (result == NULL) { + return CRYPT_MEM; + } + + if (mp_init(&prime) != MP_OKAY) { + del_point(result); + return CRYPT_MEM; + } + + if (mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; } + if ((res = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; } + + x = (unsigned long)mp_unsigned_bin_size(&result->x); + y = (unsigned long)mp_unsigned_bin_size(&result->y); + + if (*outlen < (x+y)) { + res = CRYPT_BUFFER_OVERFLOW; + goto done1; + } + *outlen = x+y; + if (mp_to_unsigned_bin(&result->x, out) != MP_OKAY) { goto error; } + if (mp_to_unsigned_bin(&result->y, out+x) != MP_OKAY) { goto error; } + + res = CRYPT_OK; + goto done1; +error: + res = CRYPT_MEM; +done1: + mp_clear(&prime); + del_point(result); + return res; +} + +int ecc_get_size(ecc_key *key) +{ + _ARGCHK(key != NULL); + if (is_valid_idx(key->idx)) + return sets[key->idx].size; + else + return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ +} + +#include "ecc_sys.c" + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/ecc_sys.c b/tnl-1.5.0/tnl/libtomcrypt/ecc_sys.c new file mode 100644 index 0000000000000000000000000000000000000000..cae3614772fa89e28d229f34b9988a7d5598862d --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/ecc_sys.c @@ -0,0 +1,424 @@ +int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + ecc_key *key) +{ + unsigned char pub_expt[256], ecc_shared[256], skey[MAXBLOCKSIZE]; + ecc_key pubkey; + unsigned long x, y, z, hashsize, pubkeysize; + int err; + + _ARGCHK(inkey != NULL); + _ARGCHK(out != NULL); + _ARGCHK(len != NULL); + _ARGCHK(key != NULL); + + /* check that wprng/cipher/hash are not invalid */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (keylen > hash_descriptor[hash].hashsize) { + return CRYPT_INVALID_HASH; + } + + /* make a random key and export the public copy */ + if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } + + pubkeysize = (unsigned long)sizeof(pub_expt); + if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + + /* now check if the out buffer is big enough */ + if (*len < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) { + ecc_free(&pubkey); + return CRYPT_BUFFER_OVERFLOW; + } + + /* make random key */ + hashsize = hash_descriptor[hash].hashsize; + x = (unsigned long)sizeof(ecc_shared); + if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + ecc_free(&pubkey); + z = (unsigned long)sizeof(skey); + if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) { + return err; + } + + /* output header */ + y = PACKET_SIZE; + + /* size of hash name and the name itself */ + out[y++] = hash_descriptor[hash].ID; + + /* length of ECC pubkey and the key itself */ + STORE32L(pubkeysize, out+y); + y += 4; + + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = pub_expt[x]; + } + + STORE32L(keylen, out+y); + y += 4; + + /* Encrypt/Store the encrypted key */ + for (x = 0; x < keylen; x++, y++) { + out[y] = skey[x] ^ inkey[x]; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY); + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(pub_expt, sizeof(pub_expt)); + zeromem(ecc_shared, sizeof(ecc_shared)); + zeromem(skey, sizeof(skey)); +#endif + *len = y; + return CRYPT_OK; +} + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + ecc_key *key) +{ + unsigned char shared_secret[256], skey[MAXBLOCKSIZE]; + unsigned long x, y, z, hashsize, keysize; + int hash, res, err; + ecc_key pubkey; + + _ARGCHK(in != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(keylen != NULL); + _ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* correct length ? */ + if (inlen < PACKET_SIZE+1+4+4) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= PACKET_SIZE+1+4+4; + } + + /* is header correct? */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + return err; + } + + /* now lets get the hash name */ + y = PACKET_SIZE; + hash = find_hash_id(in[y++]); + if (hash == -1) { + return CRYPT_INVALID_HASH; + } + + /* common values */ + hashsize = hash_descriptor[hash].hashsize; + + /* get public key */ + LOAD32L(x, in+y); + if (inlen < x) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= x; + } + y += 4; + if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) { + return err; + } + y += x; + + /* make shared key */ + x = (unsigned long)sizeof(shared_secret); + if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + ecc_free(&pubkey); + + z = (unsigned long)sizeof(skey); + if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { + return err; + } + + LOAD32L(keysize, in+y); + if (inlen < keysize) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= keysize; + } + y += 4; + + if (*keylen < keysize) { + res = CRYPT_BUFFER_OVERFLOW; + goto done; + } + + /* Decrypt the key */ + for (x = 0; x < keysize; x++, y++) { + outkey[x] = skey[x] ^ in[y]; + } + + *keylen = keysize; + + res = CRYPT_OK; +done: +#ifdef CLEAN_STACK + zeromem(shared_secret, sizeof(shared_secret)); + zeromem(skey, sizeof(skey)); +#endif + return res; +} + +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key) +{ + ecc_key pubkey; + mp_int b, p; + unsigned char epubkey[256], er[256]; + unsigned long x, y, pubkeysize, rsize; + int res, err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* is this a private key? */ + if (key->type != PK_PRIVATE) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* is the IDX valid ? */ + if (is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* make up a key and export the public copy */ + if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } + + pubkeysize = (unsigned long)sizeof(epubkey); + if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { + ecc_free(&pubkey); + return err; + } + + /* get the hash and load it as a bignum into 'b' */ + /* init the bignums */ + if (mp_init_multi(&b, &p, NULL) != MP_OKAY) { + ecc_free(&pubkey); + return CRYPT_MEM; + } + if (mp_read_radix(&p, (char *)sets[key->idx].order, 64) != MP_OKAY) { goto error; } + if (mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen) != MP_OKAY) { goto error; } + + /* find b = (m - x)/k */ + if (mp_invmod(&pubkey.k, &p, &pubkey.k) != MP_OKAY) { goto error; } /* k = 1/k */ + if (mp_submod(&b, &key->k, &p, &b) != MP_OKAY) { goto error; } /* b = m - x */ + if (mp_mulmod(&b, &pubkey.k, &p, &b) != MP_OKAY) { goto error; } /* b = (m - x)/k */ + + /* export it */ + rsize = (unsigned long)mp_unsigned_bin_size(&b); + if (rsize > (unsigned long)sizeof(er)) { + goto error; + } + (void)mp_to_unsigned_bin(&b, er); + + /* now lets check the outlen before we write */ + if (*outlen < (12 + rsize + pubkeysize)) { + res = CRYPT_BUFFER_OVERFLOW; + goto done1; + } + + /* lets output */ + y = PACKET_SIZE; + + /* size of public key */ + STORE32L(pubkeysize, out+y); + y += 4; + + /* copy the public key */ + for (x = 0; x < pubkeysize; x++, y++) { + out[y] = epubkey[x]; + } + + /* size of 'r' */ + STORE32L(rsize, out+y); + y += 4; + + /* copy r */ + for (x = 0; x < rsize; x++, y++) { + out[y] = er[x]; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED); + + /* clear memory */ + *outlen = y; + res = CRYPT_OK; + goto done1; +error: + res = CRYPT_MEM; +done1: + mp_clear_multi(&b, &p, NULL); + ecc_free(&pubkey); +#ifdef CLEAN_STACK + zeromem(er, sizeof(er)); + zeromem(epubkey, sizeof(epubkey)); +#endif + return res; +} + +/* verify that mG = (bA + Y) + * + * The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the + * public key Y = xG can verify it. + * + * b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it] + * A = kG therefore bA == ((m-x)/k)kG == (m-x)G + * + * Adding Y = xG to the bA gives us (m-x)G + xG == mG + * + * The user given only xG, kG and b cannot determine k or x which means they can't find the private key. + * + */ +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, ecc_key *key) +{ + ecc_point *mG; + ecc_key pubkey; + mp_int b, p, m, mu; + unsigned long x, y; + int res, err; + + _ARGCHK(sig != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + if (siglen < PACKET_SIZE+4+4) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= PACKET_SIZE+4+4; + } + + /* is the message format correct? */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get hash name */ + y = PACKET_SIZE; + + /* get size of public key */ + LOAD32L(x, sig+y); + if (siglen < x) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= x; + } + y += 4; + + /* load the public key */ + if ((err = ecc_import((unsigned char*)sig+y, x, &pubkey)) != CRYPT_OK) { + return err; + } + y += x; + + /* load size of 'b' */ + LOAD32L(x, sig+y); + if (siglen < x) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= x; + } + y += 4; + + /* init values */ + if (mp_init_multi(&b, &m, &p, &mu, NULL) != MP_OKAY) { + ecc_free(&pubkey); + return CRYPT_MEM; + } + + mG = new_point(); + if (mG == NULL) { + mp_clear_multi(&b, &m, &p, &mu, NULL); + ecc_free(&pubkey); + return CRYPT_MEM; + } + + /* load b */ + if (mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x) != MP_OKAY) { goto error; } + y += x; + + /* get m in binary a bignum */ + if (mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)inlen) != MP_OKAY) { goto error; } + + /* load prime */ + if (mp_read_radix(&p, (char *)sets[key->idx].prime, 64) != MP_OKAY) { goto error; } + + /* calculate barrett stuff */ + mp_set(&mu, 1); + mp_lshd(&mu, 2 * USED(&p)); + if (mp_div(&mu, &p, &mu, NULL) != MP_OKAY) { + res = CRYPT_MEM; + goto done; + } + + /* get bA */ + if (ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p) != CRYPT_OK) { goto error; } + + /* get bA + Y */ + if (add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu) != CRYPT_OK) { goto error; } + + /* get mG */ + if (mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64) != MP_OKAY) { goto error; } + if (mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64) != MP_OKAY) { goto error; } + if (ecc_mulmod(&m, mG, mG, &p) != CRYPT_OK) { goto error; } + + /* compare mG to bA + Y */ + if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) { + *stat = 1; + } + + /* clear up and return */ + res = CRYPT_OK; + goto done; +error: + res = CRYPT_ERROR; +done: + del_point(mG); + ecc_free(&pubkey); + mp_clear_multi(&p, &m, &b, &mu, NULL); + return res; +} + diff --git a/tnl-1.5.0/tnl/libtomcrypt/gf.c b/tnl-1.5.0/tnl/libtomcrypt/gf.c new file mode 100644 index 0000000000000000000000000000000000000000..47f92558a98d4a3cf52e41d0037c18096cdd3a6f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/gf.c @@ -0,0 +1,295 @@ +/* polynomial basis GF(2^w) routines */ +#include "mycrypt.h" + +#ifdef GF + +#define FORLOOP for (i = 0; i < LSIZE; i++) + +/* c = a + b */ +void gf_add(gf_intp a, gf_intp b, gf_intp c) +{ + int i; + FORLOOP c[i] = a[i]^b[i]; +} + +/* b = a */ +void gf_copy(gf_intp a, gf_intp b) +{ + int i; + FORLOOP b[i] = a[i]; +} + +/* a = 0 */ +void gf_zero(gf_intp a) +{ + int i; + FORLOOP a[i] = 0; +} + +/* is a zero? */ +int gf_iszero(gf_intp a) +{ + int i; + FORLOOP if (a[i]) { + return 0; + } + return 1; +} + +/* is a one? */ +int gf_isone(gf_intp a) +{ + int i; + for (i = 1; i < LSIZE; i++) { + if (a[i]) { + return 0; + } + } + return a[0] == 1; +} + +/* b = a << 1*/ +void gf_shl(gf_intp a, gf_intp b) +{ + int i; + gf_int tmp; + + gf_copy(a, tmp); + for (i = LSIZE-1; i > 0; i--) + b[i] = ((tmp[i]<<1)|((tmp[i-1]&0xFFFFFFFFUL)>>31))&0xFFFFFFFFUL; + b[0] = (tmp[0] << 1)&0xFFFFFFFFUL; + gf_zero(tmp); +} + +/* b = a >> 1 */ +void gf_shr(gf_intp a, gf_intp b) +{ + int i; + gf_int tmp; + + gf_copy(a, tmp); + for (i = 0; i < LSIZE-1; i++) + b[i] = (((tmp[i]&0xFFFFFFFFUL)>>1)|(tmp[i+1]<<31))&0xFFFFFFFFUL; + b[LSIZE-1] = (tmp[LSIZE-1]&0xFFFFFFFFUL)>>1; + gf_zero(tmp); +} + +/* returns -1 if its zero, otherwise degree of a */ +int gf_deg(gf_intp a) +{ + int i, ii; + unsigned long t; + + ii = -1; + for (i = LSIZE-1; i >= 0; i--) + if (a[i]) { + for (t = a[i], ii = 0; t; t >>= 1, ++ii); + break; + } + if (i == -1) i = 0; + return (i<<5)+ii; +} + +/* c = ab */ +void gf_mul(gf_intp a, gf_intp b, gf_intp c) +{ + gf_int ta, tb; + int i, n; + + gf_copy(a, ta); + gf_copy(b, tb); + gf_zero(c); + n = gf_deg(ta)+1; + for (i = 0; i < n; i++) { + if (ta[i>>5]&(1<<(i&31))) + gf_add(c, tb, c); + gf_shl(tb, tb); + } + gf_zero(ta); + gf_zero(tb); +} + +/* q = a/b, r = a%b */ +void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r) +{ + gf_int ta, tb, shifts[LSIZE*32]; + int i, magb, mag; + + mag = gf_deg(a); + magb = gf_deg(b); + + /* special cases */ + if (magb > mag) { + gf_copy(a, r); + gf_zero(q); + return; + } + if (magb == -1) { + return; + } + + /* copy locally */ + gf_copy(a, ta); + gf_copy(b, tb); + gf_zero(q); + + /* make shifted versions of "b" */ + gf_copy(tb, shifts[0]); + for (i = 1; i <= (mag-magb); i++) + gf_shl(shifts[i-1], shifts[i]); + + while (mag >= magb) { + i = (mag - magb); + q[i>>5] |= (1<<(i&31)); + gf_add(ta, shifts[i], ta); + mag = gf_deg(ta); + } + gf_copy(ta, r); + gf_zero(ta); + gf_zero(tb); + zeromem(shifts, sizeof(shifts)); +} + +/* b = a mod m */ +void gf_mod(gf_intp a, gf_intp m, gf_intp b) +{ + gf_int tmp; + gf_div(a,m,tmp,b); + gf_zero(tmp); +} + +/* c = ab (mod m) */ +void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c) +{ + gf_int tmp; + gf_mul(a, b, tmp); + gf_mod(tmp, m, c); + gf_zero(tmp); +} + +/* B = 1/A mod M */ +void gf_invmod(gf_intp A, gf_intp M, gf_intp B) +{ + gf_int m, n, p0, p1, p2, r, q, tmp; + + /* put all variables in known setup state */ + gf_zero(p0); + gf_zero(p2); + gf_copy(M, m); + gf_copy(A, n); + p0[0] = 1; + gf_div(m, n, p1, r); + gf_copy(p1, q); + + /* loop until r == 0 */ + while (!gf_iszero(r)) { + gf_copy(n, m); + gf_copy(r, n); + gf_div(m, n, q, r); + gf_mul(q, p1, tmp); + gf_add(tmp, p0, p2); + gf_copy(p1, p0); + gf_copy(p2, p1); + } + gf_copy(p0, B); + gf_zero(p0); +} + +/* find a square root modulo a prime. Note the number of + * elements is 2^k - 1, so we must square k-2 times to get the + * square root.. + */ +void gf_sqrt(gf_intp a, gf_intp M, gf_intp b) +{ + int k; + k = gf_deg(M)-2; + gf_copy(a, b); + while (k--) + gf_mulmod(b, b, M, b); +} + +/* c = gcd(A,B) */ +void gf_gcd(gf_intp A, gf_intp B, gf_intp c) +{ + gf_int a, b, r; + int n; + + gf_add(A, B, r); + n = gf_deg(r); + if (gf_deg(A) > n) { + gf_copy(A, a); + gf_copy(B, b); + } else { + gf_copy(A, b); + gf_copy(B, a); + } + + do { + gf_mod(a, b, r); + gf_copy(b, a); + gf_copy(r, b); + } while (!gf_iszero(r)); + gf_copy(a, c); + gf_zero(a); + gf_zero(b); +} + +/* returns non-zero if 'a' is irreducible */ +int gf_is_prime(gf_intp a) +{ + gf_int u, tmp; + int m, n; + + gf_zero(u); + u[0] = 2; /* u(x) = x */ + m = gf_deg(a); + for (n = 0; n < (m/2); n++) { + gf_mulmod(u, u, a, u); /* u(x) = u(x)^2 mod a(x) */ + gf_copy(u, tmp); + tmp[0] ^= 2; /* tmp(x) = u(x) - x */ + gf_gcd(tmp, a, tmp); /* tmp(x) = gcd(a(x), u(x) - x) */ + if (!gf_isone(tmp)) { + return 0; + } + } + return 1; +} + +/* returns bytes required to store a gf_int */ +int gf_size(gf_intp a) +{ + int n; + + n = gf_deg(a); + if (n == -1) { + return 4; + } + n = n + (32 - (n&31)); + return n/8; +} + +/* store a gf_int */ +void gf_toraw(gf_intp a, unsigned char *dst) +{ + int x, n; + n = gf_size(a)/4; + for (x = 0; x < n; x++) { + STORE32L(a[x], dst); + dst += 4; + } +} + +/* read a gf_int (len == in bytes) */ +void gf_readraw(gf_intp a, unsigned char *str, int len) +{ + int x; + gf_zero(a); + for (x = 0; x < len/4; x++) { + LOAD32L(a[x], str); + str += 4; + } +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/hash.c b/tnl-1.5.0/tnl/libtomcrypt/hash.c new file mode 100644 index 0000000000000000000000000000000000000000..9ebb2d6d9e5a1615f5fb2e07e524557bebda7d9a --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/hash.c @@ -0,0 +1,92 @@ +#include "mycrypt.h" + +int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen) +{ + hash_state md; + int err; + + _ARGCHK(data != NULL); + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + return CRYPT_BUFFER_OVERFLOW; + } + *outlen = hash_descriptor[hash].hashsize; + + hash_descriptor[hash].init(&md); + hash_descriptor[hash].process(&md, data, len); + hash_descriptor[hash].done(&md, dst); + return CRYPT_OK; +} + +int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + hash_state md; + unsigned char buf[512]; + size_t x; + int err; + + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(in != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if (*outlen < hash_descriptor[hash].hashsize) { + return CRYPT_BUFFER_OVERFLOW; + } + *outlen = hash_descriptor[hash].hashsize; + + hash_descriptor[hash].init(&md); + do { + x = fread(buf, 1, sizeof(buf), in); + hash_descriptor[hash].process(&md, buf, x); + } while (x == sizeof(buf)); + hash_descriptor[hash].done(&md, dst); + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +#endif +} + +int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + FILE *in; + int err; + _ARGCHK(fname != NULL); + _ARGCHK(dst != NULL); + _ARGCHK(outlen != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + err = hash_filehandle(hash, in, dst, outlen); + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + return err; +#endif +} + diff --git a/tnl-1.5.0/tnl/libtomcrypt/hmac.c b/tnl-1.5.0/tnl/libtomcrypt/hmac.c new file mode 100644 index 0000000000000000000000000000000000000000..236e5cf7003b38271d3a4d629c85decdba48dc40 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/hmac.c @@ -0,0 +1,512 @@ +/* Submited by Dobes Vandermeer (dobes@smartt.com) */ + +#include "mycrypt.h" + +/* + (1) append zeros to the end of K to create a B byte string + (e.g., if K is of length 20 bytes and B=64, then K will be + appended with 44 zero bytes 0x00) + (2) XOR (bitwise exclusive-OR) the B byte string computed in step + (1) with ipad (ipad = the byte 0x36 repeated B times) + (3) append the stream of data 'text' to the B byte string resulting + from step (2) + (4) apply H to the stream generated in step (3) + (5) XOR (bitwise exclusive-OR) the B byte string computed in + step (1) with opad (opad = the byte 0x5C repeated B times.) + (6) append the H result from step (4) to the B byte string + resulting from step (5) + (7) apply H to the stream generated in step (6) and output + the result +*/ + +#ifdef HMAC + +#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) +{ + unsigned char buf[MAXBLOCKSIZE]; + unsigned long hashsize; + unsigned long i, z; + int err; + + _ARGCHK(hmac != NULL); + _ARGCHK(key != NULL); + + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* valid key length? */ + if (keylen == 0) { + return CRYPT_INVALID_KEYSIZE; + } + + hmac->hash = hash; + + // (1) make sure we have a large enough key + hashsize = hash_descriptor[hash].hashsize; + if(keylen > HMAC_BLOCKSIZE) { + z = (unsigned long)sizeof(hmac->key); + if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { + return err; + } + if(hashsize < HMAC_BLOCKSIZE) { + zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize)); + } + keylen = hashsize; + } else { + memcpy(hmac->key, key, (size_t)keylen); + if(keylen < HMAC_BLOCKSIZE) { + zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen)); + } + } + + // Create the initial vector for step (3) + for(i=0; i < HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x36; + } + + // Pre-pend that to the hash data + hash_descriptor[hash].init(&hmac->md); + hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE); + + return CRYPT_OK; +} + +int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len) +{ + int err; + _ARGCHK(hmac != NULL); + _ARGCHK(buf != NULL); + if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) { + return err; + } + return hash_descriptor[hmac->hash].process(&hmac->md, buf, len); +} + +int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen) +{ + unsigned char buf[MAXBLOCKSIZE]; + unsigned char isha[MAXBLOCKSIZE]; + unsigned long hashsize, i; + int hash, err; + + _ARGCHK(hmac != NULL); + _ARGCHK(hashOut != NULL); + + hash = hmac->hash; + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + /* get the hash message digest size */ + hashsize = hash_descriptor[hash].hashsize; + + // Get the hash of the first HMAC vector plus the data + if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { + return err; + } + + // Create the second HMAC vector vector for step (3) + for(i=0; i < HMAC_BLOCKSIZE; i++) { + buf[i] = hmac->key[i] ^ 0x5C; + } + + // Now calculate the "outer" hash for step (5), (6), and (7) + hash_descriptor[hash].init(&hmac->md); + hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE); + hash_descriptor[hash].process(&hmac->md, isha, hashsize); + hash_descriptor[hash].done(&hmac->md, buf); + + // copy to output + for (i = 0; i < hashsize && i < *outlen; i++) { + hashOut[i] = buf[i]; + } + *outlen = i; + +#ifdef CLEAN_STACK + zeromem(isha, sizeof(buf)); + zeromem(buf, sizeof(isha)); + zeromem(hmac, sizeof(*hmac)); +#endif + return CRYPT_OK; +} + +int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, + const unsigned char *data, unsigned long len, + unsigned char *dst, unsigned long *dstlen) +{ + hmac_state hmac; + int err; + + _ARGCHK(key != NULL); + _ARGCHK(data != NULL); + _ARGCHK(dst != NULL); + + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_process(&hmac, data, len)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) { + return err; + } + return CRYPT_OK; +} + +/* hmac_file added by Tom St Denis */ +int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + hmac_state hmac; + FILE *in; + unsigned char buf[512]; + size_t x; + int err; + + _ARGCHK(fname != NULL); + _ARGCHK(key != NULL); + _ARGCHK(dst != NULL); + + if((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { + return err; + } + + in = fopen(fname, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + /* process the file contents */ + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) { + /* we don't trap this error since we're already returning an error! */ + fclose(in); + return err; + } + } while (x == sizeof(buf)); + + if (fclose(in) != 0) { + return CRYPT_ERROR; + } + + /* get final hmac */ + if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + /* clear memory */ + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +#endif +} + +/* + + TEST CASES SOURCE: + +Network Working Group P. Cheng +Request for Comments: 2202 IBM +Category: Informational R. Glenn + NIST + September 1997 + + Test Cases for HMAC-MD5 and HMAC-SHA-1 +*/ + + +int hmac_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + unsigned char digest[MAXBLOCKSIZE]; + int i; + + static const struct hmac_test_case { + int num; + char *algo; + unsigned char key[128]; + unsigned long keylen; + unsigned char data[128]; + unsigned long datalen; + unsigned char digest[MAXBLOCKSIZE]; + } cases[] = { + /* + 3. Test Cases for HMAC-SHA-1 + + test_case = 1 + key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b + key_len = 20 + data = "Hi Ther 20 + digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 + digest-96 = 0x4c1a03424b55e07fe7f27be1 + */ + { 5, "sha1", + {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c}, 20, + "Test With Truncation", 20, + {0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, + 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} }, + + /* + test_case = 6 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key - Hash Key First" + data_len = 54 + digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 + */ + { 6, "sha1", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + {0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, + 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, + 0xed, 0x40, 0x21, 0x12} }, + + /* + test_case = 7 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" + data_len = 73 + digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 + */ + { 7, "sha1", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, + {0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, + 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} }, + + /* + 2. Test Cases for HMAC-MD5 + + test_case = 1 + key = 0x0b 0b 0b 0b + 0b 0b 0b 0b + 0b 0b 0b 0b + 0b 0b 0b 0b + key_len = 16 + data = "Hi There" + data_len = 8 + digest = 0x92 94 72 7a + 36 38 bb 1c + 13 f4 8e f8 + 15 8b fc 9d + */ + { 1, "md5", + {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16, + "Hi There", 8, + {0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, + 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} }, + /* + test_case = 2 + key = "Jefe" + key_len = 4 + data = "what do ya want for nothing?" + data_len = 28 + digest = 0x750c783e6ab0b503eaa86e310a5db738 + */ + { 2, "md5", + "Jefe", 4, + "what do ya want for nothing?", 28, + {0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, + 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} }, + + /* + test_case = 3 + key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + key_len 16 + data = 0xdd repeated 50 times + data_len = 50 + digest = 0x56be34521d144c88dbb8c733f0e8b3f6 + */ + { 3, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16, + {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50, + {0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, + 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} }, + /* + + test_case = 4 + key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 + key_len 25 + data = 0xcd repeated 50 times + data_len = 50 + digest = 0x697eaf0aca3a3aea3a75164746ffaa79 + */ + { 4, "md5", + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19}, 25, + {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50, + {0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, + 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} }, + + + /* + + test_case = 5 + key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c + key_len = 16 + data = "Test With Truncation" + data_len = 20 + digest = 0x56461ef2342edc00f9bab995690efd4c + digest-96 0x56461ef2342edc00f9bab995 + */ + { 5, "md5", + {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16, + "Test With Truncation", 20, + {0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, + 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} }, + + /* + + test_case = 6 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key - Hash +Key First" + data_len = 54 + digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd + */ + { 6, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key - Hash Key First", 54, + {0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, + 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} }, + + /* + + test_case = 7 + key = 0xaa repeated 80 times + key_len = 80 + data = "Test Using Larger Than Block-Size Key and Larger + Than One Block-Size Data" + data_len = 73 + digest = 0x6f630fad67cda0ee1fb1f562db3aa53e + */ + { 7, "md5", + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, + {0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, + 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} } + }; + + unsigned long outlen; + int err; + int tested=0,failed=0; + for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + int hash = find_hash(cases[i].algo); + if (hash == -1) continue; + ++tested; + outlen = sizeof(digest); + if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) { +#if 0 + printf("HMAC-%s test #%d\n", cases[i].algo, cases[i].num); +#endif + return err; + } + + if(memcmp(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0) { +#if 0 + unsigned int j; + printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num); + printf( "Result: 0x"); + for(j=0; j < hash_descriptor[hash].hashsize; j++) { + printf("%2x ", digest[j]); + } + printf("\nCorrect: 0x"); + for(j=0; j < hash_descriptor[hash].hashsize; j++) { + printf("%2x ", cases[i].digest[j]); + } + printf("\n"); +#endif + failed++; + //return CRYPT_ERROR; + } else { + /* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */ + } + } + + if (failed != 0) { + return CRYPT_FAIL_TESTVECTOR; + } else if (tested == 0) { + return CRYPT_NOP; + } else { + return CRYPT_OK; + } + #endif +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/keyring.c b/tnl-1.5.0/tnl/libtomcrypt/keyring.c new file mode 100644 index 0000000000000000000000000000000000000000..01df75e0ad4d8b234b691a9b8139ca5a5b78fc06 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/keyring.c @@ -0,0 +1,852 @@ +/* Provides keyring functionality for libtomcrypt, Tom St Denis */ +#include + +#ifdef KR + +static const unsigned char key_magic[4] = { 0x12, 0x34, 0x56, 0x78 }; +static const unsigned char file_magic[4] = { 0x9A, 0xBC, 0xDE, 0xF0 }; +static const unsigned char sign_magic[4] = { 0x87, 0x56, 0x43, 0x21 }; +static const unsigned char enc_magic[4] = { 0x0F, 0xED, 0xCB, 0xA9 }; + +static const unsigned long crc_table[256] = { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +}; + +#define DO1(buf) crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len) +{ + //_ARGCHK(buf != NULL && len == 0); + crc = crc ^ 0xffffffffL; + while (len >= 8) { + DO8 (buf); + len -= 8; + } + + if (len > 0) { + do { + DO1 (buf); + } while (--len > 0); + } + return crc ^ 0xffffffffUL; +} + +int kr_init(pk_key **pk) +{ + _ARGCHK(pk != NULL); + + *pk = XCALLOC(1, sizeof(pk_key)); + if (*pk == NULL) { + return CRYPT_MEM; + } + (*pk)->system = NON_KEY; + return CRYPT_OK; +} + +unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description) +{ + unsigned long crc; + _ARGCHK(name != NULL); + _ARGCHK(email != NULL); + _ARGCHK(description != NULL); + crc = crc32(0UL, NULL, 0UL); + crc = crc32(crc, name, (unsigned long)MIN(MAXLEN, strlen((char *)name))); + crc = crc32(crc, email, (unsigned long)MIN(MAXLEN, strlen((char *)email))); + return crc32(crc, description, (unsigned long)MIN(MAXLEN, strlen((char *)description))); +} + +pk_key *kr_find(pk_key *pk, unsigned long ID) +{ + _ARGCHK(pk != NULL); + + while (pk != NULL) { + if (pk->system != NON_KEY && pk->ID == ID) { + return pk; + } + pk = pk->next; + } + return NULL; +} + +pk_key *kr_find_name(pk_key *pk, const char *name) +{ + _ARGCHK(pk != NULL); + _ARGCHK(name != NULL); + + while (pk != NULL) { + if (pk->system != NON_KEY && strncmp((char *)pk->name, (char *)name, sizeof(pk->name)-1) == 0) { + return pk; + } + pk = pk->next; + } + return NULL; +} + + +int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name, + const unsigned char *email, const unsigned char *description, const _pk_key *key) +{ + _ARGCHK(pk != NULL); + _ARGCHK(name != NULL); + _ARGCHK(email != NULL); + _ARGCHK(description != NULL); + _ARGCHK(key != NULL); + + /* check parameters */ + if (key_type != PK_PRIVATE && key_type != PK_PRIVATE_OPTIMIZED && key_type != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + if (sys != RSA_KEY && sys != DH_KEY && sys != ECC_KEY) { + return CRYPT_PK_INVALID_SYSTEM; + } + + /* see if its a dupe */ + if (kr_find(pk, kr_crc(name, email, description)) != NULL) { + return CRYPT_PK_DUP; + } + + /* find spot in key ring */ + while (pk->system != NON_KEY) { + if (pk->next == NULL) { + return CRYPT_ERROR; + } + pk = pk->next; + } + + /* now we have a spot make a next spot */ + pk->next = XCALLOC(1, sizeof(pk_key)); + if (pk->next == NULL) { + return CRYPT_MEM; + } + pk->next->system = NON_KEY; + + /* now add this new data to this ring spot */ + pk->key_type = key_type; + pk->system = sys; + strncpy((char *)pk->name, (char *)name, sizeof(pk->name)-1); + strncpy((char *)pk->email, (char *)email, sizeof(pk->email)-1); + strncpy((char *)pk->description, (char *)description, sizeof(pk->description)-1); + pk->ID = kr_crc(pk->name, pk->email, pk->description); + + /* clear the memory area */ + zeromem(&(pk->key), sizeof(pk->key)); + + /* copy the key */ + switch (sys) { + case RSA_KEY: + memcpy(&(pk->key.rsa), &(key->rsa), sizeof(key->rsa)); + break; + case DH_KEY: + memcpy(&(pk->key.dh), &(key->dh), sizeof(key->dh)); + break; + case ECC_KEY: + memcpy(&(pk->key.ecc), &(key->ecc), sizeof(key->ecc)); + break; + } + return CRYPT_OK; +} + +int kr_del(pk_key **_pk, unsigned long ID) +{ + pk_key *ppk, *pk; + + _ARGCHK(_pk != NULL); + + pk = *_pk; + ppk = NULL; + while (pk->system != NON_KEY && pk->ID != ID) { + ppk = pk; + pk = pk->next; + if (pk == NULL) { + return CRYPT_PK_NOT_FOUND; + } + } + + switch (pk->system) { + case RSA_KEY: + rsa_free(&(pk->key.rsa)); + break; + case DH_KEY: + dh_free(&(pk->key.dh)); + break; + case ECC_KEY: + ecc_free(&(pk->key.ecc)); + break; + } + + if (ppk == NULL) { /* the first element matches the ID */ + ppk = pk->next; /* get the 2nd element */ + XFREE(pk); /* free the first */ + *_pk = ppk; /* make the first element the second */ + } else { /* (not) first element matches the ID */ + ppk->next = pk->next; /* make the previous'es next point to the current next */ + XFREE(pk); /* free the element */ + } + return CRYPT_OK; +} + +int kr_clear(pk_key **pk) +{ + int err; + _ARGCHK(pk != NULL); + + while ((*pk)->system != NON_KEY) { + if ((err = kr_del(pk, (*pk)->ID)) != CRYPT_OK) { + return err; + } + } + XFREE(*pk); + *pk = NULL; + return CRYPT_OK; +} + +static unsigned long _write(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr) +{ +#ifdef NO_FILE + return 0; +#else + _ARGCHK(buf != NULL); + _ARGCHK(f != NULL); + if (ctr != NULL) { + if (ctr_encrypt(buf, buf, len, ctr) != CRYPT_OK) { + return 0; + } + } + return (unsigned long)fwrite(buf, 1, (size_t)len, f); +#endif +} + +static unsigned long _read(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr) +{ +#ifdef NO_FILE + return 0; +#else + unsigned long y; + _ARGCHK(buf != NULL); + _ARGCHK(f != NULL); + y = (unsigned long)fread(buf, 1, (size_t)len, f); + if (ctr != NULL) { + if (ctr_decrypt(buf, buf, y, ctr) != CRYPT_OK) { + return 0; + } + } + return y; +#endif +} + +int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[8192], *obuf; + pk_key *ppk; + unsigned long len; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find the desired key */ + ppk = kr_find(pk, ID); + if (ppk == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + if (ppk->key_type == PK_PUBLIC && key_type != PK_PUBLIC) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* this makes PK_PRIVATE an alias for PK_PRIVATE_OPTIMIZED type */ + if (ppk->key_type == PK_PRIVATE_OPTIMIZED && key_type == PK_PRIVATE) { + key_type = PK_PRIVATE_OPTIMIZED; + } + + /* now copy the header and various other details */ + memcpy(buf, key_magic, 4); /* magic info */ + buf[4] = key_type; /* key type */ + buf[5] = ppk->system; /* system */ + STORE32L(ppk->ID, buf+6); /* key ID */ + memcpy(buf+10, ppk->name, MAXLEN); /* the name */ + memcpy(buf+10+MAXLEN, ppk->email, MAXLEN); /* the email */ + memcpy(buf+10+MAXLEN+MAXLEN, ppk->description, MAXLEN); /* the description */ + + /* export key */ + len = sizeof(buf) - (6 + 4 + MAXLEN*3); + obuf = buf+6+4+MAXLEN*3; + switch (ppk->system) { + case RSA_KEY: + if ((err = rsa_export(obuf, &len, key_type, &(ppk->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_export(obuf, &len, key_type, &(ppk->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_export(obuf, &len, key_type, &(ppk->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + + /* get the entire length of the packet */ + len += 6 + 4 + 3*MAXLEN; + + if (*outlen < len) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + *outlen = len; + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_OK; + } +} + +int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen) +{ + _pk_key key; + int sys, key_type, err; + unsigned long ID; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + + if (inlen < 10) { + return CRYPT_INVALID_PACKET; + } + + if (memcmp(in, key_magic, 4) != 0) { + return CRYPT_INVALID_PACKET; + } + key_type = in[4]; /* get type */ + sys = in[5]; /* get system */ + LOAD32L(ID,in+6); /* the ID */ + + if (ID != kr_crc(in+10, in+10+MAXLEN, in+10+MAXLEN+MAXLEN)) { + return CRYPT_INVALID_PACKET; + } + + zeromem(&key, sizeof(key)); + + /* size of remaining packet */ + inlen -= 10 + 3*MAXLEN; + + switch (sys) { + case RSA_KEY: + if ((err = rsa_import(in+10+3*MAXLEN, inlen, &(key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_import(in+10+3*MAXLEN, inlen, &(key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_import(in+10+3*MAXLEN, inlen, &(key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + return kr_add(pk, key_type, sys, + in+10, /* the name */ + in+10+MAXLEN, /* email address */ + in+10+MAXLEN+MAXLEN, /* description */ + &key); +} + + +int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr) +{ + unsigned char buf[8192], blen[4]; + unsigned long len; + int res, err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + + /* init keyring */ + if ((err = kr_init(pk)) != CRYPT_OK) { + return err; + } + + /* read in magic bytes */ + if (_read(buf, 6, in, ctr) != 6) { goto done2; } + + if (memcmp(buf, file_magic, 4) != 0) { + return CRYPT_INVALID_PACKET; + } + + len = (unsigned long)buf[4] | ((unsigned long)buf[5] << 8); + if (len > CRYPT) { + return CRYPT_INVALID_PACKET; + } + + /* while there are lengths to read... */ + while (_read(blen, 4, in, ctr) == 4) { + /* get length */ + LOAD32L(len, blen); + + if (len > (unsigned long)sizeof(buf)) { + return CRYPT_INVALID_PACKET; + } + + if (_read(buf, len, in, ctr) != len) { goto done2; } + if ((err = kr_import(*pk, buf, len)) != CRYPT_OK) { + return err; + } + } + + res = CRYPT_OK; + goto done; +done2: + res = CRYPT_ERROR; +done: +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return res; +} + +int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr) +{ + unsigned char buf[8192], blen[4]; + unsigned long len; + int res, err; + + _ARGCHK(pk != NULL); + _ARGCHK(out != NULL); + + /* write out magic bytes */ + memcpy(buf, file_magic, 4); + buf[4] = (unsigned char)(CRYPT&255); + buf[5] = (unsigned char)((CRYPT>>8)&255); + if (_write(buf, 6, out, ctr) != 6) { goto done2; } + + while (pk->system != NON_KEY) { + len = sizeof(buf); + if ((err = kr_export(pk, pk->ID, pk->key_type, buf, &len)) != CRYPT_OK) { + return err; + } + + STORE32L(len, blen); + if (_write(blen, 4, out, ctr) != 4) { goto done2; } + if (_write(buf, len, out, ctr) != len) { goto done2; } + + pk = pk->next; + } + + res = CRYPT_OK; + goto done; +done2: + res = CRYPT_ERROR; +done: +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return res; +} + +int kr_make_key(pk_key *pk, prng_state *prng, int wprng, + int sys, int keysize, const unsigned char *name, + const unsigned char *email, const unsigned char *description) +{ + _pk_key key; + int key_type, err; + + _ARGCHK(pk != NULL); + _ARGCHK(name != NULL); + _ARGCHK(email != NULL); + _ARGCHK(description != NULL); + + /* valid PRNG? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* make the key first */ + zeromem(&key, sizeof(key)); + switch (sys) { + case RSA_KEY: + if ((err = rsa_make_key(prng, wprng, keysize, 65537, &(key.rsa))) != CRYPT_OK) { + return err; + } + key_type = key.rsa.type; + break; + case DH_KEY: + if ((err = dh_make_key(prng, wprng, keysize, &(key.dh))) != CRYPT_OK) { + return err; + } + key_type = key.dh.type; + break; + case ECC_KEY: + if ((err = ecc_make_key(prng, wprng, keysize, &(key.ecc))) != CRYPT_OK) { + return err; + } + key_type = key.ecc.type; + break; + default: + return CRYPT_PK_INVALID_SYSTEM; + } + + /* now add the key */ + if ((err = kr_add(pk, key_type, sys, name, email, description, &key)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(&key, sizeof(key)); +#endif + return CRYPT_OK; +} + +int kr_encrypt_key(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash) +{ + unsigned char buf[8192]; + unsigned long len; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find the key */ + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* store the header */ + memcpy(buf, enc_magic, 4); + + /* now store the ID */ + STORE32L(kr->ID,buf+4); + + /* now encrypt it */ + len = sizeof(buf)-12; + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_encrypt_key(in, inlen, buf+12, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + STORE32L(len,buf+8); + len += 12; + + if (len > *outlen) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + *outlen = len; + return CRYPT_OK; + } +} + +int kr_decrypt_key(pk_key *pk, const unsigned char *in, + unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[8192]; + unsigned long pklen, len, ID; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* check magic header */ + if (memcmp(in, enc_magic, 4)) { + return CRYPT_INVALID_PACKET; + } + + /* now try to find key */ + LOAD32L(ID,in+4); + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* is it public? */ + if (kr->key_type == PK_PUBLIC) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* now try and decrypt it */ + LOAD32L(pklen,in+8); + len = sizeof(buf); + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_decrypt_key(in+12, pklen, buf, &len, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_decrypt_key(in+12, pklen, buf, &len, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_decrypt_key(in+12, pklen, buf, &len, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + + if (len > *outlen) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + *outlen = len; + return CRYPT_OK; + } +} + +int kr_sign_hash(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng) +{ + unsigned char buf[8192]; + unsigned long len; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* find the key */ + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* is it public? */ + if (kr->key_type == PK_PUBLIC) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* store the header */ + memcpy(buf, sign_magic, 4); + + /* now store the ID */ + STORE32L(kr->ID,buf+4); + + /* now sign it */ + len = sizeof(buf)-16; + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_sign_hash(in, inlen, buf+16, &len, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + STORE32L(inlen,buf+8); + STORE32L(len,buf+12); + len += 16; + + if (len > *outlen) { + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + return CRYPT_BUFFER_OVERFLOW; + } else { + memcpy(out, buf, len); + #ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); + #endif + *outlen = len; + return CRYPT_OK; + } +} + +int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *hash, + unsigned long hashlen, int *stat) +{ + unsigned long inlen, pklen, ID; + pk_key *kr; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(in != NULL); + _ARGCHK(hash != NULL); + _ARGCHK(stat != NULL); + + /* default to not match */ + *stat = 0; + + /* check magic header */ + if (memcmp(in, sign_magic, 4)) { + return CRYPT_INVALID_PACKET; + } + + /* now try to find key */ + LOAD32L(ID,in+4); + kr = kr_find(pk, ID); + if (kr == NULL) { + return CRYPT_PK_NOT_FOUND; + } + + /* now try and verify it */ + LOAD32L(inlen,in+8); /* this is the length of the original inlen */ + LOAD32L(pklen,in+12); /* size of the PK packet */ + if (inlen != hashlen) { /* size doesn't match means the signature is invalid */ + return CRYPT_OK; + } + + switch (kr->system) { + case RSA_KEY: + if ((err = rsa_verify_hash(in+16, pklen, hash, stat, &(kr->key.rsa))) != CRYPT_OK) { + return err; + } + break; + case DH_KEY: + if ((err = dh_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) { + return err; + } + break; + case ECC_KEY: + if ((err = ecc_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) { + return err; + } + break; + } + return CRYPT_OK; +} + +int kr_fingerprint(pk_key *pk, unsigned long ID, int hash, + unsigned char *out, unsigned long *outlen) +{ + unsigned char buf[8192]; + unsigned long len; + int err; + + _ARGCHK(pk != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* valid hash? */ + if ((err = hash_is_valid(hash)) != CRYPT_OK) { + return err; + } + + len = (unsigned long)sizeof(buf); + if ((err = kr_export(pk, ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) { + return err; + } + + /* now hash it */ + if ((err = hash_memory(hash, buf, len, out, outlen)) != CRYPT_OK) { + return err; + } + +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/libtomcrypt.vcproj b/tnl-1.5.0/tnl/libtomcrypt/libtomcrypt.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..eb0b53284a2380e3cc34b61bc08fb9360327922a --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/libtomcrypt.vcproj @@ -0,0 +1,315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/makefile b/tnl-1.5.0/tnl/libtomcrypt/makefile new file mode 100644 index 0000000000000000000000000000000000000000..db830d79ec9d48294d1b7416a13d2d710731bfd5 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/makefile @@ -0,0 +1,168 @@ +# MAKEFILE for linux GCC +# +# Tom St Denis +# Modified by Clay Culver +# +# NOTE: This should later be replaced by autoconf/automake scripts, but for +# the time being this is actually pretty clean. The only ugly part is +# handling CFLAGS so that the x86 specific optimizations don't break +# a build. This is easy to remedy though, for those that have problems. + +# The version +VERSION=0.92 + +#ch1-01-1 +# Compiler and Linker Names +#CC=gcc +#LD=ld + +# Archiver [makes .a files] +#AR=ar +#ARFLAGS=r +#ch1-01-1 + +#ch1-01-3 +# Compilation flags. Note the += does not write over the user's CFLAGS! +CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -Werror + +# optimize for SPEED +#CFLAGS += -O3 -funroll-loops + +#add -fomit-frame-pointer. v3.2 is buggy for certain platforms! +#CFLAGS += -fomit-frame-pointer + +# optimize for SIZE +CFLAGS += -Os + +# compile for DEBUGING +#CFLAGS += -g3 +#ch1-01-3 + +#These flags control how the library gets built. + +#Output filenames for various targets. +LIBNAME=libtomcrypt.a +TEST=test +HASH=hashsum +CRYPT=encrypt +SMALL=small +PROF=x86_prof +TV=tv_gen + +#LIBPATH-The directory for libtomcrypt to be installed to. +#INCPATH-The directory to install the header files for libtomcrypt. +#DATAPATH-The directory to install the pdf docs. +DESTDIR= +LIBPATH=/usr/lib +INCPATH=/usr/include +DATAPATH=/usr/share/doc/libtomcrypt/pdf + +#List of objects to compile. + +#Leave MPI built-in or force developer to link against libtommath? +MPIOBJECT=mpi.o + +OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \ +bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \ +md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \ +safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \ +prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o $(MPIOBJECT) + +TESTOBJECTS=demos/test.o +HASHOBJECTS=demos/hashsum.o +CRYPTOBJECTS=demos/encrypt.o +SMALLOBJECTS=demos/small.o +PROFS=demos/x86_prof.o +TVS=demos/tv_gen.o + +#Files left over from making the crypt.pdf. +LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind + +#Compressed filenames +COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz + +#Header files used by libtomcrypt. +HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \ +mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \ +mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h + +#The default rule for make builds the libtomcrypt library. +default:library mycrypt.h mycrypt_cfg.h + +#These are the rules to make certain object files. +rsa.o: rsa.c rsa_sys.c +ecc.o: ecc.c ecc_sys.c +dh.o: dh.c dh_sys.c +aes.o: aes.c aes_tab.c +twofish.o: twofish.c twofish_tab.c +sha512.o: sha512.c sha384.c +sha256.o: sha256.c sha224.c + +#This rule makes the libtomcrypt library. +library: $(LIBNAME) + +$(LIBNAME): $(OBJECTS) + $(AR) $(ARFLAGS) $@ $(OBJECTS) + +#This rule makes the test program included with libtomcrypt +test: library $(TESTOBJECTS) + $(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN) + +#This rule makes the hash program included with libtomcrypt +hashsum: library $(HASHOBJECTS) + $(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN) + +#makes the crypt program +crypt: library $(CRYPTOBJECTS) + $(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN) + +#makes the small program +small: library $(SMALLOBJECTS) + $(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN) + +x86_prof: library $(PROFS) + $(CC) $(PROFS) $(LIBNAME) -o $(PROF) + +tv_gen: library $(TVS) + $(CC) $(TVS) $(LIBNAME) -o $(TV) + +#This rule installs the library and the header files. This must be run +#as root in order to have a high enough permission to write to the correct +#directories and to set the owner and group to root. +install: library docs + install -d -g root -o root $(DESTDIR)$(LIBPATH) + install -d -g root -o root $(DESTDIR)$(INCPATH) + install -d -g root -o root $(DESTDIR)$(DATAPATH) + install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + install -g root -o root crypt.pdf $(DESTDIR)$(DATAPATH) + +#This rule cleans the source tree of all compiled code, not including the pdf +#documentation. +clean: + rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME) + rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV) + rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt + +#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed +#from the clean command! This is because most people would like to keep the +#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to +#delete it if we are rebuilding it. +docs: crypt.tex + rm -f crypt.pdf $(LEFTOVERS) + latex crypt > /dev/null + makeindex crypt > /dev/null + pdflatex crypt > /dev/null + rm -f $(LEFTOVERS) + +#beta +beta: clean + cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \ + cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)-beta/ ; tar -c libtomcrypt-$(VERSION)-beta/* > crypt-$(VERSION)-beta.tar ; \ + bzip2 -9vv crypt-$(VERSION)-beta.tar ; zip -9 -r crypt-$(VERSION)-beta.zip libtomcrypt-$(VERSION)-beta/* + +#zipup the project (take that!) +zipup: clean docs + cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ + cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \ + bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/* diff --git a/tnl-1.5.0/tnl/libtomcrypt/md2.c b/tnl-1.5.0/tnl/libtomcrypt/md2.c new file mode 100644 index 0000000000000000000000000000000000000000..90e13958831002761987c581ad2f120a2464baf1 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/md2.c @@ -0,0 +1,204 @@ +/* MD2 (RFC 1319) hash function implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef MD2 + +const struct _hash_descriptor md2_desc = +{ + "md2", + 7, + 16, + 16, + &md2_init, + &md2_process, + &md2_done, + &md2_test +}; + +static const unsigned char PI_SUBST[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 +}; + +/* adds 16 bytes to the checksum */ +static void md2_update_chksum(hash_state *md) +{ + int j; + unsigned char L; + L = md->md2.chksum[15]; + for (j = 0; j < 16; j++) { + +/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say + otherwise. +*/ + L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255); + } +} + +static void md2_compress(hash_state *md) +{ + int j, k; + unsigned char t; + + /* copy block */ + for (j = 0; j < 16; j++) { + md->md2.X[16+j] = md->md2.buf[j]; + md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j]; + } + + t = (unsigned char)0; + + /* do 18 rounds */ + for (j = 0; j < 18; j++) { + for (k = 0; k < 48; k++) { + t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]); + } + t = (t + (unsigned char)j) & 255; + } +} + +void md2_init(hash_state *md) +{ + _ARGCHK(md != NULL); + + /* MD2 uses a zero'ed state... */ + zeromem(md->md2.X, sizeof(md->md2.X)); + zeromem(md->md2.chksum, sizeof(md->md2.chksum)); + zeromem(md->md2.buf, sizeof(md->md2.buf)); + md->md2.curlen = 0; +} + +int md2_process(hash_state *md, const unsigned char *buf, unsigned long len) +{ + unsigned long n; + _ARGCHK(md != NULL); + _ARGCHK(buf != NULL); + if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { + return CRYPT_INVALID_ARG; + } + while (len > 0) { + n = MIN(len, (16 - md->md2.curlen)); + memcpy(md->md2.buf + md->md2.curlen, buf, (size_t)n); + md->md2.curlen += n; + buf += n; + len -= n; + + /* is 16 bytes full? */ + if (md->md2.curlen == 16) { + md2_compress(md); + md2_update_chksum(md); + md->md2.curlen = 0; + } + } + return CRYPT_OK; +} + +int md2_done(hash_state * md, unsigned char *hash) +{ + unsigned long i, k; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->md2.curlen >= sizeof(md->md2.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* pad the message */ + k = 16 - md->md2.curlen; + for (i = md->md2.curlen; i < 16; i++) { + md->md2.buf[i] = (unsigned char)k; + } + + /* hash and update */ + md2_compress(md); + md2_update_chksum(md); + + /* hash checksum */ + memcpy(md->md2.buf, md->md2.chksum, 16); + md2_compress(md); + + /* output is lower 16 bytes of X */ + memcpy(hash, md->md2.X, 16); + +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int md2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d, + 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73 + } + }, + { "a", + {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72, + 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1 + } + }, + { "message digest", + {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b, + 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0 + } + }, + { "abcdefghijklmnopqrstuvwxyz", + {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab, + 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b + } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39, + 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd + } + }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d, + 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8 + } + } + }; + int i; + hash_state md; + unsigned char buf[16]; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + md2_init(&md); + md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md2_done(&md, buf); + if (memcmp(buf, tests[i].md, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/md4.c b/tnl-1.5.0/tnl/libtomcrypt/md4.c new file mode 100644 index 0000000000000000000000000000000000000000..6a2afad4cdf9aa5a5a00863b0298b9636b2168b3 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/md4.c @@ -0,0 +1,258 @@ +/* Submitted by Dobes Vandermeer (dobes@smartt.com) */ +#include "mycrypt.h" + +#ifdef MD4 + +const struct _hash_descriptor md4_desc = +{ + "md4", + 6, + 16, + 64, + &md4_init, + &md4_process, + &md4_done, + &md4_test +}; + +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 + +/* F, G and H are basic MD4 functions. */ +#define F(x, y, z) (z ^ (x & (y ^ z))) +#define G(x, y, z) ((x & y) | (z & (x | y))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* ROTATE_LEFT rotates x left n bits. */ +#define ROTATE_LEFT(x, n) ROL(x, n) + +/* FF, GG and HH are transformations for rounds 1, 2 and 3 */ +/* Rotation is separate from addition to prevent recomputation */ + +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } + +#ifdef CLEAN_STACK +static void _md4_compress(hash_state *md, unsigned char *buf) +#else +static void md4_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 x[16], a, b, c, d; + int i; + + _ARGCHK(md != NULL); + + /* copy state */ + a = md->md4.state[0]; + b = md->md4.state[1]; + c = md->md4.state[2]; + d = md->md4.state[3]; + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(x[i], buf + (4*i)); + } + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11); /* 1 */ + FF (d, a, b, c, x[ 1], S12); /* 2 */ + FF (c, d, a, b, x[ 2], S13); /* 3 */ + FF (b, c, d, a, x[ 3], S14); /* 4 */ + FF (a, b, c, d, x[ 4], S11); /* 5 */ + FF (d, a, b, c, x[ 5], S12); /* 6 */ + FF (c, d, a, b, x[ 6], S13); /* 7 */ + FF (b, c, d, a, x[ 7], S14); /* 8 */ + FF (a, b, c, d, x[ 8], S11); /* 9 */ + FF (d, a, b, c, x[ 9], S12); /* 10 */ + FF (c, d, a, b, x[10], S13); /* 11 */ + FF (b, c, d, a, x[11], S14); /* 12 */ + FF (a, b, c, d, x[12], S11); /* 13 */ + FF (d, a, b, c, x[13], S12); /* 14 */ + FF (c, d, a, b, x[14], S13); /* 15 */ + FF (b, c, d, a, x[15], S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 0], S21); /* 17 */ + GG (d, a, b, c, x[ 4], S22); /* 18 */ + GG (c, d, a, b, x[ 8], S23); /* 19 */ + GG (b, c, d, a, x[12], S24); /* 20 */ + GG (a, b, c, d, x[ 1], S21); /* 21 */ + GG (d, a, b, c, x[ 5], S22); /* 22 */ + GG (c, d, a, b, x[ 9], S23); /* 23 */ + GG (b, c, d, a, x[13], S24); /* 24 */ + GG (a, b, c, d, x[ 2], S21); /* 25 */ + GG (d, a, b, c, x[ 6], S22); /* 26 */ + GG (c, d, a, b, x[10], S23); /* 27 */ + GG (b, c, d, a, x[14], S24); /* 28 */ + GG (a, b, c, d, x[ 3], S21); /* 29 */ + GG (d, a, b, c, x[ 7], S22); /* 30 */ + GG (c, d, a, b, x[11], S23); /* 31 */ + GG (b, c, d, a, x[15], S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 0], S31); /* 33 */ + HH (d, a, b, c, x[ 8], S32); /* 34 */ + HH (c, d, a, b, x[ 4], S33); /* 35 */ + HH (b, c, d, a, x[12], S34); /* 36 */ + HH (a, b, c, d, x[ 2], S31); /* 37 */ + HH (d, a, b, c, x[10], S32); /* 38 */ + HH (c, d, a, b, x[ 6], S33); /* 39 */ + HH (b, c, d, a, x[14], S34); /* 40 */ + HH (a, b, c, d, x[ 1], S31); /* 41 */ + HH (d, a, b, c, x[ 9], S32); /* 42 */ + HH (c, d, a, b, x[ 5], S33); /* 43 */ + HH (b, c, d, a, x[13], S34); /* 44 */ + HH (a, b, c, d, x[ 3], S31); /* 45 */ + HH (d, a, b, c, x[11], S32); /* 46 */ + HH (c, d, a, b, x[ 7], S33); /* 47 */ + HH (b, c, d, a, x[15], S34); /* 48 */ + + + /* Update our state */ + md->md4.state[0] = md->md4.state[0] + a; + md->md4.state[1] = md->md4.state[1] + b; + md->md4.state[2] = md->md4.state[2] + c; + md->md4.state[3] = md->md4.state[3] + d; +} + +#ifdef CLEAN_STACK +static void md4_compress(hash_state *md, unsigned char *buf) +{ + _md4_compress(md, buf); + burn_stack(sizeof(ulong32) * 20 + sizeof(int)); +} +#endif + +void md4_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->md4.state[0] = 0x67452301UL; + md->md4.state[1] = 0xefcdab89UL; + md->md4.state[2] = 0x98badcfeUL; + md->md4.state[3] = 0x10325476UL; + md->md4.length = 0; + md->md4.curlen = 0; +} + +HASH_PROCESS(md4_process, md4_compress, md4, 64) + +int md4_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->md4.curlen >= sizeof(md->md4.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->md4.length += md->md4.curlen * 8; + + /* append the '1' bit */ + md->md4.buf[md->md4.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md4.curlen > 56) { + while (md->md4.curlen < 64) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + md4_compress(md, md->md4.buf); + md->md4.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md4.curlen < 56) { + md->md4.buf[md->md4.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md4.length, md->md4.buf+56); + md4_compress(md, md->md4.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md4.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int md4_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct md4_test_case { + char *input; + unsigned char digest[16]; + } cases[] = { + { "", + {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, + 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, + { "a", + {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, + 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, + { "abc", + {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, + 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, + { "message digest", + {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, + 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, + { "abcdefghijklmnopqrstuvwxyz", + {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, + 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, + 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, + 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, + }; + int i; + hash_state md; + unsigned char digest[16]; + + for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { + md4_init(&md); + md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input)); + md4_done(&md, digest); + if (memcmp(digest, cases[i].digest, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + } + return CRYPT_OK; + #endif +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/md5.c b/tnl-1.5.0/tnl/libtomcrypt/md5.c new file mode 100644 index 0000000000000000000000000000000000000000..b387de171e970089b9a0302c07b0eb90287ede32 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/md5.c @@ -0,0 +1,247 @@ +#include "mycrypt.h" + +#ifdef MD5 + +const struct _hash_descriptor md5_desc = +{ + "md5", + 3, + 16, + 64, + &md5_init, + &md5_process, + &md5_done, + &md5_test +}; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define G(x,y,z) (y ^ (z & (y ^ x))) +#define H(x,y,z) (x^y^z) +#define I(x,y,z) (y^(x|(~z))) + +#define FF(a,b,c,d,M,s,t) \ + a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; + +#define GG(a,b,c,d,M,s,t) \ + a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; + +#define HH(a,b,c,d,M,s,t) \ + a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; + +#define II(a,b,c,d,M,s,t) \ + a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; + +#ifdef CLEAN_STACK +static void _md5_compress(hash_state *md, unsigned char *buf) +#else +static void md5_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 i, W[16], a, b, c, d; + + _ARGCHK(md != NULL); + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32L(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->md5.state[0]; + b = md->md5.state[1]; + c = md->md5.state[2]; + d = md->md5.state[3]; + + FF(a,b,c,d,W[0],7,0xd76aa478UL) + FF(d,a,b,c,W[1],12,0xe8c7b756UL) + FF(c,d,a,b,W[2],17,0x242070dbUL) + FF(b,c,d,a,W[3],22,0xc1bdceeeUL) + FF(a,b,c,d,W[4],7,0xf57c0fafUL) + FF(d,a,b,c,W[5],12,0x4787c62aUL) + FF(c,d,a,b,W[6],17,0xa8304613UL) + FF(b,c,d,a,W[7],22,0xfd469501UL) + FF(a,b,c,d,W[8],7,0x698098d8UL) + FF(d,a,b,c,W[9],12,0x8b44f7afUL) + FF(c,d,a,b,W[10],17,0xffff5bb1UL) + FF(b,c,d,a,W[11],22,0x895cd7beUL) + FF(a,b,c,d,W[12],7,0x6b901122UL) + FF(d,a,b,c,W[13],12,0xfd987193UL) + FF(c,d,a,b,W[14],17,0xa679438eUL) + FF(b,c,d,a,W[15],22,0x49b40821UL) + GG(a,b,c,d,W[1],5,0xf61e2562UL) + GG(d,a,b,c,W[6],9,0xc040b340UL) + GG(c,d,a,b,W[11],14,0x265e5a51UL) + GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) + GG(a,b,c,d,W[5],5,0xd62f105dUL) + GG(d,a,b,c,W[10],9,0x02441453UL) + GG(c,d,a,b,W[15],14,0xd8a1e681UL) + GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) + GG(a,b,c,d,W[9],5,0x21e1cde6UL) + GG(d,a,b,c,W[14],9,0xc33707d6UL) + GG(c,d,a,b,W[3],14,0xf4d50d87UL) + GG(b,c,d,a,W[8],20,0x455a14edUL) + GG(a,b,c,d,W[13],5,0xa9e3e905UL) + GG(d,a,b,c,W[2],9,0xfcefa3f8UL) + GG(c,d,a,b,W[7],14,0x676f02d9UL) + GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) + HH(a,b,c,d,W[5],4,0xfffa3942UL) + HH(d,a,b,c,W[8],11,0x8771f681UL) + HH(c,d,a,b,W[11],16,0x6d9d6122UL) + HH(b,c,d,a,W[14],23,0xfde5380cUL) + HH(a,b,c,d,W[1],4,0xa4beea44UL) + HH(d,a,b,c,W[4],11,0x4bdecfa9UL) + HH(c,d,a,b,W[7],16,0xf6bb4b60UL) + HH(b,c,d,a,W[10],23,0xbebfbc70UL) + HH(a,b,c,d,W[13],4,0x289b7ec6UL) + HH(d,a,b,c,W[0],11,0xeaa127faUL) + HH(c,d,a,b,W[3],16,0xd4ef3085UL) + HH(b,c,d,a,W[6],23,0x04881d05UL) + HH(a,b,c,d,W[9],4,0xd9d4d039UL) + HH(d,a,b,c,W[12],11,0xe6db99e5UL) + HH(c,d,a,b,W[15],16,0x1fa27cf8UL) + HH(b,c,d,a,W[2],23,0xc4ac5665UL) + II(a,b,c,d,W[0],6,0xf4292244UL) + II(d,a,b,c,W[7],10,0x432aff97UL) + II(c,d,a,b,W[14],15,0xab9423a7UL) + II(b,c,d,a,W[5],21,0xfc93a039UL) + II(a,b,c,d,W[12],6,0x655b59c3UL) + II(d,a,b,c,W[3],10,0x8f0ccc92UL) + II(c,d,a,b,W[10],15,0xffeff47dUL) + II(b,c,d,a,W[1],21,0x85845dd1UL) + II(a,b,c,d,W[8],6,0x6fa87e4fUL) + II(d,a,b,c,W[15],10,0xfe2ce6e0UL) + II(c,d,a,b,W[6],15,0xa3014314UL) + II(b,c,d,a,W[13],21,0x4e0811a1UL) + II(a,b,c,d,W[4],6,0xf7537e82UL) + II(d,a,b,c,W[11],10,0xbd3af235UL) + II(c,d,a,b,W[2],15,0x2ad7d2bbUL) + II(b,c,d,a,W[9],21,0xeb86d391UL) + + md->md5.state[0] = md->md5.state[0] + a; + md->md5.state[1] = md->md5.state[1] + b; + md->md5.state[2] = md->md5.state[2] + c; + md->md5.state[3] = md->md5.state[3] + d; +} + +#ifdef CLEAN_STACK +static void md5_compress(hash_state *md, unsigned char *buf) +{ + _md5_compress(md, buf); + burn_stack(sizeof(ulong32) * 21); +} +#endif + +void md5_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->md5.state[0] = 0x67452301UL; + md->md5.state[1] = 0xefcdab89UL; + md->md5.state[2] = 0x98badcfeUL; + md->md5.state[3] = 0x10325476UL; + md->md5.curlen = 0; + md->md5.length = 0; +} + +HASH_PROCESS(md5_process, md5_compress, md5, 64) + +int md5_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->md5.curlen >= sizeof(md->md5.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->md5.length += md->md5.curlen * 8; + + /* append the '1' bit */ + md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->md5.curlen > 56) { + while (md->md5.curlen < 64) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + md5_compress(md, md->md5.buf); + md->md5.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->md5.curlen < 56) { + md->md5.buf[md->md5.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->md5.length, md->md5.buf+56); + md5_compress(md, md->md5.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->md5.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int md5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[16]; + } tests[] = { + { "", + { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, + { "a", + {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, + { "abc", + { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, + { "message digest", + { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, + { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, + { NULL, { 0 } } + }; + + int i; + unsigned char tmp[16]; + hash_state md; + + for (i = 0; tests[i].msg != NULL; i++) { + md5_init(&md); + md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + md5_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mem.c b/tnl-1.5.0/tnl/libtomcrypt/mem.c new file mode 100644 index 0000000000000000000000000000000000000000..41a1c12824f4c5bde139d44d6ce371c0c5806565 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mem.c @@ -0,0 +1,19 @@ +#include "mycrypt.h" + +void zeromem(void *dst, size_t len) +{ + unsigned char *mem = (unsigned char *)dst; + _ARGCHK(dst != NULL); + while (len-- > 0) + *mem++ = 0; +} + +void burn_stack(unsigned long len) +{ + unsigned char buf[32]; + zeromem(buf, sizeof(buf)); + if (len > (unsigned long)sizeof(buf)) + burn_stack(len - sizeof(buf)); +} + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mpi.c b/tnl-1.5.0/tnl/libtomcrypt/mpi.c new file mode 100644 index 0000000000000000000000000000000000000000..38f477798da1b9e4e158ede2f968df632e3702ee --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mpi.c @@ -0,0 +1,7942 @@ +/* Start: bn_error.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +static const struct { + int code; + char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +char *mp_error_to_string(int code) +{ + int x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + + +/* End: bn_error.c */ + +/* Start: bn_fast_mp_invmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes the modular inverse via binary extended euclidean algorithm, + * that is c = 1/a mod b + * + * Based on mp_invmod except this is optimized for the case where b is + * odd as per HAC Note 14.64 on pp. 610 + */ +int +fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, B, D; + int res, neg; + + /* 2. [modified] b must be odd */ + if (mp_iseven (b) == 1) { + return MP_VAL; + } + + /* init all our temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x == modulus, y == value to invert */ + if ((res = mp_copy (b, &x)) != MP_OKAY) { + goto __ERR; + } + + /* we need y = |a| */ + if ((res = mp_abs (a, &y)) != MP_OKAY) { + goto __ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto __ERR; + } + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto __ERR; + } + /* 4.2 if B is odd then */ + if (mp_isodd (&B) == 1) { + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto __ERR; + } + } + /* B = B/2 */ + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto __ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto __ERR; + } + /* 5.2 if D is odd then */ + if (mp_isodd (&D) == 1) { + /* D = (D-x)/2 */ + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto __ERR; + } + } + /* D = D/2 */ + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto __ERR; + } + } else { + /* v - v - u, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) { + goto top; + } + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto __ERR; + } + + /* b is now the inverse */ + neg = a->sign; + while (D.sign == MP_NEG) { + if ((res = mp_add (&D, b, &D)) != MP_OKAY) { + goto __ERR; + } + } + mp_exch (&D, c); + c->sign = neg; + res = MP_OKAY; + +__ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); + return res; +} + +/* End: bn_fast_mp_invmod.c */ + +/* Start: bn_fast_mp_montgomery_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes xR**-1 == x (mod N) via Montgomery Reduction + * + * This is an optimized implementation of mp_montgomery_reduce + * which uses the comba method to quickly calculate the columns of the + * reduction. + * + * Based on Algorithm 14.32 on pp.601 of HAC. +*/ +int +fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, olduse; + mp_word W[MP_WARRAY]; + + /* get old used count */ + olduse = x->used; + + /* grow a as required */ + if (x->alloc < n->used + 1) { + if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) { + return res; + } + } + + /* first we have to get the digits of the input into + * an array of double precision words W[...] + */ + { + register mp_word *_W; + register mp_digit *tmpx; + + /* alias for the W[] array */ + _W = W; + + /* alias for the digits of x*/ + tmpx = x->dp; + + /* copy the digits of a into W[0..a->used-1] */ + for (ix = 0; ix < x->used; ix++) { + *_W++ = *tmpx++; + } + + /* zero the high words of W[a->used..m->used*2] */ + for (; ix < n->used * 2 + 1; ix++) { + *_W++ = 0; + } + } + + /* now we proceed to zero successive digits + * from the least significant upwards + */ + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * m' mod b + * + * We avoid a double precision multiplication (which isn't required) + * by casting the value down to a mp_digit. Note this requires + * that W[ix-1] have the carry cleared (see after the inner loop) + */ + register mp_digit mu; + mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK); + + /* a = a + mu * m * b**i + * + * This is computed in place and on the fly. The multiplication + * by b**i is handled by offseting which columns the results + * are added to. + * + * Note the comba method normally doesn't handle carries in the + * inner loop In this case we fix the carry from the previous + * column since the Montgomery reduction requires digits of the + * result (so far) [see above] to work. This is + * handled by fixing up one carry after the inner loop. The + * carry fixups are done in order so after these loops the + * first m->used words of W[] have the carries fixed + */ + { + register int iy; + register mp_digit *tmpn; + register mp_word *_W; + + /* alias for the digits of the modulus */ + tmpn = n->dp; + + /* Alias for the columns set by an offset of ix */ + _W = W + ix; + + /* inner loop */ + for (iy = 0; iy < n->used; iy++) { + *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++); + } + } + + /* now fix carry for next digit, W[ix+1] */ + W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT); + } + + /* now we have to propagate the carries and + * shift the words downward [all those least + * significant digits we zeroed]. + */ + { + register mp_digit *tmpx; + register mp_word *_W, *_W1; + + /* nox fix rest of carries */ + + /* alias for current word */ + _W1 = W + ix; + + /* alias for next word, where the carry goes */ + _W = W + ++ix; + + for (; ix <= n->used * 2 + 1; ix++) { + *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT); + } + + /* copy out, A = A/b**n + * + * The result is A/b**n but instead of converting from an + * array of mp_word to mp_digit than calling mp_rshd + * we just copy them in the right order + */ + + /* alias for destination word */ + tmpx = x->dp; + + /* alias for shifted double precision result */ + _W = W + n->used; + + for (ix = 0; ix < n->used + 1; ix++) { + *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK)); + } + + /* zero oldused digits, if the input a was larger than + * m->used+1 we'll have to clear the digits + */ + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } + } + + /* set the max used and clamp */ + x->used = n->used + 1; + mp_clamp (x); + + /* if A >= m then A = A - m */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + return MP_OKAY; +} + +/* End: bn_fast_mp_montgomery_reduce.c */ + +/* Start: bn_fast_s_mp_mul_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* Fast (comba) multiplier + * + * This is the fast column-array [comba] multiplier. It is + * designed to compute the columns of the product first + * then handle the carries afterwards. This has the effect + * of making the nested loops that compute the columns very + * simple and schedulable on super-scalar processors. + * + * This has been modified to produce a variable number of + * digits of output so if say only a half-product is required + * you don't have to compute the upper half (a feature + * required for fast Barrett reduction). + * + * Based on Algorithm 14.12 on pp.595 of HAC. + * + */ +int +fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int olduse, res, pa, ix; + mp_word W[MP_WARRAY]; + + /* grow the destination as required */ + if (c->alloc < digs) { + if ((res = mp_grow (c, digs)) != MP_OKAY) { + return res; + } + } + + /* clear temp buf (the columns) */ + memset (W, 0, sizeof (mp_word) * digs); + + /* calculate the columns */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* this multiplier has been modified to allow you to + * control how many digits of output are produced. + * So at most we want to make upto "digs" digits of output. + * + * this adds products to distinct columns (at ix+iy) of W + * note that each step through the loop is not dependent on + * the previous which means the compiler can easily unroll + * the loop without scheduling problems + */ + { + register mp_digit tmpx, *tmpy; + register mp_word *_W; + register int iy, pb; + + /* alias for the the word on the left e.g. A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for the right side */ + tmpy = b->dp; + + /* alias for the columns, each step through the loop adds a new + term to each column + */ + _W = W + ix; + + /* the number of digits is limited by their placement. E.g. + we avoid multiplying digits that will end up above the # of + digits of precision requested + */ + pb = MIN (b->used, digs - ix); + + for (iy = 0; iy < pb; iy++) { + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); + } + } + + } + + /* setup dest */ + olduse = c->used; + c->used = digs; + + { + register mp_digit *tmpc; + + /* At this point W[] contains the sums of each column. To get the + * correct result we must take the extra bits from each column and + * carry them down + * + * Note that while this adds extra code to the multiplier it + * saves time since the carry propagation is removed from the + * above nested loop.This has the effect of reducing the work + * from N*(N+N*c)==N**2 + c*N**2 to N**2 + N*c where c is the + * cost of the shifting. On very small numbers this is slower + * but on most cryptographic size numbers it is faster. + * + * In this particular implementation we feed the carries from + * behind which means when the loop terminates we still have one + * last digit to copy + */ + tmpc = c->dp; + for (ix = 1; ix < digs; ix++) { + /* forward the carry from the previous temp */ + W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* now extract the previous digit [below the carry] */ + *tmpc++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); + } + /* fetch the last digit */ + *tmpc++ = (mp_digit) (W[digs - 1] & ((mp_word) MP_MASK)); + + /* clear unused digits [that existed in the old copy of c] */ + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } + } + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_fast_s_mp_mul_digs.c */ + +/* Start: bn_fast_s_mp_mul_high_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ + #include + +/* this is a modified version of fast_s_mp_mul_digs that only produces + * output digits *above* digs. See the comments for fast_s_mp_mul_digs + * to see how it works. + * + * This is used in the Barrett reduction since for one of the multiplications + * only the higher digits were needed. This essentially halves the work. + * + * Based on Algorithm 14.12 on pp.595 of HAC. + */ +int +fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + int oldused, newused, res, pa, pb, ix; + mp_word W[MP_WARRAY]; + + /* calculate size of product and allocate more space if required */ + newused = a->used + b->used + 1; + if (c->alloc < newused) { + if ((res = mp_grow (c, newused)) != MP_OKAY) { + return res; + } + } + + /* like the other comba method we compute the columns first */ + pa = a->used; + pb = b->used; + memset (W + digs, 0, (pa + pb + 1 - digs) * sizeof (mp_word)); + for (ix = 0; ix < pa; ix++) { + { + register mp_digit tmpx, *tmpy; + register int iy; + register mp_word *_W; + + /* work todo, that is we only calculate digits that are at "digs" or above */ + iy = digs - ix; + + /* copy of word on the left of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias for right side */ + tmpy = b->dp + iy; + + /* alias for the columns of output. Offset to be equal to or above the + * smallest digit place requested + */ + _W = W + digs; + + /* skip cases below zero where ix > digs */ + if (iy < 0) { + iy = abs(iy); + tmpy += iy; + _W += iy; + iy = 0; + } + + /* compute column products for digits above the minimum */ + for (; iy < pb; iy++) { + *_W++ += ((mp_word) tmpx) * ((mp_word)*tmpy++); + } + } + } + + /* setup dest */ + oldused = c->used; + c->used = newused; + + /* now convert the array W downto what we need + * + * See comments in bn_fast_s_mp_mul_digs.c + */ + for (ix = digs + 1; ix < newused; ix++) { + W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + c->dp[ix - 1] = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); + } + c->dp[newused - 1] = (mp_digit) (W[newused - 1] & ((mp_word) MP_MASK)); + + for (; ix < oldused; ix++) { + c->dp[ix] = 0; + } + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_fast_s_mp_mul_high_digs.c */ + +/* Start: bn_fast_s_mp_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* fast squaring + * + * This is the comba method where the columns of the product + * are computed first then the carries are computed. This + * has the effect of making a very simple inner loop that + * is executed the most + * + * W2 represents the outer products and W the inner. + * + * A further optimizations is made because the inner + * products are of the form "A * B * 2". The *2 part does + * not need to be computed until the end which is good + * because 64-bit shifts are slow! + * + * Based on Algorithm 14.16 on pp.597 of HAC. + * + */ +int +fast_s_mp_sqr (mp_int * a, mp_int * b) +{ + int olduse, newused, res, ix, pa; + mp_word W2[MP_WARRAY], W[MP_WARRAY]; + + /* calculate size of product and allocate as required */ + pa = a->used; + newused = pa + pa + 1; + if (b->alloc < newused) { + if ((res = mp_grow (b, newused)) != MP_OKAY) { + return res; + } + } + + /* zero temp buffer (columns) + * Note that there are two buffers. Since squaring requires + * a outer and inner product and the inner product requires + * computing a product and doubling it (a relatively expensive + * op to perform n**2 times if you don't have to) the inner and + * outer products are computed in different buffers. This way + * the inner product can be doubled using n doublings instead of + * n**2 + */ + memset (W, 0, newused * sizeof (mp_word)); + memset (W2, 0, newused * sizeof (mp_word)); + + /* This computes the inner product. To simplify the inner N**2 loop + * the multiplication by two is done afterwards in the N loop. + */ + for (ix = 0; ix < pa; ix++) { + /* compute the outer product + * + * Note that every outer product is computed + * for a particular column only once which means that + * there is no need todo a double precision addition + * into the W2[] array. + */ + W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); + + { + register mp_digit tmpx, *tmpy; + register mp_word *_W; + register int iy; + + /* copy of left side */ + tmpx = a->dp[ix]; + + /* alias for right side */ + tmpy = a->dp + (ix + 1); + + /* the column to store the result in */ + _W = W + (ix + ix + 1); + + /* inner products */ + for (iy = ix + 1; iy < pa; iy++) { + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); + } + } + } + + /* setup dest */ + olduse = b->used; + b->used = newused; + + /* now compute digits + * + * We have to double the inner product sums, add in the + * outer product sums, propagate carries and convert + * to single precision. + */ + { + register mp_digit *tmpb; + + /* double first value, since the inner products are + * half of what they should be + */ + W[0] += W[0] + W2[0]; + + tmpb = b->dp; + for (ix = 1; ix < newused; ix++) { + /* double/add next digit */ + W[ix] += W[ix] + W2[ix]; + + /* propagate carry forwards [from the previous digit] */ + W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* store the current digit now that the carry isn't + * needed + */ + *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); + } + /* set the last value. Note even if the carry is zero + * this is required since the next step will not zero + * it if b originally had a value at b->dp[2*a.used] + */ + *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK)); + + /* clear high digits of b if there were any originally */ + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } + } + + mp_clamp (b); + return MP_OKAY; +} + +/* End: bn_fast_s_mp_sqr.c */ + +/* Start: bn_mp_2expt.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes a = 2**b + * + * Simple algorithm which zeroes the int, grows it then just sets one bit + * as required. + */ +int +mp_2expt (mp_int * a, int b) +{ + int res; + + /* zero a as per default */ + mp_zero (a); + + /* grow a to accomodate the single bit */ + if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + + /* set the used count of where the bit will go */ + a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ + a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT); + + return MP_OKAY; +} + +/* End: bn_mp_2expt.c */ + +/* Start: bn_mp_abs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* b = |a| + * + * Simple function copies the input and fixes the sign to positive + */ +int +mp_abs (mp_int * a, mp_int * b) +{ + int res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + } + + /* force the sign of b to positive */ + b->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* End: bn_mp_abs.c */ + +/* Start: bn_mp_add.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* high level addition (handles signs) */ +int mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + /* get sign of both inputs */ + sa = a->sign; + sb = b->sign; + + /* handle two cases, not four */ + if (sa == sb) { + /* both positive or both negative */ + /* add their magnitudes, copy the sign */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* one positive, the other negative */ + /* subtract the one with the greater magnitude from */ + /* the one of the lesser magnitude. The result gets */ + /* the sign of the one with the greater magnitude. */ + if (mp_cmp_mag (a, b) == MP_LT) { + c->sign = sb; + res = s_mp_sub (b, a, c); + } else { + c->sign = sa; + res = s_mp_sub (a, b, c); + } + } + return res; +} + + +/* End: bn_mp_add.c */ + +/* Start: bn_mp_add_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* single digit addition */ +int +mp_add_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative and |a| >= b, call c = |a| - b */ + if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { + /* temporarily fix sign of a */ + a->sign = MP_ZPOS; + + /* c = |a| - b */ + res = mp_sub_d(a, b, c); + + /* fix sign */ + a->sign = c->sign = MP_NEG; + + return res; + } + + /* old number of used digits in c */ + oldused = c->used; + + /* sign always positive */ + c->sign = MP_ZPOS; + + /* source alias */ + tmpa = a->dp; + + /* destination alias */ + tmpc = c->dp; + + /* if a is positive */ + if (a->sign == MP_ZPOS) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ + mu; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + } + /* set final carry */ + ix++; + *tmpc++ = mu; + + /* setup size */ + c->used = a->used + 1; + } else { + /* a was negative and |a| < b */ + c->used = 1; + + /* the result is a single digit */ + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } + + /* setup count so the clearing of oldused + * can fall through correctly + */ + ix = 1; + } + + /* now zero to oldused */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + + return MP_OKAY; +} + + +/* End: bn_mp_add_d.c */ + +/* Start: bn_mp_addmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* d = a + b (mod c) */ +int +mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_add (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + +/* End: bn_mp_addmod.c */ + +/* Start: bn_mp_and.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* AND two ints together */ +int +mp_and (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } + + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; + } + + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_and.c */ + +/* Start: bn_mp_clamp.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* trim unused digits + * + * This is used to ensure that leading zero digits are + * trimed and the leading "used" digit will be non-zero + * Typically very fast. Also fixes the sign if there + * are no more leading digits + */ +void +mp_clamp (mp_int * a) +{ + /* decrease used while the most significant digit is + * zero. + */ + while (a->used > 0 && a->dp[a->used - 1] == 0) { + --(a->used); + } + + /* reset the sign flag if used == 0 */ + if (a->used == 0) { + a->sign = MP_ZPOS; + } +} + +/* End: bn_mp_clamp.c */ + +/* Start: bn_mp_clear.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* clear one (frees) */ +void +mp_clear (mp_int * a) +{ + /* only do anything if a hasn't been freed previously */ + if (a->dp != NULL) { + /* first zero the digits */ + memset (a->dp, 0, sizeof (mp_digit) * a->used); + + /* free ram */ + XFREE(a->dp); + + /* reset members to make debugging easier */ + a->dp = NULL; + a->alloc = a->used = 0; + a->sign = MP_ZPOS; + } +} + +/* End: bn_mp_clear.c */ + +/* Start: bn_mp_clear_multi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} + +/* End: bn_mp_clear_multi.c */ + +/* Start: bn_mp_cmp.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* compare two ints (signed)*/ +int +mp_cmp (mp_int * a, mp_int * b) +{ + /* compare based on sign */ + if (a->sign != b->sign) { + if (a->sign == MP_NEG) { + return MP_LT; + } else { + return MP_GT; + } + } + + /* compare digits */ + if (a->sign == MP_NEG) { + /* if negative compare opposite direction */ + return mp_cmp_mag(b, a); + } else { + return mp_cmp_mag(a, b); + } +} + +/* End: bn_mp_cmp.c */ + +/* Start: bn_mp_cmp_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* compare a digit */ +int mp_cmp_d(mp_int * a, mp_digit b) +{ + /* compare based on sign */ + if (a->sign == MP_NEG) { + return MP_LT; + } + + /* compare based on magnitude */ + if (a->used > 1) { + return MP_GT; + } + + /* compare the only digit of a to b */ + if (a->dp[0] > b) { + return MP_GT; + } else if (a->dp[0] < b) { + return MP_LT; + } else { + return MP_EQ; + } +} + +/* End: bn_mp_cmp_d.c */ + +/* Start: bn_mp_cmp_mag.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* compare maginitude of two ints (unsigned) */ +int mp_cmp_mag (mp_int * a, mp_int * b) +{ + int n; + mp_digit *tmpa, *tmpb; + + /* compare based on # of non-zero digits */ + if (a->used > b->used) { + return MP_GT; + } + + if (a->used < b->used) { + return MP_LT; + } + + /* alias for a */ + tmpa = a->dp + (a->used - 1); + + /* alias for b */ + tmpb = b->dp + (a->used - 1); + + /* compare based on digits */ + for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { + if (*tmpa > *tmpb) { + return MP_GT; + } + + if (*tmpa < *tmpb) { + return MP_LT; + } + } + return MP_EQ; +} + +/* End: bn_mp_cmp_mag.c */ + +/* Start: bn_mp_cnt_lsb.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a) +{ + int x; + mp_digit q; + + /* easy out */ + if (mp_iszero(a) == 1) { + return 0; + } + + /* scan lower digits until non-zero */ + for (x = 0; x < a->used && a->dp[x] == 0; x++); + q = a->dp[x]; + x *= DIGIT_BIT; + + /* now scan this digit until a 1 is found */ + while ((q & 1) == 0) { + q >>= 1; + x += 1; + } + + return x; +} + + +/* End: bn_mp_cnt_lsb.c */ + +/* Start: bn_mp_copy.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* copy, b = a */ +int +mp_copy (mp_int * a, mp_int * b) +{ + int res, n; + + /* if dst == src do nothing */ + if (a == b) { + return MP_OKAY; + } + + /* grow dest */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + /* zero b and copy the parameters over */ + { + register mp_digit *tmpa, *tmpb; + + /* pointer aliases */ + + /* source */ + tmpa = a->dp; + + /* destination */ + tmpb = b->dp; + + /* copy all the digits */ + for (n = 0; n < a->used; n++) { + *tmpb++ = *tmpa++; + } + + /* clear high digits */ + for (; n < b->used; n++) { + *tmpb++ = 0; + } + } + + /* copy used count and sign */ + b->used = a->used; + b->sign = a->sign; + return MP_OKAY; +} + +/* End: bn_mp_copy.c */ + +/* Start: bn_mp_count_bits.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* returns the number of bits in an int */ +int +mp_count_bits (mp_int * a) +{ + int r; + mp_digit q; + + /* shortcut */ + if (a->used == 0) { + return 0; + } + + /* get number of digits and add that */ + r = (a->used - 1) * DIGIT_BIT; + + /* take the last digit and count the bits in it */ + q = a->dp[a->used - 1]; + while (q > ((mp_digit) 0)) { + ++r; + q >>= ((mp_digit) 1); + } + return r; +} + +/* End: bn_mp_count_bits.c */ + +/* Start: bn_mp_div.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* integer signed division. + * c*b + d == a [e.g. a/b, c=quotient, d=remainder] + * HAC pp.598 Algorithm 14.20 + * + * Note that the description in HAC is horribly + * incomplete. For example, it doesn't consider + * the case where digits are removed from 'x' in + * the inner loop. It also doesn't consider the + * case that y has fewer than three digits, etc.. + * + * The overall algorithm is as described as + * 14.20 from HAC but fixed to treat these cases. +*/ +int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + mp_int q, x, y, t1, t2; + int res, n, t, i, norm, neg; + + /* is divisor zero ? */ + if (mp_iszero (b) == 1) { + return MP_VAL; + } + + /* if a < b then q=0, r = a */ + if (mp_cmp_mag (a, b) == MP_LT) { + if (d != NULL) { + res = mp_copy (a, d); + } else { + res = MP_OKAY; + } + if (c != NULL) { + mp_zero (c); + } + return res; + } + + if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { + return res; + } + q.used = a->used + 2; + + if ((res = mp_init (&t1)) != MP_OKAY) { + goto __Q; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto __T1; + } + + if ((res = mp_init_copy (&x, a)) != MP_OKAY) { + goto __T2; + } + + if ((res = mp_init_copy (&y, b)) != MP_OKAY) { + goto __X; + } + + /* fix the sign */ + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + x.sign = y.sign = MP_ZPOS; + + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (int)(DIGIT_BIT-1)) { + norm = (DIGIT_BIT-1) - norm; + if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) { + goto __Y; + } + if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) { + goto __Y; + } + } else { + norm = 0; + } + + /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ + n = x.used - 1; + t = y.used - 1; + + /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ + if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + goto __Y; + } + + while (mp_cmp (&x, &y) != MP_LT) { + ++(q.dp[n - t]); + if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) { + goto __Y; + } + } + + /* reset y by shifting it back down */ + mp_rshd (&y, n - t); + + /* step 3. for i from n down to (t + 1) */ + for (i = n; i >= (t + 1); i--) { + if (i > x.used) { + continue; + } + + /* step 3.1 if xi == yt then set q{i-t-1} to b-1, + * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ + if (x.dp[i] == y.dp[t]) { + q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); + } else { + mp_word tmp; + tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); + tmp |= ((mp_word) x.dp[i - 1]); + tmp /= ((mp_word) y.dp[t]); + if (tmp > (mp_word) MP_MASK) + tmp = MP_MASK; + q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); + } + + /* while (q{i-t-1} * (yt * b + y{t-1})) > + xi * b**2 + xi-1 * b + xi-2 + + do q{i-t-1} -= 1; + */ + q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; + do { + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; + + /* find left hand */ + mp_zero (&t1); + t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; + t1.dp[1] = y.dp[t]; + t1.used = 2; + if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto __Y; + } + + /* find right hand */ + t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; + t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; + t2.dp[2] = x.dp[i]; + t2.used = 3; + } while (mp_cmp_mag(&t1, &t2) == MP_GT); + + /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ + if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) { + goto __Y; + } + + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto __Y; + } + + if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) { + goto __Y; + } + + /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ + if (x.sign == MP_NEG) { + if ((res = mp_copy (&y, &t1)) != MP_OKAY) { + goto __Y; + } + if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) { + goto __Y; + } + if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) { + goto __Y; + } + + q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; + } + } + + /* now q is the quotient and x is the remainder + * [which we have to normalize] + */ + + /* get sign before writing to c */ + x.sign = a->sign; + + if (c != NULL) { + mp_clamp (&q); + mp_exch (&q, c); + c->sign = neg; + } + + if (d != NULL) { + mp_div_2d (&x, norm, &x, NULL); + mp_exch (&x, d); + } + + res = MP_OKAY; + +__Y:mp_clear (&y); +__X:mp_clear (&x); +__T2:mp_clear (&t2); +__T1:mp_clear (&t1); +__Q:mp_clear (&q); + return res; +} + +/* End: bn_mp_div.c */ + +/* Start: bn_mp_div_2.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* b = a/2 */ +int mp_div_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* copy */ + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* source alias */ + tmpa = a->dp + b->used - 1; + + /* dest alias */ + tmpb = b->dp + b->used - 1; + + /* carry */ + r = 0; + for (x = b->used - 1; x >= 0; x--) { + /* get the carry for the next iteration */ + rr = *tmpa & 1; + + /* shift the current digit, add in carry and store */ + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); + + /* forward carry to next iteration */ + r = rr; + } + + /* zero excess digits */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + mp_clamp (b); + return MP_OKAY; +} + +/* End: bn_mp_div_2.c */ + +/* Start: bn_mp_div_2d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ +int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) +{ + mp_digit D, r, rr; + int x, res; + mp_int t; + + + /* if the shift count is <= 0 then we do no work */ + if (b <= 0) { + res = mp_copy (a, c); + if (d != NULL) { + mp_zero (d); + } + return res; + } + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + /* get the remainder */ + if (d != NULL) { + if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + mp_rshd (c, b / DIGIT_BIT); + } + + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit) (b % DIGIT_BIT); + if (D != 0) { + register mp_digit *tmpc, mask, shift; + + /* mask */ + mask = (((mp_digit)1) << D) - 1; + + /* shift for lsb */ + shift = DIGIT_BIT - D; + + /* alias */ + tmpc = c->dp + (c->used - 1); + + /* carry */ + r = 0; + for (x = c->used - 1; x >= 0; x--) { + /* get the lower bits of this word in a temp */ + rr = *tmpc & mask; + + /* shift the current word and mix in the carry bits from the previous word */ + *tmpc = (*tmpc >> D) | (r << shift); + --tmpc; + + /* set the carry to the carry bits of the current word found above */ + r = rr; + } + } + mp_clamp (c); + if (d != NULL) { + mp_exch (&t, d); + } + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_div_2d.c */ + +/* Start: bn_mp_div_3.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* divide by three (based on routine from MPI and the GMP manual) */ +int +mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +{ + mp_int q; + mp_word w, t; + mp_digit b; + int res, ix; + + /* b = 2**DIGIT_BIT / 3 */ + b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= 3) { + /* multiply w by [1/3] */ + t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= (t << ((mp_word)1)) + t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3) { + t += 1; + w -= 3; + } + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } + + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + + +/* End: bn_mp_div_3.c */ + +/* Start: bn_mp_div_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + for (x = 1; x < DIGIT_BIT; x++) { + if (b == (((mp_digit)1)<dp[0] & ((1<used)) != MP_OKAY) { + return res; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); + + if (w >= b) { + t = (mp_digit)(w / b); + w -= ((mp_word)t) * ((mp_word)b); + } else { + t = 0; + } + q.dp[ix] = (mp_digit)t; + } + + if (d != NULL) { + *d = (mp_digit)w; + } + + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); + + return res; +} + + +/* End: bn_mp_div_d.c */ + +/* Start: bn_mp_dr_is_modulus.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + + +/* End: bn_mp_dr_is_modulus.c */ + +/* Start: bn_mp_dr_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. + * + * Based on algorithm from the paper + * + * "Generating Efficient Primes for Discrete Log Cryptosystems" + * Chae Hoon Lim, Pil Loong Lee, + * POSTECH Information Research Laboratories + * + * The modulus must be of a special format [see manual] + * + * Has been modified to use algorithm 7.10 from the LTM book instead + * + * Input x must be in the range 0 <= x <= (n-1)**2 + */ +int +mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k) +{ + int err, i, m; + mp_word r; + mp_digit mu, *tmpx1, *tmpx2; + + /* m = digits in modulus */ + m = n->used; + + /* ensure that "x" has at least 2m digits */ + if (x->alloc < m + m) { + if ((err = mp_grow (x, m + m)) != MP_OKAY) { + return err; + } + } + +/* top of loop, this is where the code resumes if + * another reduction pass is required. + */ +top: + /* aliases for digits */ + /* alias for lower half of x */ + tmpx1 = x->dp; + + /* alias for upper half of x, or x/B**m */ + tmpx2 = x->dp + m; + + /* set carry to zero */ + mu = 0; + + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ + for (i = 0; i < m; i++) { + r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; + *tmpx1++ = (mp_digit)(r & MP_MASK); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); + } + + /* set final carry */ + *tmpx1++ = mu; + + /* zero words above m */ + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } + + /* clamp, sub and return */ + mp_clamp (x); + + /* if x >= n then subtract and reduce again + * Each successive "recursion" makes the input smaller and smaller. + */ + if (mp_cmp_mag (x, n) != MP_LT) { + s_mp_sub(x, n, x); + goto top; + } + return MP_OKAY; +} + +/* End: bn_mp_dr_reduce.c */ + +/* Start: bn_mp_dr_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + + +/* End: bn_mp_dr_setup.c */ + +/* Start: bn_mp_exch.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* swap the elements of two integers, for cases where you can't simply swap the + * mp_int pointers around + */ +void +mp_exch (mp_int * a, mp_int * b) +{ + mp_int t; + + t = *a; + *a = *b; + *b = t; +} + +/* End: bn_mp_exch.c */ + +/* Start: bn_mp_expt_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) +{ + int res, x; + mp_int g; + + if ((res = mp_init_copy (&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set (c, 1); + + for (x = 0; x < (int) DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr (c, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { + if ((res = mp_mul (c, &g, c)) != MP_OKAY) { + mp_clear (&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + + mp_clear (&g); + return MP_OKAY; +} + +/* End: bn_mp_expt_d.c */ + +/* Start: bn_mp_exptmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + + +/* this is a shell function that calls either the normal or Montgomery + * exptmod functions. Originally the call to the montgomery code was + * embedded in the normal function but that wasted alot of stack space + * for nothing (since 99% of the time the Montgomery code would be called) + */ +int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + int dr; + + /* modulus P must be positive */ + if (P->sign == MP_NEG) { + return MP_VAL; + } + + /* if exponent X is negative we have to recurse */ + if (X->sign == MP_NEG) { + mp_int tmpG, tmpX; + int err; + + /* first compute 1/G mod P */ + if ((err = mp_init(&tmpG)) != MP_OKAY) { + return err; + } + if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + + /* now get |X| */ + if ((err = mp_init(&tmpX)) != MP_OKAY) { + mp_clear(&tmpG); + return err; + } + if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* and now compute (1/G)**|X| instead of G**X [X < 0] */ + err = mp_exptmod(&tmpG, &tmpX, P, Y); + mp_clear_multi(&tmpG, &tmpX, NULL); + return err; + } + + /* is it a DR modulus? */ + dr = mp_dr_is_modulus(P); + + /* if not, is it a uDR modulus? */ + if (dr == 0) { + dr = mp_reduce_is_2k(P) << 1; + } + + /* if the modulus is odd or dr != 0 use the fast method */ + if (mp_isodd (P) == 1 || dr != 0) { + return mp_exptmod_fast (G, X, P, Y, dr); + } else { + /* otherwise use the generic Barrett reduction technique */ + return s_mp_exptmod (G, X, P, Y); + } +} + + +/* End: bn_mp_exptmod.c */ + +/* Start: bn_mp_exptmod_fast.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 + * + * Uses a left-to-right k-ary sliding window to compute the modular exponentiation. + * The value of k changes based on the size of the exponent. + * + * Uses Montgomery or Diminished Radix reduction [whichever appropriate] + */ + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int +mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) +{ + mp_int M[TAB_SIZE], res; + mp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* use a pointer to the reduction algorithm. This allows us to use + * one of many reduction algorithms without modding the guts of + * the code with if statements everywhere. + */ + int (*redux)(mp_int*,mp_int*,mp_digit); + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* determine and setup reduction code */ + if (redmode == 0) { + /* now setup montgomery */ + if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) { + goto __M; + } + + /* automatically pick the comba one if available (saves quite a few calls/ifs) */ + if (((P->used * 2 + 1) < MP_WARRAY) && + P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + redux = fast_mp_montgomery_reduce; + } else { + /* use slower baseline Montgomery method */ + redux = mp_montgomery_reduce; + } + } else if (redmode == 1) { + /* setup DR reduction for moduli of the form B**k - b */ + mp_dr_setup(P, &mp); + redux = mp_dr_reduce; + } else { + /* setup DR reduction for moduli of the form 2**k - b */ + if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { + goto __M; + } + redux = mp_reduce_2k; + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto __M; + } + + /* create M table + * + * The M table contains powers of the input base, e.g. M[x] = G^x mod P + * + * The first half of the table is not computed though accept for M[0] and M[1] + */ + + if (redmode == 0) { + /* now we need R mod m */ + if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) { + goto __RES; + } + + /* now set M[1] to G * R mod m */ + if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) { + goto __RES; + } + } else { + mp_set(&res, 1); + if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { + goto __RES; + } + } + + /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __RES; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* create upper table */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&M[x], P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ + if (digidx == -1) { + break; + } + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + + /* get next bit of the window */ + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = redux (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + } + } + } + + if (redmode == 0) { + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ + if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { + goto __RES; + } + } + + /* swap res with Y */ + mp_exch (&res, Y); + err = MP_OKAY; +__RES:mp_clear (&res); +__M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + +/* End: bn_mp_exptmod_fast.c */ + +/* Start: bn_mp_fread.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + + +/* End: bn_mp_fread.c */ + +/* Start: bn_mp_fwrite.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +int mp_fwrite(mp_int *a, int radix, FILE *stream) +{ + char *buf; + int err, len, x; + + len = mp_radix_size(a, radix); + if (len == 0) { + return MP_VAL; + } + + buf = XMALLOC (len); + if (buf == NULL) { + return MP_MEM; + } + + if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { + XFREE (buf); + return err; + } + + for (x = 0; x < len; x++) { + if (fputc(buf[x], stream) == EOF) { + XFREE (buf); + return MP_VAL; + } + } + + XFREE (buf); + return MP_OKAY; +} + + +/* End: bn_mp_fwrite.c */ + +/* Start: bn_mp_gcd.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* Greatest Common Divisor using the binary method */ +int mp_gcd (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int u, v; + int k, u_lsb, v_lsb, res; + + /* either zero than gcd is the largest */ + if (mp_iszero (a) == 1 && mp_iszero (b) == 0) { + return mp_abs (b, c); + } + if (mp_iszero (a) == 0 && mp_iszero (b) == 1) { + return mp_abs (a, c); + } + + /* optimized. At this point if a == 0 then + * b must equal zero too + */ + if (mp_iszero (a) == 1) { + mp_zero(c); + return MP_OKAY; + } + + /* get copies of a and b we can modify */ + if ((res = mp_init_copy (&u, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init_copy (&v, b)) != MP_OKAY) { + goto __U; + } + + /* must be positive for the remainder of the algorithm */ + u.sign = v.sign = MP_ZPOS; + + /* B1. Find the common power of two for u and v */ + u_lsb = mp_cnt_lsb(&u); + v_lsb = mp_cnt_lsb(&v); + k = MIN(u_lsb, v_lsb); + + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto __V; + } + + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto __V; + } + } + + /* divide any remaining factors of two out */ + if (u_lsb != k) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + goto __V; + } + } + + if (v_lsb != k) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + goto __V; + } + } + + while (mp_iszero(&v) == 0) { + /* make sure v is the largest */ + if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ + mp_exch(&u, &v); + } + + /* subtract smallest from largest */ + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + goto __V; + } + + /* Divide out all factors of two */ + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + goto __V; + } + } + + /* multiply by 2**k which we divided out at the beginning */ + if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { + goto __V; + } + c->sign = MP_ZPOS; + res = MP_OKAY; +__V:mp_clear (&u); +__U:mp_clear (&v); + return res; +} + +/* End: bn_mp_gcd.c */ + +/* Start: bn_mp_grow.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* grow as required */ +int mp_grow (mp_int * a, int size) +{ + int i; + mp_digit *tmp; + + /* if the alloc size is smaller alloc more ram */ + if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* reallocate the array a->dp + * + * We store the return in a temporary variable + * in case the operation failed we don't want + * to overwrite the dp member of a. + */ + tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * size); + if (tmp == NULL) { + /* reallocation failed but "a" is still valid [can be freed] */ + return MP_MEM; + } + + /* reallocation succeeded so set a->dp */ + a->dp = tmp; + + /* zero excess digits */ + i = a->alloc; + a->alloc = size; + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } + } + return MP_OKAY; +} + +/* End: bn_mp_grow.c */ + +/* Start: bn_mp_init.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* init a new bigint */ +int mp_init (mp_int * a) +{ + /* allocate memory required and clear it */ + a->dp = OPT_CAST XCALLOC (sizeof (mp_digit), MP_PREC); + if (a->dp == NULL) { + return MP_MEM; + } + + /* set the used to zero, allocated digits to the default precision + * and sign to positive */ + a->used = 0; + a->alloc = MP_PREC; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* End: bn_mp_init.c */ + +/* Start: bn_mp_init_copy.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* creates "a" then copies b into it */ +int mp_init_copy (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_init (a)) != MP_OKAY) { + return res; + } + return mp_copy (b, a); +} + +/* End: bn_mp_init_copy.c */ + +/* Start: bn_mp_init_multi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} + + +/* End: bn_mp_init_multi.c */ + +/* Start: bn_mp_init_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* init an mp_init for a given size */ +int mp_init_size (mp_int * a, int size) +{ + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); + + /* alloc mem */ + a->dp = OPT_CAST XCALLOC (sizeof (mp_digit), size); + if (a->dp == NULL) { + return MP_MEM; + } + a->used = 0; + a->alloc = size; + a->sign = MP_ZPOS; + + return MP_OKAY; +} + +/* End: bn_mp_init_size.c */ + +/* Start: bn_mp_invmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* hac 14.61, pp608 */ +int mp_invmod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x, y, u, v, A, B, C, D; + int res; + + /* b cannot be negative */ + if (b->sign == MP_NEG || mp_iszero(b) == 1) { + return MP_VAL; + } + + /* if the modulus is odd we can use a faster routine instead */ + if (mp_isodd (b) == 1) { + return fast_mp_invmod (a, b, c); + } + + /* init temps */ + if ((res = mp_init_multi(&x, &y, &u, &v, + &A, &B, &C, &D, NULL)) != MP_OKAY) { + return res; + } + + /* x = a, y = b */ + if ((res = mp_copy (a, &x)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_copy (b, &y)) != MP_OKAY) { + goto __ERR; + } + + /* 2. [modified] if x,y are both even then return an error! */ + if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { + res = MP_VAL; + goto __ERR; + } + + /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ + if ((res = mp_copy (&x, &u)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_copy (&y, &v)) != MP_OKAY) { + goto __ERR; + } + mp_set (&A, 1); + mp_set (&D, 1); + +top: + /* 4. while u is even do */ + while (mp_iseven (&u) == 1) { + /* 4.1 u = u/2 */ + if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { + goto __ERR; + } + /* 4.2 if A or B is odd then */ + if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) { + /* A = (A+y)/2, B = (B-x)/2 */ + if ((res = mp_add (&A, &y, &A)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { + goto __ERR; + } + } + /* A = A/2, B = B/2 */ + if ((res = mp_div_2 (&A, &A)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { + goto __ERR; + } + } + + /* 5. while v is even do */ + while (mp_iseven (&v) == 1) { + /* 5.1 v = v/2 */ + if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { + goto __ERR; + } + /* 5.2 if C or D is odd then */ + if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) { + /* C = (C+y)/2, D = (D-x)/2 */ + if ((res = mp_add (&C, &y, &C)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { + goto __ERR; + } + } + /* C = C/2, D = D/2 */ + if ((res = mp_div_2 (&C, &C)) != MP_OKAY) { + goto __ERR; + } + if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* 6. if u >= v then */ + if (mp_cmp (&u, &v) != MP_LT) { + /* u = u - v, A = A - C, B = B - D */ + if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { + goto __ERR; + } + } else { + /* v - v - u, C = C - A, D = D - B */ + if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) { + goto __ERR; + } + + if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { + goto __ERR; + } + } + + /* if not zero goto step 4 */ + if (mp_iszero (&u) == 0) + goto top; + + /* now a = C, b = D, gcd == g*v */ + + /* if v != 1 then there is no inverse */ + if (mp_cmp_d (&v, 1) != MP_EQ) { + res = MP_VAL; + goto __ERR; + } + + /* if its too low */ + while (mp_cmp_d(&C, 0) == MP_LT) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { + goto __ERR; + } + } + + /* too big */ + while (mp_cmp_mag(&C, b) != MP_LT) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { + goto __ERR; + } + } + + /* C is now the inverse */ + mp_exch (&C, c); + res = MP_OKAY; +__ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); + return res; +} + +/* End: bn_mp_invmod.c */ + +/* Start: bn_mp_jacobi.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * HAC pp. 73 Algorithm 2.149 + */ +int mp_jacobi (mp_int * a, mp_int * p, int *c) +{ + mp_int a1, p1; + int k, s, r, res; + mp_digit residue; + + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + + /* step 1. if a == 0, return 0 */ + if (mp_iszero (a) == 1) { + *c = 0; + return MP_OKAY; + } + + /* step 2. if a == 1, return 1 */ + if (mp_cmp_d (a, 1) == MP_EQ) { + *c = 1; + return MP_OKAY; + } + + /* default */ + s = 0; + + /* step 3. write a = a1 * 2**k */ + if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&p1)) != MP_OKAY) { + goto __A1; + } + + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto __P1; + } + + /* step 4. if e is even set s=1 */ + if ((k & 1) == 0) { + s = 1; + } else { + /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ + residue = p->dp[0] & 7; + + if (residue == 1 || residue == 7) { + s = 1; + } else if (residue == 3 || residue == 5) { + s = -1; + } + } + + /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ + if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { + s = -s; + } + + /* if a1 == 1 we're done */ + if (mp_cmp_d (&a1, 1) == MP_EQ) { + *c = s; + } else { + /* n1 = n mod a1 */ + if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { + goto __P1; + } + if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { + goto __P1; + } + *c = s * r; + } + + /* done */ + res = MP_OKAY; +__P1:mp_clear (&p1); +__A1:mp_clear (&a1); + return res; +} + +/* End: bn_mp_jacobi.c */ + +/* Start: bn_mp_karatsuba_mul.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* c = |a| * |b| using Karatsuba Multiplication using + * three half size multiplications + * + * Let B represent the radix [e.g. 2**DIGIT_BIT] and + * let n represent half of the number of digits in + * the min(a,b) + * + * a = a1 * B**n + a0 + * b = b1 * B**n + b0 + * + * Then, a * b => + a1b1 * B**2n + ((a1 - a0)(b1 - b0) + a0b0 + a1b1) * B + a0b0 + * + * Note that a1b1 and a0b0 are used twice and only need to be + * computed once. So in total three half size (half # of + * digit) multiplications are performed, a0b0, a1b1 and + * (a1-b1)(a0-b0) + * + * Note that a multiplication of half the digits requires + * 1/4th the number of single precision multiplications so in + * total after one call 25% of the single precision multiplications + * are saved. Note also that the call to mp_mul can end up back + * in this function if the a0, a1, b0, or b1 are above the threshold. + * This is known as divide-and-conquer and leads to the famous + * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than + * the standard O(N**2) that the baseline/comba methods use. + * Generally though the overhead of this method doesn't pay off + * until a certain size (N ~ 80) is reached. + */ +int +mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int x0, x1, y0, y1, t1, x0y0, x1y1; + int B, err; + + /* default the return code to an error */ + err = MP_MEM; + + /* min # of digits */ + B = MIN (a->used, b->used); + + /* now divide in two */ + B = B / 2; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + if (mp_init_size (&y0, B) != MP_OKAY) + goto X1; + if (mp_init_size (&y1, b->used - B) != MP_OKAY) + goto Y0; + + /* init temps */ + if (mp_init_size (&t1, B * 2) != MP_OKAY) + goto Y1; + if (mp_init_size (&x0y0, B * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x1y1, B * 2) != MP_OKAY) + goto X0Y0; + + /* now shift the digits */ + x0.sign = x1.sign = a->sign; + y0.sign = y1.sign = b->sign; + + x0.used = y0.used = B; + x1.used = a->used - B; + y1.used = b->used - B; + + { + register int x; + register mp_digit *tmpa, *tmpb, *tmpx, *tmpy; + + /* we copy the digits directly instead of using higher level functions + * since we also need to shift the digits + */ + tmpa = a->dp; + tmpb = b->dp; + + tmpx = x0.dp; + tmpy = y0.dp; + for (x = 0; x < B; x++) { + *tmpx++ = *tmpa++; + *tmpy++ = *tmpb++; + } + + tmpx = x1.dp; + for (x = B; x < a->used; x++) { + *tmpx++ = *tmpa++; + } + + tmpy = y1.dp; + for (x = B; x < b->used; x++) { + *tmpy++ = *tmpb++; + } + } + + /* only need to clamp the lower words since by definition the + * upper words x1/y1 must have a known number of digits + */ + mp_clamp (&x0); + mp_clamp (&y0); + + /* now calc the products x0y0 and x1y1 */ + /* after this x0 is no longer required, free temp [x0==t2]! */ + if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY) + goto X1Y1; /* x0y0 = x0*y0 */ + if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY) + goto X1Y1; /* x1y1 = x1*y1 */ + + /* now calc x1-x0 and y1-y0 */ + if (mp_sub (&x1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x1 - x0 */ + if (mp_sub (&y1, &y0, &x0) != MP_OKAY) + goto X1Y1; /* t2 = y1 - y0 */ + if (mp_mul (&t1, &x0, &t1) != MP_OKAY) + goto X1Y1; /* t1 = (x1 - x0) * (y1 - y0) */ + + /* add x0y0 */ + if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY) + goto X1Y1; /* t2 = x0y0 + x1y1 */ + if (mp_sub (&x0, &t1, &t1) != MP_OKAY) + goto X1Y1; /* t1 = x0y0 + x1y1 - (x1-x0)*(y1-y0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))< + +/* Karatsuba squaring, computes b = a*a using three + * half size squarings + * + * See comments of mp_karatsuba_mul for details. It + * is essentially the same algorithm but merely + * tuned to perform recursive squarings. + */ +int +mp_karatsuba_sqr (mp_int * a, mp_int * b) +{ + mp_int x0, x1, t1, t2, x0x0, x1x1; + int B, err; + + err = MP_MEM; + + /* min # of digits */ + B = a->used; + + /* now divide in two */ + B = B / 2; + + /* init copy all the temps */ + if (mp_init_size (&x0, B) != MP_OKAY) + goto ERR; + if (mp_init_size (&x1, a->used - B) != MP_OKAY) + goto X0; + + /* init temps */ + if (mp_init_size (&t1, a->used * 2) != MP_OKAY) + goto X1; + if (mp_init_size (&t2, a->used * 2) != MP_OKAY) + goto T1; + if (mp_init_size (&x0x0, B * 2) != MP_OKAY) + goto T2; + if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY) + goto X0X0; + + { + register int x; + register mp_digit *dst, *src; + + src = a->dp; + + /* now shift the digits */ + dst = x0.dp; + for (x = 0; x < B; x++) { + *dst++ = *src++; + } + + dst = x1.dp; + for (x = B; x < a->used; x++) { + *dst++ = *src++; + } + } + + x0.used = B; + x1.used = a->used - B; + + mp_clamp (&x0); + + /* now calc the products x0*x0 and x1*x1 */ + if (mp_sqr (&x0, &x0x0) != MP_OKAY) + goto X1X1; /* x0x0 = x0*x0 */ + if (mp_sqr (&x1, &x1x1) != MP_OKAY) + goto X1X1; /* x1x1 = x1*x1 */ + + /* now calc (x1-x0)**2 */ + if (mp_sub (&x1, &x0, &t1) != MP_OKAY) + goto X1X1; /* t1 = x1 - x0 */ + if (mp_sqr (&t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ + + /* add x0y0 */ + if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) + goto X1X1; /* t2 = x0x0 + x1x1 */ + if (mp_sub (&t2, &t1, &t1) != MP_OKAY) + goto X1X1; /* t1 = x0x0 + x1x1 - (x1-x0)*(x1-x0) */ + + /* shift by B */ + if (mp_lshd (&t1, B) != MP_OKAY) + goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))< + +/* computes least common multiple as |a*b|/(a, b) */ +int mp_lcm (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t1, t2; + + + if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) { + return res; + } + + /* t1 = get the GCD of the two inputs */ + if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) { + goto __T; + } + + /* divide the smallest by the GCD */ + if (mp_cmp_mag(a, b) == MP_LT) { + /* store quotient in t2 such that t2 * b is the LCM */ + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + goto __T; + } + res = mp_mul(b, &t2, c); + } else { + /* store quotient in t2 such that t2 * a is the LCM */ + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + goto __T; + } + res = mp_mul(a, &t2, c); + } + + /* fix the sign to positive */ + c->sign = MP_ZPOS; + +__T: + mp_clear_multi (&t1, &t2, NULL); + return res; +} + +/* End: bn_mp_lcm.c */ + +/* Start: bn_mp_lshd.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* shift left a certain amount of digits */ +int mp_lshd (mp_int * a, int b) +{ + int x, res; + + /* if its less than zero return */ + if (b <= 0) { + return MP_OKAY; + } + + /* grow to fit the new digits */ + if (a->alloc < a->used + b) { + if ((res = mp_grow (a, a->used + b)) != MP_OKAY) { + return res; + } + } + + { + register mp_digit *top, *bottom; + + /* increment the used by the shift amount then copy upwards */ + a->used += b; + + /* top */ + top = a->dp + a->used - 1; + + /* base */ + bottom = a->dp + a->used - 1 - b; + + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } + return MP_OKAY; +} + +/* End: bn_mp_lshd.c */ + +/* Start: bn_mp_mod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* c = a mod b, 0 <= c < b */ +int +mp_mod (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int t; + int res; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + + if (t.sign == MP_NEG) { + res = mp_add (b, &t, c); + } else { + res = MP_OKAY; + mp_exch (&t, c); + } + + mp_clear (&t); + return res; +} + +/* End: bn_mp_mod.c */ + +/* Start: bn_mp_mod_2d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* calc a value mod 2**b */ +int +mp_mod_2d (mp_int * a, int b, mp_int * c) +{ + int x, res; + + /* if b is <= 0 then zero the int */ + if (b <= 0) { + mp_zero (c); + return MP_OKAY; + } + + /* if the modulus is larger than the value than return */ + if (b > (int) (a->used * DIGIT_BIT)) { + res = mp_copy (a, c); + return res; + } + + /* copy */ + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + + /* zero digits above the last digit of the modulus */ + for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } + /* clear the digit that is not completely outside/inside the modulus */ + c->dp[b / DIGIT_BIT] &= + (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1)); + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_mp_mod_2d.c */ + +/* Start: bn_mp_mod_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +int +mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) +{ + return mp_div_d(a, b, NULL, c); +} + +/* End: bn_mp_mod_d.c */ + +/* Start: bn_mp_montgomery_calc_normalization.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* calculates a = B^n mod b for Montgomery reduction + * Where B is the base [e.g. 2^DIGIT_BIT]. + * B^n mod b is computed by first computing + * A = B^(n-1) which doesn't require a reduction but a simple OR. + * then C = A * B = B^n is computed by performing upto DIGIT_BIT + * shifts with subtractions when the result is greater than b. + * + * The method is slightly modified to shift B unconditionally upto just under + * the leading bit of b. This saves alot of multiple precision shifting. + */ +int +mp_montgomery_calc_normalization (mp_int * a, mp_int * b) +{ + int x, bits, res; + + /* how many bits of last digit does b use */ + bits = mp_count_bits (b) % DIGIT_BIT; + + /* compute A = B^(n-1) * 2^(bits-1) */ + if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) { + return res; + } + + /* now compute C = A * B mod b */ + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2 (a, a)) != MP_OKAY) { + return res; + } + if (mp_cmp_mag (a, b) != MP_LT) { + if ((res = s_mp_sub (a, b, a)) != MP_OKAY) { + return res; + } + } + } + + return MP_OKAY; +} + +/* End: bn_mp_montgomery_calc_normalization.c */ + +/* Start: bn_mp_montgomery_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes xR**-1 == x (mod N) via Montgomery Reduction */ +int +mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) +{ + int ix, res, digs; + mp_digit mu; + + /* can the fast reduction [comba] method be used? + * + * Note that unlike in mp_mul you're safely allowed *less* + * than the available columns [255 per default] since carries + * are fixed up in the inner loop. + */ + digs = n->used * 2 + 1; + if ((digs < MP_WARRAY) && + n->used < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_mp_montgomery_reduce (x, n, rho); + } + + /* grow the input as required */ + if (x->alloc < digs) { + if ((res = mp_grow (x, digs)) != MP_OKAY) { + return res; + } + } + x->used = digs; + + for (ix = 0; ix < n->used; ix++) { + /* mu = ai * rho mod b + * + * The value of rho must be precalculated via + * bn_mp_montgomery_setup() such that + * it equals -1/n0 mod b this allows the + * following inner loop to reduce the + * input one digit at a time + */ + mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK); + + /* a = a + mu * m * b**i */ + { + register int iy; + register mp_digit *tmpn, *tmpx, u; + register mp_word r; + + /* alias for digits of the modulus */ + tmpn = n->dp; + + /* alias for the digits of x [the input] */ + tmpx = x->dp + ix; + + /* set the carry to zero */ + u = 0; + + /* Multiply and add in place */ + for (iy = 0; iy < n->used; iy++) { + /* compute product and sum */ + r = ((mp_word)mu) * ((mp_word)*tmpn++) + + ((mp_word) u) + ((mp_word) * tmpx); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* fix digit */ + *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK)); + } + /* At this point the ix'th digit of x should be zero */ + + + /* propagate carries upwards as required*/ + while (u) { + *tmpx += u; + u = *tmpx >> DIGIT_BIT; + *tmpx++ &= MP_MASK; + } + } + } + + /* at this point the n.used'th least + * significant digits of x are all zero + * which means we can shift x to the + * right by n.used digits and the + * residue is unchanged. + */ + + /* x = x/b**n.used */ + mp_clamp(x); + mp_rshd (x, n->used); + + /* if x >= n then x = x - n */ + if (mp_cmp_mag (x, n) != MP_LT) { + return s_mp_sub (x, n, x); + } + + return MP_OKAY; +} + +/* End: bn_mp_montgomery_reduce.c */ + +/* Start: bn_mp_montgomery_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* setups the montgomery reduction stuff */ +int +mp_montgomery_setup (mp_int * n, mp_digit * rho) +{ + mp_digit x, b; + +/* fast inversion mod 2**k + * + * Based on the fact that + * + * XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) + * => 2*X*A - X*X*A*A = 1 + * => 2*(1) - (1) = 1 + */ + b = n->dp[0]; + + if ((b & 1) == 0) { + return MP_VAL; + } + + x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ + x *= 2 - b * x; /* here x*a==1 mod 2**8 */ +#if !defined(MP_8BIT) + x *= 2 - b * x; /* here x*a==1 mod 2**16 */ +#endif +#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT)) + x *= 2 - b * x; /* here x*a==1 mod 2**32 */ +#endif +#ifdef MP_64BIT + x *= 2 - b * x; /* here x*a==1 mod 2**64 */ +#endif + + /* rho = -1/m mod b */ + *rho = (((mp_digit) 1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK; + + return MP_OKAY; +} + +/* End: bn_mp_montgomery_setup.c */ + +/* Start: bn_mp_mul.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* high level multiplication (handles sign) */ +int mp_mul (mp_int * a, mp_int * b, mp_int * c) +{ + int res, neg; + neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; + + /* use Toom-Cook? */ + if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); + /* use Karatsuba? */ + } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul (a, b, c); + } else { + /* can we use the fast multiplier? + * + * The fast multiplier can be used if the output will + * have less than MP_WARRAY digits and the number of + * digits won't affect carry propagation + */ + int digs = a->used + b->used + 1; + + if ((digs < MP_WARRAY) && + MIN(a->used, b->used) <= + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + res = fast_s_mp_mul_digs (a, b, c, digs); + } else { + res = s_mp_mul (a, b, c); + } + + } + c->sign = neg; + return res; +} + +/* End: bn_mp_mul.c */ + +/* Start: bn_mp_mul_2.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* b = a*2 */ +int mp_mul_2(mp_int * a, mp_int * b) +{ + int x, res, oldused; + + /* grow to accomodate result */ + if (b->alloc < a->used + 1) { + if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) { + return res; + } + } + + oldused = b->used; + b->used = a->used; + + { + register mp_digit r, rr, *tmpa, *tmpb; + + /* alias for source */ + tmpa = a->dp; + + /* alias for dest */ + tmpb = b->dp; + + /* carry */ + r = 0; + for (x = 0; x < a->used; x++) { + + /* get what will be the *next* carry bit from the + * MSB of the current digit + */ + rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1)); + + /* now shift up this digit, add in the carry [from the previous] */ + *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK; + + /* copy the carry that would be from the source + * digit into the next iteration + */ + r = rr; + } + + /* new leading digit? */ + if (r != 0) { + /* add a MSB which is always 1 at this point */ + *tmpb = 1; + ++(b->used); + } + + /* now zero any excess digits on the destination + * that we didn't write to + */ + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } + } + b->sign = a->sign; + return MP_OKAY; +} + +/* End: bn_mp_mul_2.c */ + +/* Start: bn_mp_mul_2d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* shift left by a certain bit count */ +int mp_mul_2d (mp_int * a, int b, mp_int * c) +{ + mp_digit d; + int res; + + /* copy */ + if (a != c) { + if ((res = mp_copy (a, c)) != MP_OKAY) { + return res; + } + } + + if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) { + if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) { + return res; + } + } + + /* shift by as many digits in the bit count */ + if (b >= (int)DIGIT_BIT) { + if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) { + return res; + } + } + + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit) (b % DIGIT_BIT); + if (d != 0) { + register mp_digit *tmpc, shift, mask, r, rr; + register int x; + + /* bitmask for carries */ + mask = (((mp_digit)1) << d) - 1; + + /* shift for msbs */ + shift = DIGIT_BIT - d; + + /* alias */ + tmpc = c->dp; + + /* carry */ + r = 0; + for (x = 0; x < c->used; x++) { + /* get the higher bits of the current word */ + rr = (*tmpc >> shift) & mask; + + /* shift the current word and OR in the carry */ + *tmpc = ((*tmpc << d) | r) & MP_MASK; + ++tmpc; + + /* set the carry to the carry bits of the current word */ + r = rr; + } + + /* set final carry */ + if (r != 0) { + c->dp[(c->used)++] = r; + } + } + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_mp_mul_2d.c */ + +/* Start: bn_mp_mul_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* multiply by a digit */ +int +mp_mul_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit u, *tmpa, *tmpc; + mp_word r; + int ix, res, olduse; + + /* make sure c is big enough to hold a*b */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* get the original destinations used count */ + olduse = c->used; + + /* set the sign */ + c->sign = a->sign; + + /* alias for a->dp [source] */ + tmpa = a->dp; + + /* alias for c->dp [dest] */ + tmpc = c->dp; + + /* zero carry */ + u = 0; + + /* compute columns */ + for (ix = 0; ix < a->used; ix++) { + /* compute product and carry sum for this term */ + r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b); + + /* mask off higher bits to get a single digit */ + *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* send carry into next iteration */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + + /* store final carry [if any] */ + *tmpc++ = u; + + /* now zero digits above the top */ + while (ix++ < olduse) { + *tmpc++ = 0; + } + + /* set used count */ + c->used = a->used + 1; + mp_clamp(c); + + return MP_OKAY; +} + +/* End: bn_mp_mul_d.c */ + +/* Start: bn_mp_mulmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* d = a * b (mod c) */ +int +mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_mul (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + +/* End: bn_mp_mulmod.c */ + +/* Start: bn_mp_n_root.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root (mp_int * a, mp_digit b, mp_int * c) +{ + mp_int t1, t2, t3; + int res, neg; + + /* input must be positive if b is even */ + if ((b & 1) == 0 && a->sign == MP_NEG) { + return MP_VAL; + } + + if ((res = mp_init (&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init (&t2)) != MP_OKAY) { + goto __T1; + } + + if ((res = mp_init (&t3)) != MP_OKAY) { + goto __T2; + } + + /* if a is negative fudge the sign but keep track */ + neg = a->sign; + a->sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set (&t2, 2); + + do { + /* t1 = t2 */ + if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { + goto __T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { + goto __T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { + goto __T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { + goto __T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { + goto __T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto __T3; + } + + if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { + goto __T3; + } + } while (mp_cmp (&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { + goto __T3; + } + + if (mp_cmp (&t2, a) == MP_GT) { + if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { + goto __T3; + } + } else { + break; + } + } + + /* reset the sign of a first */ + a->sign = neg; + + /* set the result */ + mp_exch (&t1, c); + + /* set the sign of the result */ + c->sign = neg; + + res = MP_OKAY; + +__T3:mp_clear (&t3); +__T2:mp_clear (&t2); +__T1:mp_clear (&t1); + return res; +} + +/* End: bn_mp_n_root.c */ + +/* Start: bn_mp_neg.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* b = -a */ +int mp_neg (mp_int * a, mp_int * b) +{ + int res; + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } + if (mp_iszero(b) != 1) { + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + } + return MP_OKAY; +} + +/* End: bn_mp_neg.c */ + +/* Start: bn_mp_or.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* OR two ints together */ +int mp_or (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_or.c */ + +/* Start: bn_mp_prime_fermat.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* performs one Fermat test. + * + * If "a" were prime then b**a == b (mod a) since the order of + * the multiplicative sub-group would be phi(a) = a-1. That means + * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). + * + * Sets result to 1 if the congruence holds, or zero otherwise. + */ +int mp_prime_fermat (mp_int * a, mp_int * b, int *result) +{ + mp_int t; + int err; + + /* default to composite */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* init t */ + if ((err = mp_init (&t)) != MP_OKAY) { + return err; + } + + /* compute t = b**a mod a */ + if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { + goto __T; + } + + /* is it equal to b? */ + if (mp_cmp (&t, b) == MP_EQ) { + *result = MP_YES; + } + + err = MP_OKAY; +__T:mp_clear (&t); + return err; +} + +/* End: bn_mp_prime_fermat.c */ + +/* Start: bn_mp_prime_is_divisible.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible (mp_int * a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod __prime_tab[ix] */ + if ((err = mp_mod_d (a, __prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} + +/* End: bn_mp_prime_is_divisible.c */ + +/* Start: bn_mp_prime_is_prime.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* performs a variable number of rounds of Miller-Rabin + * + * Probability of error after t rounds is no more than + * (1/4)^t when 1 <= t <= PRIME_SIZE + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime (mp_int * a, int t, int *result) +{ + mp_int b; + int ix, err, res; + + /* default to no */ + *result = MP_NO; + + /* valid value of t? */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* is the input equal to one of the primes in the table? */ + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, __prime_tab[ix]) == MP_EQ) { + *result = 1; + return MP_OKAY; + } + } + + /* first perform trial division */ + if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { + return err; + } + + /* return if it was trivially divisible */ + if (res == MP_YES) { + return MP_OKAY; + } + + /* now perform the miller-rabin rounds */ + if ((err = mp_init (&b)) != MP_OKAY) { + return err; + } + + for (ix = 0; ix < t; ix++) { + /* set the prime */ + mp_set (&b, __prime_tab[ix]); + + if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { + goto __B; + } + + if (res == MP_NO) { + goto __B; + } + } + + /* passed the test */ + *result = MP_YES; +__B:mp_clear (&b); + return err; +} + +/* End: bn_mp_prime_is_prime.c */ + +/* Start: bn_mp_prime_miller_rabin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* Miller-Rabin test of "a" to the base of "b" as described in + * HAC pp. 139 Algorithm 4.24 + * + * Sets result to 0 if definitely composite or 1 if probably prime. + * Randomly the chance of error is no more than 1/4 and often + * very much lower. + */ +int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result) +{ + mp_int n1, y, r; + int s, j, err; + + /* default */ + *result = MP_NO; + + /* ensure b > 1 */ + if (mp_cmp_d(b, 1) != MP_GT) { + return MP_VAL; + } + + /* get n1 = a - 1 */ + if ((err = mp_init_copy (&n1, a)) != MP_OKAY) { + return err; + } + if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) { + goto __N1; + } + + /* set 2**s * r = n1 */ + if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) { + goto __N1; + } + + /* count the number of least significant bits + * which are zero + */ + s = mp_cnt_lsb(&r); + + /* now divide n - 1 by 2**s */ + if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) { + goto __R; + } + + /* compute y = b**r mod a */ + if ((err = mp_init (&y)) != MP_OKAY) { + goto __R; + } + if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) { + goto __Y; + } + + /* if y != 1 and y != n1 do */ + if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) { + j = 1; + /* while j <= s-1 and y != n1 */ + while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) { + if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) { + goto __Y; + } + + /* if y == 1 then composite */ + if (mp_cmp_d (&y, 1) == MP_EQ) { + goto __Y; + } + + ++j; + } + + /* if y != n1 then composite */ + if (mp_cmp (&y, &n1) != MP_EQ) { + goto __Y; + } + } + + /* probably prime now */ + *result = MP_YES; +__Y:mp_clear (&y); +__R:mp_clear (&r); +__N1:mp_clear (&n1); + return err; +} + +/* End: bn_mp_prime_miller_rabin.c */ + +/* Start: bn_mp_prime_next_prime.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) +{ + int err, res, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; + mp_int b; + + /* ensure t is valid */ + if (t <= 0 || t > PRIME_SIZE) { + return MP_VAL; + } + + /* force positive */ + a->sign = MP_ZPOS; + + /* simple algo if a is less than the largest prime in the table */ + if (mp_cmp_d(a, __prime_tab[PRIME_SIZE-1]) == MP_LT) { + /* find which prime it is bigger than */ + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, __prime_tab[x]) != MP_LT) { + if (bbs_style == 1) { + /* ok we found a prime smaller or + * equal [so the next is larger] + * + * however, the prime must be + * congruent to 3 mod 4 + */ + if ((__prime_tab[x + 1] & 3) != 3) { + /* scan upwards for a prime congruent to 3 mod 4 */ + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((__prime_tab[y] & 3) == 3) { + mp_set(a, __prime_tab[y]); + return MP_OKAY; + } + } + } + } else { + mp_set(a, __prime_tab[x + 1]); + return MP_OKAY; + } + } + } + /* at this point a maybe 1 */ + if (mp_cmp_d(a, 1) == MP_EQ) { + mp_set(a, 2); + return MP_OKAY; + } + /* fall through to the sieve */ + } + + /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */ + if (bbs_style == 1) { + kstep = 4; + } else { + kstep = 2; + } + + /* at this point we will use a combination of a sieve and Miller-Rabin */ + + if (bbs_style == 1) { + /* if a mod 4 != 3 subtract the correct value to make it so */ + if ((a->dp[0] & 3) != 3) { + if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; }; + } + } else { + if (mp_iseven(a) == 1) { + /* force odd */ + if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) { + return err; + } + } + } + + /* generate the restable */ + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, __prime_tab[x], res_tab + x)) != MP_OKAY) { + return err; + } + } + + /* init temp used for Miller-Rabin Testing */ + if ((err = mp_init(&b)) != MP_OKAY) { + return err; + } + + for (;;) { + /* skip to the next non-trivially divisible candidate */ + step = 0; + do { + /* y == 1 if any residue was zero [e.g. cannot be prime] */ + y = 0; + + /* increase step to next candidate */ + step += kstep; + + /* compute the new residue without using division */ + for (x = 1; x < PRIME_SIZE; x++) { + /* add the step to each residue */ + res_tab[x] += kstep; + + /* subtract the modulus [instead of using division] */ + if (res_tab[x] >= __prime_tab[x]) { + res_tab[x] -= __prime_tab[x]; + } + + /* set flag if zero */ + if (res_tab[x] == 0) { + y = 1; + } + } + } while (y == 1 && step < ((((mp_digit)1)<= ((((mp_digit)1)< + +/* makes a truly random prime of a given size (bytes), + * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + * The prime generated will be larger than 2^(8*size). + */ + +/* this sole function may hold the key to enslaving all mankind! */ +int mp_prime_random(mp_int *a, int t, int size, int bbs, ltm_prime_callback cb, void *dat) +{ + unsigned char *tmp; + int res, err; + + /* sanity check the input */ + if (size <= 0) { + return MP_VAL; + } + + /* we need a buffer of size+1 bytes */ + tmp = XMALLOC(size+1); + if (tmp == NULL) { + return MP_MEM; + } + + /* fix MSB */ + tmp[0] = 1; + + do { + /* read the bytes */ + if (cb(tmp+1, size, dat) != size) { + err = MP_VAL; + goto error; + } + + /* fix the LSB */ + tmp[size] |= (bbs ? 3 : 1); + + /* read it in */ + if ((err = mp_read_unsigned_bin(a, tmp, size+1)) != MP_OKAY) { + goto error; + } + + /* is it prime? */ + if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) { + goto error; + } + } while (res == MP_NO); + + err = MP_OKAY; +error: + XFREE(tmp); + return err; +} + + + +/* End: bn_mp_prime_random.c */ + +/* Start: bn_mp_radix_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* returns size of ASCII reprensentation */ +int +mp_radix_size (mp_int * a, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + + /* special case for binary */ + if (radix == 2) { + return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + } + + /* make sure the radix is in range */ + if (radix < 2 || radix > 64) { + return 0; + } + + /* init a copy of the input */ + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return 0; + } + + /* digs is the digit count */ + digs = 0; + + /* if it's negative add one for the sign */ + if (t.sign == MP_NEG) { + ++digs; + t.sign = MP_ZPOS; + } + + /* fetch out all of the digits */ + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + ++digs; + } + mp_clear (&t); + + /* return digs + 1, the 1 is for the NULL byte that would be required. */ + return digs + 1; +} + + +/* End: bn_mp_radix_size.c */ + +/* Start: bn_mp_radix_smap.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +/* End: bn_mp_radix_smap.c */ + +/* Start: bn_mp_rand.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* makes a pseudo-random int of a given size */ +int +mp_rand (mp_int * a, int digits) +{ + int res; + mp_digit d; + + mp_zero (a); + if (digits <= 0) { + return MP_OKAY; + } + + /* first place a random non-zero digit */ + do { + d = ((mp_digit) abs (rand ())); + } while (d == 0); + + if ((res = mp_add_d (a, d, a)) != MP_OKAY) { + return res; + } + + while (digits-- > 0) { + if ((res = mp_lshd (a, 1)) != MP_OKAY) { + return res; + } + + if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { + return res; + } + } + + return MP_OKAY; +} + +/* End: bn_mp_rand.c */ + +/* Start: bn_mp_read_radix.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read a string [ASCII] in a given radix */ +int +mp_read_radix (mp_int * a, char *str, int radix) +{ + int y, res, neg; + char ch; + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} + +/* End: bn_mp_read_radix.c */ + +/* Start: bn_mp_read_signed_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read signed bin, big endian, first byte is 0==positive or 1==negative */ +int +mp_read_signed_bin (mp_int * a, unsigned char *b, int c) +{ + int res; + + /* read magnitude */ + if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) { + return res; + } + + /* first byte is 0 for positive, non-zero for negative */ + if (b[0] == 0) { + a->sign = MP_ZPOS; + } else { + a->sign = MP_NEG; + } + + return MP_OKAY; +} + +/* End: bn_mp_read_signed_bin.c */ + +/* Start: bn_mp_read_unsigned_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reads a unsigned char array, assumes the msb is stored first [big endian] */ +int +mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) +{ + int res; + + /* make sure there are at least two digits */ + if (a->alloc < 2) { + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; + } + } + + /* zero the int */ + mp_zero (a); + + /* read the bytes in */ + while (c-- > 0) { + if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) { + return res; + } + +#ifndef MP_8BIT + a->dp[0] |= *b++; + a->used += 1; +#else + a->dp[0] = (*b & MP_MASK); + a->dp[1] |= ((*b++ >> 7U) & 1); + a->used += 2; +#endif + } + mp_clamp (a); + return MP_OKAY; +} + +/* End: bn_mp_read_unsigned_bin.c */ + +/* Start: bn_mp_reduce.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reduces x mod m, assumes 0 < x < m**2, mu is + * precomputed via mp_reduce_setup. + * From HAC pp.604 Algorithm 14.42 + */ +int +mp_reduce (mp_int * x, mp_int * m, mp_int * mu) +{ + mp_int q; + int res, um = m->used; + + /* q = x */ + if ((res = mp_init_copy (&q, x)) != MP_OKAY) { + return res; + } + + /* q1 = x / b**(k-1) */ + mp_rshd (&q, um - 1); + + /* according to HAC this optimization is ok */ + if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { + if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { + goto CLEANUP; + } + } else { + if ((res = s_mp_mul_high_digs (&q, mu, &q, um - 1)) != MP_OKAY) { + goto CLEANUP; + } + } + + /* q3 = q2 / b**(k+1) */ + mp_rshd (&q, um + 1); + + /* x = x mod b**(k+1), quick (no division) */ + if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + goto CLEANUP; + } + + /* q = q * m mod b**(k+1), quick (no division) */ + if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) { + goto CLEANUP; + } + + /* x = x - q */ + if ((res = mp_sub (x, &q, x)) != MP_OKAY) { + goto CLEANUP; + } + + /* If x < 0, add b**(k+1) to it */ + if (mp_cmp_d (x, 0) == MP_LT) { + mp_set (&q, 1); + if ((res = mp_lshd (&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if ((res = mp_add (x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while (mp_cmp (x, m) != MP_LT) { + if ((res = s_mp_sub (x, m, x)) != MP_OKAY) { + goto CLEANUP; + } + } + +CLEANUP: + mp_clear (&q); + + return res; +} + +/* End: bn_mp_reduce.c */ + +/* Start: bn_mp_reduce_2k.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reduces a modulo n where n is of the form 2**p - k */ +int +mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (k != 1) { + /* q = q * k */ + if ((res = mp_mul_d(&q, k, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + + +/* End: bn_mp_reduce_2k.c */ + +/* Start: bn_mp_reduce_2k_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines the setup value */ +int +mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} + +/* End: bn_mp_reduce_2k_setup.c */ + +/* Start: bn_mp_reduce_is_2k.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if mp_reduce_2k can be used */ +int mp_reduce_is_2k(mp_int *a) +{ + int ix, iy, iz, iw; + + if (a->used == 0) { + return 0; + } else if (a->used == 1) { + return 1; + } else if (a->used > 1) { + iy = mp_count_bits(a); + iz = 1; + iw = 1; + + /* Test every bit from the second digit up, must be 1 */ + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[iw] & iz) == 0) { + return 0; + } + iz <<= 1; + if (iz > (int)MP_MASK) { + ++iw; + iz = 1; + } + } + } + return 1; +} + + +/* End: bn_mp_reduce_is_2k.c */ + +/* Start: bn_mp_reduce_setup.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int +mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} + +/* End: bn_mp_reduce_setup.c */ + +/* Start: bn_mp_rshd.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* shift right a certain amount of digits */ +void mp_rshd (mp_int * a, int b) +{ + int x; + + /* if b <= 0 then ignore it */ + if (b <= 0) { + return; + } + + /* if b > used then simply zero it and return */ + if (a->used <= b) { + mp_zero (a); + return; + } + + { + register mp_digit *bottom, *top; + + /* shift the digits down */ + + /* bottom */ + bottom = a->dp; + + /* top [offset into digits] */ + top = a->dp + b; + + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } + + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } + + /* remove excess digits */ + a->used -= b; +} + +/* End: bn_mp_rshd.c */ + +/* Start: bn_mp_set.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* set to a digit */ +void mp_set (mp_int * a, mp_digit b) +{ + mp_zero (a); + a->dp[0] = b & MP_MASK; + a->used = (a->dp[0] != 0) ? 1 : 0; +} + +/* End: bn_mp_set.c */ + +/* Start: bn_mp_set_int.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* set a 32-bit const */ +int mp_set_int (mp_int * a, unsigned long b) +{ + int x, res; + + mp_zero (a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (b >> 28) & 15; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp (a); + return MP_OKAY; +} + +/* End: bn_mp_set_int.c */ + +/* Start: bn_mp_shrink.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* shrink a bignum */ +int mp_shrink (mp_int * a) +{ + mp_digit *tmp; + if (a->alloc != a->used) { + if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) { + return MP_MEM; + } + a->dp = tmp; + a->alloc = a->used; + } + return MP_OKAY; +} + +/* End: bn_mp_shrink.c */ + +/* Start: bn_mp_signed_bin_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* get the size for an signed equivalent */ +int +mp_signed_bin_size (mp_int * a) +{ + return 1 + mp_unsigned_bin_size (a); +} + +/* End: bn_mp_signed_bin_size.c */ + +/* Start: bn_mp_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* computes b = a*a */ +int +mp_sqr (mp_int * a, mp_int * b) +{ + int res; + /* use Toom-Cook? */ + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); + /* Karatsuba? */ + } else if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr (a, b); + } else { + /* can we use the fast comba multiplier? */ + if ((a->used * 2 + 1) < MP_WARRAY && + a->used < + (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { + res = fast_s_mp_sqr (a, b); + } else { + res = s_mp_sqr (a, b); + } + } + b->sign = MP_ZPOS; + return res; +} + +/* End: bn_mp_sqr.c */ + +/* Start: bn_mp_sqrmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* c = a * a (mod b) */ +int +mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) +{ + int res; + mp_int t; + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sqr (a, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, b, c); + mp_clear (&t); + return res; +} + +/* End: bn_mp_sqrmod.c */ + +/* Start: bn_mp_sub.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* high level subtraction (handles signs) */ +int +mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int sa, sb, res; + + sa = a->sign; + sb = b->sign; + + if (sa != sb) { + /* subtract a negative from a positive, OR */ + /* subtract a positive from a negative. */ + /* In either case, ADD their magnitudes, */ + /* and use the sign of the first number. */ + c->sign = sa; + res = s_mp_add (a, b, c); + } else { + /* subtract a positive from a positive, OR */ + /* subtract a negative from a negative. */ + /* First, take the difference between their */ + /* magnitudes, then... */ + if (mp_cmp_mag (a, b) != MP_LT) { + /* Copy the sign from the first */ + c->sign = sa; + /* The first has a larger or equal magnitude */ + res = s_mp_sub (a, b, c); + } else { + /* The result has the *opposite* sign from */ + /* the first number. */ + c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; + /* The second has a larger magnitude */ + res = s_mp_sub (b, a, c); + } + } + return res; +} + + +/* End: bn_mp_sub.c */ + +/* Start: bn_mp_sub_d.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* single digit subtraction */ +int +mp_sub_d (mp_int * a, mp_digit b, mp_int * c) +{ + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; + + /* grow c as required */ + if (c->alloc < a->used + 1) { + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; + } + } + + /* if a is negative just do an unsigned + * addition [with fudged signs] + */ + if (a->sign == MP_NEG) { + a->sign = MP_ZPOS; + res = mp_add_d(a, b, c); + a->sign = c->sign = MP_NEG; + return res; + } + + /* setup regs */ + oldused = c->used; + tmpa = a->dp; + tmpc = c->dp; + + /* if a <= b simply fix the single digit */ + if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } + ix = 1; + + /* negative/1digit */ + c->sign = MP_NEG; + c->used = 1; + } else { + /* positive/size */ + c->sign = MP_ZPOS; + c->used = a->used; + + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { + *tmpc = *tmpa++ - mu; + mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1); + *tmpc++ &= MP_MASK; + } + } + + /* zero excess digits */ + while (ix++ < oldused) { + *tmpc++ = 0; + } + mp_clamp(c); + return MP_OKAY; +} + + +/* End: bn_mp_sub_d.c */ + +/* Start: bn_mp_submod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* d = a - b (mod c) */ +int +mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) +{ + int res; + mp_int t; + + + if ((res = mp_init (&t)) != MP_OKAY) { + return res; + } + + if ((res = mp_sub (a, b, &t)) != MP_OKAY) { + mp_clear (&t); + return res; + } + res = mp_mod (&t, c, d); + mp_clear (&t); + return res; +} + +/* End: bn_mp_submod.c */ + +/* Start: bn_mp_to_signed_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* store in signed [big endian] format */ +int +mp_to_signed_bin (mp_int * a, unsigned char *b) +{ + int res; + + if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) { + return res; + } + b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1); + return MP_OKAY; +} + +/* End: bn_mp_to_signed_bin.c */ + +/* Start: bn_mp_to_unsigned_bin.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* store in unsigned [big endian] format */ +int +mp_to_unsigned_bin (mp_int * a, unsigned char *b) +{ + int x, res; + mp_int t; + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + x = 0; + while (mp_iszero (&t) == 0) { +#ifndef MP_8BIT + b[x++] = (unsigned char) (t.dp[0] & 255); +#else + b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7)); +#endif + if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) { + mp_clear (&t); + return res; + } + } + bn_reverse (b, x); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_to_unsigned_bin.c */ + +/* Start: bn_mp_toom_mul.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* multiplication using the Toom-Cook 3-way algorithm */ +int +mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + + +/* End: bn_mp_toom_mul.c */ + +/* Start: bn_mp_toom_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + + +/* End: bn_mp_toom_sqr.c */ + +/* Start: bn_mp_toradix.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* stores a bignum as a ASCII string in a given radix (2..64) */ +int +mp_toradix (mp_int * a, char *str, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + char *_s = str; + + /* check range of the radix */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* quick out if its zero */ + if (mp_iszero(a) == 1) { + *str++ = '0'; + *str = '\0'; + return MP_OKAY; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + + /* if it is negative output a - */ + if (t.sign == MP_NEG) { + ++_s; + *str++ = '-'; + t.sign = MP_ZPOS; + } + + digs = 0; + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return res; + } + *str++ = mp_s_rmap[d]; + ++digs; + } + + /* reverse the digits of the string. In this case _s points + * to the first digit [exluding the sign] of the number] + */ + bn_reverse ((unsigned char *)_s, digs); + + /* append a NULL so the string is properly terminated */ + *str = '\0'; + + mp_clear (&t); + return MP_OKAY; +} + + +/* End: bn_mp_toradix.c */ + +/* Start: bn_mp_unsigned_bin_size.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* get the size for an unsigned equivalent */ +int +mp_unsigned_bin_size (mp_int * a) +{ + int size = mp_count_bits (a); + return (size / 8 + ((size & 7) != 0 ? 1 : 0)); +} + +/* End: bn_mp_unsigned_bin_size.c */ + +/* Start: bn_mp_xor.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* XOR two ints together */ +int +mp_xor (mp_int * a, mp_int * b, mp_int * c) +{ + int res, ix, px; + mp_int t, *x; + + if (a->used > b->used) { + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return res; + } + px = b->used; + x = b; + } else { + if ((res = mp_init_copy (&t, b)) != MP_OKAY) { + return res; + } + px = a->used; + x = a; + } + + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp (&t); + mp_exch (c, &t); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_mp_xor.c */ + +/* Start: bn_mp_zero.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* set to zero */ +void +mp_zero (mp_int * a) +{ + a->sign = MP_ZPOS; + a->used = 0; + memset (a->dp, 0, sizeof (mp_digit) * a->alloc); +} + +/* End: bn_mp_zero.c */ + +/* Start: bn_prime_sizes_tab.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */ +static const struct { + int k, t; +} sizes[] = { +{ 128, 28 }, +{ 256, 16 }, +{ 384, 10 }, +{ 512, 7 }, +{ 640, 6 }, +{ 768, 5 }, +{ 896, 4 }, +{ 1024, 4 }, +{ 1152, 3 }, +{ 1280, 3 }, +{ 1408, 3 }, +{ 1536, 3 }, +{ 1664, 3 }, +{ 1792, 2 }, +{ 1920, 2 }, +{ 2048, 2 }, +{ 2176, 2 }, +{ 2304, 2 }, +{ 2432, 2 }, +{ 2560, 2 }, +{ 2688, 2 }, +{ 2816, 2 }, +{ 2944, 2 }, +{ 3072, 2 }, +{ 3200, 2 }, +{ 3328, 2 }, +{ 3456, 2 }, +{ 3584, 2 }, +{ 3712, 2 }, +{ 3840, 1 }, +{ 3968, 1 }, +{ 4096, 1 } }; + +/* returns # of RM trials required for a given bit size */ +int mp_prime_rabin_miller_trials(int size) +{ + int x; + + for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) { + if (sizes[x].k == size) { + return sizes[x].t; + } else if (sizes[x].k > size) { + return (x == 0) ? sizes[0].t : sizes[x - 1].t; + } + } + return 1; +} + + + +/* End: bn_prime_sizes_tab.c */ + +/* Start: bn_prime_tab.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include +const mp_digit __prime_tab[] = { + 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, + 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, + 0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059, + 0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, +#ifndef MP_8BIT + 0x0083, + 0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD, + 0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF, + 0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107, + 0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137, + + 0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167, + 0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199, + 0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9, + 0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7, + 0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239, + 0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265, + 0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293, + 0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF, + + 0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301, + 0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B, + 0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371, + 0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD, + 0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5, + 0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419, + 0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449, + 0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B, + + 0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7, + 0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503, + 0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529, + 0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F, + 0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3, + 0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7, + 0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623, + 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 +#endif +}; + +/* End: bn_prime_tab.c */ + +/* Start: bn_reverse.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reverse an array, used for radix code */ +void +bn_reverse (unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} + +/* End: bn_reverse.c */ + +/* Start: bn_s_mp_add.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* low level addition, based on HAC pp.594, Algorithm 14.7 */ +int +s_mp_add (mp_int * a, mp_int * b, mp_int * c) +{ + mp_int *x; + int olduse, res, min, max; + + /* find sizes, we let |a| <= |b| which means we have to sort + * them. "x" will point to the input with the most digits + */ + if (a->used > b->used) { + min = b->used; + max = a->used; + x = a; + } else { + min = a->used; + max = b->used; + x = b; + } + + /* init result */ + if (c->alloc < max + 1) { + if ((res = mp_grow (c, max + 1)) != MP_OKAY) { + return res; + } + } + + /* get old used digit count and set new one */ + olduse = c->used; + c->used = max + 1; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + + /* first input */ + tmpa = a->dp; + + /* second input */ + tmpb = b->dp; + + /* destination */ + tmpc = c->dp; + + /* zero the carry */ + u = 0; + for (i = 0; i < min; i++) { + /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ + *tmpc = *tmpa++ + *tmpb++ + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, that is in A+B + * if A or B has more digits add those in + */ + if (min != max) { + for (; i < max; i++) { + /* T[i] = X[i] + U */ + *tmpc = x->dp[i] + u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)DIGIT_BIT); + + /* take away carry bit from T[i] */ + *tmpc++ &= MP_MASK; + } + } + + /* add carry */ + *tmpc++ = u; + + /* clear digits above oldused */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + +/* End: bn_s_mp_add.c */ + +/* Start: bn_s_mp_exptmod.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +#ifdef MP_LOW_MEM + #define TAB_SIZE 32 +#else + #define TAB_SIZE 256 +#endif + +int +s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + mp_int M[TAB_SIZE], res, mu; + mp_digit buf; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + + /* find window size */ + x = mp_count_bits (X); + if (x <= 7) { + winsize = 2; + } else if (x <= 36) { + winsize = 3; + } else if (x <= 140) { + winsize = 4; + } else if (x <= 450) { + winsize = 5; + } else if (x <= 1303) { + winsize = 6; + } else if (x <= 3529) { + winsize = 7; + } else { + winsize = 8; + } + +#ifdef MP_LOW_MEM + if (winsize > 5) { + winsize = 5; + } +#endif + + /* init M array */ + /* init first cell */ + if ((err = mp_init(&M[1])) != MP_OKAY) { + return err; + } + + /* now init the second half of the array */ + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + if ((err = mp_init(&M[x])) != MP_OKAY) { + for (y = 1<<(winsize-1); y < x; y++) { + mp_clear (&M[y]); + } + mp_clear(&M[1]); + return err; + } + } + + /* create mu, used for Barrett reduction */ + if ((err = mp_init (&mu)) != MP_OKAY) { + goto __M; + } + if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) { + goto __MU; + } + + /* create M table + * + * The M table contains powers of the base, + * e.g. M[x] = G**x mod P + * + * The first half of the table is not + * computed though accept for M[0] and M[1] + */ + if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) { + goto __MU; + } + + /* compute the value at M[1<<(winsize-1)] by squaring + * M[1] (winsize-1) times + */ + if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __MU; + } + + for (x = 0; x < (winsize - 1); x++) { + if ((err = mp_sqr (&M[1 << (winsize - 1)], + &M[1 << (winsize - 1)])) != MP_OKAY) { + goto __MU; + } + if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) { + goto __MU; + } + } + + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ + for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { + if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { + goto __MU; + } + if ((err = mp_reduce (&M[x], P, &mu)) != MP_OKAY) { + goto __MU; + } + } + + /* setup result */ + if ((err = mp_init (&res)) != MP_OKAY) { + goto __MU; + } + mp_set (&res, 1); + + /* set initial mode and bit cnt */ + mode = 0; + bitcnt = 1; + buf = 0; + digidx = X->used - 1; + bitcpy = 0; + bitbuf = 0; + + for (;;) { + /* grab next digit as required */ + if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ + if (digidx == -1) { + break; + } + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int) DIGIT_BIT; + } + + /* grab the next msb from the exponent */ + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + buf <<= (mp_digit)1; + + /* if the bit is zero and mode == 0 then we ignore it + * These represent the leading zero bits before the first 1 bit + * in the exponent. Technically this opt is not required but it + * does lower the # of trivial squaring/reductions used + */ + if (mode == 0 && y == 0) { + continue; + } + + /* if the bit is zero and mode == 1 then we square */ + if (mode == 1 && y == 0) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + continue; + } + + /* else we add it to the window */ + bitbuf |= (y << (winsize - ++bitcpy)); + mode = 2; + + if (bitcpy == winsize) { + /* ok window is filled so square as required and multiply */ + /* square first */ + for (x = 0; x < winsize; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + } + + /* then multiply */ + if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) { + goto __MU; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __MU; + } + + /* empty window and reset */ + bitcpy = 0; + bitbuf = 0; + mode = 1; + } + } + + /* if bits remain then square/multiply */ + if (mode == 2 && bitcpy > 0) { + /* square then multiply if the bit is set */ + for (x = 0; x < bitcpy; x++) { + if ((err = mp_sqr (&res, &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + + bitbuf <<= 1; + if ((bitbuf & (1 << winsize)) != 0) { + /* then multiply */ + if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) { + goto __RES; + } + if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) { + goto __RES; + } + } + } + } + + mp_exch (&res, Y); + err = MP_OKAY; +__RES:mp_clear (&res); +__MU:mp_clear (&mu); +__M: + mp_clear(&M[1]); + for (x = 1<<(winsize-1); x < (1 << winsize); x++) { + mp_clear (&M[x]); + } + return err; +} + +/* End: bn_s_mp_exptmod.c */ + +/* Start: bn_s_mp_mul_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* multiplies |a| * |b| and only computes upto digs digits of result + * HAC pp. 595, Algorithm 14.12 Modified so you can control how + * many digits of output are created. + */ +int +s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((digs) < MP_WARRAY) && + MIN (a->used, b->used) < + (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, digs)) != MP_OKAY) { + return res; + } + t.used = digs; + + /* compute the digits of the product directly */ + pa = a->used; + for (ix = 0; ix < pa; ix++) { + /* set the carry to zero */ + u = 0; + + /* limit ourselves to making digs digits of output */ + pb = MIN (b->used, digs - ix); + + /* setup some aliases */ + /* copy of the digit from a used within the nested loop */ + tmpx = a->dp[ix]; + + /* an alias for the destination shifted ix places */ + tmpt = t.dp + ix; + + /* an alias for the digits of b */ + tmpy = b->dp; + + /* compute the columns of the output and propagate the carry */ + for (iy = 0; iy < pb; iy++) { + /* compute the column as a mp_word */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* the new column is the lower part of the result */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry word from the result */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + /* set carry if it is placed below digs */ + if (ix + iy < digs) { + *tmpt = u; + } + } + + mp_clamp (&t); + mp_exch (&t, c); + + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_s_mp_mul_digs.c */ + +/* Start: bn_s_mp_mul_high_digs.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* multiplies |a| * |b| and does not compute the lower digs digits + * [meant to get the higher part of the product] + */ +int +s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) +{ + mp_int t; + int res, pa, pb, ix, iy; + mp_digit u; + mp_word r; + mp_digit tmpx, *tmpt, *tmpy; + + /* can we use the fast multiplier? */ + if (((a->used + b->used + 1) < MP_WARRAY) + && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { + return fast_s_mp_mul_high_digs (a, b, c, digs); + } + + if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) { + return res; + } + t.used = a->used + b->used + 1; + + pa = a->used; + pb = b->used; + for (ix = 0; ix < pa; ix++) { + /* clear the carry */ + u = 0; + + /* left hand side of A[ix] * B[iy] */ + tmpx = a->dp[ix]; + + /* alias to the address of where the digits will be stored */ + tmpt = &(t.dp[digs]); + + /* alias for where to read the right hand side from */ + tmpy = b->dp + (digs - ix); + + for (iy = digs - ix; iy < pb; iy++) { + /* calculate the double precision result */ + r = ((mp_word)*tmpt) + + ((mp_word)tmpx) * ((mp_word)*tmpy++) + + ((mp_word) u); + + /* get the lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* carry the carry */ + u = (mp_digit) (r >> ((mp_word) DIGIT_BIT)); + } + *tmpt = u; + } + mp_clamp (&t); + mp_exch (&t, c); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_s_mp_mul_high_digs.c */ + +/* Start: bn_s_mp_sqr.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ +int +s_mp_sqr (mp_int * a, mp_int * b) +{ + mp_int t; + int res, ix, iy, pa; + mp_word r; + mp_digit u, tmpx, *tmpt; + + pa = a->used; + if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) { + return res; + } + + /* default used is maximum possible size */ + t.used = 2*pa + 1; + + for (ix = 0; ix < pa; ix++) { + /* first calculate the digit at 2*ix */ + /* calculate double precision result */ + r = ((mp_word) t.dp[2*ix]) + + ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]); + + /* store lower part in result */ + t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get the carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + + /* left hand side of A[ix] * A[iy] */ + tmpx = a->dp[ix]; + + /* alias for where to store the results */ + tmpt = t.dp + (2*ix + 1); + + for (iy = ix + 1; iy < pa; iy++) { + /* first calculate the product */ + r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]); + + /* now calculate the double precision result, note we use + * addition instead of *2 since it's easier to optimize + */ + r = ((mp_word) *tmpt) + r + r + ((mp_word) u); + + /* store lower part */ + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + + /* get carry */ + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + /* propagate upwards */ + while (u != ((mp_digit) 0)) { + r = ((mp_word) *tmpt) + ((mp_word) u); + *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); + u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); + } + } + + mp_clamp (&t); + mp_exch (&t, b); + mp_clear (&t); + return MP_OKAY; +} + +/* End: bn_s_mp_sqr.c */ + +/* Start: bn_s_mp_sub.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ +int +s_mp_sub (mp_int * a, mp_int * b, mp_int * c) +{ + int olduse, res, min, max; + + /* find sizes */ + min = b->used; + max = a->used; + + /* init result */ + if (c->alloc < max) { + if ((res = mp_grow (c, max)) != MP_OKAY) { + return res; + } + } + olduse = c->used; + c->used = max; + + { + register mp_digit u, *tmpa, *tmpb, *tmpc; + register int i; + + /* alias for digit pointers */ + tmpa = a->dp; + tmpb = b->dp; + tmpc = c->dp; + + /* set carry to zero */ + u = 0; + for (i = 0; i < min; i++) { + /* T[i] = A[i] - B[i] - U */ + *tmpc = *tmpa++ - *tmpb++ - u; + + /* U = carry bit of T[i] + * Note this saves performing an AND operation since + * if a carry does occur it will propagate all the way to the + * MSB. As a result a single shift is enough to get the carry + */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* now copy higher words if any, e.g. if A has more digits than B */ + for (; i < max; i++) { + /* T[i] = A[i] - U */ + *tmpc = *tmpa++ - u; + + /* U = carry bit of T[i] */ + u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1)); + + /* Clear carry from T[i] */ + *tmpc++ &= MP_MASK; + } + + /* clear digits above used (since we may not have grown result above) */ + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } + } + + mp_clamp (c); + return MP_OKAY; +} + + +/* End: bn_s_mp_sub.c */ + +/* Start: bncore.c */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 /GCC v3.2 / 70/ 108 + AMD Athlon XP /GCC v3.2 / 109/ 127 + +*/ + +/* configured for a AMD XP Thoroughbred core with etc/tune.c */ +int KARATSUBA_MUL_CUTOFF = 109, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 127, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; + +/* End: bncore.c */ + + +/* EOF */ diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt.h new file mode 100644 index 0000000000000000000000000000000000000000..bed089627b46d059ae29efadfe2148a4c41fb579 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt.h @@ -0,0 +1,80 @@ +#ifndef CRYPT_H_ +#define CRYPT_H_ +#include +#include +#include +#include +#include +#include +#include + +/* if there is a custom definition header file use it */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ +#define CRYPT 0x0092 +#define SCRYPT "0.92" + +/* max size of either a cipher/hash block or symmetric key [largest of the two] */ +#define MAXBLOCKSIZE 128 + +/* ch1-01-1 */ +/* error codes [will be expanded in future releases] */ +enum { + CRYPT_OK=0, /* Result OK */ + CRYPT_ERROR, /* Generic Error */ + CRYPT_NOP, /* Not a failure but no operation was performed */ + + CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ + CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ + CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ + + CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ + CRYPT_INVALID_PACKET, /* Invalid input packet given */ + + CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ + CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ + + CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ + CRYPT_INVALID_HASH, /* Invalid hash specified */ + CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ + + CRYPT_MEM, /* Out of memory */ + + CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ + CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ + + CRYPT_INVALID_ARG, /* Generic invalid argument */ + CRYPT_FILE_NOTFOUND, /* File Not Found */ + + CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ + CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ + CRYPT_PK_DUP, /* Duplicate key already in key ring */ + CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ + + CRYPT_INVALID_PRIME_SIZE/* Invalid size of prime requested */ +}; +/* ch1-01-1 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus + } +#endif + +#endif /* CRYPT_H_ */ + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_argchk.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_argchk.h new file mode 100644 index 0000000000000000000000000000000000000000..8f38e546795eaed57c53e1447378a9cd93e4a7a5 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_argchk.h @@ -0,0 +1,24 @@ +/* Defines the _ARGCHK macro used within the library */ + +/* ch1-01-1 */ +/* ARGTYPE is defined in mycrypt_cfg.h */ +#if ARGTYPE == 0 + +#include + +/* this is the default LibTomCrypt macro */ +extern void crypt_argchk(char *v, char *s, int d); +#define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } + +#elif ARGTYPE == 1 + +/* fatal type of error */ +#define _ARGCHK(x) assert((x)) + +#elif ARGTYPE == 2 + +#define _ARGCHK(x) + +#endif +/* ch1-01-1 */ + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cfg.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..02107fca96f2ffdacaad5add68e32289f74d7b4e --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cfg.h @@ -0,0 +1,78 @@ +/* This is the build config file. + * + * With this you can setup what to inlcude/exclude automatically during any build. Just comment + * out the line that #define's the word for the thing you want to remove. phew! + */ + +#ifndef MYCRYPT_CFG_H +#define MYCRYPT_CFG_H + +/* you can change how memory allocation works ... */ +extern void *XMALLOC(size_t n); +extern void *REALLOC(void *p, size_t n); +extern void *XCALLOC(size_t n, size_t s); +extern void XFREE(void *p); + +/* change the clock function too */ +extern clock_t XCLOCK(void); + +/* ch1-01-1 */ +/* type of argument checking, 0=default, 1=fatal and 2=none */ +#define ARGTYPE 0 +/* ch1-01-1 */ + +/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */ +/* detect x86-32 machines somewhat */ +#if (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))) + #define ENDIAN_LITTLE + #define ENDIAN_32BITWORD +#endif + +/* detects MIPS R5900 processors (PS2) */ +#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD +#endif + +/* #define ENDIAN_LITTLE */ +/* #define ENDIAN_BIG */ + +/* #define ENDIAN_32BITWORD */ +/* #define ENDIAN_64BITWORD */ + +#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) + #error You must specify a word size as well as endianess in mycrypt_cfg.h +#endif + +#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) + #define ENDIAN_NEUTRAL +#endif + +#ifdef YARROW + #ifndef CTR + #error YARROW requires CTR chaining mode to be defined! + #endif +#endif + +/* packet code */ +#if defined(MRSA) || defined(MDH) || defined(MECC) + #define PACKET + + /* size of a packet header in bytes */ + #define PACKET_SIZE 4 + + /* Section tags */ + #define PACKET_SECT_RSA 0 + #define PACKET_SECT_DH 1 + #define PACKET_SECT_ECC 2 + #define PACKET_SECT_DSA 3 + + /* Subsection Tags for the first three sections */ + #define PACKET_SUB_KEY 0 + #define PACKET_SUB_ENCRYPTED 1 + #define PACKET_SUB_SIGNED 2 + #define PACKET_SUB_ENC_KEY 3 +#endif + +#endif /* MYCRYPT_CFG_H */ + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cipher.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cipher.h new file mode 100644 index 0000000000000000000000000000000000000000..25d195319af3e15a4e4caae1666c741ac8ecc4d4 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cipher.h @@ -0,0 +1,376 @@ +/* ---- SYMMETRIC KEY STUFF ----- + * + * We put each of the ciphers scheduled keys in their own structs then we put all of + * the key formats in one union. This makes the function prototypes easier to use. + */ +#ifdef BLOWFISH +struct blowfish_key { + ulong32 S[4][256]; + ulong32 K[18]; +}; +#endif + +#ifdef RC5 +struct rc5_key { + int rounds; + ulong32 K[50]; +}; +#endif + +#ifdef RC6 +struct rc6_key { + ulong32 K[44]; +}; +#endif + +#ifdef SAFERP +struct saferp_key { + unsigned char K[33][16]; + long rounds; +}; +#endif + +#ifdef RIJNDAEL +struct rijndael_key { + ulong32 eK[64], dK[64]; + int Nr; +}; +#endif + +#ifdef XTEA +struct xtea_key { + unsigned long A[32], B[32]; +}; +#endif + +#ifdef TWOFISH +#ifndef TWOFISH_SMALL + struct twofish_key { + ulong32 S[4][256], K[40]; + }; +#else + struct twofish_key { + ulong32 K[40]; + unsigned char S[32], start; + }; +#endif +#endif + +#ifdef SAFER +#define SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define SAFER_MAX_NOF_ROUNDS 13 +#define SAFER_BLOCK_LEN 8 +#define SAFER_KEY_LEN (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[SAFER_KEY_LEN]; +struct safer_key { safer_key_t key; }; +#endif + +#ifdef RC2 +struct rc2_key { unsigned xkey[64]; }; +#endif + +#ifdef DES +struct des_key { + ulong32 ek[32], dk[32]; +}; + +struct des3_key { + ulong32 ek[3][32], dk[3][32]; +}; +#endif + +#ifdef CAST5 +struct cast5_key { + ulong32 K[32], keylen; +}; +#endif + +#ifdef NOEKEON +struct noekeon_key { + ulong32 K[4], dK[4]; +}; +#endif + +#ifdef SKIPJACK +struct skipjack_key { + unsigned char key[10]; +}; +#endif + +typedef union Symmetric_key { +#ifdef DES + struct des_key des; + struct des3_key des3; +#endif +#ifdef RC2 + struct rc2_key rc2; +#endif +#ifdef SAFER + struct safer_key safer; +#endif +#ifdef TWOFISH + struct twofish_key twofish; +#endif +#ifdef BLOWFISH + struct blowfish_key blowfish; +#endif +#ifdef RC5 + struct rc5_key rc5; +#endif +#ifdef RC6 + struct rc6_key rc6; +#endif +#ifdef SAFERP + struct saferp_key saferp; +#endif +#ifdef RIJNDAEL + struct rijndael_key rijndael; +#endif +#ifdef XTEA + struct xtea_key xtea; +#endif +#ifdef CAST5 + struct cast5_key cast5; +#endif +#ifdef NOEKEON + struct noekeon_key noekeon; +#endif +#ifdef SKIPJACK + struct skipjack_key skipjack; +#endif +} symmetric_key; + +/* A block cipher ECB structure */ +typedef struct { + int cipher, blocklen; + symmetric_key key; +} symmetric_ECB; + +/* A block cipher CFB structure */ +typedef struct { + int cipher, blocklen, padlen; + unsigned char IV[MAXBLOCKSIZE], pad[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_CFB; + +/* A block cipher OFB structure */ +typedef struct { + int cipher, blocklen, padlen; + unsigned char IV[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_OFB; + +/* A block cipher CBC structure */ +typedef struct Symmetric_CBC { + int cipher, blocklen; + unsigned char IV[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_CBC; + +/* A block cipher CTR structure */ +typedef struct Symmetric_CTR { + int cipher, blocklen, padlen; + unsigned char ctr[MAXBLOCKSIZE], pad[MAXBLOCKSIZE]; + symmetric_key key; +} symmetric_CTR; + +/* cipher descriptor table, last entry has "name == NULL" to mark the end of table */ +extern struct _cipher_descriptor { + char *name; + unsigned char ID; + int min_key_length, max_key_length, block_length, default_rounds; + int (*setup)(const unsigned char *key, int keylength, int num_rounds, symmetric_key *skey); + void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *key); + void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *key); + int (*test)(void); + int (*keysize)(int *desired_keysize); +} cipher_descriptor[]; + +#ifdef BLOWFISH +extern int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int blowfish_test(void); +extern int blowfish_keysize(int *desired_keysize); +extern const struct _cipher_descriptor blowfish_desc; +#endif + +#ifdef RC5 +extern int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rc5_test(void); +extern int rc5_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rc5_desc; +#endif + +#ifdef RC6 +extern int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rc6_test(void); +extern int rc6_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rc6_desc; +#endif + +#ifdef RC2 +extern int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rc2_test(void); +extern int rc2_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rc2_desc; +#endif + +#ifdef SAFERP +extern int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int saferp_test(void); +extern int saferp_keysize(int *desired_keysize); +extern const struct _cipher_descriptor saferp_desc; +#endif + +#ifdef SAFER +extern int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); + +extern int safer_k64_test(void); +extern int safer_sk64_test(void); +extern int safer_sk128_test(void); + +extern int safer_64_keysize(int *desired_keysize); +extern int safer_128_keysize(int *desired_keysize); +extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; +#endif + +#ifdef RIJNDAEL + +/* make aes an alias */ +#define aes_setup rijndael_setup +#define aes_ecb_encrypt rijndael_ecb_encrypt +#define aes_ecb_decrypt rijndael_ecb_decrypt +#define aes_test rijndael_test +#define aes_keysize rijndael_keysize + +extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int rijndael_test(void); +extern int rijndael_keysize(int *desired_keysize); +extern const struct _cipher_descriptor rijndael_desc, aes_desc; +#endif + +#ifdef XTEA +extern int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int xtea_test(void); +extern int xtea_keysize(int *desired_keysize); +extern const struct _cipher_descriptor xtea_desc; +#endif + +#ifdef TWOFISH +extern int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int twofish_test(void); +extern int twofish_keysize(int *desired_keysize); +extern const struct _cipher_descriptor twofish_desc; +#endif + +#ifdef DES +extern int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int des_test(void); +extern int des_keysize(int *desired_keysize); + +extern int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int des3_test(void); +extern int des3_keysize(int *desired_keysize); + +extern const struct _cipher_descriptor des_desc, des3_desc; +#endif + +#ifdef CAST5 +extern int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int cast5_test(void); +extern int cast5_keysize(int *desired_keysize); +extern const struct _cipher_descriptor cast5_desc; +#endif + +#ifdef NOEKEON +extern int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int noekeon_test(void); +extern int noekeon_keysize(int *desired_keysize); +extern const struct _cipher_descriptor noekeon_desc; +#endif + +#ifdef SKIPJACK +extern int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +extern void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +extern void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +extern int skipjack_test(void); +extern int skipjack_keysize(int *desired_keysize); +extern const struct _cipher_descriptor skipjack_desc; +#endif + +#ifdef ECB +extern int ecb_start(int cipher, const unsigned char *key, + int keylen, int num_rounds, symmetric_ECB *ecb); +extern int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb); +extern int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb); +#endif + +#ifdef CFB +extern int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb); +extern int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); +extern int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); +#endif + +#ifdef OFB +extern int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb); +extern int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); +extern int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); +#endif + +#ifdef CBC +extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc); +extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc); +extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc); +#endif + +#ifdef CTR +extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CTR *ctr); +extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); +extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); +#endif + +extern int find_cipher(const char *name); +extern int find_cipher_any(const char *name, int blocklen, int keylen); +extern int find_cipher_id(unsigned char ID); + +extern int register_cipher(const struct _cipher_descriptor *cipher); +extern int unregister_cipher(const struct _cipher_descriptor *cipher); + +extern int cipher_is_valid(int idx); + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_custom.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_custom.h new file mode 100644 index 0000000000000000000000000000000000000000..200097fc5177d4217dc89361ee32af0b655a23f9 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_custom.h @@ -0,0 +1,91 @@ +/* This header is meant to be included before mycrypt.h in projects where + * you don't want to throw all the defines in a makefile. + */ + +#ifndef MYCRYPT_CUSTOM_H_ +#define MYCRYPT_CUSTOM_H_ + +#ifdef CRYPT + #error mycrypt_custom.h should be included before mycrypt.h +#endif + +#if defined(__MWERKS__) && defined(__cplusplus) +// codewarrior needs namespace version for c++ (otherwise we get ambiguity errors) +#include +#define XMALLOC std::malloc +#define XREALLOC std::realloc +#define XCALLOC std::calloc +#define XFREE std::free +#else +#define XMALLOC malloc +#define XREALLOC realloc +#define XCALLOC calloc +#define XFREE free +#endif +#define XCLOCK clock +#define XCLOCKS_PER_SEC CLOCKS_PER_SEC +#define SMALL_CODE +#define LTC_TEST +#define BLOWFISH +#define RC2 +#define RC5 +#define RC6 +#define SAFERP +#define SAFER +#define RIJNDAEL +#define XTEA +#define TWOFISH +#define TWOFISH_TABLES +#define DES +#define CAST5 +#define NOEKEON +#define SKIPJACK +#define CFB +#define OFB +#define ECB +#define CBC +#define CTR +#define SHA512 +#define SHA384 +#define SHA256 +#define SHA224 +#define TIGER +#define SHA1 +#define MD5 +#define MD4 +#define MD2 +#define RIPEMD128 +#define RIPEMD160 +#define HMAC +#define OMAC +#define BASE64 +#define YARROW +#define SPRNG +#define RC4 +#define DEVRANDOM +#define MRSA +#define MDSA +#define MDH +#define MECC +#define DH768 +#define DH1024 +#define DH1280 +#define DH1536 +#define DH1792 +#define DH2048 +#define DH2560 +#define DH3072 +#define DH4096 +#define ECC160 +#define ECC192 +#define ECC224 +#define ECC256 +#define ECC384 +#define ECC521 +#define MPI + + +#include + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_gf.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_gf.h new file mode 100644 index 0000000000000000000000000000000000000000..331065dcf56b92317184563b49f1e5ad09709bfc --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_gf.h @@ -0,0 +1,32 @@ + +/* ---- GF(2^w) polynomial basis ---- */ +#ifdef GF +#define LSIZE 32 /* handle upto 1024-bit GF numbers */ + +typedef unsigned long gf_int[LSIZE]; +typedef unsigned long *gf_intp; + +extern void gf_copy(gf_intp a, gf_intp b); +extern void gf_zero(gf_intp a); +extern int gf_iszero(gf_intp a); +extern int gf_isone(gf_intp a); +extern int gf_deg(gf_intp a); + +extern void gf_shl(gf_intp a, gf_intp b); +extern void gf_shr(gf_intp a, gf_intp b); +extern void gf_add(gf_intp a, gf_intp b, gf_intp c); +extern void gf_mul(gf_intp a, gf_intp b, gf_intp c); +extern void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r); + +extern void gf_mod(gf_intp a, gf_intp m, gf_intp b); +extern void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c); +extern void gf_invmod(gf_intp A, gf_intp M, gf_intp B); +extern void gf_sqrt(gf_intp a, gf_intp M, gf_intp b); +extern void gf_gcd(gf_intp A, gf_intp B, gf_intp c); +extern int gf_is_prime(gf_intp a); + +extern int gf_size(gf_intp a); +extern void gf_toraw(gf_intp a, unsigned char *dst); +extern void gf_readraw(gf_intp a, unsigned char *str, int len); + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_hash.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..40a4fc764960209ad87f2368df18210ce8d5a716 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_hash.h @@ -0,0 +1,293 @@ +/* ---- HASH FUNCTIONS ---- */ +#ifdef SHA512 +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; +#endif + +#ifdef SHA256 +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef SHA1 +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef MD5 +struct md5_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef MD4 +struct md4_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef TIGER +struct tiger_state { + ulong64 state[3], length; + unsigned long curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef MD2 +struct md2_state { + unsigned char chksum[16], X[48], buf[16]; + unsigned long curlen; +}; +#endif + +#ifdef RIPEMD128 +struct rmd128_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[4]; +}; +#endif + +#ifdef RIPEMD160 +struct rmd160_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[5]; +}; +#endif + +typedef union Hash_state { +#ifdef SHA512 + struct sha512_state sha512; +#endif +#ifdef SHA256 + struct sha256_state sha256; +#endif +#ifdef SHA1 + struct sha1_state sha1; +#endif +#ifdef MD5 + struct md5_state md5; +#endif +#ifdef MD4 + struct md4_state md4; +#endif +#ifdef MD2 + struct md2_state md2; +#endif +#ifdef TIGER + struct tiger_state tiger; +#endif +#ifdef RIPEMD128 + struct rmd128_state rmd128; +#endif +#ifdef RIPEMD160 + struct rmd160_state rmd160; +#endif +} hash_state; + +extern struct _hash_descriptor { + char *name; + unsigned char ID; + unsigned long hashsize; /* digest output size in bytes */ + unsigned long blocksize; /* the block size the hash uses */ + void (*init)(hash_state *); + int (*process)(hash_state *, const unsigned char *, unsigned long); + int (*done)(hash_state *, unsigned char *); + int (*test)(void); +} hash_descriptor[]; + +#ifdef SHA512 +extern void sha512_init(hash_state * md); +extern int sha512_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int sha512_done(hash_state * md, unsigned char *hash); +extern int sha512_test(void); +extern const struct _hash_descriptor sha512_desc; +#endif + +#ifdef SHA384 +#ifndef SHA512 + #error SHA512 is required for SHA384 +#endif +extern void sha384_init(hash_state * md); +#define sha384_process sha512_process +extern int sha384_done(hash_state * md, unsigned char *hash); +extern int sha384_test(void); +extern const struct _hash_descriptor sha384_desc; +#endif + +#ifdef SHA256 +extern void sha256_init(hash_state * md); +extern int sha256_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int sha256_done(hash_state * md, unsigned char *hash); +extern int sha256_test(void); +extern const struct _hash_descriptor sha256_desc; + +#ifdef SHA224 +#ifndef SHA256 + #error SHA256 is required for SHA224 +#endif +extern void sha224_init(hash_state * md); +#define sha224_process sha256_process +extern int sha224_done(hash_state * md, unsigned char *hash); +extern int sha224_test(void); +extern const struct _hash_descriptor sha224_desc; +#endif +#endif + +#ifdef SHA1 +extern void sha1_init(hash_state * md); +extern int sha1_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int sha1_done(hash_state * md, unsigned char *hash); +extern int sha1_test(void); +extern const struct _hash_descriptor sha1_desc; +#endif + +#ifdef MD5 +extern void md5_init(hash_state * md); +extern int md5_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int md5_done(hash_state * md, unsigned char *hash); +extern int md5_test(void); +extern const struct _hash_descriptor md5_desc; +#endif + +#ifdef MD4 +extern void md4_init(hash_state * md); +extern int md4_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int md4_done(hash_state * md, unsigned char *hash); +extern int md4_test(void); +extern const struct _hash_descriptor md4_desc; +#endif + +#ifdef MD2 +extern void md2_init(hash_state * md); +extern int md2_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int md2_done(hash_state * md, unsigned char *hash); +extern int md2_test(void); +extern const struct _hash_descriptor md2_desc; +#endif + +#ifdef TIGER +extern void tiger_init(hash_state * md); +extern int tiger_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int tiger_done(hash_state * md, unsigned char *hash); +extern int tiger_test(void); +extern const struct _hash_descriptor tiger_desc; +#endif + +#ifdef RIPEMD128 +extern void rmd128_init(hash_state * md); +extern int rmd128_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int rmd128_done(hash_state * md, unsigned char *hash); +extern int rmd128_test(void); +extern const struct _hash_descriptor rmd128_desc; +#endif + +#ifdef RIPEMD160 +extern void rmd160_init(hash_state * md); +extern int rmd160_process(hash_state * md, const unsigned char *buf, unsigned long len); +extern int rmd160_done(hash_state * md, unsigned char *hash); +extern int rmd160_test(void); +extern const struct _hash_descriptor rmd160_desc; +#endif + + +extern int find_hash(const char *name); +extern int find_hash_id(unsigned char ID); +extern int register_hash(const struct _hash_descriptor *hash); +extern int unregister_hash(const struct _hash_descriptor *hash); +extern int hash_is_valid(int idx); + +extern int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen); +extern int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen); +extern int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen); + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (hash_state * md, const unsigned char *buf, unsigned long len) \ +{ \ + unsigned long n; \ + _ARGCHK(md != NULL); \ + _ARGCHK(buf != NULL); \ + if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + while (len > 0) { \ + if (md-> state_var .curlen == 0 && len >= block_size) { \ + compress_name (md, (unsigned char *)buf); \ + md-> state_var .length += block_size * 8; \ + buf += block_size; \ + len -= block_size; \ + } else { \ + n = MIN(len, (block_size - md-> state_var .curlen)); \ + memcpy(md-> state_var .buf + md-> state_var.curlen, buf, (size_t)n); \ + md-> state_var .curlen += n; \ + buf += n; \ + len -= n; \ + if (md-> state_var .curlen == block_size) { \ + compress_name (md, md-> state_var .buf); \ + md-> state_var .length += 8*block_size; \ + md-> state_var .curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +#ifdef HMAC +typedef struct Hmac_state { + hash_state md; + int hash; + hash_state hashstate; + unsigned char key[MAXBLOCKSIZE]; +} hmac_state; + +extern int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); +extern int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len); +extern int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen); +extern int hmac_test(void); +extern int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, + const unsigned char *data, unsigned long len, + unsigned char *dst, unsigned long *dstlen); +extern int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +#endif + +#ifdef OMAC + +typedef struct { + int cipher_idx, + buflen, + blklen; + unsigned char block[MAXBLOCKSIZE], + prev[MAXBLOCKSIZE], + Lu[2][MAXBLOCKSIZE]; + symmetric_key key; +} omac_state; + +extern int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); +extern int omac_process(omac_state *state, const unsigned char *buf, unsigned long len); +extern int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen); +extern int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); +extern int omac_file(int cipher, const unsigned char *key, unsigned long keylen, + const char *filename, unsigned char *out, unsigned long *outlen); +extern int omac_test(void); +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_kr.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_kr.h new file mode 100644 index 0000000000000000000000000000000000000000..6dc16cd8fcbc2ff7fe4de999595257eb9811991f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_kr.h @@ -0,0 +1,81 @@ +#ifdef KR + +#if !defined(MRSA) || !defined(MDH) || !defined(MECC) + #error "Keyring code requires all three public key algorithms." +#endif + +#define MAXLEN 256 + +enum { + NON_KEY=0, + RSA_KEY, + DH_KEY, + ECC_KEY +}; + +typedef union { + rsa_key rsa; + dh_key dh; + ecc_key ecc; +} _pk_key; + +typedef struct Pk_key { + int key_type, /* PUBLIC, PRIVATE, PRIVATE_OPTIMIZED */ + system; /* RSA, ECC or DH ? */ + + unsigned char + name[MAXLEN], /* various info's about this key */ + email[MAXLEN], + description[MAXLEN]; + + unsigned long ID; /* CRC32 of the name/email/description together */ + + _pk_key key; + + struct Pk_key *next; /* linked list chain */ +} pk_key; + +extern int kr_init(pk_key **pk); + +extern unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description); + +extern pk_key *kr_find(pk_key *pk, unsigned long ID); +extern pk_key *kr_find_name(pk_key *pk, const char *name); + +extern int kr_add(pk_key *pk, int key_type, int sys, const unsigned char *name, + const unsigned char *email, const unsigned char *description, const _pk_key *key); + +extern int kr_del(pk_key **_pk, unsigned long ID); +extern int kr_clear(pk_key **pk); +extern int kr_make_key(pk_key *pk, prng_state *prng, int wprng, + int sys, int keysize, const unsigned char *name, + const unsigned char *email, const unsigned char *description); + +extern int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen); +extern int kr_import(pk_key *pk, const unsigned char *in, unsigned long inlen); + +extern int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr); +extern int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr); + +extern int kr_encrypt_key(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash); + +extern int kr_decrypt_key(pk_key *pk, const unsigned char *in, + unsigned char *out, unsigned long *outlen); + +extern int kr_sign_hash(pk_key *pk, unsigned long ID, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng); + +extern int kr_verify_hash(pk_key *pk, const unsigned char *in, + const unsigned char *hash, unsigned long hashlen, + int *stat); + +extern int kr_fingerprint(pk_key *pk, unsigned long ID, int hash, + unsigned char *out, unsigned long *outlen); + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_macros.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..0d5f636dd1cce25ced1fae9118d26e2788dd848f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_macros.h @@ -0,0 +1,241 @@ +/* fix for MSVC ...evil! */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; +#endif + +/* this is the "32-bit at least" data type + * Re-define it to suit your platform but it must be at least 32-bits + */ +typedef unsigned long ulong32; + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[3] & 255)<<24) | \ + ((unsigned long)((y)[2] & 255)<<16) | \ + ((unsigned long)((y)[1] & 255)<<8) | \ + ((unsigned long)((y)[0] & 255)); } + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#endif /* ENDIAN_NEUTRAL */ + +#ifdef ENDIAN_LITTLE + +#define STORE32H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32H(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64H(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64L(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32L(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64L(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64L(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ + +#endif /* ENDIAN_LITTLE */ + +#ifdef ENDIAN_BIG +#define STORE32L(x, y) \ + { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } + +#define LOAD32L(x, y) \ + { x = ((unsigned long)((y)[0] & 255)<<24) | \ + ((unsigned long)((y)[1] & 255)<<16) | \ + ((unsigned long)((y)[2] & 255)<<8) | \ + ((unsigned long)((y)[3] & 255)); } + +#define STORE64L(x, y) \ + { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } + +#define LOAD64L(x, y) \ + { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + memcpy(&(x), y, 4); + +#define STORE64H(x, y) \ + { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } + +#define LOAD64H(x, y) \ + { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + { unsigned long __t = (x); memcpy(y, &__t, 4); } + +#define LOAD32H(x, y) \ + { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } + +#define STORE64H(x, y) \ + { ulong64 __t = (x); memcpy(y, &__t, 8); } + +#define LOAD64H(x, y) \ + { memcpy(&(x), y, 8); } + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + +#ifdef _MSC_VER + +/* instrinsic rotate */ +#include +#pragma intrinsic(_lrotr,_lrotl) +#define ROR(x,n) _lrotr(x,n) +#define ROL(x,n) _lrotl(x,n) + +#elif defined(__GNUC__) && defined(__i386__) + +static inline unsigned long ROL(unsigned long word, int i) +{ + __asm__("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline unsigned long ROR(unsigned long word, int i) +{ + __asm__("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) + +#endif + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#undef MAX +#undef MIN +#define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#define MIN(x, y) ( ((x)<(y))?(x):(y) ) + +/* extract a byte portably */ +#ifdef _MSC_VER + #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) +#else + #define byte(x, n) (((x) >> (8 * (n))) & 255) +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_misc.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_misc.h new file mode 100644 index 0000000000000000000000000000000000000000..b5e804c64d9d7b1013ed848c54b1c94808f8027a --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_misc.h @@ -0,0 +1,17 @@ +/* ---- BASE64 Routines ---- */ +#ifdef BASE64 +extern int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); + +extern int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +/* ---- MEM routines ---- */ +extern void zeromem(void *dst, size_t len); +extern void burn_stack(unsigned long len); + +extern const char *error_to_string(int err); +extern int mpi_to_ltc_error(int err); + +extern const char *crypt_build_settings; diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_pk.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_pk.h new file mode 100644 index 0000000000000000000000000000000000000000..0945243ee85125ba18561893ca7a4aa7fff5a379 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_pk.h @@ -0,0 +1,198 @@ +/* ---- NUMBER THEORY ---- */ +#ifdef MPI + +#include "tommath.h" + +extern int is_prime(mp_int *, int *); +extern int rand_prime(mp_int *N, long len, prng_state *prng, int wprng); +extern mp_err mp_init_multi(mp_int* mp, ...); +extern void mp_clear_multi(mp_int* mp, ...); + +#else + #ifdef MRSA + #error RSA requires the big int library + #endif + #ifdef MECC + #error ECC requires the big int library + #endif + #ifdef MDH + #error DH requires the big int library + #endif + #ifdef MDSA + #error DSA requires the big int library + #endif +#endif /* MPI */ + + +/* ---- PUBLIC KEY CRYPTO ---- */ + +#define PK_PRIVATE 0 /* PK private keys */ +#define PK_PUBLIC 1 /* PK public keys */ +#define PK_PRIVATE_OPTIMIZED 2 /* PK private key [rsa optimized] */ + +/* ---- PACKET ---- */ +#ifdef PACKET + +extern void packet_store_header(unsigned char *dst, int section, int subsection); +extern int packet_valid_header(unsigned char *src, int section, int subsection); + +#endif + + +/* ---- RSA ---- */ +#ifdef MRSA +typedef struct Rsa_key { + int type; + mp_int e, d, N, qP, pQ, dP, dQ, p, q; +} rsa_key; + +extern int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); + +extern int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +extern int rsa_pad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int wprng, prng_state *prng); + +extern int rsa_signpad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +extern int rsa_depad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +extern int rsa_signdepad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + +extern void rsa_free(rsa_key *key); + +extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, + unsigned char *outkey, unsigned long *outlen, + prng_state *prng, int wprng, rsa_key *key); + +extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + rsa_key *key); + +extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + rsa_key *key); + +extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, int *stat, rsa_key *key); + +extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); +extern int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); +#endif + +/* ---- DH Routines ---- */ +#ifdef MDH + +typedef struct Dh_key { + int idx, type; + mp_int x, y; +} dh_key; + +extern int dh_test(void); +extern void dh_sizes(int *low, int *high); +extern int dh_get_size(dh_key *key); + +extern int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key); +extern void dh_free(dh_key *key); + +extern int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key); +extern int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key); + +extern int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen); + +extern int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + dh_key *key); + +extern int dh_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + dh_key *key); + +extern int dh_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dh_key *key); + +extern int dh_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dh_key *key); + + +#endif + +/* ---- ECC Routines ---- */ +#ifdef MECC +typedef struct { + mp_int x, y; +} ecc_point; + +typedef struct { + int type, idx; + ecc_point pubkey; + mp_int k; +} ecc_key; + +extern int ecc_test(void); +extern void ecc_sizes(int *low, int *high); +extern int ecc_get_size(ecc_key *key); + +extern int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); +extern void ecc_free(ecc_key *key); + +extern int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +extern int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); + +extern int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen); + +extern int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen, + unsigned char *out, unsigned long *len, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +extern int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + ecc_key *key); + +extern int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +extern int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); +#endif + +#ifdef MDSA + +typedef struct { + int type, qord; + mp_int g, q, p, x, y; +} dsa_key; + +extern int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); +extern void dsa_free(dsa_key *key); + +extern int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); + +extern int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long inlen, + int *stat, dsa_key *key); + +extern int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); + +extern int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); + +extern int dsa_verify_key(dsa_key *key, int *stat); + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_prng.h b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_prng.h new file mode 100644 index 0000000000000000000000000000000000000000..b96fa431ea884b39ae7dd076ebc17d0c301b835a --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/mycrypt_prng.h @@ -0,0 +1,66 @@ +/* ---- PRNG Stuff ---- */ +struct yarrow_prng { + int cipher, hash; + unsigned char pool[MAXBLOCKSIZE]; + symmetric_CTR ctr; +}; + +struct rc4_prng { + int x, y; + unsigned char buf[256]; +}; + +typedef union Prng_state { + struct yarrow_prng yarrow; + struct rc4_prng rc4; +} prng_state; + +extern struct _prng_descriptor { + char *name; + int (*start)(prng_state *); + int (*add_entropy)(const unsigned char *, unsigned long, prng_state *); + int (*ready)(prng_state *); + unsigned long (*read)(unsigned char *, unsigned long len, prng_state *); +} prng_descriptor[]; + +#ifdef YARROW +extern int yarrow_start(prng_state *prng); +extern int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng); +extern int yarrow_ready(prng_state *prng); +extern unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng); +extern const struct _prng_descriptor yarrow_desc; +#endif + +#ifdef RC4 +extern int rc4_start(prng_state *prng); +extern int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng); +extern int rc4_ready(prng_state *prng); +extern unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng); +extern const struct _prng_descriptor rc4_desc; +#endif + +#ifdef SPRNG +extern int sprng_start(prng_state *prng); +extern int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng); +extern int sprng_ready(prng_state *prng); +extern unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng); +extern const struct _prng_descriptor sprng_desc; +#endif + +extern int find_prng(const char *name); +extern int register_prng(const struct _prng_descriptor *prng); +extern int unregister_prng(const struct _prng_descriptor *prng); +extern int prng_is_valid(int idx); + + +/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this + * might not work on all platforms as planned + */ +/* ch2-02-1 */ +extern unsigned long rng_get_bytes(unsigned char *buf, + unsigned long len, + void (*callback)(void)); +/* ch2-02-1 */ + +extern int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); + diff --git a/tnl-1.5.0/tnl/libtomcrypt/noekeon.c b/tnl-1.5.0/tnl/libtomcrypt/noekeon.c new file mode 100644 index 0000000000000000000000000000000000000000..d2c81561964909c302e94c55cf00d1031c62ea78 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/noekeon.c @@ -0,0 +1,280 @@ +/* Implementation of the Noekeon block cipher by Tom St Denis */ +#include "mycrypt.h" + +#ifdef NOEKEON + +const struct _cipher_descriptor noekeon_desc = +{ + "noekeon", + 16, + 16, 16, 16, 16, + &noekeon_setup, + &noekeon_ecb_encrypt, + &noekeon_ecb_decrypt, + &noekeon_test, + &noekeon_keysize +}; + +static const ulong32 RC[] = { + 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL, + 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL, + 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL, + 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL, + 0x000000d4UL +}; + + +#define kTHETA(a, b, c, d) \ + temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + b ^= temp; d ^= temp; \ + temp = b^d; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + a ^= temp; c ^= temp; + +#define THETA(k, a, b, c, d) \ + temp = a^c; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + b ^= temp ^ k[1]; d ^= temp ^ k[3]; \ + temp = b^d; temp = temp ^ ROL(temp, 8) ^ ROR(temp, 8); \ + a ^= temp ^ k[0]; c ^= temp ^ k[2]; + +#define GAMMA(a, b, c, d) \ + b ^= ~(d|c); \ + a ^= c&b; \ + temp = d; d = a; a = temp;\ + c ^= a ^ b ^ d; \ + b ^= ~(d|c); \ + a ^= c&b; + +#define PI1(a, b, c, d) \ + a = ROL(a, 1); c = ROL(c, 5); d = ROL(d, 2); + +#define PI2(a, b, c, d) \ + a = ROR(a, 1); c = ROR(c, 5); d = ROR(d, 2); + +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + ulong32 temp; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + LOAD32L(skey->noekeon.K[0],&key[0]); + LOAD32L(skey->noekeon.K[1],&key[4]); + LOAD32L(skey->noekeon.K[2],&key[8]); + LOAD32L(skey->noekeon.K[3],&key[12]); + + LOAD32L(skey->noekeon.dK[0],&key[0]); + LOAD32L(skey->noekeon.dK[1],&key[4]); + LOAD32L(skey->noekeon.dK[2],&key[8]); + LOAD32L(skey->noekeon.dK[3],&key[12]); + + kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]); + + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +static void _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,temp; +#ifdef SMALL_CODE + int r; +#endif + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); + LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); + + +#ifdef SMALL_CODE +#define ROUND \ + a ^= RC[r]; \ + THETA(key->noekeon.K, a,b,c,d); \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + for (r = 0; r < 16; ++r) { + ROUND; + } +#else + +#define ROUND(i) \ + a ^= RC[i]; \ + THETA(key->noekeon.K, a,b,c,d); \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + ROUND( 0); ROUND( 1); ROUND( 2); ROUND( 3); + ROUND( 4); ROUND( 5); ROUND( 6); ROUND( 7); + ROUND( 8); ROUND( 9); ROUND(10); ROUND(11); + ROUND(12); ROUND(13); ROUND(14); ROUND(15); +#endif + +#undef ROUND + + a ^= RC[16]; + THETA(key->noekeon.K, a, b, c, d); + + STORE32L(a,&ct[0]); STORE32L(b,&ct[4]); + STORE32L(c,&ct[8]); STORE32L(d,&ct[12]); +} + +#ifdef CLEAN_STACK +void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _noekeon_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d, temp; +#ifdef SMALL_CODE + int r; +#endif + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(a,&ct[0]); LOAD32L(b,&ct[4]); + LOAD32L(c,&ct[8]); LOAD32L(d,&ct[12]); + + +#ifdef SMALL_CODE + +#define ROUND \ + THETA(key->noekeon.dK, a,b,c,d); \ + a ^= RC[r]; \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + for (r = 16; r > 0; --r) { + ROUND; + } + +#else + +#define ROUND(i) \ + THETA(key->noekeon.dK, a,b,c,d); \ + a ^= RC[i]; \ + PI1(a,b,c,d); \ + GAMMA(a,b,c,d); \ + PI2(a,b,c,d); + + ROUND(16); ROUND(15); ROUND(14); ROUND(13); + ROUND(12); ROUND(11); ROUND(10); ROUND( 9); + ROUND( 8); ROUND( 7); ROUND( 6); ROUND( 5); + ROUND( 4); ROUND( 3); ROUND( 2); ROUND( 1); + +#endif + +#undef ROUND + + THETA(key->noekeon.dK, a,b,c,d); + a ^= RC[0]; + STORE32L(a,&pt[0]); STORE32L(b, &pt[4]); + STORE32L(c,&pt[8]); STORE32L(d, &pt[12]); +} + +#ifdef CLEAN_STACK +void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _noekeon_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 5 + sizeof(int)); +} +#endif + +int noekeon_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 0x57, 0x9a, 0x6c, 0xe8, 0x91, 0x16, 0x52, 0x53, + 0x32, 0x00, 0xca, 0x0a, 0x17, 0x5d, 0x28, 0x0e } + } + }; + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + zeromem(&key, sizeof(key)); + if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key); + noekeon_ecb_decrypt(tmp[0], tmp[1], &key); + if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { +#if 0 + printf("\n\nTest %d failed\n", i); + if (memcmp(tmp[0], tests[i].ct, 16)) { + printf("CT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[0][i]); + } + printf("\n"); + } else { + printf("PT: "); + for (i = 0; i < 16; i++) { + printf("%02x ", tmp[1][i]); + } + printf("\n"); + } +#endif + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int noekeon_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *desired_keysize = 16; + return CRYPT_OK; + } +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/ofb.c b/tnl-1.5.0/tnl/libtomcrypt/ofb.c new file mode 100644 index 0000000000000000000000000000000000000000..808e32cd86a30754a5a0a37bd74768f6a9038d10 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/ofb.c @@ -0,0 +1,67 @@ +#include "mycrypt.h" + +#ifdef OFB + +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb) +{ + int x, err; + + _ARGCHK(IV != NULL); + _ARGCHK(key != NULL); + _ARGCHK(ofb != NULL); + + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + /* copy details */ + ofb->cipher = cipher; + ofb->blocklen = cipher_descriptor[cipher].block_length; + for (x = 0; x < ofb->blocklen; x++) { + ofb->IV[x] = IV[x]; + } + + /* init the cipher */ + ofb->padlen = ofb->blocklen; + return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key); +} + +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb) +{ + int err; + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ofb != NULL); + if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { + return err; + } + + /* is blocklen/padlen valid? */ + if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || + ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { + return CRYPT_INVALID_ARG; + } + + while (len-- > 0) { + if (ofb->padlen == ofb->blocklen) { + cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key); + ofb->padlen = 0; + } + *ct++ = *pt++ ^ ofb->IV[ofb->padlen++]; + } + return CRYPT_OK; +} + +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb) +{ + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(ofb != NULL); + return ofb_encrypt(ct, pt, len, ofb); +} + + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/omac.c b/tnl-1.5.0/tnl/libtomcrypt/omac.c new file mode 100644 index 0000000000000000000000000000000000000000..ccb681e0a4c5b4cb8a26985edfad9b338cfeadd3 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/omac.c @@ -0,0 +1,244 @@ +/* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */ +#include "mycrypt.h" + +#ifdef OMAC + +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen) +{ + int err, x, y, mask, msb, len; + + _ARGCHK(omac != NULL); + _ARGCHK(key != NULL); + + /* schedule the key */ + if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { + return err; + } + + if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) { + return err; + } + + /* ok now we need Lu and Lu^2 [calc one from the other] */ + + /* first calc L which is Ek(0) */ + zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); + cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key); + + /* now setup the system */ + switch (cipher_descriptor[cipher].block_length) { + case 8: mask = 0x1B; + len = 8; + break; + case 16: mask = 0x87; + len = 16; + break; + default: return CRYPT_INVALID_ARG; + } + + /* now do the mults, whoopy! */ + for (x = 0; x < 2; x++) { + /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */ + msb = omac->Lu[x][0] >> 7; + + /* shift left */ + for (y = 0; y < (len - 1); y++) { + omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255; + } + omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255; + + /* copy up as require */ + if (x == 0) { + memcpy(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0])); + } + } + + /* setup state */ + omac->cipher_idx = cipher; + omac->buflen = 0; + omac->blklen = len; + zeromem(omac->prev, sizeof(omac->prev)); + zeromem(omac->block, sizeof(omac->block)); + + return CRYPT_OK; +} + +int omac_process(omac_state *state, const unsigned char *buf, unsigned long len) +{ + int err, n, x; + + _ARGCHK(state != NULL); + _ARGCHK(buf != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->blklen > (int)sizeof(state->block)) || (state->buflen > state->blklen)) { + return CRYPT_INVALID_ARG; + } + + while (len != 0) { + /* ok if the block is full we xor in prev, encrypt and replace prev */ + if (state->buflen == state->blklen) { + for (x = 0; x < state->blklen; x++) { + state->block[x] ^= state->prev[x]; + } + cipher_descriptor[state->cipher_idx].ecb_encrypt(state->block, state->prev, &state->key); + state->buflen = 0; + } + + /* add bytes */ + n = MIN(len, (unsigned long)(state->blklen - state->buflen)); + memcpy(state->block + state->buflen, buf, n); + state->buflen += n; + len -= n; + buf += n; + } + + return CRYPT_OK; +} + +int omac_done(omac_state *state, unsigned char *out, unsigned long *outlen) +{ + int err, mode, x; + + _ARGCHK(state != NULL); + _ARGCHK(out != NULL); + if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { + return err; + } + + if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || + (state->blklen > (int)sizeof(state->block)) || (state->buflen > state->blklen)) { + return CRYPT_INVALID_ARG; + } + + /* figure out mode */ + if (state->buflen != state->blklen) { + /* add the 0x80 byte */ + state->block[state->buflen++] = 0x80; + + /* pad with 0x00 */ + while (state->buflen < state->blklen) { + state->block[state->buflen++] = 0x00; + } + mode = 1; + } else { + mode = 0; + } + + /* now xor prev + Lu[mode] */ + for (x = 0; x < state->blklen; x++) { + state->block[x] ^= state->prev[x] ^ state->Lu[mode][x]; + } + + /* encrypt it */ + cipher_descriptor[state->cipher_idx].ecb_encrypt(state->block, state->block, &state->key); + + /* output it */ + for (x = 0; x < state->blklen && (unsigned long)x < *outlen; x++) { + out[x] = state->block[x]; + } + *outlen = x; + +#ifdef CLEAN_STACK + zeromem(state, sizeof(*state)); +#endif + return CRYPT_OK; +} + +int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen) +{ + int err; + omac_state omac; + + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + return err; + } + if ((err = omac_process(&omac, msg, msglen)) != CRYPT_OK) { + return err; + } + if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { + return err; + } + return CRYPT_OK; +} + +int omac_file(int cipher, const unsigned char *key, unsigned long keylen, + const char *filename, unsigned char *out, unsigned long *outlen) +{ +#ifdef NO_FILE + return CRYPT_NOP; +#else + int err, x; + omac_state omac; + FILE *in; + unsigned char buf[512]; + + in = fopen(filename, "rb"); + if (in == NULL) { + return CRYPT_FILE_NOTFOUND; + } + + if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { + fclose(in); + return err; + } + + do { + x = fread(buf, 1, sizeof(buf), in); + if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) { + fclose(in); + return err; + } + } while (x == sizeof(buf)); + fclose(in); + + if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { + return err; + } + return CRYPT_OK; +#endif +} + +int omac_test(void) +{ +#if !defined(LTC_TEST) + return CRYPT_NOP; +#else + static const unsigned char key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; + static const unsigned char pt[] = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }; + static const unsigned char tag[] = { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, + 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }; + unsigned char out[16]; + int err, idx; + unsigned long len; + + + /* AES can be under rijndael or aes... try to find it */ + if ((idx = find_cipher("aes")) == -1) { + if ((idx = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + len = sizeof(out); + if ((err = omac_memory(idx, key, 16, pt, 40, out, &len)) != CRYPT_OK) { + return err; + } + + if (memcmp(out, tag, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/packet.c b/tnl-1.5.0/tnl/libtomcrypt/packet.c new file mode 100644 index 0000000000000000000000000000000000000000..44da4455b7dee9cb343920a82052ac7ee1a69540 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/packet.c @@ -0,0 +1,41 @@ +#include "mycrypt.h" + +#ifdef PACKET + +void packet_store_header(unsigned char *dst, int section, int subsection) +{ + _ARGCHK(dst != NULL); + + /* store version number */ + dst[0] = (unsigned char)(CRYPT&255); + dst[1] = (unsigned char)((CRYPT>>8)&255); + + /* store section and subsection */ + dst[2] = (unsigned char)(section & 255); + dst[3] = (unsigned char)(subsection & 255); + +} + +int packet_valid_header(unsigned char *src, int section, int subsection) +{ + unsigned long ver; + + _ARGCHK(src != NULL); + + /* check version */ + ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8U); + if (CRYPT < ver) { + return CRYPT_INVALID_PACKET; + } + + /* check section and subsection */ + if (section != (int)src[2] || subsection != (int)src[3]) { + return CRYPT_INVALID_PACKET; + } + + return CRYPT_OK; +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/prime.c b/tnl-1.5.0/tnl/libtomcrypt/prime.c new file mode 100644 index 0000000000000000000000000000000000000000..4837a0ad34100c25cbd575243d86eb36b59b833b --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/prime.c @@ -0,0 +1,70 @@ +#include "mycrypt.h" + +#ifdef MPI + +struct rng_data { + prng_state *prng; + int wprng; +}; + + +#define UPPER_LIMIT PRIME_SIZE + +/* figures out if a number is prime (MR test) */ +int is_prime(mp_int *N, int *result) +{ + int err; + _ARGCHK(N != NULL); + _ARGCHK(result != NULL); + if ((err = mp_prime_is_prime(N, mp_prime_rabin_miller_trials(mp_count_bits(N)), result)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + return CRYPT_OK; +} + +static int rand_prime_helper(unsigned char *dst, int len, void *dat) +{ + return (int)prng_descriptor[((struct rng_data *)dat)->wprng].read(dst, len, ((struct rng_data *)dat)->prng); +} + +int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) +{ + struct rng_data rng; + int type, err; + + _ARGCHK(N != NULL); + + /* allow sizes between 2 and 256 bytes for a prime size */ + if (len < 2 || len > 256) { + return CRYPT_INVALID_PRIME_SIZE; + } + + /* valid PRNG? Better be! */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* setup our callback data, then world domination! */ + rng.prng = prng; + rng.wprng = wprng; + + /* get type */ + if (len < 0) { + type = 1; + len = -len; + } else { + type = 0; + } + + /* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!! + -- Gir: Yeah, oh wait, er, no. + */ + if ((err = mp_prime_random(N, mp_prime_rabin_miller_trials(len*8), len, type, rand_prime_helper, &rng)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rc2.c b/tnl-1.5.0/tnl/libtomcrypt/rc2.c new file mode 100644 index 0000000000000000000000000000000000000000..a352f7cc7cd9b7ea9d579e04259697faee0cd66d --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rc2.c @@ -0,0 +1,305 @@ +/**********************************************************************\ +* To commemorate the 1996 RSA Data Security Conference, the following * +* code is released into the public domain by its author. Prost! * +* * +* This cipher uses 16-bit words and little-endian byte ordering. * +* I wonder which processor it was optimized for? * +* * +* Thanks to CodeView, SoftIce, and D86 for helping bring this code to * +* the public. * +\**********************************************************************/ + +#include + +#ifdef RC2 + +const struct _cipher_descriptor rc2_desc = { + "rc2", + 12, 8, 128, 8, 16, + &rc2_setup, + &rc2_ecb_encrypt, + &rc2_ecb_decrypt, + &rc2_test, + &rc2_keysize +}; + + +/**********************************************************************\ +* Expand a variable-length user key (between 1 and 128 bytes) to a * +* 64-short working rc2 key, of at most "bits" effective key bits. * +* The effective key bits parameter looks like an export control hack. * +* For normal use, it should always be set to 1024. For convenience, * +* zero is accepted as an alias for 1024. * +\**********************************************************************/ + + /* 256-entry permutation table, probably derived somehow from pi */ + static const unsigned char permute[256] = { + 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, + 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, + 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, + 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, + 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, + 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, + 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, + 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, + 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, + 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, + 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, + 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, + 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, + 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, + 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, + 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173 + }; + +int rc2_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey) +{ + unsigned *xkey = skey->rc2.xkey; + unsigned char tmp[128]; + unsigned T8, TM; + int i, bits; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + if (rounds != 0 && rounds != 16) { + return CRYPT_INVALID_ROUNDS; + } + + for (i = 0; i < keylen; i++) { + tmp[i] = key[i] & 255; + } + + /* Phase 1: Expand input key to 128 bytes */ + if (keylen < 128) { + for (i = keylen; i < 128; i++) { + tmp[i] = permute[(int)((tmp[i - 1] + tmp[i - keylen]) & 255)]; + } + } + + /* Phase 2 - reduce effective key size to "bits" */ + bits = keylen*8; + T8 = (unsigned)(bits+7)>>3; + TM = (255 >> (unsigned)(7 & -bits)); + tmp[128 - T8] = permute[(int)(tmp[128 - T8] & TM)]; + for (i = 127 - T8; i >= 0; i--) { + tmp[i] = permute[(int)(tmp[i + 1] ^ tmp[i + T8])]; + } + + /* Phase 3 - copy to xkey in little-endian order */ + i = 63; + do { + xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8); + } while (i-- > 0); + +#ifdef CLEAN_STACK + zeromem(tmp, sizeof(tmp)); +#endif + + return CRYPT_OK; +} + +/**********************************************************************\ +* Encrypt an 8-byte block of plaintext using the given key. * +\**********************************************************************/ +#ifdef CLEAN_STACK +static void _rc2_ecb_encrypt( const unsigned char *plain, + unsigned char *cipher, + symmetric_key *skey) +#else +void rc2_ecb_encrypt( const unsigned char *plain, + unsigned char *cipher, + symmetric_key *skey) +#endif +{ + unsigned *xkey = skey->rc2.xkey; + unsigned x76, x54, x32, x10, i; + + _ARGCHK(plain != NULL); + _ARGCHK(cipher != NULL); + _ARGCHK(skey != NULL); + + x76 = ((unsigned)plain[7] << 8) + (unsigned)plain[6]; + x54 = ((unsigned)plain[5] << 8) + (unsigned)plain[4]; + x32 = ((unsigned)plain[3] << 8) + (unsigned)plain[2]; + x10 = ((unsigned)plain[1] << 8) + (unsigned)plain[0]; + + for (i = 0; i < 16; i++) { + x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF; + x10 = ((x10 << 1) | (x10 >> 15)) & 0xFFFF; + + x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF; + x32 = ((x32 << 2) | (x32 >> 14)) & 0xFFFF; + + x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF; + x54 = ((x54 << 3) | (x54 >> 13)) & 0xFFFF; + + x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF; + x76 = ((x76 << 5) | (x76 >> 11)) & 0xFFFF; + + if (i == 4 || i == 10) { + x10 = (x10 + xkey[x76 & 63]) & 0xFFFF; + x32 = (x32 + xkey[x10 & 63]) & 0xFFFF; + x54 = (x54 + xkey[x32 & 63]) & 0xFFFF; + x76 = (x76 + xkey[x54 & 63]) & 0xFFFF; + } + } + + cipher[0] = (unsigned char)x10; + cipher[1] = (unsigned char)(x10 >> 8); + cipher[2] = (unsigned char)x32; + cipher[3] = (unsigned char)(x32 >> 8); + cipher[4] = (unsigned char)x54; + cipher[5] = (unsigned char)(x54 >> 8); + cipher[6] = (unsigned char)x76; + cipher[7] = (unsigned char)(x76 >> 8); +} + +#ifdef CLEAN_STACK +void rc2_ecb_encrypt( const unsigned char *plain, + unsigned char *cipher, + symmetric_key *skey) +{ + _rc2_ecb_encrypt(plain, cipher, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); +} +#endif + +/**********************************************************************\ +* Decrypt an 8-byte block of ciphertext using the given key. * +\**********************************************************************/ + +#ifdef CLEAN_STACK +static void _rc2_ecb_decrypt( const unsigned char *cipher, + unsigned char *plain, + symmetric_key *skey) +#else +void rc2_ecb_decrypt( const unsigned char *cipher, + unsigned char *plain, + symmetric_key *skey) +#endif +{ + unsigned x76, x54, x32, x10; + unsigned *xkey = skey->rc2.xkey; + int i; + + _ARGCHK(plain != NULL); + _ARGCHK(cipher != NULL); + _ARGCHK(skey != NULL); + + x76 = ((unsigned)cipher[7] << 8) + (unsigned)cipher[6]; + x54 = ((unsigned)cipher[5] << 8) + (unsigned)cipher[4]; + x32 = ((unsigned)cipher[3] << 8) + (unsigned)cipher[2]; + x10 = ((unsigned)cipher[1] << 8) + (unsigned)cipher[0]; + + for (i = 15; i >= 0; i--) { + if (i == 4 || i == 10) { + x76 = (x76 - xkey[x54 & 63]) & 0xFFFF; + x54 = (x54 - xkey[x32 & 63]) & 0xFFFF; + x32 = (x32 - xkey[x10 & 63]) & 0xFFFF; + x10 = (x10 - xkey[x76 & 63]) & 0xFFFF; + } + + x76 = ((x76 << 11) | (x76 >> 5)) & 0xFFFF; + x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF; + + x54 = ((x54 << 13) | (x54 >> 3)) & 0xFFFF; + x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF; + + x32 = ((x32 << 14) | (x32 >> 2)) & 0xFFFF; + x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF; + + x10 = ((x10 << 15) | (x10 >> 1)) & 0xFFFF; + x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF; + } + + plain[0] = (unsigned char)x10; + plain[1] = (unsigned char)(x10 >> 8); + plain[2] = (unsigned char)x32; + plain[3] = (unsigned char)(x32 >> 8); + plain[4] = (unsigned char)x54; + plain[5] = (unsigned char)(x54 >> 8); + plain[6] = (unsigned char)x76; + plain[7] = (unsigned char)(x76 >> 8); +} + +#ifdef CLEAN_STACK +void rc2_ecb_decrypt( const unsigned char *cipher, + unsigned char *plain, + symmetric_key *skey) +{ + _rc2_ecb_decrypt(cipher, plain, skey); + burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); +} +#endif + +int rc2_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + + { 8, + { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } + + }, + { 16, + { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, + 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 } + } + }; + int x, y, err; + symmetric_key skey; + unsigned char tmp[2][8]; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + zeromem(tmp, sizeof(tmp)); + if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + + rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); + rc2_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (memcmp(tmp[0], tests[x].ct, 8) != 0 || memcmp(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rc2_keysize(int *keysize) +{ + _ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*keysize > 128) { + *keysize = 128; + } + return CRYPT_OK; +} + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rc4.c b/tnl-1.5.0/tnl/libtomcrypt/rc4.c new file mode 100644 index 0000000000000000000000000000000000000000..e60cadadde991c98eb54edf35aabaea7f4aff8da --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rc4.c @@ -0,0 +1,97 @@ +#include "mycrypt.h" + +#ifdef RC4 + +const struct _prng_descriptor rc4_desc = +{ + "rc4", + &rc4_start, + &rc4_add_entropy, + &rc4_ready, + &rc4_read +}; + +int rc4_start(prng_state *prng) +{ + _ARGCHK(prng != NULL); + + /* set keysize to zero */ + prng->rc4.x = 0; + + return CRYPT_OK; +} + +int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) +{ + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + if (prng->rc4.x + len > 256) { + return CRYPT_INVALID_KEYSIZE; + } + + while (len--) { + prng->rc4.buf[prng->rc4.x++] = *buf++; + } + + return CRYPT_OK; + +} + +int rc4_ready(prng_state *prng) +{ + unsigned char key[256], tmp; + int keylen, x, y; + + _ARGCHK(prng != NULL); + + /* extract the key */ + memcpy(key, prng->rc4.buf, 256); + keylen = prng->rc4.x; + + /* make RC4 perm and shuffle */ + for (x = 0; x < 256; x++) { + prng->rc4.buf[x] = x; + } + + for (x = y = 0; x < 256; x++) { + y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255; + tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp; + } + prng->rc4.x = x; + prng->rc4.y = y; + +#ifdef CLEAN_STACK + zeromem(key, sizeof(key)); +#endif + + return CRYPT_OK; +} + +unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng) +{ + int x, y; + unsigned char *s, tmp; + unsigned long n; + + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + n = len; + x = prng->rc4.x; + y = prng->rc4.y; + s = prng->rc4.buf; + while (len--) { + x = (x + 1) & 255; + y = (y + s[x]) & 255; + tmp = s[x]; s[x] = s[y]; s[y] = tmp; + tmp = (s[x] + s[y]) & 255; + *buf++ ^= s[tmp]; + } + prng->rc4.x = x; + prng->rc4.y = y; + return n; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rc5.c b/tnl-1.5.0/tnl/libtomcrypt/rc5.c new file mode 100644 index 0000000000000000000000000000000000000000..135db08c2fcf7fafead91de3b1255a8eef37b4ea --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rc5.c @@ -0,0 +1,257 @@ +#include "mycrypt.h" + +#ifdef RC5 + +const struct _cipher_descriptor rc5_desc = +{ + "rc5", + 2, + 8, 128, 8, 12, + &rc5_setup, + &rc5_ecb_encrypt, + &rc5_ecb_decrypt, + &rc5_test, + &rc5_keysize +}; + +static const ulong32 stab[50] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL, +0x62482413UL, 0x007f9dccUL +}; + +#ifdef CLEAN_STACK +static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], *S, A, B, i, j, v, s, t, l; + + _ARGCHK(skey != NULL); + _ARGCHK(key != NULL); + + + /* test parameters */ + if (num_rounds == 0) { + num_rounds = rc5_desc.default_rounds; + } + + if (num_rounds < 12 || num_rounds > 24) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + skey->rc5.rounds = num_rounds; + S = skey->rc5.K; + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if ((i & 3) == 0) { + L[j++] = BSWAP(A); + A = 0; + } + } + + if ((keylen & 3) != 0) { + A <<= (ulong32)((8 * (4 - (keylen&3)))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + t = (ulong32)(2 * (num_rounds + 1)); + memcpy(S, stab, t * sizeof(*S)); + + /* mix buffer */ + s = 3 * MAX(t, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROL(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == t) { i = 0; } + if (++j == l) { j = 0; } + } + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc5_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122 + sizeof(int)); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 A, B, *K; + int r; + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(A, &pt[0]); + LOAD32L(B, &pt[4]); + A += key->rc5.K[0]; + B += key->rc5.K[1]; + K = key->rc5.K + 2; + + if ((key->rc5.rounds & 1) == 0) { + for (r = 0; r < key->rc5.rounds; r += 2) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + A = ROL(A ^ B, B) + K[2]; + B = ROL(B ^ A, A) + K[3]; + K += 4; + } + } else { + for (r = 0; r < key->rc5.rounds; r++) { + A = ROL(A ^ B, B) + K[0]; + B = ROL(B ^ A, A) + K[1]; + K += 2; + } + } + STORE32L(A, &ct[0]); + STORE32L(B, &ct[4]); +} + +#ifdef CLEAN_STACK +void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _rc5_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 A, B, *K; + int r; + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(A, &ct[0]); + LOAD32L(B, &ct[4]); + K = key->rc5.K + (key->rc5.rounds << 1); + + if ((key->rc5.rounds & 1) == 0) { + K -= 2; + for (r = key->rc5.rounds - 1; r >= 0; r -= 2) { + B = ROR(B - K[3], A) ^ A; + A = ROR(A - K[2], B) ^ B; + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 4; + } + } else { + for (r = key->rc5.rounds - 1; r >= 0; r--) { + B = ROR(B - K[1], A) ^ A; + A = ROR(A - K[0], B) ^ B; + K -= 2; + } + } + A -= key->rc5.K[0]; + B -= key->rc5.K[1]; + STORE32L(A, &pt[0]); + STORE32L(B, &pt[4]); +} + +#ifdef CLEAN_STACK +void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _rc5_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 2 + sizeof(int)); +} +#endif + +int rc5_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[16], pt[8], ct[8]; + } tests[] = { + { + { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51, + 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 }, + { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d }, + { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 } + }, + { + { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f, + 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 }, + { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 } + }, + { + { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f, + 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf }, + { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }, + { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc } + } + }; + unsigned char tmp[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc5_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc5_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (memcmp(tmp[0], tests[x].ct, 8) != 0 || memcmp(tmp[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rc5_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 128) { + *desired_keysize = 128; + } + return CRYPT_OK; +} + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rc6.c b/tnl-1.5.0/tnl/libtomcrypt/rc6.c new file mode 100644 index 0000000000000000000000000000000000000000..3a0d974b8186b6f5011f15b49022f0db4fcaeee8 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rc6.c @@ -0,0 +1,269 @@ +#include "mycrypt.h" + +#ifdef RC6 + +const struct _cipher_descriptor rc6_desc = +{ + "rc6", + 3, + 8, 128, 16, 20, + &rc6_setup, + &rc6_ecb_encrypt, + &rc6_ecb_decrypt, + &rc6_test, + &rc6_keysize +}; + +static const ulong32 stab[44] = { +0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, +0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, +0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, +0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, +0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, +0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL }; + +#ifdef CLEAN_STACK +static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ + ulong32 L[64], S[50], A, B, i, j, v, s, l; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* test parameters */ + if (num_rounds != 0 && num_rounds != 20) { + return CRYPT_INVALID_ROUNDS; + } + + /* key must be between 64 and 1024 bits */ + if (keylen < 8 || keylen > 128) { + return CRYPT_INVALID_KEYSIZE; + } + + /* copy the key into the L array */ + for (A = i = j = 0; i < (ulong32)keylen; ) { + A = (A << 8) | ((ulong32)(key[i++] & 255)); + if (!(i & 3)) { + L[j++] = BSWAP(A); + A = 0; + } + } + + /* handle odd sized keys */ + if (keylen & 3) { + A <<= (8 * (4 - (keylen&3))); + L[j++] = BSWAP(A); + } + + /* setup the S array */ + memcpy(S, stab, 44 * sizeof(stab[0])); + + /* mix buffer */ + s = 3 * MAX(44, j); + l = j; + for (A = B = i = j = v = 0; v < s; v++) { + A = S[i] = ROL(S[i] + A + B, 3); + B = L[j] = ROL(L[j] + A + B, (A+B)); + if (++i == 44) { i = 0; } + if (++j == l) { j = 0; } + } + + /* copy to key */ + for (i = 0; i < 44; i++) { + skey->rc6.K[i] = S[i]; + } + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _rc6_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(ulong32) * 122); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]); + + b += key->rc6.K[0]; + d += key->rc6.K[1]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROL(t, 5); \ + u = (d * (d + d + 1)); u = ROL(u, 5); \ + a = ROL(a^t,u) + K[0]; \ + c = ROL(c^u,t) + K[1]; K += 2; + + K = key->rc6.K + 2; + for (r = 0; r < 20; r += 4) { + RND(a,b,c,d); + RND(b,c,d,a); + RND(c,d,a,b); + RND(d,a,b,c); + } + +#undef RND + + a += key->rc6.K[42]; + c += key->rc6.K[43]; + STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); +} + +#ifdef CLEAN_STACK +void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _rc6_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,t,u, *K; + int r; + + _ARGCHK(key != NULL); + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + + LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]); + a -= key->rc6.K[42]; + c -= key->rc6.K[43]; + +#define RND(a,b,c,d) \ + t = (b * (b + b + 1)); t = ROL(t, 5); \ + u = (d * (d + d + 1)); u = ROL(u, 5); \ + c = ROR(c - K[1], t) ^ u; \ + a = ROR(a - K[0], u) ^ t; K -= 2; + + K = key->rc6.K + 40; + + for (r = 0; r < 20; r += 4) { + RND(d,a,b,c); + RND(c,d,a,b); + RND(b,c,d,a); + RND(a,b,c,d); + } + +#undef RND + + b -= key->rc6.K[0]; + d -= key->rc6.K[1]; + STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); +} + +#ifdef CLEAN_STACK +void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _rc6_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 6 + sizeof(int)); +} +#endif + +int rc6_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, + 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 } + }, + { + 24, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04, + 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 } + }, + { + 32, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, + 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, + 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, + { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, + 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, + { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89, + 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 } + } + }; + unsigned char tmp[2][16]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + rc6_ecb_encrypt(tests[x].pt, tmp[0], &key); + rc6_ecb_decrypt(tmp[0], tmp[1], &key); + + /* compare */ + if (memcmp(tmp[0], tests[x].ct, 16) || memcmp(tmp[1], tests[x].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; + #endif +} + +int rc6_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 128) { + *desired_keysize = 128; + } + return CRYPT_OK; +} + +#endif /*RC6*/ + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rmd128.c b/tnl-1.5.0/tnl/libtomcrypt/rmd128.c new file mode 100644 index 0000000000000000000000000000000000000000..89fa5b69402be1d2423bb860468c634d4667d309 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rmd128.c @@ -0,0 +1,353 @@ +/* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ +#include "mycrypt.h" + +#ifdef RIPEMD128 + +const struct _hash_descriptor rmd128_desc = +{ + "rmd128", + 8, + 16, + 64, + &rmd128_init, + &rmd128_process, + &rmd128_done, + &rmd128_test +}; + +/* the four basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) + +/* the eight basic operations FF() through III() */ +#define FF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)); + +#define GG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)); + +#define HH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)); + +#define II(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)); + +#define FFF(a, b, c, d, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)); + +#define GGG(a, b, c, d, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)); + +#define HHH(a, b, c, d, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)); + +#define III(a, b, c, d, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)); + +#ifdef CLEAN_STACK +static void _rmd128_compress(hash_state *md, unsigned char *buf) +#else +static void rmd128_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd128.state[0]; + bb = bbb = md->rmd128.state[1]; + cc = ccc = md->rmd128.state[2]; + dd = ddd = md->rmd128.state[3]; + + /* round 1 */ + FF(aa, bb, cc, dd, X[ 0], 11); + FF(dd, aa, bb, cc, X[ 1], 14); + FF(cc, dd, aa, bb, X[ 2], 15); + FF(bb, cc, dd, aa, X[ 3], 12); + FF(aa, bb, cc, dd, X[ 4], 5); + FF(dd, aa, bb, cc, X[ 5], 8); + FF(cc, dd, aa, bb, X[ 6], 7); + FF(bb, cc, dd, aa, X[ 7], 9); + FF(aa, bb, cc, dd, X[ 8], 11); + FF(dd, aa, bb, cc, X[ 9], 13); + FF(cc, dd, aa, bb, X[10], 14); + FF(bb, cc, dd, aa, X[11], 15); + FF(aa, bb, cc, dd, X[12], 6); + FF(dd, aa, bb, cc, X[13], 7); + FF(cc, dd, aa, bb, X[14], 9); + FF(bb, cc, dd, aa, X[15], 8); + + /* round 2 */ + GG(aa, bb, cc, dd, X[ 7], 7); + GG(dd, aa, bb, cc, X[ 4], 6); + GG(cc, dd, aa, bb, X[13], 8); + GG(bb, cc, dd, aa, X[ 1], 13); + GG(aa, bb, cc, dd, X[10], 11); + GG(dd, aa, bb, cc, X[ 6], 9); + GG(cc, dd, aa, bb, X[15], 7); + GG(bb, cc, dd, aa, X[ 3], 15); + GG(aa, bb, cc, dd, X[12], 7); + GG(dd, aa, bb, cc, X[ 0], 12); + GG(cc, dd, aa, bb, X[ 9], 15); + GG(bb, cc, dd, aa, X[ 5], 9); + GG(aa, bb, cc, dd, X[ 2], 11); + GG(dd, aa, bb, cc, X[14], 7); + GG(cc, dd, aa, bb, X[11], 13); + GG(bb, cc, dd, aa, X[ 8], 12); + + /* round 3 */ + HH(aa, bb, cc, dd, X[ 3], 11); + HH(dd, aa, bb, cc, X[10], 13); + HH(cc, dd, aa, bb, X[14], 6); + HH(bb, cc, dd, aa, X[ 4], 7); + HH(aa, bb, cc, dd, X[ 9], 14); + HH(dd, aa, bb, cc, X[15], 9); + HH(cc, dd, aa, bb, X[ 8], 13); + HH(bb, cc, dd, aa, X[ 1], 15); + HH(aa, bb, cc, dd, X[ 2], 14); + HH(dd, aa, bb, cc, X[ 7], 8); + HH(cc, dd, aa, bb, X[ 0], 13); + HH(bb, cc, dd, aa, X[ 6], 6); + HH(aa, bb, cc, dd, X[13], 5); + HH(dd, aa, bb, cc, X[11], 12); + HH(cc, dd, aa, bb, X[ 5], 7); + HH(bb, cc, dd, aa, X[12], 5); + + /* round 4 */ + II(aa, bb, cc, dd, X[ 1], 11); + II(dd, aa, bb, cc, X[ 9], 12); + II(cc, dd, aa, bb, X[11], 14); + II(bb, cc, dd, aa, X[10], 15); + II(aa, bb, cc, dd, X[ 0], 14); + II(dd, aa, bb, cc, X[ 8], 15); + II(cc, dd, aa, bb, X[12], 9); + II(bb, cc, dd, aa, X[ 4], 8); + II(aa, bb, cc, dd, X[13], 9); + II(dd, aa, bb, cc, X[ 3], 14); + II(cc, dd, aa, bb, X[ 7], 5); + II(bb, cc, dd, aa, X[15], 6); + II(aa, bb, cc, dd, X[14], 8); + II(dd, aa, bb, cc, X[ 5], 6); + II(cc, dd, aa, bb, X[ 6], 5); + II(bb, cc, dd, aa, X[ 2], 12); + + /* parallel round 1 */ + III(aaa, bbb, ccc, ddd, X[ 5], 8); + III(ddd, aaa, bbb, ccc, X[14], 9); + III(ccc, ddd, aaa, bbb, X[ 7], 9); + III(bbb, ccc, ddd, aaa, X[ 0], 11); + III(aaa, bbb, ccc, ddd, X[ 9], 13); + III(ddd, aaa, bbb, ccc, X[ 2], 15); + III(ccc, ddd, aaa, bbb, X[11], 15); + III(bbb, ccc, ddd, aaa, X[ 4], 5); + III(aaa, bbb, ccc, ddd, X[13], 7); + III(ddd, aaa, bbb, ccc, X[ 6], 7); + III(ccc, ddd, aaa, bbb, X[15], 8); + III(bbb, ccc, ddd, aaa, X[ 8], 11); + III(aaa, bbb, ccc, ddd, X[ 1], 14); + III(ddd, aaa, bbb, ccc, X[10], 14); + III(ccc, ddd, aaa, bbb, X[ 3], 12); + III(bbb, ccc, ddd, aaa, X[12], 6); + + /* parallel round 2 */ + HHH(aaa, bbb, ccc, ddd, X[ 6], 9); + HHH(ddd, aaa, bbb, ccc, X[11], 13); + HHH(ccc, ddd, aaa, bbb, X[ 3], 15); + HHH(bbb, ccc, ddd, aaa, X[ 7], 7); + HHH(aaa, bbb, ccc, ddd, X[ 0], 12); + HHH(ddd, aaa, bbb, ccc, X[13], 8); + HHH(ccc, ddd, aaa, bbb, X[ 5], 9); + HHH(bbb, ccc, ddd, aaa, X[10], 11); + HHH(aaa, bbb, ccc, ddd, X[14], 7); + HHH(ddd, aaa, bbb, ccc, X[15], 7); + HHH(ccc, ddd, aaa, bbb, X[ 8], 12); + HHH(bbb, ccc, ddd, aaa, X[12], 7); + HHH(aaa, bbb, ccc, ddd, X[ 4], 6); + HHH(ddd, aaa, bbb, ccc, X[ 9], 15); + HHH(ccc, ddd, aaa, bbb, X[ 1], 13); + HHH(bbb, ccc, ddd, aaa, X[ 2], 11); + + /* parallel round 3 */ + GGG(aaa, bbb, ccc, ddd, X[15], 9); + GGG(ddd, aaa, bbb, ccc, X[ 5], 7); + GGG(ccc, ddd, aaa, bbb, X[ 1], 15); + GGG(bbb, ccc, ddd, aaa, X[ 3], 11); + GGG(aaa, bbb, ccc, ddd, X[ 7], 8); + GGG(ddd, aaa, bbb, ccc, X[14], 6); + GGG(ccc, ddd, aaa, bbb, X[ 6], 6); + GGG(bbb, ccc, ddd, aaa, X[ 9], 14); + GGG(aaa, bbb, ccc, ddd, X[11], 12); + GGG(ddd, aaa, bbb, ccc, X[ 8], 13); + GGG(ccc, ddd, aaa, bbb, X[12], 5); + GGG(bbb, ccc, ddd, aaa, X[ 2], 14); + GGG(aaa, bbb, ccc, ddd, X[10], 13); + GGG(ddd, aaa, bbb, ccc, X[ 0], 13); + GGG(ccc, ddd, aaa, bbb, X[ 4], 7); + GGG(bbb, ccc, ddd, aaa, X[13], 5); + + /* parallel round 4 */ + FFF(aaa, bbb, ccc, ddd, X[ 8], 15); + FFF(ddd, aaa, bbb, ccc, X[ 6], 5); + FFF(ccc, ddd, aaa, bbb, X[ 4], 8); + FFF(bbb, ccc, ddd, aaa, X[ 1], 11); + FFF(aaa, bbb, ccc, ddd, X[ 3], 14); + FFF(ddd, aaa, bbb, ccc, X[11], 14); + FFF(ccc, ddd, aaa, bbb, X[15], 6); + FFF(bbb, ccc, ddd, aaa, X[ 0], 14); + FFF(aaa, bbb, ccc, ddd, X[ 5], 6); + FFF(ddd, aaa, bbb, ccc, X[12], 9); + FFF(ccc, ddd, aaa, bbb, X[ 2], 12); + FFF(bbb, ccc, ddd, aaa, X[13], 9); + FFF(aaa, bbb, ccc, ddd, X[ 9], 12); + FFF(ddd, aaa, bbb, ccc, X[ 7], 5); + FFF(ccc, ddd, aaa, bbb, X[10], 15); + FFF(bbb, ccc, ddd, aaa, X[14], 8); + + /* combine results */ + ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ + md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; + md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; + md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; + md->rmd128.state[0] = ddd; +} + +#ifdef CLEAN_STACK +static void rmd128_compress(hash_state *md, unsigned char *buf) +{ + _rmd128_compress(md, buf); + burn_stack(sizeof(ulong32) * 24 + sizeof(int)); +} +#endif + +void rmd128_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->rmd128.state[0] = 0x67452301UL; + md->rmd128.state[1] = 0xefcdab89UL; + md->rmd128.state[2] = 0x98badcfeUL; + md->rmd128.state[3] = 0x10325476UL; + md->rmd128.curlen = 0; + md->rmd128.length = 0; +} + +HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) + +int rmd128_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd128.length += md->rmd128.curlen * 8; + + /* append the '1' bit */ + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd128.curlen > 56) { + while (md->rmd128.curlen < 64) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + rmd128_compress(md, md->rmd128.buf); + md->rmd128.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd128.curlen < 56) { + md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd128.length, md->rmd128.buf+56); + rmd128_compress(md, md->rmd128.buf); + + /* copy output */ + for (i = 0; i < 4; i++) { + STORE32L(md->rmd128.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int rmd128_test(void) +{ + static const struct { + char *msg; + unsigned char md[16]; + } tests[] = { + { "", + { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, + 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } + }, + { "a", + { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, + 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } + }, + { "abc", + { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, + 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } + }, + { "message digest", + { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, + 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, + 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, + 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } + } + }; + int x; + unsigned char buf[16]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd128_init(&md); + rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd128_done(&md, buf); + if (memcmp(buf, tests[x].md, 16) != 0) { + #if 0 + printf("Failed test %d\n", x); + #endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rmd160.c b/tnl-1.5.0/tnl/libtomcrypt/rmd160.c new file mode 100644 index 0000000000000000000000000000000000000000..c429215f28e14518c7d872903efb13604c1cce8f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rmd160.c @@ -0,0 +1,412 @@ +/* Implementation of RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC + * + * This source has been radically overhauled to be portable and work within + * the LibTomCrypt API by Tom St Denis + */ +#include "mycrypt.h" + +#ifdef RIPEMD160 + +const struct _hash_descriptor rmd160_desc = +{ + "rmd160", + 9, + 20, + 64, + &rmd160_init, + &rmd160_process, + &rmd160_done, + &rmd160_test +}; + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define GG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define HH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define II(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define JJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define FFF(a, b, c, d, e, x, s) \ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define GGG(a, b, c, d, e, x, s) \ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define HHH(a, b, c, d, e, x, s) \ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define III(a, b, c, d, e, x, s) \ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + +#define JJJ(a, b, c, d, e, x, s) \ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); + + +#ifdef CLEAN_STACK +static void _rmd160_compress(hash_state *md, unsigned char *buf) +#else +static void rmd160_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; + int i; + + /* load words X */ + for (i = 0; i < 16; i++){ + LOAD32L(X[i], buf + (4 * i)); + } + + /* load state */ + aa = aaa = md->rmd160.state[0]; + bb = bbb = md->rmd160.state[1]; + cc = ccc = md->rmd160.state[2]; + dd = ddd = md->rmd160.state[3]; + ee = eee = md->rmd160.state[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */ + md->rmd160.state[1] = md->rmd160.state[2] + dd + eee; + md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa; + md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb; + md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc; + md->rmd160.state[0] = ddd; +} + +#ifdef CLEAN_STACK +static void rmd160_compress(hash_state *md, unsigned char *buf) +{ + _rmd160_compress(md, buf); + burn_stack(sizeof(ulong32) * 26 + sizeof(int)); +} +#endif + +void rmd160_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->rmd160.state[0] = 0x67452301UL; + md->rmd160.state[1] = 0xefcdab89UL; + md->rmd160.state[2] = 0x98badcfeUL; + md->rmd160.state[3] = 0x10325476UL; + md->rmd160.state[4] = 0xc3d2e1f0UL; + md->rmd160.curlen = 0; + md->rmd160.length = 0; +} + +HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64) + +int rmd160_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->rmd160.length += md->rmd160.curlen * 8; + + /* append the '1' bit */ + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->rmd160.curlen > 56) { + while (md->rmd160.curlen < 64) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + rmd160_compress(md, md->rmd160.buf); + md->rmd160.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->rmd160.curlen < 56) { + md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->rmd160.length, md->rmd160.buf+56); + rmd160_compress(md, md->rmd160.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32L(md->rmd160.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int rmd160_test(void) +{ + static const struct { + char *msg; + unsigned char md[20]; + } tests[] = { + { "", + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 } + }, + { "a", + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe } + }, + { "abc", + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc } + }, + { "message digest", + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 } + }, + { "abcdefghijklmnopqrstuvwxyz", + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b } + } + }; + int x; + unsigned char buf[20]; + hash_state md; + + for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { + rmd160_init(&md); + rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); + rmd160_done(&md, buf); + if (memcmp(buf, tests[x].md, 20) != 0) { +#if 0 + printf("Failed test %d\n", x); +#endif + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; +} + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rsa.c b/tnl-1.5.0/tnl/libtomcrypt/rsa.c new file mode 100644 index 0000000000000000000000000000000000000000..0673e1cda7afc2651de912d1ad6a11736eb08624 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rsa.c @@ -0,0 +1,477 @@ +#include "mycrypt.h" + +#ifdef MRSA + +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) +{ + mp_int p, q, tmp1, tmp2, tmp3; + int res, err; + + _ARGCHK(key != NULL); + + if ((size < (1024/8)) || (size > (4096/8))) { + return CRYPT_INVALID_KEYSIZE; + } + + if ((e < 3) || ((e & 1) == 0)) { + return CRYPT_INVALID_ARG; + } + + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + if (mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + /* make primes p and q (optimization provided by Wayne Scott) */ + if (mp_set_int(&tmp3, e) != MP_OKAY) { goto error; } /* tmp3 = e */ + + /* make prime "p" */ + do { + if (rand_prime(&p, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; } + if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = p-1 */ + if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(p-1, e) */ + } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides p-1 */ + + /* make prime "q" */ + do { + if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; } + if (mp_sub_d(&q, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = q-1 */ + if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(q-1, e) */ + } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides q-1 */ + + /* tmp1 = lcm(p-1, q-1) */ + if (mp_sub_d(&p, 1, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = p-1 */ + /* tmp1 = q-1 (previous do/while loop) */ + if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = lcm(p-1, q-1) */ + + /* make key */ + if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, + &key->qP, &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) { + goto error; + } + + if (mp_set_int(&key->e, e) != MP_OKAY) { goto error2; } /* key->e = e */ + if (mp_invmod(&key->e, &tmp1, &key->d) != MP_OKAY) { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */ + if (mp_mul(&p, &q, &key->N) != MP_OKAY) { goto error2; } /* key->N = pq */ + +/* optimize for CRT now */ + /* find d mod q-1 and d mod p-1 */ + if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error2; } /* tmp1 = q-1 */ + if (mp_sub_d(&q, 1, &tmp2) != MP_OKAY) { goto error2; } /* tmp2 = p-1 */ + + if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */ + if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */ + + if (mp_invmod(&q, &p, &key->qP) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */ + if (mp_mulmod(&key->qP, &q, &key->N, &key->qP)) { goto error2; } /* qP = q * (1/q mod p) mod N */ + + if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */ + if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) { goto error2; } /* pQ = p * (1/p mod q) mod N */ + + if (mp_copy(&p, &key->p) != MP_OKAY) { goto error2; } + if (mp_copy(&q, &key->q) != MP_OKAY) { goto error2; } + + /* shrink ram required */ + if (mp_shrink(&key->e) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->d) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->N) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->dQ) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->dP) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->qP) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->pQ) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->p) != MP_OKAY) { goto error2; } + if (mp_shrink(&key->q) != MP_OKAY) { goto error2; } + + res = CRYPT_OK; + key->type = PK_PRIVATE_OPTIMIZED; + goto done; +error2: + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, + &key->qP, &key->pQ, &key->p, &key->q, NULL); +error: + res = CRYPT_MEM; +done: + mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL); + return res; +} + +void rsa_free(rsa_key *key) +{ + _ARGCHK(key != NULL); + mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, + &key->qP, &key->pQ, &key->p, &key->q, NULL); +} + +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key) +{ + mp_int tmp, tmpa, tmpb; + unsigned long x; + int res; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* must be a private or public operation */ + if (which != PK_PRIVATE && which != PK_PUBLIC) { + return CRYPT_PK_INVALID_TYPE; + } + + /* init and copy into tmp */ + if (mp_init_multi(&tmp, &tmpa, &tmpb, NULL) != MP_OKAY) { goto error; } + if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen) != MP_OKAY) { goto error; } + + /* sanity check on the input */ + if (mp_cmp(&key->N, &tmp) == MP_LT) { + res = CRYPT_PK_INVALID_SIZE; + goto done; + } + + /* are we using the private exponent and is the key optimized? */ + if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) { + /* tmpa = tmp^dP mod p */ + if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY) { goto error; } + + /* tmpb = tmp^dQ mod q */ + if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY) { goto error; } + + /* tmp = tmpa*qP + tmpb*pQ mod N */ + if (mp_mul(&tmpa, &key->qP, &tmpa) != MP_OKAY) { goto error; } + if (mp_mul(&tmpb, &key->pQ, &tmpb) != MP_OKAY) { goto error; } + if (mp_addmod(&tmpa, &tmpb, &key->N, &tmp) != MP_OKAY) { goto error; } + } else { + /* exptmod it */ + if (mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp) != MP_OKAY) { goto error; } + } + + /* read it back */ + x = (unsigned long)mp_unsigned_bin_size(&tmp); + if (x > *outlen) { + res = CRYPT_BUFFER_OVERFLOW; + goto done; + } + *outlen = x; + + /* convert it */ + if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) { goto error; } + + /* clean up and return */ + res = CRYPT_OK; + goto done; +error: + res = CRYPT_MEM; +done: + mp_clear_multi(&tmp, &tmpa, &tmpb, NULL); + return res; +} + +int rsa_signpad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if (*outlen < (3 * inlen)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* check inlen */ + if (inlen > 512) { + return CRYPT_PK_INVALID_SIZE; + } + + for (y = x = 0; x < inlen; x++) + out[y++] = (unsigned char)0xFF; + for (x = 0; x < inlen; x++) + out[y++] = in[x]; + for (x = 0; x < inlen; x++) + out[y++] = (unsigned char)0xFF; + *outlen = 3 * inlen; + return CRYPT_OK; +} + +int rsa_pad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int wprng, prng_state *prng) +{ + unsigned char buf[1536]; + unsigned long x; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + /* is output big enough? */ + if (*outlen < (3 * inlen)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* get random padding required */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* check inlen */ + if (inlen > 512) { + return CRYPT_PK_INVALID_SIZE; + } + + if (prng_descriptor[wprng].read(buf, inlen*2-2, prng) != (inlen*2 - 2)) { + return CRYPT_ERROR_READPRNG; + } + + /* pad it like a sandwhich + * + * Looks like 0xFF R1 M R2 0xFF + * + * Where R1/R2 are random and exactly equal to the length of M minus one byte. + */ + for (x = 0; x < inlen-1; x++) { + out[x+1] = buf[x]; + } + + for (x = 0; x < inlen; x++) { + out[x+inlen] = in[x]; + } + + for (x = 0; x < inlen-1; x++) { + out[x+inlen+inlen] = buf[x+inlen-1]; + } + + /* last and first bytes are 0xFF */ + out[0] = out[inlen+inlen+inlen-1] = (unsigned char)0xFF; + + /* clear up and return */ +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + *outlen = inlen*3; + return CRYPT_OK; +} + +int rsa_signdepad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if (*outlen < inlen/3) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* check padding bytes */ + for (x = 0; x < inlen/3; x++) { + if (in[x] != (unsigned char)0xFF || in[x+(inlen/3)+(inlen/3)] != (unsigned char)0xFF) { + return CRYPT_INVALID_PACKET; + } + } + for (x = 0; x < inlen/3; x++) { + out[x] = in[x+(inlen/3)]; + } + *outlen = inlen/3; + return CRYPT_OK; +} + +int rsa_depad(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + + if (*outlen < inlen/3) { + return CRYPT_BUFFER_OVERFLOW; + } + for (x = 0; x < inlen/3; x++) { + out[x] = in[x+(inlen/3)]; + } + *outlen = inlen/3; + return CRYPT_OK; +} + +#define OUTPUT_BIGNUM(num, buf2, y, z) \ +{ \ + z = (unsigned long)mp_unsigned_bin_size(num); \ + STORE32L(z, buf2+y); \ + y += 4; \ + if (mp_to_unsigned_bin(num, buf2+y) != MP_OKAY) { return CRYPT_MEM; } \ + y += z; \ +} + + +#define INPUT_BIGNUM(num, in, x, y) \ +{ \ + /* load value */ \ + if (y + 4 > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error2; \ + } \ + LOAD32L(x, in+y); \ + y += 4; \ + \ + /* sanity check... */ \ + if (y+x > inlen) { \ + err = CRYPT_INVALID_PACKET; \ + goto error2; \ + } \ + \ + /* load it */ \ + if (mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x) != MP_OKAY) {\ + err = CRYPT_MEM; \ + goto error2; \ + } \ + y += x; \ + \ + if (mp_shrink(num) != MP_OKAY) { \ + err = CRYPT_MEM; \ + goto error2; \ + } \ +} + +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) +{ + unsigned char buf2[5120]; + unsigned long y, z; + + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* type valid? */ + if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) && + (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) { + return CRYPT_PK_INVALID_TYPE; + } + + /* start at offset y=PACKET_SIZE */ + y = PACKET_SIZE; + + /* output key type */ + buf2[y++] = type; + + /* output modulus */ + OUTPUT_BIGNUM(&key->N, buf2, y, z); + + /* output public key */ + OUTPUT_BIGNUM(&key->e, buf2, y, z); + + if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) { + OUTPUT_BIGNUM(&key->d, buf2, y, z); + } + + if (type == PK_PRIVATE_OPTIMIZED) { + OUTPUT_BIGNUM(&key->dQ, buf2, y, z); + OUTPUT_BIGNUM(&key->dP, buf2, y, z); + OUTPUT_BIGNUM(&key->pQ, buf2, y, z); + OUTPUT_BIGNUM(&key->qP, buf2, y, z); + OUTPUT_BIGNUM(&key->p, buf2, y, z); + OUTPUT_BIGNUM(&key->q, buf2, y, z); + } + + /* check size */ + if (*outlen < y) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store packet header */ + packet_store_header(buf2, PACKET_SECT_RSA, PACKET_SUB_KEY); + + /* copy to the user buffer */ + memcpy(out, buf2, (size_t)y); + *outlen = y; + + /* clear stack and return */ +#ifdef CLEAN_STACK + zeromem(buf2, sizeof(buf2)); +#endif + return CRYPT_OK; +} + +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) +{ + unsigned long x, y; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(key != NULL); + + /* check length */ + if (inlen < 1+PACKET_SIZE) { + return CRYPT_INVALID_PACKET; + } + + /* test packet header */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) { + return err; + } + + /* init key */ + if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, + &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + /* get key type */ + y = PACKET_SIZE; + key->type = (int)in[y++]; + + /* load the modulus */ + INPUT_BIGNUM(&key->N, in, x, y); + + /* load public exponent */ + INPUT_BIGNUM(&key->e, in, x, y); + + /* get private exponent */ + if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) { + INPUT_BIGNUM(&key->d, in, x, y); + } + + /* get CRT private data if required */ + if (key->type == PK_PRIVATE_OPTIMIZED) { + INPUT_BIGNUM(&key->dQ, in, x, y); + INPUT_BIGNUM(&key->dP, in, x, y); + INPUT_BIGNUM(&key->pQ, in, x, y); + INPUT_BIGNUM(&key->qP, in, x, y); + INPUT_BIGNUM(&key->p, in, x, y); + INPUT_BIGNUM(&key->q, in, x, y); + } + + /* free up ram not required */ + if (key->type != PK_PRIVATE_OPTIMIZED) { + mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL); + } + if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { + mp_clear(&key->d); + } + + return CRYPT_OK; +error2: + mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, + &key->pQ, &key->qP, &key->p, &key->q, NULL); + return err; +} + +#include "rsa_sys.c" + +#endif /* RSA */ + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/rsa_sys.c b/tnl-1.5.0/tnl/libtomcrypt/rsa_sys.c new file mode 100644 index 0000000000000000000000000000000000000000..4c562b8dd92b31809806283bd1b5eb8d95477da2 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/rsa_sys.c @@ -0,0 +1,262 @@ +/* these are smaller routines written by Clay Culver. They do the same function as the rsa_encrypt/decrypt + * except that they are used to RSA encrypt/decrypt a single value and not a packet. + */ +int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, + unsigned char *outkey, unsigned long *outlen, + prng_state *prng, int wprng, rsa_key *key) +{ + unsigned char rsa_in[4096], rsa_out[4096]; + unsigned long x, y, rsa_size; + int err; + + _ARGCHK(inkey != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* only allow keys from 64 to 256 bits */ + if (inlen < 8 || inlen > 32) { + return CRYPT_INVALID_ARG; + } + + /* are the parameters valid? */ + if ((err = prng_is_valid(wprng)) != CRYPT_OK) { + return err; + } + + /* rsa_pad the symmetric key */ + y = (unsigned long)sizeof(rsa_in); + if ((err = rsa_pad(inkey, inlen, rsa_in, &y, wprng, prng)) != CRYPT_OK) { + return CRYPT_ERROR; + } + + /* rsa encrypt it */ + rsa_size = (unsigned long)sizeof(rsa_out); + if ((err = rsa_exptmod(rsa_in, y, rsa_out, &rsa_size, PK_PUBLIC, key)) != CRYPT_OK) { + return CRYPT_ERROR; + } + + /* check size */ + if (*outlen < (PACKET_SIZE+4+rsa_size)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* now lets make the header */ + y = PACKET_SIZE; + + /* store the size of the RSA value */ + STORE32L(rsa_size, (outkey+y)); + y += 4; + + /* store the rsa value */ + for (x = 0; x < rsa_size; x++, y++) { + outkey[y] = rsa_out[x]; + } + + /* store header */ + packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY); + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(rsa_in, sizeof(rsa_in)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + *outlen = y; + return CRYPT_OK; +} + +int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *outkey, unsigned long *keylen, + rsa_key *key) +{ + unsigned char sym_key[MAXBLOCKSIZE], rsa_out[4096]; + unsigned long x, y, z, i, rsa_size; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(outkey != NULL); + _ARGCHK(keylen != NULL); + _ARGCHK(key != NULL); + + /* right key type? */ + if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { + return CRYPT_PK_NOT_PRIVATE; + } + + if (inlen < PACKET_SIZE+4) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= PACKET_SIZE+4; + } + + /* check the header */ + if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + return err; + } + + /* grab length of the rsa key */ + y = PACKET_SIZE; + LOAD32L(rsa_size, (in+y)); + if (inlen < rsa_size) { + return CRYPT_INVALID_PACKET; + } else { + inlen -= rsa_size; + } + y += 4; + + /* decrypt it */ + x = (unsigned long)sizeof(rsa_out); + if ((err = rsa_exptmod(in+y, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) { + return err; + } + y += rsa_size; + + /* depad it */ + z = (unsigned long)sizeof(sym_key); + if ((err = rsa_depad(rsa_out, x, sym_key, &z)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (*keylen < z) { + return CRYPT_BUFFER_OVERFLOW; + } + + for (i = 0; i < z; i++) { + outkey[i] = sym_key[i]; + } + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(sym_key, sizeof(sym_key)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + *keylen = z; + return CRYPT_OK; +} + +int rsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + rsa_key *key) +{ + unsigned long rsa_size, x, y; + unsigned char rsa_in[4096], rsa_out[4096]; + int err; + + _ARGCHK(in != NULL); + _ARGCHK(out != NULL); + _ARGCHK(outlen != NULL); + _ARGCHK(key != NULL); + + /* reject nonsense sizes */ + if (inlen > MAXBLOCKSIZE || inlen < 16) { + return CRYPT_INVALID_ARG; + } + + /* type of key? */ + if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) { + return CRYPT_PK_NOT_PRIVATE; + } + + /* pad it */ + x = (unsigned long)sizeof(rsa_out); + if ((err = rsa_signpad(in, inlen, rsa_out, &x)) != CRYPT_OK) { + return err; + } + + /* sign it */ + rsa_size = (unsigned long)sizeof(rsa_in); + if ((err = rsa_exptmod(rsa_out, x, rsa_in, &rsa_size, PK_PRIVATE, key)) != CRYPT_OK) { + return err; + } + + /* check size */ + if (*outlen < (PACKET_SIZE+4+rsa_size)) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* now lets output the message */ + y = PACKET_SIZE; + + /* output the len */ + STORE32L(rsa_size, (out+y)); + y += 4; + + /* store the signature */ + for (x = 0; x < rsa_size; x++, y++) { + out[y] = rsa_in[x]; + } + + /* store header */ + packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED); + +#ifdef CLEAN_STACK + /* clean up */ + zeromem(rsa_in, sizeof(rsa_in)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + *outlen = y; + return CRYPT_OK; +} + +int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *md, int *stat, rsa_key *key) +{ + unsigned long rsa_size, x, y, z; + unsigned char rsa_in[4096], rsa_out[4096]; + int err; + + _ARGCHK(sig != NULL); + _ARGCHK(md != NULL); + _ARGCHK(stat != NULL); + _ARGCHK(key != NULL); + + /* always be incorrect by default */ + *stat = 0; + + if (siglen < PACKET_SIZE+4) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= PACKET_SIZE+4; + } + + /* verify header */ + if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) { + return err; + } + + /* get the len */ + y = PACKET_SIZE; + LOAD32L(rsa_size, (sig+y)); + if (siglen < rsa_size) { + return CRYPT_INVALID_PACKET; + } else { + siglen -= rsa_size; + } + y += 4; + + /* exptmod it */ + x = (unsigned long)sizeof(rsa_out); + if ((err = rsa_exptmod(sig+y, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) { + return err; + } + y += rsa_size; + + /* depad it */ + z = (unsigned long)sizeof(rsa_in); + if ((err = rsa_signdepad(rsa_out, x, rsa_in, &z)) != CRYPT_OK) { + return err; + } + + /* check? */ + if (memcmp(rsa_in, md, (size_t)z) == 0) { + *stat = 1; + } + +#ifdef CLEAN_STACK + zeromem(rsa_in, sizeof(rsa_in)); + zeromem(rsa_out, sizeof(rsa_out)); +#endif + return CRYPT_OK; +} + diff --git a/tnl-1.5.0/tnl/libtomcrypt/safer+.c b/tnl-1.5.0/tnl/libtomcrypt/safer+.c new file mode 100644 index 0000000000000000000000000000000000000000..89d50e8a69d9a5eda0e43998cc5cd7ec3e20e364 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/safer+.c @@ -0,0 +1,499 @@ +/* SAFER+ Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef SAFERP + +const struct _cipher_descriptor saferp_desc = +{ + "safer+", + 4, + 16, 32, 16, 8, + &saferp_setup, + &saferp_ecb_encrypt, + &saferp_ecb_decrypt, + &saferp_test, + &saferp_keysize +}; + +/* ROUND(b,i) + * + * This is one forward key application. Note the basic form is + * key addition, substitution, key addition. The safer_ebox and safer_lbox + * are the exponentiation box and logarithm boxes respectively. + * The value of 'i' is the current round number which allows this + * function to be unrolled massively. Most of SAFER+'s speed + * comes from not having to compute indirect accesses into the + * array of 16 bytes b[0..15] which is the block of data +*/ + +extern const unsigned char safer_ebox[], safer_lbox[]; + +#define ROUND(b, i) \ + b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ + b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ + b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ + b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ + b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ + b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ + b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ + b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ + b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ + b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ + b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ + b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ + b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ + b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ + b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ + b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; + +/* This is one inverse key application */ +#define iROUND(b, i) \ + b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \ + b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \ + b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \ + b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \ + b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \ + b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \ + b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \ + b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \ + b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \ + b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \ + b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \ + b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \ + b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \ + b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \ + b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \ + b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15]; + +/* This is a forward single layer PHT transform. */ +#define PHT(b) \ + b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \ + b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \ + b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \ + b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \ + b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ + b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ + b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ + b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; + +/* This is an inverse single layer PHT transform */ +#define iPHT(b) \ + b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \ + b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \ + b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \ + b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \ + b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \ + b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \ + b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \ + b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \ + +/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ +#define SHUF(b, b2) \ + b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ + b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ + b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ + b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; + +/* This is the inverse shuffle. It takes from b and gives to b2 */ +#define iSHUF(b, b2) \ + b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ + b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ + b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ + b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; + +/* The complete forward Linear Transform layer. + * Note that alternating usage of b and b2. + * Each round of LT starts in 'b' and ends in 'b2'. + */ +#define LT(b, b2) \ + PHT(b); SHUF(b, b2); \ + PHT(b2); SHUF(b2, b); \ + PHT(b); SHUF(b, b2); \ + PHT(b2); + +/* This is the inverse linear transform layer. */ +#define iLT(b, b2) \ + iPHT(b); \ + iSHUF(b, b2); iPHT(b2); \ + iSHUF(b2, b); iPHT(b); \ + iSHUF(b, b2); iPHT(b2); + +#ifdef SMALL_CODE + +static void _round(unsigned char *b, int i, symmetric_key *skey) +{ + ROUND(b, i); +} + +static void _iround(unsigned char *b, int i, symmetric_key *skey) +{ + iROUND(b, i); +} + +static void _lt(unsigned char *b, unsigned char *b2) +{ + LT(b, b2); +} + +static void _ilt(unsigned char *b, unsigned char *b2) +{ + iLT(b, b2); +} + +#undef ROUND +#define ROUND(b, i) _round(b, i, skey) + +#undef iROUND +#define iROUND(b, i) _iround(b, i, skey) + +#undef LT +#define LT(b, b2) _lt(b, b2) + +#undef iLT +#define iLT(b, b2) _ilt(b, b2) + +#endif + +/* These are the 33, 128-bit bias words for the key schedule */ +static const unsigned char safer_bias[33][16] = { +{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100}, +{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61}, +{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160}, +{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148}, +{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143}, +{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202}, +{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44}, +{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51}, +{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56}, +{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215}, +{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210}, +{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53}, +{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244}, +{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131}, +{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241}, +{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172}, +{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239}, +{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202}, +{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246}, +{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152}, +{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236}, +{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150}, +{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30}, +{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6}, +{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104}, +{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175}, +{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35}, +{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7}, +{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207}, +{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247}, +{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255}, +{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}}; + +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned x, y, z; + unsigned char t[33]; + static const int rounds[3] = { 8, 12, 16 }; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* Is the number of rounds valid? Either use zero for default or + * 8,12,16 rounds for 16,24,32 byte keys + */ + if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { + return CRYPT_INVALID_ROUNDS; + } + + /* 128 bit key version */ + if (keylen == 16) { + /* copy key into t */ + for (x = y = 0; x < 16; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[16] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + /* make the 16 other keys as a transformation of the first key */ + for (x = 1; x < 17; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 17; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 17) { z = 0; } + } + } + skey->saferp.rounds = 8; + } else if (keylen == 24) { + /* copy key into t */ + for (x = y = 0; x < 24; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[24] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 25; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 25; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 25) { z = 0; } + } + } + skey->saferp.rounds = 12; + } else { + /* copy key into t */ + for (x = y = 0; x < 32; x++) { + t[x] = key[x]; + y ^= key[x]; + } + t[32] = y; + + /* make round keys */ + for (x = 0; x < 16; x++) { + skey->saferp.K[0][x] = t[x]; + } + + for (x = 1; x < 33; x++) { + /* rotate 3 bits each */ + for (y = 0; y < 33; y++) { + t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; + } + + /* select and add */ + z = x; + for (y = 0; y < 16; y++) { + skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; + if (++z == 33) { z = 0; } + } + } + skey->saferp.rounds = 16; + } +#ifdef CLEAN_STACK + zeromem(t, sizeof(t)); +#endif + return CRYPT_OK; +} + +void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + /* do eight rounds */ + for (x = 0; x < 16; x++) { + b[x] = pt[x]; + } + ROUND(b, 0); LT(b, ct); + ROUND(ct, 2); LT(ct, b); + ROUND(b, 4); LT(b, ct); + ROUND(ct, 6); LT(ct, b); + ROUND(b, 8); LT(b, ct); + ROUND(ct, 10); LT(ct, b); + ROUND(b, 12); LT(b, ct); + ROUND(ct, 14); LT(ct, b); + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + ROUND(b, 16); LT(b, ct); + ROUND(ct, 18); LT(ct, b); + ROUND(b, 20); LT(b, ct); + ROUND(ct, 22); LT(ct, b); + } + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + ROUND(b, 24); LT(b, ct); + ROUND(ct, 26); LT(ct, b); + ROUND(b, 28); LT(b, ct); + ROUND(ct, 30); LT(ct, b); + } + ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; +#ifdef CLEAN_STACK + zeromem(b, sizeof(b)); +#endif +} + +void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) +{ + unsigned char b[16]; + int x; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(skey != NULL); + + /* do eight rounds */ + b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; + b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255; + b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255; + b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; + b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; + b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255; + b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255; + b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; + b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; + b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255; + b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255; + b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; + b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; + b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255; + b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255; + b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; + /* 256-bit key? */ + if (skey->saferp.rounds > 12) { + iLT(b, pt); iROUND(pt, 30); + iLT(pt, b); iROUND(b, 28); + iLT(b, pt); iROUND(pt, 26); + iLT(pt, b); iROUND(b, 24); + } + /* 192-bit key? */ + if (skey->saferp.rounds > 8) { + iLT(b, pt); iROUND(pt, 22); + iLT(pt, b); iROUND(b, 20); + iLT(b, pt); iROUND(pt, 18); + iLT(pt, b); iROUND(b, 16); + } + iLT(b, pt); iROUND(pt, 14); + iLT(pt, b); iROUND(b, 12); + iLT(b, pt); iROUND(pt,10); + iLT(pt, b); iROUND(b, 8); + iLT(b, pt); iROUND(pt,6); + iLT(pt, b); iROUND(b, 4); + iLT(b, pt); iROUND(pt,2); + iLT(pt, b); iROUND(b, 0); + for (x = 0; x < 16; x++) { + pt[x] = b[x]; + } +#ifdef CLEAN_STACK + zeromem(b, sizeof(b)); +#endif +} + +int saferp_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { + 16, + { 41, 35, 190, 132, 225, 108, 214, 174, + 82, 144, 73, 241, 241, 187, 233, 235 }, + { 179, 166, 219, 60, 135, 12, 62, 153, + 36, 94, 13, 28, 6, 183, 71, 222 }, + { 224, 31, 182, 10, 12, 255, 84, 70, + 127, 13, 89, 249, 9, 57, 165, 220 } + }, { + 24, + { 72, 211, 143, 117, 230, 217, 29, 42, + 229, 192, 247, 43, 120, 129, 135, 68, + 14, 95, 80, 0, 212, 97, 141, 190 }, + { 123, 5, 21, 7, 59, 51, 130, 31, + 24, 112, 146, 218, 100, 84, 206, 177 }, + { 92, 136, 4, 63, 57, 95, 100, 0, + 150, 130, 130, 16, 193, 111, 219, 133 } + }, { + 32, + { 243, 168, 141, 254, 190, 242, 235, 113, + 255, 160, 208, 59, 117, 6, 140, 126, + 135, 120, 115, 77, 208, 190, 130, 190, + 219, 194, 70, 65, 43, 140, 250, 48 }, + { 127, 112, 240, 167, 84, 134, 50, 149, + 170, 91, 104, 19, 11, 230, 252, 245 }, + { 88, 11, 25, 36, 172, 229, 202, 213, + 170, 65, 105, 153, 220, 104, 153, 138 } + } + }; + + unsigned char tmp[2][16]; + symmetric_key skey; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) { + return err; + } + saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey); + saferp_ecb_decrypt(tmp[0], tmp[1], &skey); + + /* compare */ + if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int saferp_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize < 24) { + *desired_keysize = 16; + } else if (*desired_keysize < 32) { + *desired_keysize = 24; + } else { + *desired_keysize = 32; + } + return CRYPT_OK; +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/safer.c b/tnl-1.5.0/tnl/libtomcrypt/safer.c new file mode 100644 index 0000000000000000000000000000000000000000..664ec7dad4ba10b20f4a0787f1271ff58585580f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/safer.c @@ -0,0 +1,457 @@ +/******************************************************************************* +* +* FILE: safer.c +* +* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption +* Routine) in its four versions: SAFER K-64, SAFER K-128, +* SAFER SK-64 and SAFER SK-128. +* +* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch) +* Signal and Information Processing Laboratory +* Swiss Federal Institute of Technology +* CH-8092 Zuerich, Switzerland +* +* DATE: September 9, 1995 +* +* CHANGE HISTORY: +* +*******************************************************************************/ + +#include + +#ifdef SAFER + +const struct _cipher_descriptor + safer_k64_desc = { + "safer-k64", + 8, 8, 8, 8, SAFER_K64_DEFAULT_NOF_ROUNDS, + &safer_k64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_k64_test, + &safer_64_keysize + }, + + safer_sk64_desc = { + "safer-sk64", + 9, 8, 8, 8, SAFER_SK64_DEFAULT_NOF_ROUNDS, + &safer_sk64_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk64_test, + &safer_64_keysize + }, + + safer_k128_desc = { + "safer-k128", + 10, 16, 16, 8, SAFER_K128_DEFAULT_NOF_ROUNDS, + &safer_k128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_128_keysize + }, + + safer_sk128_desc = { + "safer-sk128", + 11, 16, 16, 8, SAFER_SK128_DEFAULT_NOF_ROUNDS, + &safer_sk128_setup, + &safer_ecb_encrypt, + &safer_ecb_decrypt, + &safer_sk128_test, + &safer_128_keysize + }; + +/******************* Constants ************************************************/ +// #define TAB_LEN 256 + +/******************* Assertions ***********************************************/ + +/******************* Macros ***************************************************/ +#define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\ + |(unsigned int)((x) & 0xFF) >> (8 - (n)))) +#define EXP(x) safer_ebox[(x) & 0xFF] +#define LOG(x) safer_lbox[(x) & 0xFF] +#define PHT(x, y) { y += x; x += y; } +#define IPHT(x, y) { x -= y; y -= x; } + +/******************* Types ****************************************************/ +extern const unsigned char safer_ebox[], safer_lbox[]; + +#ifdef CLEAN_STACK +static void _Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#else +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +#endif +{ unsigned int i, j, k; + unsigned char ka[SAFER_BLOCK_LEN + 1]; + unsigned char kb[SAFER_BLOCK_LEN + 1]; + + if (SAFER_MAX_NOF_ROUNDS < nof_rounds) + nof_rounds = SAFER_MAX_NOF_ROUNDS; + *key++ = (unsigned char)nof_rounds; + ka[SAFER_BLOCK_LEN] = (unsigned char)0; + kb[SAFER_BLOCK_LEN] = (unsigned char)0; + k = 0; + for (j = 0; j < SAFER_BLOCK_LEN; j++) { + ka[j] = ROL8(userkey_1[j], 5); + ka[SAFER_BLOCK_LEN] ^= ka[j]; + kb[j] = *key++ = userkey_2[j]; + kb[SAFER_BLOCK_LEN] ^= kb[j]; + } + for (i = 1; i <= nof_rounds; i++) { + for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) { + ka[j] = ROL8(ka[j], 6); + kb[j] = ROL8(kb[j], 6); + } + if (strengthened) { + k = 2 * i - 1; + while (k >= (SAFER_BLOCK_LEN + 1)) { k -= SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (ka[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + if (++k == (SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; + } + } + if (strengthened) { + k = 2 * i; + while (k >= (SAFER_BLOCK_LEN + 1)) { k -= SAFER_BLOCK_LEN + 1; } + } + for (j = 0; j < SAFER_BLOCK_LEN; j++) { + if (strengthened) { + *key++ = (kb[k] + + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + if (++k == (SAFER_BLOCK_LEN + 1)) { k = 0; } + } else { + *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; + } + } + } + +#ifdef CLEAN_STACK + zeromem(ka, sizeof(ka)); + zeromem(kb, sizeof(kb)); +#endif +} + +#ifdef CLEAN_STACK +static void Safer_Expand_Userkey(const unsigned char *userkey_1, + const unsigned char *userkey_2, + unsigned int nof_rounds, + int strengthened, + safer_key_t key) +{ + _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key); + burn_stack(sizeof(unsigned char) * (2 * (SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2); +} +#endif + +int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 8) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); + return CRYPT_OK; +} + +int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) +{ + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +static void _safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +void safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + _ARGCHK(block_in != NULL); + _ARGCHK(block_out != NULL); + _ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS; + while(round-- > 0) + { + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + a = EXP(a) + *++key; b = LOG(b) ^ *++key; + c = LOG(c) ^ *++key; d = EXP(d) + *++key; + e = EXP(e) + *++key; f = LOG(f) ^ *++key; + g = LOG(g) ^ *++key; h = EXP(h) + *++key; + PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); + PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); + PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); + t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; + } + a ^= *++key; b += *++key; c += *++key; d ^= *++key; + e ^= *++key; f += *++key; g += *++key; h ^= *++key; + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; +} + +#ifdef CLEAN_STACK +void safer_ecb_encrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + _safer_ecb_encrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); +} +#endif + +#ifdef CLEAN_STACK +static void _safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#else +void safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +#endif +{ unsigned char a, b, c, d, e, f, g, h, t; + unsigned int round; + unsigned char *key; + + _ARGCHK(block_in != NULL); + _ARGCHK(block_out != NULL); + _ARGCHK(skey != NULL); + + key = skey->safer.key; + a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; + e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; + if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS; + key += SAFER_BLOCK_LEN * (1 + 2 * round); + h ^= *key; g -= *--key; f -= *--key; e ^= *--key; + d ^= *--key; c -= *--key; b -= *--key; a ^= *--key; + while (round--) + { + t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; + IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); + IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); + IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); + h -= *--key; g ^= *--key; f ^= *--key; e -= *--key; + d -= *--key; c ^= *--key; b ^= *--key; a -= *--key; + h = LOG(h) ^ *--key; g = EXP(g) - *--key; + f = EXP(f) - *--key; e = LOG(e) ^ *--key; + d = LOG(d) ^ *--key; c = EXP(c) - *--key; + b = EXP(b) - *--key; a = LOG(a) ^ *--key; + } + block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; + block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; + block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; + block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; +} + +#ifdef CLEAN_STACK +void safer_ecb_decrypt(const unsigned char *block_in, + unsigned char *block_out, + symmetric_key *skey) +{ + _safer_ecb_decrypt(block_in, block_out, skey); + burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); +} +#endif + +int safer_64_keysize(int *keysize) +{ + _ARGCHK(keysize != NULL); + if (*keysize < 8) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 8; + return CRYPT_OK; + } +} + +int safer_128_keysize(int *keysize) +{ + _ARGCHK(keysize != NULL); + if (*keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } else { + *keysize = 16; + return CRYPT_OK; + } +} + +int safer_k64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, + k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err; + + /* test K64 */ + if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(k64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (memcmp(buf[0], k64_ct, 8) != 0 || memcmp(buf[1], k64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + + +int safer_sk64_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK64 */ + if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) { + return err; + } + + safer_ecb_encrypt(sk64_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (memcmp(buf[0], sk64_ct, 8) != 0 || memcmp(buf[1], sk64_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +int safer_sk128_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, + sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, + 0, 0, 0, 0, 0, 0, 0, 0 }, + sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 }; + + symmetric_key skey; + unsigned char buf[2][8]; + int err, y; + + /* test SK128 */ + if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + safer_ecb_encrypt(sk128_pt, buf[0], &skey); + safer_ecb_decrypt(buf[0], buf[1], &skey); + + if (memcmp(buf[0], sk128_ct, 8) != 0 || memcmp(buf[1], sk128_pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); + for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + return CRYPT_OK; + #endif +} + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/safer_tab.c b/tnl-1.5.0/tnl/libtomcrypt/safer_tab.c new file mode 100644 index 0000000000000000000000000000000000000000..79242cd5839bb909ad5b51f3480316e9a527808e --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/safer_tab.c @@ -0,0 +1,48 @@ +#include "mycrypt.h" + +#if defined(SAFERP) || defined(SAFER) + +/* This is the box defined by ebox[x] = 45^x mod 257. + * Its assumed that the value "256" corresponds to zero. */ +const unsigned char safer_ebox[256] = { + 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, +255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, +241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, +129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, +249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, +193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, +128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, +253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, +225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 +}; + +/* This is the inverse of ebox or the base 45 logarithm */ +const unsigned char safer_lbox[256] = { +128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, +192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, +112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, +201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, +175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, +121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, +189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, +208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, +210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, +164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, +122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, +109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, +184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 +}; + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/sha1.c b/tnl-1.5.0/tnl/libtomcrypt/sha1.c new file mode 100644 index 0000000000000000000000000000000000000000..049feb2bfdf43e3571353a57a7cd9f09fe942377 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/sha1.c @@ -0,0 +1,213 @@ +#include "mycrypt.h" + +#ifdef SHA1 + +const struct _hash_descriptor sha1_desc = +{ + "sha1", + 2, + 20, + 64, + &sha1_init, + &sha1_process, + &sha1_done, + &sha1_test +}; + +#define F0(x,y,z) (z ^ (x & (y ^ z))) +#define F1(x,y,z) (x ^ y ^ z) +#define F2(x,y,z) ((x & y) | (z & (x | y))) +#define F3(x,y,z) (x ^ y ^ z) + +#ifdef CLEAN_STACK +static void _sha1_compress(hash_state *md, unsigned char *buf) +#else +static void sha1_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong32 a,b,c,d,e,W[80],i; + + _ARGCHK(md != NULL); + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* copy state */ + a = md->sha1.state[0]; + b = md->sha1.state[1]; + c = md->sha1.state[2]; + d = md->sha1.state[3]; + e = md->sha1.state[4]; + + /* expand it */ + for (i = 16; i < 80; i++) { + W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); + } + + /* compress */ + /* round one */ + #define FF0(a,b,c,d,e,i) e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30); + #define FF1(a,b,c,d,e,i) e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30); + #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30); + #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30); + + for (i = 0; i < 20; ) { + FF0(a,b,c,d,e,i++); + FF0(e,a,b,c,d,i++); + FF0(d,e,a,b,c,i++); + FF0(c,d,e,a,b,i++); + FF0(b,c,d,e,a,i++); + } + + /* round two */ + for (; i < 40; ) { + FF1(a,b,c,d,e,i++); + FF1(e,a,b,c,d,i++); + FF1(d,e,a,b,c,i++); + FF1(c,d,e,a,b,i++); + FF1(b,c,d,e,a,i++); + } + + /* round three */ + for (; i < 60; ) { + FF2(a,b,c,d,e,i++); + FF2(e,a,b,c,d,i++); + FF2(d,e,a,b,c,i++); + FF2(c,d,e,a,b,i++); + FF2(b,c,d,e,a,i++); + } + + /* round four */ + for (; i < 80; ) { + FF3(a,b,c,d,e,i++); + FF3(e,a,b,c,d,i++); + FF3(d,e,a,b,c,i++); + FF3(c,d,e,a,b,i++); + FF3(b,c,d,e,a,i++); + } + + #undef FF0 + #undef FF1 + #undef FF2 + #undef FF3 + + /* store */ + md->sha1.state[0] = md->sha1.state[0] + a; + md->sha1.state[1] = md->sha1.state[1] + b; + md->sha1.state[2] = md->sha1.state[2] + c; + md->sha1.state[3] = md->sha1.state[3] + d; + md->sha1.state[4] = md->sha1.state[4] + e; +} + +#ifdef CLEAN_STACK +static void sha1_compress(hash_state *md, unsigned char *buf) +{ + _sha1_compress(md, buf); + burn_stack(sizeof(ulong32) * 87); +} +#endif + +void sha1_init(hash_state * md) +{ + _ARGCHK(md != NULL); + md->sha1.state[0] = 0x67452301UL; + md->sha1.state[1] = 0xefcdab89UL; + md->sha1.state[2] = 0x98badcfeUL; + md->sha1.state[3] = 0x10325476UL; + md->sha1.state[4] = 0xc3d2e1f0UL; + md->sha1.curlen = 0; + md->sha1.length = 0; +} + +HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) + +int sha1_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha1.curlen >= sizeof(md->sha1.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha1.length += md->sha1.curlen * 8; + + /* append the '1' bit */ + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha1.curlen > 56) { + while (md->sha1.curlen < 64) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + sha1_compress(md, md->sha1.buf); + md->sha1.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha1.curlen < 56) { + md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha1.length, md->sha1.buf+56); + sha1_compress(md, md->sha1.buf); + + /* copy output */ + for (i = 0; i < 5; i++) { + STORE32H(md->sha1.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int sha1_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[20]; + } tests[] = { + { "abc", + { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, + 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, + 0x9c, 0xd0, 0xd8, 0x9d } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, + 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, + 0xE5, 0x46, 0x70, 0xF1 } + } + }; + + int i; + unsigned char tmp[20]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha1_init(&md); + sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha1_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 20) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/sha224.c b/tnl-1.5.0/tnl/libtomcrypt/sha224.c new file mode 100644 index 0000000000000000000000000000000000000000..c7c578754b4b8565299f5b79c77b8e2083fe46e8 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/sha224.c @@ -0,0 +1,82 @@ +/* SHA-224 new NIST standard based off of SHA-256 truncated to 224 bits */ +const struct _hash_descriptor sha224_desc = +{ + "sha224", + 10, + 28, + 64, + &sha224_init, + &sha256_process, + &sha224_done, + &sha224_test +}; + +/* init the sha256 er... sha224 state ;-) */ +void sha224_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0xc1059ed8UL; + md->sha256.state[1] = 0x367cd507UL; + md->sha256.state[2] = 0x3070dd17UL; + md->sha256.state[3] = 0xf70e5939UL; + md->sha256.state[4] = 0xffc00b31UL; + md->sha256.state[5] = 0x68581511UL; + md->sha256.state[6] = 0x64f98fa7UL; + md->sha256.state[7] = 0xbefa4fa4UL; +} + +int sha224_done(hash_state * md, unsigned char *hash) +{ + unsigned char buf[32]; + int err; + + err = sha256_done(md, buf); + memcpy(hash, buf, 28); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return err; +} + +int sha224_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[28]; + } tests[] = { + { "abc", + { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, + 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, + 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, + 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, + 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, + 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, + 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } + }, + }; + + int i; + unsigned char tmp[28]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha224_init(&md); + sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha224_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 28) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + diff --git a/tnl-1.5.0/tnl/libtomcrypt/sha256.c b/tnl-1.5.0/tnl/libtomcrypt/sha256.c new file mode 100644 index 0000000000000000000000000000000000000000..0695250945e4578b7e388956d8b2e52d7d16b949 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/sha256.c @@ -0,0 +1,293 @@ +#include "mycrypt.h" + +#ifdef SHA256 + +const struct _hash_descriptor sha256_desc = +{ + "sha256", + 0, + 32, + 64, + &sha256_init, + &sha256_process, + &sha256_done, + &sha256_test +}; + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +/* compress 512-bits */ +#ifdef CLEAN_STACK +static void _sha256_compress(hash_state * md, unsigned char *buf) +#else +static void sha256_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong32 S[8], W[64], t0, t1; + int i; + + _ARGCHK(md != NULL); + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha256.state[i]; + } + + /* copy the state into 512-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD32H(W[i], buf + (4*i)); + } + + /* fill W[16..63] */ + for (i = 16; i < 64; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef SMALL_CODE +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 64; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#else +#define RND(a,b,c,d,e,f,g,h,i,ki) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); + +#undef RND + +#endif + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha256.state[i] = md->sha256.state[i] + S[i]; + } + +} + +#ifdef CLEAN_STACK +static void sha256_compress(hash_state * md, unsigned char *buf) +{ + _sha256_compress(md, buf); + burn_stack(sizeof(ulong32) * 74); +} +#endif + +/* init the sha256 state */ +void sha256_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha256.curlen = 0; + md->sha256.length = 0; + md->sha256.state[0] = 0x6A09E667UL; + md->sha256.state[1] = 0xBB67AE85UL; + md->sha256.state[2] = 0x3C6EF372UL; + md->sha256.state[3] = 0xA54FF53AUL; + md->sha256.state[4] = 0x510E527FUL; + md->sha256.state[5] = 0x9B05688CUL; + md->sha256.state[6] = 0x1F83D9ABUL; + md->sha256.state[7] = 0x5BE0CD19UL; +} + +HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) + +int sha256_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha256.curlen >= sizeof(md->sha256.buf)) { + return CRYPT_INVALID_ARG; + } + + + /* increase the length of the message */ + md->sha256.length += md->sha256.curlen * 8; + + /* append the '1' bit */ + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha256.curlen > 56) { + while (md->sha256.curlen < 64) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + sha256_compress(md, md->sha256.buf); + md->sha256.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->sha256.curlen < 56) { + md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha256.length, md->sha256.buf+56); + sha256_compress(md, md->sha256.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE32H(md->sha256.state[i], hash+(4*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int sha256_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[32]; + } tests[] = { + { "abc", + { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } + }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } + }, + }; + + int i; + unsigned char tmp[32]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha256_init(&md); + sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha256_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 32) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#ifdef SHA224 +#include "sha224.c" +#endif + +#endif + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/sha384.c b/tnl-1.5.0/tnl/libtomcrypt/sha384.c new file mode 100644 index 0000000000000000000000000000000000000000..8d05bcf0bb0e7786f59d2ff040d685e22ec5f616 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/sha384.c @@ -0,0 +1,96 @@ +/* included in sha512.c */ + +const struct _hash_descriptor sha384_desc = +{ + "sha384", + 4, + 48, + 128, + &sha384_init, + &sha512_process, + &sha384_done, + &sha384_test +}; + +void sha384_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); + md->sha512.state[1] = CONST64(0x629a292a367cd507); + md->sha512.state[2] = CONST64(0x9159015a3070dd17); + md->sha512.state[3] = CONST64(0x152fecd8f70e5939); + md->sha512.state[4] = CONST64(0x67332667ffc00b31); + md->sha512.state[5] = CONST64(0x8eb44a8768581511); + md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); + md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); +} + +int sha384_done(hash_state * md, unsigned char *hash) +{ + unsigned char buf[64]; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + sha512_done(md, buf); + memcpy(hash, buf, 48); +#ifdef CLEAN_STACK + zeromem(buf, sizeof(buf)); +#endif + return CRYPT_OK; +} + +int sha384_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[48]; + } tests[] = { + { "abc", + { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } + }, + }; + + int i; + unsigned char tmp[48]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha384_init(&md); + sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha384_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 48) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + + + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/sha512.c b/tnl-1.5.0/tnl/libtomcrypt/sha512.c new file mode 100644 index 0000000000000000000000000000000000000000..f6cb5c99f755285c8bddb8579ce787ae54df865f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/sha512.c @@ -0,0 +1,271 @@ +#include "mycrypt.h" + +#ifdef SHA512 + +const struct _hash_descriptor sha512_desc = +{ + "sha512", + 5, + 64, + 128, + &sha512_init, + &sha512_process, + &sha512_done, + &sha512_test +}; + +/* the K array */ +static const ulong64 K[80] = { +CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), +CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), +CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), +CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), +CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), +CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), +CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), +CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), +CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), +CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), +CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), +CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), +CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), +CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), +CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), +CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), +CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), +CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), +CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), +CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), +CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), +CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), +CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), +CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), +CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), +CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), +CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), +CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), +CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), +CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), +CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), +CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), +CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), +CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), +CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), +CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), +CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), +CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), +CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), +CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) +}; + +/* Various logical functions */ +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) ROR64((x),(n)) +#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) +#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) +#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) +#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) +#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) + +/* compress 1024-bits */ +#ifdef CLEAN_STACK +static void _sha512_compress(hash_state * md, unsigned char *buf) +#else +static void sha512_compress(hash_state * md, unsigned char *buf) +#endif +{ + ulong64 S[8], W[80], t0, t1; + int i; + + _ARGCHK(md != NULL); + + /* copy state into S */ + for (i = 0; i < 8; i++) { + S[i] = md->sha512.state[i]; + } + + /* copy the state into 1024-bits into W[0..15] */ + for (i = 0; i < 16; i++) { + LOAD64H(W[i], buf + (8*i)); + } + + /* fill W[16..79] */ + for (i = 16; i < 80; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#ifdef SMALL_CODE + for (i = 0; i < 80; i++) { + t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i]; + t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); + S[7] = S[6]; + S[6] = S[5]; + S[5] = S[4]; + S[4] = S[3] + t0; + S[3] = S[2]; + S[2] = S[1]; + S[1] = S[0]; + S[0] = t0 + t1; + } +#else +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < 80; i += 8) { + RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); + RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); + RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); + RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); + RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); + RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); + RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); + RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); + } +#endif + + + /* feedback */ + for (i = 0; i < 8; i++) { + md->sha512.state[i] = md->sha512.state[i] + S[i]; + } +} + +/* compress 1024-bits */ +#ifdef CLEAN_STACK +static void sha512_compress(hash_state * md, unsigned char *buf) +{ + _sha512_compress(md, buf); + burn_stack(sizeof(ulong64) * 90 + sizeof(int)); +} +#endif + +/* init the sha512 state */ +void sha512_init(hash_state * md) +{ + _ARGCHK(md != NULL); + + md->sha512.curlen = 0; + md->sha512.length = 0; + md->sha512.state[0] = CONST64(0x6a09e667f3bcc908); + md->sha512.state[1] = CONST64(0xbb67ae8584caa73b); + md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b); + md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1); + md->sha512.state[4] = CONST64(0x510e527fade682d1); + md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f); + md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b); + md->sha512.state[7] = CONST64(0x5be0cd19137e2179); +} + +HASH_PROCESS(sha512_process, sha512_compress, sha512, 128) + +int sha512_done(hash_state * md, unsigned char *hash) +{ + int i; + + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->sha512.curlen >= sizeof(md->sha512.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->sha512.length += md->sha512.curlen * CONST64(8); + + /* append the '1' bit */ + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80; + + /* if the length is currently above 112 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. + */ + if (md->sha512.curlen > 112) { + while (md->sha512.curlen < 128) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + sha512_compress(md, md->sha512.buf); + md->sha512.curlen = 0; + } + + /* pad upto 120 bytes of zeroes + * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash + * > 2^64 bits of data... :-) + */ + while (md->sha512.curlen < 120) { + md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64H(md->sha512.length, md->sha512.buf+120); + sha512_compress(md, md->sha512.buf); + + /* copy output */ + for (i = 0; i < 8; i++) { + STORE64H(md->sha512.state[i], hash+(8*i)); + } +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + return CRYPT_OK; +} + +int sha512_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[64]; + } tests[] = { + { "abc", + { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } + }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } + }, + }; + + int i; + unsigned char tmp[64]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + sha512_init(&md); + sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + sha512_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 64) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#ifdef SHA384 + #include "sha384.c" +#endif + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/skipjack.c b/tnl-1.5.0/tnl/libtomcrypt/skipjack.c new file mode 100644 index 0000000000000000000000000000000000000000..68f40272b326a8e335e88907b8f9e5ee7702fa34 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/skipjack.c @@ -0,0 +1,279 @@ +/* Skipjack Implementation by Tom St Denis */ +#include "mycrypt.h" + +#ifdef SKIPJACK + +const struct _cipher_descriptor skipjack_desc = +{ + "skipjack", + 17, + 10, 10, 8, 32, + &skipjack_setup, + &skipjack_ecb_encrypt, + &skipjack_ecb_decrypt, + &skipjack_test, + &skipjack_keysize +}; + +static const unsigned char sbox[256] = { + 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, + 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, + 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, + 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, + 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, + 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, + 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, + 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, + 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, + 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, + 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, + 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, + 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, + 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, + 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, + 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 +}; + +/* simple x + 1 (mod 10) in one step. */ +static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + +/* simple x - 1 (mod 10) in one step */ +static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + if (keylen != 10) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 32 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + /* make sure the key is in range for platforms where CHAR_BIT != 8 */ + for (x = 0; x < 10; x++) { + skey->skipjack.key[x] = key[x] & 255; + } + + return CRYPT_OK; +} + +#define RULE_A \ + tmp = g_func(w1, &kp, key->skipjack.key); \ + w1 = tmp ^ w4 ^ x; \ + w4 = w3; w3 = w2; \ + w2 = tmp; + +#define RULE_B \ + tmp = g_func(w1, &kp, key->skipjack.key); \ + tmp1 = w4; w4 = w3; \ + w3 = w1 ^ w2 ^ x; \ + w1 = tmp1; w2 = tmp; + +#define RULE_A1 \ + tmp = w1 ^ w2 ^ x; \ + w1 = ig_func(w2, &kp, key->skipjack.key); \ + w2 = w3; w3 = w4; w4 = tmp; + +#define RULE_B1 \ + tmp = ig_func(w2, &kp, key->skipjack.key); \ + w2 = tmp ^ w3 ^ x; \ + w3 = w4; w4 = w1; w1 = tmp; + +static unsigned g_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; + g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +static unsigned ig_func(unsigned w, int *kp, unsigned char *key) +{ + unsigned char g1,g2; + + g1 = (w >> 8) & 255; g2 = w & 255; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; + *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; + return ((unsigned)g1<<8)|(unsigned)g2; +} + +#ifdef CLEAN_STACK +static void _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + unsigned w1,w2,w3,w4,tmp,tmp1; + int x, kp; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + /* load block */ + w1 = ((unsigned)pt[0]<<8)|pt[1]; + w2 = ((unsigned)pt[2]<<8)|pt[3]; + w3 = ((unsigned)pt[4]<<8)|pt[5]; + w4 = ((unsigned)pt[6]<<8)|pt[7]; + + /* 8 rounds of RULE A */ + for (x = 1, kp = 0; x < 9; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 17; x++) { + RULE_B; + } + + /* 8 rounds of RULE A */ + for (; x < 25; x++) { + RULE_A; + } + + /* 8 rounds of RULE B */ + for (; x < 33; x++) { + RULE_B; + } + + /* store block */ + ct[0] = (w1>>8)&255; ct[1] = w1&255; + ct[2] = (w2>>8)&255; ct[3] = w2&255; + ct[4] = (w3>>8)&255; ct[5] = w3&255; + ct[6] = (w4>>8)&255; ct[7] = w4&255; +} + +#ifdef CLEAN_STACK +void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _skipjack_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); +} +#endif + +#ifdef CLEAN_STACK +static void _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + unsigned w1,w2,w3,w4,tmp; + int x, kp; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + /* load block */ + w1 = ((unsigned)ct[0]<<8)|ct[1]; + w2 = ((unsigned)ct[2]<<8)|ct[3]; + w3 = ((unsigned)ct[4]<<8)|ct[5]; + w4 = ((unsigned)ct[6]<<8)|ct[7]; + + /* 8 rounds of RULE B^-1 + + Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8 + */ + for (x = 32, kp = 8; x > 24; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 16; x--) { + RULE_A1; + } + + + /* 8 rounds of RULE B^-1 */ + for (; x > 8; x--) { + RULE_B1; + } + + /* 8 rounds of RULE A^-1 */ + for (; x > 0; x--) { + RULE_A1; + } + + /* store block */ + pt[0] = (w1>>8)&255; pt[1] = w1&255; + pt[2] = (w2>>8)&255; pt[3] = w2&255; + pt[4] = (w3>>8)&255; pt[5] = w3&255; + pt[6] = (w4>>8)&255; pt[7] = w4&255; +} + +#ifdef CLEAN_STACK +void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _skipjack_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); +} +#endif + +int skipjack_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + unsigned char key[10], pt[8], ct[8]; + } tests[] = { + { + { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, + { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa }, + { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 } + } + }; + unsigned char buf[2][8]; + int x, y, err; + symmetric_key key; + + for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { + /* setup key */ + if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) { + return err; + } + + /* encrypt and decrypt */ + skipjack_ecb_encrypt(tests[x].pt, buf[0], &key); + skipjack_ecb_decrypt(buf[0], buf[1], &key); + + /* compare */ + if (memcmp(buf[0], tests[x].ct, 8) != 0 || memcmp(buf[1], tests[x].pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) buf[0][y] = 0; + for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key); + for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key); + for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + + return CRYPT_OK; + #endif +} + +int skipjack_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 10) { + return CRYPT_INVALID_KEYSIZE; + } else if (*desired_keysize > 10) { + *desired_keysize = 10; + } + return CRYPT_OK; +} + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/sprng.c b/tnl-1.5.0/tnl/libtomcrypt/sprng.c new file mode 100644 index 0000000000000000000000000000000000000000..e3e4b2b7453a4a3eca59296dd64e0f902c86f75f --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/sprng.c @@ -0,0 +1,42 @@ +/* A secure PRNG using the RNG functions. Basically this is a + * wrapper that allows you to use a secure RNG as a PRNG + * in the various other functions. + */ +#include "mycrypt.h" + +#ifdef SPRNG + +const struct _prng_descriptor sprng_desc = +{ + "sprng", + &sprng_start, + &sprng_add_entropy, + &sprng_ready, + &sprng_read +}; + +int sprng_start(prng_state *prng) +{ + return CRYPT_OK; +} + +int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) +{ + return CRYPT_OK; +} + +int sprng_ready(prng_state *prng) +{ + return CRYPT_OK; +} + +unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng) +{ + _ARGCHK(buf != NULL); + return rng_get_bytes(buf, len, NULL); +} + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/strings.c b/tnl-1.5.0/tnl/libtomcrypt/strings.c new file mode 100644 index 0000000000000000000000000000000000000000..2bd4297a421ec919eff89d26f68c058fef997c3c --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/strings.c @@ -0,0 +1,72 @@ +/* Future releases will make use of this */ +#include "mycrypt.h" + +static const char *err_2_str[] = +{ + "CRYPT_OK", + "CRYPT_ERROR", + "Non-fatal 'no-operation' requested.", + + "Invalid keysize for block cipher.", + "Invalid number of rounds for block cipher.", + "Algorithm failed test vectors.", + + "Buffer overflow.", + "Invalid input packet.", + + "Invalid number of bits for a PRNG.", + "Error reading the PRNG.", + + "Invalid cipher specified.", + "Invalid hash specified.", + "Invalid PRNG specified.", + + "Out of memory.", + + "Invalid PK key or key type specified for function.", + "A private PK key is required.", + + "Invalid argument provided.", + "File Not Found", + + "Invalid PK type.", + "Invalid PK system.", + "Duplicate PK key found on keyring.", + "Key not found in keyring.", + "Invalid sized parameter.", + + "Invalid size for prime.", + +}; + +static const struct { + int mpi_code, ltc_code; +} mpi_to_ltc_codes[] = { + { MP_OKAY , CRYPT_OK}, + { MP_MEM , CRYPT_MEM}, + { MP_VAL , CRYPT_INVALID_ARG}, +}; + +const char *error_to_string(int err) +{ + if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { + return "Invalid error code."; + } else { + return err_2_str[err]; + } +} + +/* convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) */ +int mpi_to_ltc_error(int err) +{ + int x; + + for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { + if (err == mpi_to_ltc_codes[x].mpi_code) { + return mpi_to_ltc_codes[x].ltc_code; + } + } + return CRYPT_ERROR; +} + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/tiger.c b/tnl-1.5.0/tnl/libtomcrypt/tiger.c new file mode 100644 index 0000000000000000000000000000000000000000..f326c365dc9a8a440297898c227f06e49f26a9c8 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/tiger.c @@ -0,0 +1,762 @@ +#include "mycrypt.h" + +#ifdef TIGER + +const struct _hash_descriptor tiger_desc = +{ + "tiger", + 1, + 24, + 64, + &tiger_init, + &tiger_process, + &tiger_done, + &tiger_test +}; + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +static const ulong64 table[4*256] = { + CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */, + CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */, + CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */, + CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */, + CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */, + CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */, + CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */, + CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */, + CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */, + CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */, + CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */, + CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */, + CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */, + CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */, + CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */, + CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */, + CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */, + CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */, + CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */, + CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */, + CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */, + CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */, + CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */, + CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */, + CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */, + CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */, + CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */, + CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */, + CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */, + CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */, + CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */, + CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */, + CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */, + CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */, + CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */, + CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */, + CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */, + CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */, + CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */, + CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */, + CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */, + CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */, + CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */, + CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */, + CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */, + CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */, + CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */, + CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */, + CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */, + CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */, + CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */, + CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */, + CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */, + CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */, + CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */, + CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */, + CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */, + CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */, + CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */, + CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */, + CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */, + CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */, + CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */, + CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */, + CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */, + CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */, + CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */, + CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */, + CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */, + CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */, + CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */, + CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */, + CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */, + CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */, + CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */, + CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */, + CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */, + CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */, + CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */, + CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */, + CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */, + CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */, + CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */, + CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */, + CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */, + CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */, + CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */, + CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */, + CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */, + CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */, + CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */, + CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */, + CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */, + CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */, + CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */, + CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */, + CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */, + CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */, + CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */, + CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */, + CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */, + CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */, + CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */, + CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */, + CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */, + CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */, + CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */, + CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */, + CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */, + CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */, + CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */, + CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */, + CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */, + CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */, + CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */, + CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */, + CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */, + CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */, + CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */, + CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */, + CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */, + CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */, + CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */, + CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */, + CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */, + CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */, + CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */, + CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */, + CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */, + CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */, + CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */, + CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */, + CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */, + CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */, + CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */, + CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */, + CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */, + CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */, + CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */, + CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */, + CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */, + CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */, + CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */, + CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */, + CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */, + CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */, + CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */, + CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */, + CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */, + CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */, + CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */, + CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */, + CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */, + CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */, + CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */, + CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */, + CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */, + CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */, + CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */, + CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */, + CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */, + CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */, + CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */, + CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */, + CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */, + CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */, + CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */, + CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */, + CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */, + CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */, + CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */, + CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */, + CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */, + CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */, + CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */, + CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */, + CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */, + CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */, + CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */, + CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */, + CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */, + CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */, + CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */, + CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */, + CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */, + CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */, + CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */, + CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */, + CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */, + CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */, + CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */, + CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */, + CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */, + CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */, + CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */, + CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */, + CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */, + CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */, + CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */, + CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */, + CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */, + CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */, + CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */, + CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */, + CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */, + CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */, + CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */, + CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */, + CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */, + CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */, + CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */, + CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */, + CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */, + CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */, + CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */, + CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */, + CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */, + CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */, + CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */, + CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */, + CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */, + CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */, + CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */, + CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */, + CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */, + CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */, + CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */, + CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */, + CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */, + CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */, + CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */, + CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */, + CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */, + CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */, + CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */, + CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */, + CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */, + CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */, + CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */, + CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */, + CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */, + CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */, + CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */, + CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */, + CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */, + CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */, + CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */, + CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */, + CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */, + CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */, + CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */, + CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */, + CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */, + CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */, + CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */, + CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */, + CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */, + CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */, + CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */, + CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */, + CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */, + CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */, + CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */, + CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */, + CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */, + CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */, + CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */, + CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */, + CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */, + CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */, + CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */, + CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */, + CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */, + CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */, + CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */, + CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */, + CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */, + CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */, + CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */, + CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */, + CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */, + CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */, + CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */, + CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */, + CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */, + CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */, + CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */, + CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */, + CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */, + CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */, + CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */, + CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */, + CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */, + CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */, + CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */, + CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */, + CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */, + CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */, + CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */, + CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */, + CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */, + CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */, + CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */, + CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */, + CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */, + CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */, + CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */, + CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */, + CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */, + CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */, + CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */, + CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */, + CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */, + CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */, + CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */, + CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */, + CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */, + CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */, + CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */, + CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */, + CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */, + CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */, + CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */, + CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */, + CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */, + CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */, + CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */, + CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */, + CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */, + CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */, + CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */, + CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */, + CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */, + CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */, + CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */, + CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */, + CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */, + CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */, + CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */, + CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */, + CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */, + CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */, + CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */, + CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */, + CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */, + CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */, + CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */, + CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */, + CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */, + CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */, + CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */, + CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */, + CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */, + CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */, + CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */, + CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */, + CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */, + CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */, + CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */, + CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */, + CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */, + CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */, + CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */, + CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */, + CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */, + CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */, + CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */, + CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */, + CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */, + CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */, + CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */, + CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */, + CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */, + CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */, + CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */, + CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */, + CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */, + CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */, + CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */, + CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */, + CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */, + CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */, + CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */, + CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */, + CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */, + CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */, + CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */, + CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */, + CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */, + CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */, + CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */, + CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */, + CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */, + CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */, + CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */, + CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */, + CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */, + CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */, + CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */, + CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */, + CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */, + CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */, + CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */, + CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */, + CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */, + CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */, + CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */, + CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */, + CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */, + CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */, + CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */, + CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */, + CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */, + CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */, + CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */, + CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */, + CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */, + CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */, + CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */, + CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */, + CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */, + CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */, + CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */, + CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */, + CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */, + CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */, + CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */, + CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */, + CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */, + CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */, + CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */, + CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */, + CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */, + CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */, + CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */, + CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */, + CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */, + CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */, + CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */, + CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */, + CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */, + CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */, + CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */, + CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */, + CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */, + CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */, + CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */, + CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */, + CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */, + CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */, + CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */, + CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */, + CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */, + CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */, + CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */, + CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */, + CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */, + CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */, + CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */, + CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */, + CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */, + CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */, + CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */, + CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */, + CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */, + CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */, + CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */, + CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */, + CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */, + CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */, + CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */, + CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */, + CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */, + CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */, + CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */, + CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */, + CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */, + CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */, + CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */, + CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */, + CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */, + CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */, + CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */, + CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */, + CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */, + CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */, + CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */, + CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */, + CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */, + CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */, + CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */, + CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */, + CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */, + CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */, + CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */, + CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */, + CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */, + CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */, + CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */, + CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */, + CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */, + CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */, + CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */, + CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */, + CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */, + CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */, + CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */, + CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */, + CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */, + CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */, + CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */, + CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */}; + +#ifdef _MSC_VER + #define INLINE __inline +#else + #define INLINE +#endif + +/* one round of the hash function */ +INLINE static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) +{ + ulong64 tmp; + tmp = (*c ^= x); + *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; + tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); + switch (mul) { + case 5: *b = (tmp << 2) + tmp; break; + case 7: *b = (tmp << 3) - tmp; break; + case 9: *b = (tmp << 3) + tmp; break; + } +} + +/* one complete pass */ +static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul) +{ + round(a,b,c,x[0],mul); + round(b,c,a,x[1],mul); + round(c,a,b,x[2],mul); + round(a,b,c,x[3],mul); + round(b,c,a,x[4],mul); + round(c,a,b,x[5],mul); + round(a,b,c,x[6],mul); + round(b,c,a,x[7],mul); +} + +/* The key mixing schedule */ +static void key_schedule(ulong64 *x) { + x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); + x[1] ^= x[0]; + x[2] += x[1]; + x[3] -= x[2] ^ ((~x[1])<<19); + x[4] ^= x[3]; + x[5] += x[4]; + x[6] -= x[5] ^ ((~x[4])>>23); + x[7] ^= x[6]; + x[0] += x[7]; + x[1] -= x[0] ^ ((~x[7])<<19); + x[2] ^= x[1]; + x[3] += x[2]; + x[4] -= x[3] ^ ((~x[2])>>23); + x[5] ^= x[4]; + x[6] += x[5]; + x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF); +} + +#ifdef CLEAN_STACK +static void _tiger_compress(hash_state *md, unsigned char *buf) +#else +static void tiger_compress(hash_state *md, unsigned char *buf) +#endif +{ + ulong64 a, b, c, x[8]; + unsigned long i; + + _ARGCHK(md != NULL); + + /* load words */ + for (i = 0; i < 8; i++) { + LOAD64L(x[i],&buf[8*i]); + } + a = md->tiger.state[0]; + b = md->tiger.state[1]; + c = md->tiger.state[2]; + + pass(&a,&b,&c,x,5); + key_schedule(x); + pass(&c,&a,&b,x,7); + key_schedule(x); + pass(&b,&c,&a,x,9); + + /* store state */ + md->tiger.state[0] = a ^ md->tiger.state[0]; + md->tiger.state[1] = b - md->tiger.state[1]; + md->tiger.state[2] = c + md->tiger.state[2]; +} + +#ifdef CLEAN_STACK +static void tiger_compress(hash_state *md, unsigned char *buf) +{ + _tiger_compress(md, buf); + burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long)); +} +#endif + +void tiger_init(hash_state *md) +{ + _ARGCHK(md != NULL); + md->tiger.state[0] = CONST64(0x0123456789ABCDEF); + md->tiger.state[1] = CONST64(0xFEDCBA9876543210); + md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187); + md->tiger.curlen = 0; + md->tiger.length = 0; +} + +HASH_PROCESS(tiger_process, tiger_compress, tiger, 64) + +int tiger_done(hash_state * md, unsigned char *hash) +{ + _ARGCHK(md != NULL); + _ARGCHK(hash != NULL); + + if (md->tiger.curlen >= sizeof(md->tiger.buf)) { + return CRYPT_INVALID_ARG; + } + + /* increase the length of the message */ + md->tiger.length += md->tiger.curlen * 8; + + /* append the '1' bit */ + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01; + + /* if the length is currently above 56 bytes we append zeros + * then compress. Then we can fall back to padding zeros and length + * encoding like normal. */ + if (md->tiger.curlen > 56) { + while (md->tiger.curlen < 64) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + tiger_compress(md, md->tiger.buf); + md->tiger.curlen = 0; + } + + /* pad upto 56 bytes of zeroes */ + while (md->tiger.curlen < 56) { + md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; + } + + /* store length */ + STORE64L(md->tiger.length, md->tiger.buf+56); + tiger_compress(md, md->tiger.buf); + + /* copy output */ + STORE64L(md->tiger.state[0], &hash[0]); + STORE64L(md->tiger.state[1], &hash[8]); + STORE64L(md->tiger.state[2], &hash[16]); +#ifdef CLEAN_STACK + zeromem(md, sizeof(hash_state)); +#endif + + return CRYPT_OK; +} + +int tiger_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + char *msg; + unsigned char hash[24]; + } tests[] = { + { "", + { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24, + 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16, + 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 } + }, + { "abc", + { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2, + 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52, + 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 } + }, + { "Tiger", + { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f, + 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27, + 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87, + 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47, + 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 } + }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00, + 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76, + 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 } + }, + }; + + int i; + unsigned char tmp[24]; + hash_state md; + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + tiger_init(&md); + tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); + tiger_done(&md, tmp); + if (memcmp(tmp, tests[i].hash, 24) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + } + return CRYPT_OK; + #endif +} + +#endif + +/* +Hash of "": + 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A +Hash of "abc": + F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951 +Hash of "Tiger": + 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386 +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789": + 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham": + 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.": + EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193 +Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.": + 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC +Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": + 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4 +*/ + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/tommath.h b/tnl-1.5.0/tnl/libtomcrypt/tommath.h new file mode 100644 index 0000000000000000000000000000000000000000..1af3396583a95418f461ef8cb8f83c2896d52a06 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/tommath.h @@ -0,0 +1,513 @@ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org + */ +#ifndef BN_H_ +#define BN_H_ + +#include +#include +#include +#include +#include + +#undef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#undef MAX +#define MAX(x,y) ((x)>(y)?(x):(y)) + +#ifdef __cplusplus +extern "C" { + +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST (mp_digit *) + +#else + +/* C on the other hand doesn't care */ +#define OPT_CAST + +#endif + +/* some default configurations. + * + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits + * + * At the very least a mp_digit must be able to hold 7 bits + * [any size beyond that is ok provided it doesn't overflow the data type] + */ +#ifdef MP_8BIT + typedef unsigned char mp_digit; + typedef unsigned short mp_word; +#elif defined(MP_16BIT) + typedef unsigned short mp_digit; + typedef unsigned long mp_word; +#elif defined(MP_64BIT) + /* for GCC only on supported platforms */ +#ifndef CRYPT + typedef unsigned long long ulong64; + typedef signed long long long64; +#endif + + typedef ulong64 mp_digit; + typedef unsigned long mp_word __attribute__ ((mode(TI))); + + #define DIGIT_BIT 60 +#else + /* this is the default case, 28-bit digits */ + + /* this is to make porting into LibTomCrypt easier :-) */ +#ifndef CRYPT + #if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 ulong64; + typedef signed __int64 long64; + #else + typedef unsigned long long ulong64; + typedef signed long long long64; + #endif +#endif + + typedef unsigned long mp_digit; + typedef ulong64 mp_word; + +#ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ + #define DIGIT_BIT 31 +#else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ + #define DIGIT_BIT 28 + #define MP_28BIT +#endif +#endif + +/* define heap macros */ +#ifndef CRYPT + /* default to libc stuff */ + #ifndef XMALLOC + #define XMALLOC malloc + #define XFREE free + #define XREALLOC realloc + #define XCALLOC calloc + #endif + + /* prototypes for our heap functions */ + extern void *XMALLOC(size_t n); + extern void *REALLOC(void *p, size_t n); + extern void *XCALLOC(size_t n, size_t s); + extern void XFREE(void *p); +#endif + + +/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ +#ifndef DIGIT_BIT + #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ +#endif + +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_MAX MP_MASK + +/* equalities */ +#define MP_LT -1 /* less than */ +#define MP_EQ 0 /* equal to */ +#define MP_GT 1 /* greater than */ + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + +#define MP_OKAY 0 /* ok result */ +#define MP_MEM -2 /* out of mem */ +#define MP_VAL -3 /* invalid input */ +#define MP_RANGE MP_VAL + +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ + +typedef int mp_err; + +/* you'll have to tune these... */ +extern int KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF; + +/* various build options */ +#define MP_PREC 64 /* default digits of precision */ + +/* define this to use lower memory usage routines (exptmods mostly) */ +/* #define MP_LOW_MEM */ + +/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ +#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) + +/* the infamous mp_int structure */ +typedef struct { + int used, alloc, sign; + mp_digit *dp; +} mp_int; + +/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m,k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) + +/* error code to char* string */ +char *mp_error_to_string(int code); + +/* ---> init and deinit bignum functions <--- */ +/* init a bignum */ +int mp_init(mp_int *a); + +/* free a bignum */ +void mp_clear(mp_int *a); + +/* init a null terminated series of arguments */ +int mp_init_multi(mp_int *mp, ...); + +/* clear a null terminated series of arguments */ +void mp_clear_multi(mp_int *mp, ...); + +/* exchange two ints */ +void mp_exch(mp_int *a, mp_int *b); + +/* shrink ram required for a bignum */ +int mp_shrink(mp_int *a); + +/* grow an int to a given size */ +int mp_grow(mp_int *a, int size); + +/* init to a given number of digits */ +int mp_init_size(mp_int *a, int size); + +/* ---> Basic Manipulations <--- */ +#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) +#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) +#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) + +/* set to zero */ +void mp_zero(mp_int *a); + +/* set to a digit */ +void mp_set(mp_int *a, mp_digit b); + +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b); + +/* copy, b = a */ +int mp_copy(mp_int *a, mp_int *b); + +/* inits and copies, a = b */ +int mp_init_copy(mp_int *a, mp_int *b); + +/* trim unused digits */ +void mp_clamp(mp_int *a); + +/* ---> digit manipulation <--- */ + +/* right shift by "b" digits */ +void mp_rshd(mp_int *a, int b); + +/* left shift by "b" digits */ +int mp_lshd(mp_int *a, int b); + +/* c = a / 2**b */ +int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); + +/* b = a/2 */ +int mp_div_2(mp_int *a, mp_int *b); + +/* c = a * 2**b */ +int mp_mul_2d(mp_int *a, int b, mp_int *c); + +/* b = a*2 */ +int mp_mul_2(mp_int *a, mp_int *b); + +/* c = a mod 2**d */ +int mp_mod_2d(mp_int *a, int b, mp_int *c); + +/* computes a = 2**b */ +int mp_2expt(mp_int *a, int b); + +/* Counts the number of lsbs which are zero before the first zero bit */ +int mp_cnt_lsb(mp_int *a); + +/* I Love Earth! */ + +/* makes a pseudo-random int of a given size */ +int mp_rand(mp_int *a, int digits); + +/* ---> binary operations <--- */ +/* c = a XOR b */ +int mp_xor(mp_int *a, mp_int *b, mp_int *c); + +/* c = a OR b */ +int mp_or(mp_int *a, mp_int *b, mp_int *c); + +/* c = a AND b */ +int mp_and(mp_int *a, mp_int *b, mp_int *c); + +/* ---> Basic arithmetic <--- */ + +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b); + +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b); + +/* compare a to b */ +int mp_cmp(mp_int *a, mp_int *b); + +/* compare |a| to |b| */ +int mp_cmp_mag(mp_int *a, mp_int *b); + +/* c = a + b */ +int mp_add(mp_int *a, mp_int *b, mp_int *c); + +/* c = a - b */ +int mp_sub(mp_int *a, mp_int *b, mp_int *c); + +/* c = a * b */ +int mp_mul(mp_int *a, mp_int *b, mp_int *c); + +/* b = a*a */ +int mp_sqr(mp_int *a, mp_int *b); + +/* a/b => cb + d == a */ +int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a mod b, 0 <= c < b */ +int mp_mod(mp_int *a, mp_int *b, mp_int *c); + +/* ---> single digit functions <--- */ + +/* compare against a single digit */ +int mp_cmp_d(mp_int *a, mp_digit b); + +/* c = a + b */ +int mp_add_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a - b */ +int mp_sub_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a * b */ +int mp_mul_d(mp_int *a, mp_digit b, mp_int *c); + +/* a/b => cb + d == a */ +int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); + +/* a/3 => 3c + d == a */ +int mp_div_3(mp_int *a, mp_int *c, mp_digit *d); + +/* c = a**b */ +int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); + +/* c = a mod b, 0 <= c < b */ +int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); + +/* ---> number theory <--- */ + +/* d = a + b (mod c) */ +int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a - b (mod c) */ +int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* d = a * b (mod c) */ +int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* c = a * a (mod b) */ +int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = 1/a (mod b) */ +int mp_invmod(mp_int *a, mp_int *b, mp_int *c); + +/* c = (a, b) */ +int mp_gcd(mp_int *a, mp_int *b, mp_int *c); + +/* c = [a, b] or (a*b)/(a, b) */ +int mp_lcm(mp_int *a, mp_int *b, mp_int *c); + +/* finds one of the b'th root of a, such that |c|**b <= |a| + * + * returns error if a < 0 and b is even + */ +int mp_n_root(mp_int *a, mp_digit b, mp_int *c); + +/* shortcut for square root */ +#define mp_sqrt(a, b) mp_n_root(a, 2, b) + +/* computes the jacobi c = (a | n) (or Legendre if b is prime) */ +int mp_jacobi(mp_int *a, mp_int *n, int *c); + +/* used to setup the Barrett reduction for a given modulus b */ +int mp_reduce_setup(mp_int *a, mp_int *b); + +/* Barrett Reduction, computes a (mod b) with a precomputed value c + * + * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely + * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. + */ +int mp_reduce(mp_int *a, mp_int *b, mp_int *c); + +/* setups the montgomery reduction */ +int mp_montgomery_setup(mp_int *a, mp_digit *mp); + +/* computes a = B**n mod b without division or multiplication useful for + * normalizing numbers in a Montgomery system. + */ +int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); + +/* computes x/R == x (mod N) via Montgomery Reduction */ +int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); + +/* returns 1 if a is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a); + +/* sets the value of "d" required for mp_dr_reduce */ +void mp_dr_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b using the Diminished Radix method */ +int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); + +/* returns true if a can be reduced with mp_reduce_2k */ +int mp_reduce_is_2k(mp_int *a); + +/* determines k value for 2k reduction */ +int mp_reduce_2k_setup(mp_int *a, mp_digit *d); + +/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ +int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k); + +/* d = a**b (mod c) */ +int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); + +/* ---> Primes <--- */ + +/* number of primes */ +#ifdef MP_8BIT + #define PRIME_SIZE 31 +#else + #define PRIME_SIZE 256 +#endif + +/* table of first PRIME_SIZE primes */ +extern const mp_digit __prime_tab[]; + +/* result=1 if a is divisible by one of the first PRIME_SIZE primes */ +int mp_prime_is_divisible(mp_int *a, int *result); + +/* performs one Fermat test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_fermat(mp_int *a, mp_int *b, int *result); + +/* performs one Miller-Rabin test of "a" using base "b". + * Sets result to 0 if composite or 1 if probable prime + */ +int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); + +/* This gives [for a given bit size] the number of trials required + * such that Miller-Rabin gives a prob of failure lower than 2^-96 + */ +int mp_prime_rabin_miller_trials(int size); + +/* performs t rounds of Miller-Rabin on "a" using the first + * t prime bases. Also performs an initial sieve of trial + * division. Determines if "a" is prime with probability + * of error no more than (1/4)**t. + * + * Sets result to 1 if probably prime, 0 otherwise + */ +int mp_prime_is_prime(mp_int *a, int t, int *result); + +/* finds the next prime after the number "a" using "t" trials + * of Miller-Rabin. + * + * bbs_style = 1 means the prime must be congruent to 3 mod 4 + */ +int mp_prime_next_prime(mp_int *a, int t, int bbs_style); + +/* makes a truly random prime of a given size (bytes), + * call with bbs = 1 if you want it to be congruent to 3 mod 4 + * + * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can + * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself + * so it can be NULL + * + * The prime generated will be larger than 2^(8*size). + */ +int mp_prime_random(mp_int *a, int t, int size, int bbs, ltm_prime_callback cb, void *dat); + + +/* ---> radix conversion <--- */ +int mp_count_bits(mp_int *a); + +int mp_unsigned_bin_size(mp_int *a); +int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c); +int mp_to_unsigned_bin(mp_int *a, unsigned char *b); + +int mp_signed_bin_size(mp_int *a); +int mp_read_signed_bin(mp_int *a, unsigned char *b, int c); +int mp_to_signed_bin(mp_int *a, unsigned char *b); + +int mp_read_radix(mp_int *a, char *str, int radix); +int mp_toradix(mp_int *a, char *str, int radix); +int mp_radix_size(mp_int *a, int radix); + +int mp_fread(mp_int *a, int radix, FILE *stream); +int mp_fwrite(mp_int *a, int radix, FILE *stream); + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +/* lowlevel functions, do not call! */ +int s_mp_add(mp_int *a, mp_int *b, mp_int *c); +int s_mp_sub(mp_int *a, mp_int *b, mp_int *c); +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs); +int fast_s_mp_sqr(mp_int *a, mp_int *b); +int s_mp_sqr(mp_int *a, mp_int *b); +int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c); +int mp_karatsuba_sqr(mp_int *a, mp_int *b); +int mp_toom_sqr(mp_int *a, mp_int *b); +int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); +int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); +int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); +int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); +void bn_reverse(unsigned char *s, int len); + +extern const char *mp_s_rmap; + +#ifdef __cplusplus + } +#endif + +#endif + diff --git a/tnl-1.5.0/tnl/libtomcrypt/twofish.c b/tnl-1.5.0/tnl/libtomcrypt/twofish.c new file mode 100644 index 0000000000000000000000000000000000000000..6199cc6ac8ce6d01a7cbf060a90444e0ce40b1a0 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/twofish.c @@ -0,0 +1,652 @@ +/* Implementation of Twofish by Tom St Denis */ +#include "mycrypt.h" + +#ifdef TWOFISH + +/* first TWOFISH_ALL_TABLES must ensure TWOFISH_TABLES is defined */ +#ifdef TWOFISH_ALL_TABLES +#ifndef TWOFISH_TABLES +#define TWOFISH_TABLES +#endif +#endif + +const struct _cipher_descriptor twofish_desc = +{ + "twofish", + 7, + 16, 32, 16, 16, + &twofish_setup, + &twofish_ecb_encrypt, + &twofish_ecb_decrypt, + &twofish_test, + &twofish_keysize +}; + +/* the two polynomials */ +#define MDS_POLY 0x169 +#define RS_POLY 0x14D + +/* The 4x4 MDS Linear Transform */ +static const unsigned char MDS[4][4] = { + { 0x01, 0xEF, 0x5B, 0x5B }, + { 0x5B, 0xEF, 0xEF, 0x01 }, + { 0xEF, 0x5B, 0x01, 0xEF }, + { 0xEF, 0x01, 0xEF, 0x5B } +}; + +/* The 4x8 RS Linear Transform */ +static const unsigned char RS[4][8] = { + { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E }, + { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 }, + { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 }, + { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 } +}; + +/* sbox usage orderings */ +static const unsigned char qord[4][5] = { + { 1, 1, 0, 0, 1 }, + { 0, 1, 1, 0, 0 }, + { 0, 0, 0, 1, 1 }, + { 1, 0, 1, 1, 0 } +}; + +#ifdef TWOFISH_TABLES + +#include "twofish_tab.c" + +#define sbox(i, x) ((ulong32)SBOX[i][(x)&255]) + +#else + +/* The Q-box tables */ +static const unsigned char qbox[2][4][16] = { +{ + { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 }, + { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD }, + { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 }, + { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA } +}, +{ + { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 }, + { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 }, + { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF }, + { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA } +} +}; + +/* computes S_i[x] */ +#ifdef CLEAN_STACK +static ulong32 _sbox(int i, ulong32 x) +#else +static ulong32 sbox(int i, ulong32 x) +#endif +{ + unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y; + + /* a0,b0 = [x/16], x mod 16 */ + a0 = (unsigned char)((x>>4)&15); + b0 = (unsigned char)((x)&15); + + /* a1 = a0 ^ b0 */ + a1 = a0 ^ b0; + + /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */ + b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15; + + /* a2,b2 = t0[a1], t1[b1] */ + a2 = qbox[i][0][(int)a1]; + b2 = qbox[i][1][(int)b1]; + + /* a3 = a2 ^ b2 */ + a3 = a2 ^ b2; + + /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */ + b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15; + + /* a4,b4 = t2[a3], t3[b3] */ + a4 = qbox[i][2][(int)a3]; + b4 = qbox[i][3][(int)b3]; + + /* y = 16b4 + a4 */ + y = (b4 << 4) + a4; + + /* return result */ + return (ulong32)y; +} + +#ifdef CLEAN_STACK +static ulong32 sbox(int i, ulong32 x) +{ + ulong32 y; + y = _sbox(i, x); + burn_stack(sizeof(unsigned char) * 11); + return y; +} +#endif /* CLEAN_STACK */ + +#endif /* TWOFISH_TABLES */ + +/* computes ab mod p */ +static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p) +{ + ulong32 result, B[2], P[2]; + + P[1] = p; + B[1] = b; + result = P[0] = B[0] = 0; + + /* unrolled branchless GF multiplier */ + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); + result ^= B[a&1]; + + return result; +} + +/* computes [y0 y1 y2 y3] = MDS . [x0] */ +#ifndef TWOFISH_TABLES +static ulong32 mds_column_mult(unsigned char in, int col) +{ + ulong32 x01, x5B, xEF; + + x01 = in; + x5B = gf_mult(in, 0x5B, MDS_POLY); + xEF = gf_mult(in, 0xEF, MDS_POLY); + + switch (col) { + case 0: + return (x01 << 0 ) | + (x5B << 8 ) | + (xEF << 16) | + (xEF << 24); + case 1: + return (xEF << 0 ) | + (xEF << 8 ) | + (x5B << 16) | + (x01 << 24); + case 2: + return (x5B << 0 ) | + (xEF << 8 ) | + (x01 << 16) | + (xEF << 24); + case 3: + return (x5B << 0 ) | + (x01 << 8 ) | + (xEF << 16) | + (x5B << 24); + } + /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */ + return 0; +} + +#else /* !TWOFISH_TABLES */ + +#define mds_column_mult(x, i) mds_tab[i][x] + +#endif /* TWOFISH_TABLES */ + +/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */ +static void mds_mult(const unsigned char *in, unsigned char *out) +{ + int x; + ulong32 tmp; + for (tmp = x = 0; x < 4; x++) { + tmp ^= mds_column_mult(in[x], x); + } + STORE32L(tmp, out); +} + +#ifdef TWOFISH_ALL_TABLES +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + ulong32 tmp; + tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^ + rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]]; + STORE32L(tmp, out); +} + +#else /* !TWOFISH_ALL_TABLES */ + +/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ +static void rs_mult(const unsigned char *in, unsigned char *out) +{ + int x, y; + for (x = 0; x < 4; x++) { + out[x] = 0; + for (y = 0; y < 8; y++) { + out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY); + } + } +} + +#endif + +/* computes h(x) */ +static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset) +{ + int x; + unsigned char y[4]; + for (x = 0; x < 4; x++) { + y[x] = in[x]; + } + switch (k) { + case 4: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]); + y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]); + y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]); + case 3: + y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]); + y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]); + y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]); + y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]); + case 2: + y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0])); + y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1])); + y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2])); + y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3])); + } + mds_mult(y, out); +} + +#ifndef TWOFISH_SMALL + +/* for GCC we don't use pointer aliases */ +#if defined(__GNUC__) + #define S1 key->twofish.S[0] + #define S2 key->twofish.S[1] + #define S3 key->twofish.S[2] + #define S4 key->twofish.S[3] +#endif + +/* the G function */ +#define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)]) +#define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)]) + +#else + +#ifdef CLEAN_STACK +static ulong32 _g_func(ulong32 x, symmetric_key *key) +#else +static ulong32 g_func(ulong32 x, symmetric_key *key) +#endif +{ + unsigned char g, i, y, z; + ulong32 res; + + res = 0; + for (y = 0; y < 4; y++) { + z = key->twofish.start; + + /* do unkeyed substitution */ + g = sbox(qord[y][z++], (x >> (8*y)) & 255); + + /* first subkey */ + i = 0; + + /* do key mixing+sbox until z==5 */ + while (z != 5) { + g = g ^ key->twofish.S[4*i++ + y]; + g = sbox(qord[y][z++], g); + } + + /* multiply g by a column of the MDS */ + res ^= mds_column_mult(g, y); + } + return res; +} + +#define g1_func(x, key) g_func(ROL(x, 8), key) + +#ifdef CLEAN_STACK +static ulong32 g_func(ulong32 x, symmetric_key *key) +{ + ulong32 y; + y = _g_func(x, key); + burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32)); + return y; +} +#endif /* CLEAN_STACK */ + +#endif /* TWOFISH_SMALL */ + +#ifdef CLEAN_STACK +static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#else +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +#endif +{ +#ifndef TWOFISH_SMALL + unsigned char S[4*4], tmpx0, tmpx1; +#endif + int k, x, y; + unsigned char tmp[4], tmp2[4], M[8*4]; + ulong32 A, B; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* invalid arguments? */ + if (num_rounds != 16 && num_rounds != 0) { + return CRYPT_INVALID_ROUNDS; + } + + if (keylen != 16 && keylen != 24 && keylen != 32) { + return CRYPT_INVALID_KEYSIZE; + } + + /* k = keysize/64 [but since our keysize is in bytes...] */ + k = keylen / 8; + + /* copy the key into M */ + for (x = 0; x < keylen; x++) { + M[x] = key[x] & 255; + } + + /* create the S[..] words */ +#ifndef TWOFISH_SMALL + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), S+(x*4)); + } +#else + for (x = 0; x < k; x++) { + rs_mult(M+(x*8), skey->twofish.S+(x*4)); + } +#endif + + /* make subkeys */ + for (x = 0; x < 20; x++) { + /* A = h(p * 2x, Me) */ + for (y = 0; y < 4; y++) { + tmp[y] = x+x; + } + h_func(tmp, tmp2, M, k, 0); + LOAD32L(A, tmp2); + + /* B = ROL(h(p * (2x + 1), Mo), 8) */ + for (y = 0; y < 4; y++) { + tmp[y] = (unsigned char)(x+x+1); + } + h_func(tmp, tmp2, M, k, 1); + LOAD32L(B, tmp2); + B = ROL(B, 8); + + /* K[2i] = A + B */ + skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL; + + /* K[2i+1] = (A + 2B) <<< 9 */ + skey->twofish.K[x+x+1] = ROL(B + B + A, 9); + } + +#ifndef TWOFISH_SMALL + /* make the sboxes (large ram variant) */ + if (k == 2) { + for (x = 0; x < 256; x++) { + tmpx0 = sbox(0, x); + tmpx1 = sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); + } + } else if (k == 3) { + for (x = 0; x < 256; x++) { + tmpx0 = sbox(0, x); + tmpx1 = sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); + } + } else { + for (x = 0; x < 256; x++) { + tmpx0 = sbox(0, x); + tmpx1 = sbox(1, x); + skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); + skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); + skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); + skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); + } + } +#else + /* where to start in the sbox layers */ + /* small ram variant */ + switch (k) { + case 4 : skey->twofish.start = 0; break; + case 3 : skey->twofish.start = 1; break; + default: skey->twofish.start = 2; break; + } +#endif + return CRYPT_OK; +} + +#ifdef CLEAN_STACK +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + int x; + x = _twofish_setup(key, keylen, num_rounds, skey); + burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2); + return x; +} +#endif + +#ifdef CLEAN_STACK +static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#else +void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + S1 = key->twofish.S[0]; + S2 = key->twofish.S[1]; + S3 = key->twofish.S[2]; + S4 = key->twofish.S[3]; +#endif + + LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); + LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); + a ^= key->twofish.K[0]; + b ^= key->twofish.K[1]; + c ^= key->twofish.K[2]; + d ^= key->twofish.K[3]; + + k = key->twofish.K + 8; + for (r = 0; r < 16; r += 2) { + t1 = g_func(a, key); + t2 = g1_func(b, key); + c = ROR(c ^ (t1 + t2 + k[0]), 1); + d = ROL(d, 1) ^ (t2 + t2 + t1 + k[1]); + k += 2; + + t1 = g_func(c, key); + t2 = g1_func(d, key); + a = ROR(a ^ (t1 + t2 + k[0]), 1); + b = ROL(b, 1) ^ (t2 + t2 + t1 + k[1]); + k += 2; + } + + /* output with "undo last swap" */ + ta = c ^ key->twofish.K[4]; + tb = d ^ key->twofish.K[5]; + tc = a ^ key->twofish.K[6]; + td = b ^ key->twofish.K[7]; + + /* store output */ + STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); + STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); +} + +#ifdef CLEAN_STACK +void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + _twofish_ecb_encrypt(pt, ct, key); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); +} +#endif + +#ifdef CLEAN_STACK +static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#else +void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +#endif +{ + ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; + int r; +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + ulong32 *S1, *S2, *S3, *S4; +#endif + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + +#if !defined(TWOFISH_SMALL) && !defined(__GNUC__) + S1 = key->twofish.S[0]; + S2 = key->twofish.S[1]; + S3 = key->twofish.S[2]; + S4 = key->twofish.S[3]; +#endif + + /* load input */ + LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); + LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); + + /* undo undo final swap */ + a = tc ^ key->twofish.K[6]; + b = td ^ key->twofish.K[7]; + c = ta ^ key->twofish.K[4]; + d = tb ^ key->twofish.K[5]; + + k = key->twofish.K + 38; + for (r = 14; r >= 0; r -= 2) { + t1 = g_func(c, key); + t2 = g1_func(d, key); + a = ROL(a, 1) ^ (t1 + t2 + k[0]); + b = ROR(b ^ (t2 + t2 + t1 + k[1]), 1); + k -= 2; + + t1 = g_func(a, key); + t2 = g1_func(b, key); + c = ROL(c, 1) ^ (t1 + t2 + k[0]); + d = ROR(d ^ (t2 + t2 + t1 + k[1]), 1); + k -= 2; + } + + /* pre-white */ + a ^= key->twofish.K[0]; + b ^= key->twofish.K[1]; + c ^= key->twofish.K[2]; + d ^= key->twofish.K[3]; + + /* store */ + STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); + STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); +} + +#ifdef CLEAN_STACK +void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + _twofish_ecb_decrypt(ct, pt, key); + burn_stack(sizeof(ulong32) * 10 + sizeof(int)); +} +#endif + +int twofish_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const struct { + int keylen; + unsigned char key[32], pt[16], ct[16]; + } tests[] = { + { 16, + { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, + { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, + 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }, + { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, + 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 } + }, { + 24, + { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, + 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, + 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }, + { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, + 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, + { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, + 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } + }, { + 32, + { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, + 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, + 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, + 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }, + { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, + 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }, + { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, + 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA } + } +}; + + + symmetric_key key; + unsigned char tmp[2][16]; + int err, i, y; + + for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { + if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { + return err; + } + twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); + twofish_ecb_decrypt(tmp[0], tmp[1], &key); + if (memcmp(tmp[0], tests[i].ct, 16) != 0 || memcmp(tmp[1], tests[i].pt, 16) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 16; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); + for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + } + return CRYPT_OK; +#endif +} + +int twofish_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize); + if (*desired_keysize < 16) + return CRYPT_INVALID_KEYSIZE; + if (*desired_keysize < 24) { + *desired_keysize = 16; + return CRYPT_OK; + } else if (*desired_keysize < 32) { + *desired_keysize = 24; + return CRYPT_OK; + } else { + *desired_keysize = 32; + return CRYPT_OK; + } +} + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/twofish_tab.c b/tnl-1.5.0/tnl/libtomcrypt/twofish_tab.c new file mode 100644 index 0000000000000000000000000000000000000000..99f7aba20200fc8c50eb0e2a87fb24afda240093 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/twofish_tab.c @@ -0,0 +1,477 @@ +#ifdef TWOFISH_TABLES + +/* pre generated 8x8 tables from the four 4x4s */ +static const unsigned char SBOX[2][256] = { +{ + 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, + 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98, + 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, + 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, + 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01, + 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, + 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, + 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, + 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, + 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5, + 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, + 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, + 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d, + 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, + 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, + 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, + 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, + 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f, + 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, + 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, + 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7, + 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, + 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, + 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, + 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, + 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0}, +{ + 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, + 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd, + 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, + 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, + 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84, + 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, + 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, + 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, + 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff, + 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, + 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, + 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94, + 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, + 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, + 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, + 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, + 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e, + 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, + 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, + 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e, + 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, + 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, + 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, + 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, + 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91} +}; + +/* the 4x4 MDS in a nicer format */ +static const ulong32 mds_tab[4][256] = { +{ +0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL, +0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL, +0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL, +0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL, +0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL, +0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL, +0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL, +0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL, +0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL, +0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL, +0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL, +0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL, +0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL, +0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL, +0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL, +0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL, +0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL, +0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL, +0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL, +0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL, +0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL, +0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL, +0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL, +0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL, +0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL, +0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL, +0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL, +0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL, +0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL, +0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL, +0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL, +0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL +}, +{ +0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL, +0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL, +0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL, +0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL, +0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL, +0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL, +0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL, +0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL, +0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL, +0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL, +0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL, +0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL, +0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL, +0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL, +0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL, +0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL, +0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL, +0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL, +0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL, +0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL, +0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL, +0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL, +0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL, +0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL, +0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL, +0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL, +0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL, +0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL, +0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL, +0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL, +0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL, +0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL +}, +{ +0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL, +0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL, +0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL, +0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL, +0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL, +0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL, +0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL, +0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL, +0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL, +0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL, +0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL, +0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL, +0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL, +0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL, +0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL, +0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL, +0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL, +0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL, +0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL, +0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL, +0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL, +0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL, +0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL, +0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL, +0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL, +0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL, +0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL, +0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL, +0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL, +0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL, +0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL, +0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL +}, +{ +0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL, +0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL, +0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL, +0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL, +0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL, +0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL, +0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL, +0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL, +0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL, +0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL, +0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL, +0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL, +0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL, +0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL, +0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL, +0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL, +0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL, +0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL, +0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL, +0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL, +0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL, +0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL, +0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL, +0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL, +0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL, +0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL, +0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL, +0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL, +0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL, +0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL, +0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL, +0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL +}}; + +#ifdef TWOFISH_ALL_TABLES + +/* the 4x8 RS transform */ +static const ulong32 rs_tab0[256] = { +0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU, +0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU, +0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU, +0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU, +0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU, +0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU, +0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU, +0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU, +0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU, +0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU, +0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU, +0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU, +0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU, +0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU, +0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU, +0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU, +0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU, +0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU, +0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU, +0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU, +0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU, +0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU, +0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU, +0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU, +0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU, +0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU, +0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU, +0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU, +0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU, +0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU, +0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU, +0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU }; + +static const ulong32 rs_tab1[256] = { +0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU, +0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU, +0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU, +0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU, +0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU, +0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU, +0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU, +0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU, +0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU, +0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU, +0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU, +0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU, +0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU, +0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU, +0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU, +0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU, +0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU, +0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU, +0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU, +0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU, +0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU, +0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU, +0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU, +0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU, +0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU, +0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU, +0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU, +0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU, +0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU, +0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU, +0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU, +0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU }; + +static const ulong32 rs_tab2[256] = { +0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU, +0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU, +0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU, +0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU, +0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU, +0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU, +0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU, +0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU, +0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU, +0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU, +0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU, +0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU, +0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU, +0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU, +0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU, +0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU, +0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU, +0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU, +0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU, +0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU, +0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU, +0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU, +0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU, +0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU, +0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU, +0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU, +0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU, +0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU, +0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU, +0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU, +0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU, +0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU }; + +static const ulong32 rs_tab3[256] = { +0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU, +0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU, +0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU, +0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU, +0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU, +0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU, +0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU, +0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU, +0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU, +0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU, +0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU, +0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU, +0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU, +0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU, +0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU, +0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU, +0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU, +0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU, +0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU, +0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU, +0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU, +0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU, +0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU, +0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU, +0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU, +0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU, +0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU, +0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU, +0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU, +0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU, +0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU, +0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU }; + +static const ulong32 rs_tab4[256] = { +0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU, +0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU, +0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU, +0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU, +0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU, +0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU, +0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU, +0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU, +0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU, +0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU, +0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU, +0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU, +0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU, +0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU, +0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU, +0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU, +0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU, +0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU, +0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU, +0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU, +0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU, +0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU, +0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU, +0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU, +0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU, +0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU, +0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU, +0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU, +0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU, +0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU, +0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU, +0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU }; + +static const ulong32 rs_tab5[256] = { +0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU, +0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU, +0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU, +0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU, +0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU, +0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU, +0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU, +0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU, +0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU, +0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU, +0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU, +0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU, +0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU, +0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU, +0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU, +0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU, +0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU, +0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU, +0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU, +0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU, +0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU, +0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU, +0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU, +0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU, +0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU, +0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU, +0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU, +0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU, +0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU, +0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU, +0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU, +0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU }; + +static const ulong32 rs_tab6[256] = { +0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU, +0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU, +0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU, +0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU, +0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU, +0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU, +0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU, +0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU, +0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU, +0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU, +0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU, +0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU, +0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU, +0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU, +0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU, +0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU, +0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU, +0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU, +0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU, +0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU, +0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU, +0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU, +0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU, +0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU, +0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU, +0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU, +0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU, +0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU, +0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU, +0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU, +0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU, +0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU }; + +static const ulong32 rs_tab7[256] = { +0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU, +0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU, +0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU, +0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU, +0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU, +0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU, +0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU, +0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU, +0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU, +0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU, +0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU, +0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU, +0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU, +0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU, +0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU, +0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU, +0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU, +0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU, +0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU, +0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU, +0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU, +0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU, +0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU, +0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU, +0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU, +0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU, +0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU, +0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU, +0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU, +0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU, +0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU, +0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU }; + +#endif /* TWOFISH_ALL_TABLES */ + +#endif diff --git a/tnl-1.5.0/tnl/libtomcrypt/xtea.c b/tnl-1.5.0/tnl/libtomcrypt/xtea.c new file mode 100644 index 0000000000000000000000000000000000000000..6c528d3294609831691c9ad3f103753e9ada6501 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/xtea.c @@ -0,0 +1,158 @@ +#include "mycrypt.h" + +#ifdef XTEA + +const struct _cipher_descriptor xtea_desc = +{ + "xtea", + 1, + 16, 16, 8, 32, + &xtea_setup, + &xtea_ecb_encrypt, + &xtea_ecb_decrypt, + &xtea_test, + &xtea_keysize +}; + +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) +{ + unsigned long x, sum, K[4]; + + _ARGCHK(key != NULL); + _ARGCHK(skey != NULL); + + /* check arguments */ + if (keylen != 16) { + return CRYPT_INVALID_KEYSIZE; + } + + if (num_rounds != 0 && num_rounds != 32) { + return CRYPT_INVALID_ROUNDS; + } + + /* load key */ + LOAD32L(K[0], key+0); + LOAD32L(K[1], key+4); + LOAD32L(K[2], key+8); + LOAD32L(K[3], key+12); + + for (x = sum = 0; x < 32; x++) { + skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL; + sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL; + skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL; + } + +#ifdef CLEAN_STACK + zeromem(&K, sizeof(K)); +#endif + + return CRYPT_OK; +} + +void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key) +{ + unsigned long y, z; + int r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32L(y, &pt[0]); + LOAD32L(z, &pt[4]); + for (r = 0; r < 32; r += 4) { + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+1])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+1])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+2])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+2])) & 0xFFFFFFFFUL; + + y = (y + ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r+3])) & 0xFFFFFFFFUL; + z = (z + ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r+3])) & 0xFFFFFFFFUL; + } + STORE32L(y, &ct[0]); + STORE32L(z, &ct[4]); +} + +void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key) +{ + unsigned long y, z; + int r; + + _ARGCHK(pt != NULL); + _ARGCHK(ct != NULL); + _ARGCHK(key != NULL); + + LOAD32L(y, &ct[0]); + LOAD32L(z, &ct[4]); + for (r = 31; r >= 0; r -= 4) { + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-1])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-1])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-2])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-2])) & 0xFFFFFFFFUL; + + z = (z - ((((y<<4)^(y>>5)) + y) ^ key->xtea.B[r-3])) & 0xFFFFFFFFUL; + y = (y - ((((z<<4)^(z>>5)) + z) ^ key->xtea.A[r-3])) & 0xFFFFFFFFUL; + } + STORE32L(y, &pt[0]); + STORE32L(z, &pt[4]); +} + +int xtea_test(void) +{ + #ifndef LTC_TEST + return CRYPT_NOP; + #else + static const unsigned char key[16] = + { 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a, + 0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d }; + static const unsigned char pt[8] = + { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + static const unsigned char ct[8] = + { 0x75, 0xd7, 0xc5, 0xbf, 0xcf, 0x58, 0xc9, 0x3f }; + unsigned char tmp[2][8]; + symmetric_key skey; + int err, y; + + if ((err = xtea_setup(key, 16, 0, &skey)) != CRYPT_OK) { + return err; + } + xtea_ecb_encrypt(pt, tmp[0], &skey); + xtea_ecb_decrypt(tmp[0], tmp[1], &skey); + + if (memcmp(tmp[0], ct, 8) != 0 || memcmp(tmp[1], pt, 8) != 0) { + return CRYPT_FAIL_TESTVECTOR; + } + + /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ + for (y = 0; y < 8; y++) tmp[0][y] = 0; + for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey); + for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; + + return CRYPT_OK; + #endif +} + +int xtea_keysize(int *desired_keysize) +{ + _ARGCHK(desired_keysize != NULL); + if (*desired_keysize < 16) { + return CRYPT_INVALID_KEYSIZE; + } + *desired_keysize = 16; + return CRYPT_OK; +} + + +#endif + + + diff --git a/tnl-1.5.0/tnl/libtomcrypt/yarrow.c b/tnl-1.5.0/tnl/libtomcrypt/yarrow.c new file mode 100644 index 0000000000000000000000000000000000000000..ee4d0165786095eec414fa505d726ddbf422d372 --- /dev/null +++ b/tnl-1.5.0/tnl/libtomcrypt/yarrow.c @@ -0,0 +1,156 @@ +#include "mycrypt.h" + +#ifdef YARROW + +const struct _prng_descriptor yarrow_desc = +{ + "yarrow", + &yarrow_start, + &yarrow_add_entropy, + &yarrow_ready, + &yarrow_read +}; + +int yarrow_start(prng_state *prng) +{ + int err; + + _ARGCHK(prng != NULL); + + /* these are the default hash/cipher combo used */ +#ifdef RIJNDAEL + prng->yarrow.cipher = register_cipher(&rijndael_desc); +#elif defined(BLOWFISH) + prng->yarrow.cipher = register_cipher(&blowfish_desc); +#elif defined(TWOFISH) + prng->yarrow.cipher = register_cipher(&twofish_desc); +#elif defined(RC6) + prng->yarrow.cipher = register_cipher(&rc6_desc); +#elif defined(RC5) + prng->yarrow.cipher = register_cipher(&rc5_desc); +#elif defined(SAFERP) + prng->yarrow.cipher = register_cipher(&saferp_desc); +#elif defined(RC2) + prng->yarrow.cipher = register_cipher(&rc2_desc); +#elif defined(NOEKEON) + prng->yarrow.cipher = register_cipher(&noekeon_desc); +#elif defined(CAST5) + prng->yarrow.cipher = register_cipher(&cast5_desc); +#elif defined(XTEA) + prng->yarrow.cipher = register_cipher(&xtea_desc); +#elif defined(SAFER) + prng->yarrow.cipher = register_cipher(&safer_sk128_desc); +#elif defined(DES) + prng->yarrow.cipher = register_cipher(&des3_desc); +#elif + #error YARROW needs at least one CIPHER +#endif + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + return err; + } + +#ifdef SHA256 + prng->yarrow.hash = register_hash(&sha256_desc); +#elif defined(SHA512) + prng->yarrow.hash = register_hash(&sha512_desc); +#elif defined(TIGER) + prng->yarrow.hash = register_hash(&tiger_desc); +#elif defined(SHA1) + prng->yarrow.hash = register_hash(&sha1_desc); +#elif defined(RIPEMD160) + prng->yarrow.hash = register_hash(&rmd160_desc); +#elif defined(RIPEMD128) + prng->yarrow.hash = register_hash(&rmd128_desc); +#elif defined(MD5) + prng->yarrow.hash = register_hash(&md5_desc); +#elif defined(MD4) + prng->yarrow.hash = register_hash(&md4_desc); +#elif defined(MD2) + prng->yarrow.hash = register_hash(&md2_desc); +#else + #error YARROW needs at least one HASH +#endif + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + /* zero the memory used */ + zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); + + return CRYPT_OK; +} + +int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) +{ + hash_state md; + int err; + + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + /* start the hash */ + hash_descriptor[prng->yarrow.hash].init(&md); + + /* hash the current pool */ + hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize); + + /* add the new entropy */ + hash_descriptor[prng->yarrow.hash].process(&md, buf, len); + + /* store result */ + hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); + + return CRYPT_OK; +} + +int yarrow_ready(prng_state *prng) +{ + int ks, err; + + _ARGCHK(prng != NULL); + + if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { + return err; + } + + if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { + return err; + } + + /* setup CTR mode using the "pool" as the key */ + ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; + if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { + return err; + } + + if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ + prng->yarrow.pool, /* IV */ + prng->yarrow.pool, ks, /* KEY and key size */ + 0, /* number of rounds */ + &prng->yarrow.ctr)) != CRYPT_OK) { + return err; + } + return CRYPT_OK; +} + +unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) +{ + _ARGCHK(buf != NULL); + _ARGCHK(prng != NULL); + + /* put buf in predictable state first */ + zeromem(buf, len); + + /* now randomize it */ + if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) { + return 0; + } + return len; +} + +#endif + diff --git a/tnl-1.5.0/tnl/master/Makefile b/tnl-1.5.0/tnl/master/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5dbdf7f6db52a2621640e7ec1e1470c9d5f2cc26 --- /dev/null +++ b/tnl-1.5.0/tnl/master/Makefile @@ -0,0 +1,27 @@ +# TNL Makefile +# (c) 2003 GarageGames +# +# This makefile is for Linux atm. + + +# +# Configuration +# +CC=g++ -g -I../tnl #-O2 + +OBJECTS_MASTER=\ + main.o\ + masterInterface.o\ + config.o + +CFLAGS= + +.cpp.o : + $(CC) -c $(CFLAGS) $< + +default: $(OBJECTS_MASTER) + $(CC) -o ../exe/master $(OBJECTS_MASTER) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a -lstdc++ -lm + +clean: + rm -f $(OBJECTS_MASTER) ../exe/master + diff --git a/tnl-1.5.0/tnl/master/config.cpp b/tnl-1.5.0/tnl/master/config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b39c509c04ca45bbf9e6a41b07c449fd263c6a0d --- /dev/null +++ b/tnl-1.5.0/tnl/master/config.cpp @@ -0,0 +1,209 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - Master Server +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include +#include +#include "tnl.h" +#include "tnlLog.h" +using namespace TNL; + +extern U32 gMasterPort; + +extern Vector MOTDTypeVec; +extern Vector MOTDStringVec; + +void processConfigLine(int argc, const char **argv) +{ + if(!stricmp(argv[0], "port") && argc > 1) + { + gMasterPort = atoi(argv[1]); + } + else if(!stricmp(argv[0], "motd") && argc > 2) + { + char *type = strdup(argv[1]); + char *message = strdup(argv[2]); + + MOTDTypeVec.push_back(type); + MOTDStringVec.push_back(message); + } +} + +enum { + MaxArgc = 128, + MaxArgLen = 100, +}; + +static char *argv[MaxArgc]; +static char argv_buffer[MaxArgc][MaxArgLen]; +static int argc; +static int argLen = 0; +static const char *argString; + +inline char getNextChar() +{ + while(*argString == '\r') + argString++; + return *argString++; +} + +inline void addCharToArg(char c) +{ + if(argc < MaxArgc && argLen < MaxArgLen-1) + { + argv[argc][argLen] = c; + argLen++; + } +} + +inline void addArg() +{ + if(argc < MaxArgc) + { + argv[argc][argLen] = 0; + argc++; + argLen = 0; + } +} + +int parseArgs(const char *string) +{ + int numObjects = 0; + + argc = 0; + argLen = 0; + argString = string; + char c; + + for(U32 i = 0; i < MaxArgc; i++) + argv[i] = argv_buffer[i]; + +stateEatingWhitespace: + c = getNextChar(); + if(c == ' ' || c == '\t') + goto stateEatingWhitespace; + if(c == '\n' || !c) + goto stateLineParseDone; + if(c == '\"') + goto stateReadString; + if(c == '#') + goto stateEatingComment; +stateAddCharToIdent: + addCharToArg(c); + c = getNextChar(); + if(c == ' ' || c == '\t') + { + addArg(); + goto stateEatingWhitespace; + } + if(c == '\n' || !c) + { + addArg(); + goto stateLineParseDone; + } + if(c == '\"') + { + addArg(); + goto stateReadString; + } + goto stateAddCharToIdent; +stateReadString: + c = getNextChar(); + if(c == '\"') + { + addArg(); + goto stateEatingWhitespace; + } + if(c == '\n' || !c) + { + addArg(); + goto stateLineParseDone; + } + if(c == '\\') + { + c = getNextChar(); + if(c == 'n') + { + addCharToArg('\n'); + goto stateReadString; + } + if(c == 't') + { + addCharToArg('\t'); + goto stateReadString; + } + if(c == '\\') + { + addCharToArg('\\'); + goto stateReadString; + } + if(c == '\n' || !c) + { + addArg(); + goto stateLineParseDone; + } + } + addCharToArg(c); + goto stateReadString; +stateEatingComment: + c = getNextChar(); + if(c != '\n' && c) + goto stateEatingComment; +stateLineParseDone: + if(argc) + processConfigLine(argc, (const char **) argv); + argc = 0; + argLen = 0; + if(c) + goto stateEatingWhitespace; + return numObjects; +} + +void readConfigFile() +{ + FILE *f = fopen("master.cfg", "r"); + if(!f) + { + logprintf("Unable to open config file."); + return; + } + for(S32 i = 0; i < MOTDTypeVec.size();i++) + { + free(MOTDTypeVec[i]); + free(MOTDStringVec[i]); + } + MOTDTypeVec.clear(); + MOTDStringVec.clear(); + + char fileData[32768]; + + size_t bytesRead = fread(fileData, 1, sizeof(fileData), f); + fileData[bytesRead] = 0; + + parseArgs(fileData); + + fclose(f); +} + diff --git a/tnl-1.5.0/tnl/master/main.cpp b/tnl-1.5.0/tnl/master/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8f097e9647ac0f565a75a3523d7ddf2ff47d6554 --- /dev/null +++ b/tnl-1.5.0/tnl/master/main.cpp @@ -0,0 +1,647 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - Master Server +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlNetInterface.h" +#include "masterInterface.h" +#include "tnlVector.h" +#include "tnlAsymmetricKey.h" + +using namespace TNL; + +NetInterface *gNetInterface = NULL; +class MissionGameType : public Object +{ +public: + MissionGameType(const StringTableEntry &name) { mName = name; } + StringTableEntry mName; +}; + +Vector MOTDTypeVec; +Vector MOTDStringVec; + + +class MasterServerConnection; + +class GameConnectRequest +{ +public: + SafePtr initiator; + SafePtr host; + + U32 initiatorQueryId; + U32 hostQueryId; + U32 requestTime; +}; + +class MasterServerConnection : public MasterServerInterface +{ +private: + typedef MasterServerInterface Parent; +protected: + + /// @name Linked List + /// + /// The server stores its connections on a linked list. + /// + /// @{ + + /// + MasterServerConnection *mNext; + MasterServerConnection *mPrev; + + /// @} + + /// @name Globals + /// @{ + + /// + static MasterServerConnection gServerList; + static Vector< SafePtr > gMissionTypeList; + static Vector< SafePtr > gGameTypeList; + static Vector< GameConnectRequest* > gConnectList; + + + /// @} + + + /// @name Connection Info + /// + /// General information about this connection. + /// + /// @{ + + /// + bool mIsGameServer; ///< True if this is a game server. + U32 mStrikeCount; ///< Number of "strikes" this connection has... 3 strikes and you're out! + U32 mLastQueryId; ///< The last query id for info from this master. + U32 mLastActivityTime; ///< The last time we got a request or an update from this host. + + /// A list of connection requests we're working on fulfilling for this connection. + Vector< GameConnectRequest* > mConnectList; + + /// @} + + /// @name Server Info + /// + /// This info is filled in if this connection maps to a + /// game server. + /// + /// @{ + + U32 mRegionCode; ///< The region code in which this server operates. + StringTableEntry mGameString; ///< The unique game string for this server or client. + U32 mCPUSpeed; ///< The CPU speed of this server. + U32 mInfoFlags; ///< Info flags describing this server. + U32 mPlayerCount; ///< Current number of players on this server. + U32 mMaxPlayers; ///< Maximum number of players on this server. + U32 mNumBots; ///< Current number of bots on this server. + RefPtr mCurrentGameType; + RefPtr mCurrentMissionType; + + + + void setGameType(const StringTableEntry &gameType) + { + for(S32 i = 0; i < gGameTypeList.size(); i++) + { + if(gGameTypeList[i].isValid() && gGameTypeList[i]->mName == gameType) + { + mCurrentGameType = gGameTypeList[i]; + return; + } + } + mCurrentGameType = new MissionGameType(gameType); + gGameTypeList.push_back((MissionGameType *)mCurrentGameType); + } + + void setMissionType(const StringTableEntry &missionType) + { + for(S32 i = 0; i < gMissionTypeList.size(); i++) + { + if(gMissionTypeList[i].isValid() && gMissionTypeList[i]->mName == missionType) + { + mCurrentMissionType = gMissionTypeList[i]; + return; + } + } + mCurrentMissionType = new MissionGameType(missionType); + gMissionTypeList.push_back((MissionGameType *) mCurrentMissionType); + } + + /// @} + +public: + + /// Constructor initializes the linked list info with + /// "safe" values so we don't explode if we destruct + /// right away. + MasterServerConnection() + { + mStrikeCount = 0; + mLastActivityTime = 0; + mNext = this; + mPrev = this; + setIsConnectionToClient(); + setIsAdaptive(); + } + + /// Destructor removes the connection from the doubly linked list of + /// server connections. + ~MasterServerConnection() + { + // unlink it if it's in the list + mPrev->mNext = mNext; + mNext->mPrev = mPrev; + logprintf("%s disconnected", getNetAddress().toString()); + } + + /// Adds this connection to the doubly linked list of servers. + void linkToServerList() + { + mNext = gServerList.mNext; + mPrev = gServerList.mNext->mPrev; + mNext->mPrev = this; + mPrev->mNext = this; + } + + /// RPC's a list of mission and game types to the requesting client. + /// This function also cleans up any game types from the global lists + /// that are no longer referenced. + TNL_DECLARE_RPC_OVERRIDE(c2mQueryGameTypes, (U32 queryId)) + { + Vector gameTypes(GameMissionTypesPerPacket); + Vector missionTypes(GameMissionTypesPerPacket); + U32 listSize = 0; + + // Iterate through game types list, culling out any null entries. + // Add all non-null entries to the gameTypes vector. + for(S32 i = 0; i < gGameTypeList.size(); ) + { + if(gGameTypeList[i].isNull()) + { + gGameTypeList.erase_fast(i); + continue; + } + + gameTypes.push_back(gGameTypeList[i]->mName); + i++; + + listSize++; + if(listSize >= GameMissionTypesPerPacket) + { + m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); + listSize = 0; + gameTypes.clear(); + } + } + + + // Iterate through mission types list, culling out any null entries. + // Add all non-null entries to the missionTypes vector. + for(S32 i = 0; i < gMissionTypeList.size(); ) + { + if(gMissionTypeList[i].isNull()) + { + gMissionTypeList.erase_fast(i); + continue; + } + missionTypes.push_back(gMissionTypeList[i]->mName); + i++; + listSize++; + if(listSize >= GameMissionTypesPerPacket) + { + m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); + listSize = 0; + gameTypes.clear(); + missionTypes.clear(); + } + } + + // Send the last lists to the client. + m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); + + // Send a pair of empty lists to the client to signify that the + // query is done. + if(gameTypes.size() || missionTypes.size()) + { + gameTypes.clear(); + missionTypes.clear(); + m2cQueryGameTypesResponse(queryId, gameTypes, missionTypes); + } + } + + /// The query server method builds a piecewise list of servers + /// that match the client's particular filter criteria and + /// sends it to the client, followed by a QueryServersDone RPC. + TNL_DECLARE_RPC_OVERRIDE(c2mQueryServers, + (U32 queryId, U32 regionMask, U32 minPlayers, U32 maxPlayers, + U32 infoFlags, U32 maxBots, U32 minCPUSpeed, + StringTableEntry gameType, StringTableEntry missionType) + ) + { + Vector theVector(IPMessageAddressCount); + theVector.reserve(IPMessageAddressCount); + + for(MasterServerConnection *walk = gServerList.mNext; walk != &gServerList; walk = walk->mNext) + { + // Skip to the next if we don't match on any particular... + if(walk->mGameString != mGameString) + continue; + if(!(walk->mRegionCode & regionMask)) + continue; + if(walk->mPlayerCount > maxPlayers || walk->mPlayerCount < minPlayers) + continue; + if(infoFlags & ~walk->mInfoFlags) + continue; + if(maxBots < walk->mNumBots) + continue; + if(minCPUSpeed > walk->mCPUSpeed) + continue; + if(gameType.isNotNull() && (gameType != walk->mCurrentGameType->mName)) + continue; + if(missionType.isNotNull() && (missionType != walk->mCurrentMissionType->mName)) + continue; + + // Somehow we matched! Add us to the results list. + theVector.push_back(walk->getNetAddress().toIPAddress()); + + // If we get a packet's worth, send it to the client and empty our buffer... + if(theVector.size() == IPMessageAddressCount) + { + m2cQueryServersResponse(queryId, theVector); + theVector.clear(); + } + } + m2cQueryServersResponse(queryId, theVector); + // If we sent any with the previous message, send another list with no servers. + if(theVector.size()) + { + theVector.clear(); + m2cQueryServersResponse(queryId, theVector); + } + } + + /// checkActivityTime validates that this particular connection is + /// not issuing too many requests at once in an attempt to DOS + /// by flooding either the master server or any other server + /// connected to it. A client whose last activity time falls + /// within the specified delta gets a strike... 3 strikes and + /// you're out! Strikes go away after being good for a while. + void checkActivityTime(U32 timeDeltaMinimum) + { + U32 currentTime = Platform::getRealMilliseconds(); + if(currentTime - mLastActivityTime < timeDeltaMinimum) + { + mStrikeCount++; + if(mStrikeCount == 3) + disconnect("You're out!"); + } + else if(mStrikeCount > 0) + mStrikeCount--; + } + + void removeConnectRequest(GameConnectRequest *gcr) + { + for(S32 j = 0; j < mConnectList.size(); j++) + { + if(gcr == mConnectList[j]) + { + mConnectList.erase_fast(j); + break; + } + } + } + + GameConnectRequest *findAndRemoveRequest(U32 requestId) + { + GameConnectRequest *req = NULL; + for(S32 j = 0; j < mConnectList.size(); j++) + { + if(mConnectList[j]->hostQueryId == requestId) + { + req = mConnectList[j]; + mConnectList.erase_fast(j); + break; + } + } + if(!req) + return NULL; + + if(req->initiator.isValid()) + req->initiator->removeConnectRequest(req); + for(S32 j = 0; j < gConnectList.size(); j++) + { + if(gConnectList[j] == req) + { + gConnectList.erase_fast(j); + break; + } + } + return req; + } + + // This is called when a client wishes to arrange a connection with a + // server. + TNL_DECLARE_RPC_OVERRIDE(c2mRequestArrangedConnection, (U32 requestId, + IPAddress remoteAddress, IPAddress internalAddress, + ByteBufferPtr connectionParameters)) + { + // First, make sure that we're connected with the server that they're requesting a connection with. + MasterServerConnection *conn = (MasterServerConnection *) gNetInterface->findConnection(remoteAddress); + if(!conn) + { + ByteBufferPtr ptr = new ByteBuffer((U8 *) MasterNoSuchHost, strlen(MasterNoSuchHost) + 1); + c2mRejectArrangedConnection(requestId, ptr); + return; + } + + // Record the request... + GameConnectRequest *req = new GameConnectRequest; + req->initiator = this; + req->host = conn; + req->initiatorQueryId = requestId; + req->hostQueryId = mLastQueryId++; + req->requestTime = Platform::getRealMilliseconds(); + + char buf[256]; + strcpy(buf, getNetAddress().toString()); + logprintf("Client: %s requested connection to %s", + buf, conn->getNetAddress().toString()); + + // Add the request to the relevant lists (the global list, this connection's list, + // and the other connection's list). + mConnectList.push_back(req); + conn->mConnectList.push_back(req); + gConnectList.push_back(req); + + // Do some DOS checking... + checkActivityTime(2000); + + // Get our address... + Address theAddress = getNetAddress(); + + // Record some different addresses to try... + Vector possibleAddresses; + + // The address, but port+1 + theAddress.port++; + possibleAddresses.push_back(theAddress.toIPAddress()); + + // The address, with the original port + theAddress.port--; + possibleAddresses.push_back(theAddress.toIPAddress()); + + // Or the address the port thinks it's talking to. + Address theInternalAddress(internalAddress); + Address anyAddress; + + // (Only store that last one if it's not the any address.) + if(!theInternalAddress.isEqualAddress(anyAddress) && theInternalAddress != theAddress) + possibleAddresses.push_back(internalAddress); + + // And inform the other part of the request. + conn->m2cClientRequestedArrangedConnection(req->hostQueryId, possibleAddresses, connectionParameters); + } + + // Called to indicate a connect request is being accepted. + TNL_DECLARE_RPC_OVERRIDE(c2mAcceptArrangedConnection, (U32 requestId, IPAddress internalAddress, ByteBufferPtr connectionData)) + { + GameConnectRequest *req = findAndRemoveRequest(requestId); + if(!req) + return; + + Address theAddress = getNetAddress(); + Vector possibleAddresses; + theAddress.port++; + possibleAddresses.push_back(theAddress.toIPAddress()); + theAddress.port--; + possibleAddresses.push_back(theAddress.toIPAddress()); + Address theInternalAddress(internalAddress); + Address anyAddress; + + if(!theInternalAddress.isEqualAddress(anyAddress) && theInternalAddress != theAddress) + possibleAddresses.push_back(internalAddress); + + char buffer[256]; + strcpy(buffer, getNetAddress().toString()); + + logprintf("Server: %s accept connection request from %s", buffer, + req->initiator.isValid() ? req->initiator->getNetAddress().toString() : "Unknown"); + + // If we still know about the requestor, tell him his connection was accepted... + if(req->initiator.isValid()) + req->initiator->m2cArrangedConnectionAccepted(req->initiatorQueryId, possibleAddresses, connectionData); + + delete req; + } + + + // Called to indicate a connect request is being rejected. + TNL_DECLARE_RPC_OVERRIDE(c2mRejectArrangedConnection, (U32 requestId, ByteBufferPtr rejectData)) + { + GameConnectRequest *req = findAndRemoveRequest(requestId); + if(!req) + return; + + logprintf("Server: %s reject connection request from %s", + getNetAddress().toString(), + req->initiator.isValid() ? req->initiator->getNetAddress().toString() : "Unknown"); + + if(req->initiator.isValid()) + req->initiator->m2cArrangedConnectionRejected(req->initiatorQueryId, rejectData); + + delete req; + } + + // Called to update the status of a game server. + TNL_DECLARE_RPC_OVERRIDE(c2mUpdateServerStatus, ( + StringTableEntry gameType, StringTableEntry missionType, + U32 botCount, U32 playerCount, U32 maxPlayers, U32 infoFlags)) + { + // If we didn't know we were a game server, don't accept updates. + if(!mIsGameServer) + return; + + setGameType(gameType); + setMissionType(missionType); + mNumBots = botCount; + mPlayerCount = playerCount; + mMaxPlayers = maxPlayers; + mInfoFlags = infoFlags; + + checkActivityTime(15000); + + logprintf("Server: %s updated server status (%s, %s, %d, %d, %d)", getNetAddress().toString(), gameType.getString(), missionType.getString(), botCount, playerCount, maxPlayers); + } + + bool readConnectRequest(BitStream *bstream, const char **errorString) + { + if(!Parent::readConnectRequest(bstream, errorString)) + return false; + + char gameString[256]; + bstream->readString(gameString); + mGameString = gameString; + + // If it's a game server, read status info... + if((mIsGameServer = bstream->readFlag()) == true) + { + bstream->read(&mCPUSpeed); + bstream->read(&mRegionCode); + bstream->read(&mNumBots); + bstream->read(&mPlayerCount); + bstream->read(&mMaxPlayers); + bstream->read(&mInfoFlags); + bstream->readString(gameString); + + setGameType(StringTableEntry(gameString)); + bstream->readString(gameString); + setMissionType(StringTableEntry(gameString)); + + linkToServerList(); + } + logprintf("%s online at %s", mIsGameServer ? "Server" : "client", getNetAddress().toString()); + if(getEventClassVersion() > 0) + { + U32 matchLen = 0; + const char *motdString = "Welcome to TNL. Have a nice day."; + for(S32 i = 0; i < MOTDTypeVec.size(); i++) + { + U32 len; + const char *type = MOTDTypeVec[i]; + for(len = 0; type[len] == gameString[len] && type[len] != 0; len++) + ; + if(len > matchLen) + { + matchLen = len; + motdString = MOTDStringVec[i]; + } + } + m2cSetMOTD(motdString); + } + return true; + } + + static void checkConnectTimeouts() + { + U32 currentTime = Platform::getRealMilliseconds(); + + // Expire any connect requests that have grown old... + for(S32 i = 0; i < gConnectList.size(); ) + { + GameConnectRequest *gcr = gConnectList[i]; + if(currentTime - gcr->requestTime > ConnectRequestTimeout) + { + // It's old! + + // So remove it from the initiator's list... + if(gcr->initiator.isValid()) + { + gcr->initiator->removeConnectRequest(gcr); + ByteBufferPtr reqTimeoutBuffer = new ByteBuffer((U8 *) MasterRequestTimedOut, strlen(MasterRequestTimedOut) + 1); + gcr->initiator->c2mRejectArrangedConnection(gcr->initiatorQueryId, reqTimeoutBuffer); + } + + // And the host's lists.. + if(gcr->host.isValid()) + gcr->host->removeConnectRequest(gcr); + + // Delete it... + delete gcr; + + // And remove it from our list, too. + gConnectList.erase_fast(i); + continue; + } + + i++; + } + } + + TNL_DECLARE_NETCONNECTION(MasterServerConnection); +}; + +TNL_IMPLEMENT_NETCONNECTION(MasterServerConnection, NetClassGroupMaster, true); + +Vector< SafePtr > MasterServerConnection::gMissionTypeList; +Vector< SafePtr > MasterServerConnection::gGameTypeList; +Vector< GameConnectRequest* > MasterServerConnection::gConnectList; + +MasterServerConnection MasterServerConnection::gServerList; + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- + +#include + +class StdoutLogConsumer : public LogConsumer +{ +public: + void logString(const char *string) + { + printf("%s\n", string); + } +} gStdoutLogConsumer; + +enum { + DefaultMasterPort = 29005, +}; + +U32 gMasterPort = DefaultMasterPort; +extern void readConfigFile(); + +int main(int argc, const char **argv) +{ + // Parse command line parameters... + readConfigFile(); + + // Initialize our net interface so we can accept connections... + gNetInterface = new NetInterface(Address(IPProtocol, Address::Any, gMasterPort)); + + //for the master server alone, we don't need a key exchange - that would be a waste + //gNetInterface->setRequiresKeyExchange(true); + //gNetInterface->setPrivateKey(new AsymmetricKey(20)); + + logprintf("Master Server created - listening on port %d", gMasterPort); + + // And until infinity, process whatever comes our way. + U32 lastConfigReadTime = Platform::getRealMilliseconds(); + + for(;;) + { + U32 currentTime = Platform::getRealMilliseconds(); + gNetInterface->checkIncomingPackets(); + gNetInterface->processConnections(); + if(currentTime - lastConfigReadTime > 5000) + { + lastConfigReadTime = currentTime; + readConfigFile(); + } + Platform::sleep(1); + } + return 0; +} diff --git a/tnl-1.5.0/tnl/master/master.vcproj b/tnl-1.5.0/tnl/master/master.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..c66fc7528636c2f204297b3d7010e5f1d01c9c8c --- /dev/null +++ b/tnl-1.5.0/tnl/master/master.vcproj @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/master/masterInterface.cpp b/tnl-1.5.0/tnl/master/masterInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..208998b70e360f105dd7ae8b283c5c97817acd93 --- /dev/null +++ b/tnl-1.5.0/tnl/master/masterInterface.cpp @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - Master Server +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + + +#include "masterInterface.h" + +// Since this is an interface, we implement a bunch of stubs. + +TNL_IMPLEMENT_RPC(MasterServerInterface, c2mQueryGameTypes, (U32 queryId), (queryId), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, m2cQueryGameTypesResponse, + (U32 queryId, Vector gameTypes, Vector missionTypes), (queryId, gameTypes, missionTypes), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, c2mQueryServers, + (U32 queryId, U32 regionMask, U32 minPlayers, U32 maxPlayers, U32 infoFlags, + U32 maxBots, U32 minCPUSpeed, StringTableEntry gameType, StringTableEntry missionType), + (queryId, regionMask, minPlayers, maxPlayers, infoFlags, maxBots, minCPUSpeed, gameType, missionType), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, m2cQueryServersResponse, + (U32 queryId, Vector ipList), (queryId, ipList), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, c2mRequestArrangedConnection, (U32 requestId, + IPAddress remoteAddress, IPAddress internalAddress, ByteBufferPtr connectionParameters), + (requestId, remoteAddress, internalAddress, connectionParameters), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, m2cClientRequestedArrangedConnection, + (U32 requestId, Vector possibleAddresses, ByteBufferPtr connectionParameters), + (requestId, possibleAddresses, connectionParameters), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, c2mAcceptArrangedConnection, + (U32 requestId, IPAddress internalAddress, ByteBufferPtr connectionData), + (requestId, internalAddress, connectionData), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, c2mRejectArrangedConnection, + (U32 requestId, ByteBufferPtr rejectData), + (requestId, rejectData), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, m2cArrangedConnectionAccepted, + (U32 requestId, Vector possibleAddresses, ByteBufferPtr connectionData), + (requestId, possibleAddresses, connectionData), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, m2cArrangedConnectionRejected, + (U32 requestId, ByteBufferPtr rejectData), + (requestId, rejectData), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, c2mUpdateServerStatus, ( + StringTableEntry gameType, StringTableEntry missionType, + U32 botCount, U32 playerCount, U32 maxPlayers, U32 infoFlags), + (gameType, missionType, botCount, playerCount, maxPlayers, infoFlags), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) {} + +TNL_IMPLEMENT_RPC(MasterServerInterface, m2cSetMOTD, (StringPtr motdString), (motdString), + NetClassGroupMasterMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) {} \ No newline at end of file diff --git a/tnl-1.5.0/tnl/master/masterInterface.h b/tnl-1.5.0/tnl/master/masterInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..1871245bf9433d1814fabf75753d42af1170a5b8 --- /dev/null +++ b/tnl-1.5.0/tnl/master/masterInterface.h @@ -0,0 +1,144 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - Master Server +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _MASTERINTERFACE_H_ +#define _MASTERINTERFACE_H_ + +#include "tnlEventConnection.h" +#include "tnlRPC.h" + +using namespace TNL; + +// Useful string constants... +static const char *MasterNoSuchHost = "No Such Host"; +static const char *MasterRequestTimedOut = "Timed Out"; + +enum MasterConstants { + ConnectRequestTimeout = 30000, + IPMessageAddressCount = 30, + GameMissionTypesPerPacket = 20, +}; + +/// The MasterServerInterface is the RPC interface to the TNL example Master Server. +/// The default Master Server tracks a list of public servers and allows clients +/// to query for them based on different filter criteria, including maximum number of players, +/// region codes, game or mission type, and others. +/// +/// When a client wants to initiate a connection with a server listed by the master, it +/// can ask the Master Server to arranage a connection. The masterclient example that +/// ships with TNL demonstrates a client/server console application that uses the Master +/// Server to arrange connections between a client and a server instance. +/// +/// Client/Server programs using the Master Server for server listing should create +/// a subclass of MasterServerInterface named "MasterServerConnection", and override +/// all of the RPC methods that begin with m2c, as they signify master to client messages. +/// RPC methods can be overridden with the TNL_DECLARE_RPC_OVERRIDE and TNL_IMPLEMENT_RPC_OVERRIDE methods. +class MasterServerInterface : public EventConnection +{ +protected: +public: + enum { + MasterServerInterfaceVersion = 1, + }; + + /// c2mQueryGameTypes is sent from the client to the master to request a list of + /// game and mission types that current game servers are reporting. The queryId + /// is specified by the client to identify the returning list from the master server. + TNL_DECLARE_RPC(c2mQueryGameTypes, (U32 queryId)); + + /// m2cQueryGameTypesResponse is sent by the master server in response to a c2mQueryGameTypes + /// from a client. The queryId will match the original queryId sent by the client. Clients + /// should override this method in their custom MasterServerConnection classes. If there are + /// more game or mission types than will fit in a single message, the master server will send + /// multiple m2cQueryGameTypesResponse RPCs. The master will always send a final + /// m2cQueryGameTypesResponse with Vectors of size 0 to indicate that no more game or mission + /// types are to be added. + TNL_DECLARE_RPC(m2cQueryGameTypesResponse, (U32 queryId, Vector gameTypes, Vector missionTypes)); + + /// c2mQueryServers is sent by the client to the master server to request a list of + /// servers that match the specified filter criteria. A c2mQueryServers request will + /// result in one or more m2cQueryServersResponse RPCs, with the final call having an empty + /// Vector of servers. + TNL_DECLARE_RPC(c2mQueryServers, (U32 queryId, U32 regionMask, + U32 minPlayers, U32 maxPlayers, U32 infoFlags, + U32 maxBots, U32 minCPUSpeed, StringTableEntry gameType, StringTableEntry missionType)); + + /// m2cQueryServersResponse is sent by the master server in response to a c2mQueryServers RPC, to + /// return a partial list of the servers that matched the specified filter criteria. Because packets + /// are limited in size, the response server list is broken up into lists of at most IPMessageAddressCount IP addresses + /// per message. The Master Server will always send a final, empty m2cQueryServersResponse to signify that the list + /// is complete. + TNL_DECLARE_RPC(m2cQueryServersResponse, (U32 queryId, Vector ipList)); + + /// c2mRequestArrangedConnection is an RPC sent from the client to the master to request an arranged + /// connection with the specified server address. The internalAddress should be the client's own self-reported + /// IP address. The connectionParameters buffer will be sent without modification to the specified + /// server. + TNL_DECLARE_RPC(c2mRequestArrangedConnection, (U32 requestId, + IPAddress remoteAddress, IPAddress internalAddress, + ByteBufferPtr connectionParameters)); + + /// m2cClientRequestedArranged connection is sent from the master to a server to notify it that + /// a client has requested a connection. The possibleAddresses vector is a list of possible IP addresses + /// that the server should attempt to connect to for that client if it accepts the connection request. + TNL_DECLARE_RPC(m2cClientRequestedArrangedConnection, (U32 requestId, Vector possibleAddresses, + ByteBufferPtr connectionParameters)); + + /// c2mAcceptArrangedConnection is sent by a server to notify the master that it will accept the connection + /// request from a client. The requestId parameter sent by the MasterServer in m2cClientRequestedArrangedConnection + /// should be sent back as the requestId field. The internalAddress is the server's self-determined IP address. + TNL_DECLARE_RPC(c2mAcceptArrangedConnection, (U32 requestId, IPAddress internalAddress, ByteBufferPtr connectionData)); + + /// c2mRejectArrangedConnection notifies the Master Server that the server is rejecting the arranged connection + /// request specified by the requestId. The rejectData will be passed along to the requesting client. + TNL_DECLARE_RPC(c2mRejectArrangedConnection, (U32 requestId, ByteBufferPtr rejectData)); + + /// m2cArrangedConnectionAccepted is sent to a client that has previously requested a connection to a listed server + /// via c2mRequestArrangedConnection if the server accepted the connection. The possibleAddresses vector is the list + /// of IP addresses the client should attempt to connect to, and the connectionData buffer is the buffer sent by the + /// server upon accepting the connection. + TNL_DECLARE_RPC(m2cArrangedConnectionAccepted, (U32 requestId, Vector possibleAddresses, ByteBufferPtr connectionData)); + + /// m2cArrangedConnectionRejected is sent to a client when an arranged connection request is rejected by the + /// server, or when the request times out because the server never responded. + TNL_DECLARE_RPC(m2cArrangedConnectionRejected, (U32 requestId, ByteBufferPtr rejectData)); + + /// c2mUpdateServerStatus updates the status of a server to the Master Server, specifying the current game + /// and mission types, any player counts and the current info flags. + TNL_DECLARE_RPC(c2mUpdateServerStatus, ( + StringTableEntry gameType, StringTableEntry missionType, + U32 botCount, U32 playerCount, U32 maxPlayers, U32 infoFlags)); + + // Version 1 protocol messages: + + /// m2cSetMOTD is sent to a client when the connection is established. The + /// client's game string is used to pick which MOTD will be sent. + TNL_DECLARE_RPC(m2cSetMOTD, (StringPtr motdString)); + +}; + + +#endif diff --git a/tnl-1.5.0/tnl/masterclient/Makefile b/tnl-1.5.0/tnl/masterclient/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4ca5bc45930cf1e0adfe715144b33a1abbb97e44 --- /dev/null +++ b/tnl-1.5.0/tnl/masterclient/Makefile @@ -0,0 +1,26 @@ +# TNL Makefile +# (c) 2003 GarageGames +# +# This makefile is for Linux atm. + + +# +# Configuration +# +CC=g++ -g -I../tnl #-O2 + +OBJECTS_MASTER=\ + ../master/masterInterface.o\ + main.o + +CFLAGS= + +.cpp.o : + $(CC) -c $(CFLAGS) $< + +default: $(OBJECTS_MASTER) + $(CC) -o masterclient $(OBJECTS_MASTER) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a -lstdc++ -lm + +clean: + rm -f $(OBJECTS_MASTER) masterclient + diff --git a/tnl-1.5.0/tnl/masterclient/main.cpp b/tnl-1.5.0/tnl/masterclient/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a62587adc0697c0223f3d34acbffc579c2db110 --- /dev/null +++ b/tnl-1.5.0/tnl/masterclient/main.cpp @@ -0,0 +1,456 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - Master Server Game Client/Server example +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +// Master server test client. +// +// This program operates in one of two modes - as a game client +// or a game server. +// +// In game server mode, which you can access by running: +// +// masterclient -server +// +// the process creates a MasterServerConnection to the master server +// and periodically updates its server status with a random game type +// and mission string. If the connection to the master server times +// out or is disconnected, the server will attempt to reconnect to the +// master. If a client requests an arranged connection, the server will +// accept it 75% of the time, using a GameConnection instance for +// the arranged connection. The GameConnection lasts between 15 and +// 30 seconds (random), at which point the server will force a disconnect +// with the client. +// +// The client behaves in much the same way. It will log in to the +// master server, and upon successful connection will query the master +// for a list of game servers. It will pick one of the servers +// out of the list to connect to randomly and will initiate an +// arranged connection with that host. If the connection to the +// server is rejected, or if it connects succesfully and later disconnects, +// it will restart the process of requesting a server list from the master. +// +// This example client demonstrates everything you need to know to implement +// your own master server clients. + + +#include +#include "tnlNetInterface.h" +#include "../master/masterInterface.h" +#include "tnlVector.h" +#include "tnlRandom.h" + +using namespace TNL; + +class MasterServerConnection; +class GameConnection; + +//------------------------------------------------------------------------ + +RefPtr gMasterServerConnection; +RefPtr gClientConnection; +StringTableEntry gCurrentGameType("SomeGameType"); +StringTableEntry gCurrentMissionType("SomeMissionType"); + +bool gIsServer = false; +bool gQuit = false; + +void GameConnectionDone(); + +//------------------------------------------------------------------------ + +class GameConnection : public EventConnection +{ +public: + // The server maintains a linked list of clients... + GameConnection *mNext; + GameConnection *mPrev; + static GameConnection gClientList; + + // Time in milliseconds at which we were created. + U32 mCreateTime; + + GameConnection() + { + mNext = mPrev = this; + mCreateTime = Platform::getRealMilliseconds(); + } + + ~GameConnection() + { + // unlink ourselves if we're in the client list + mPrev->mNext = mNext; + mNext->mPrev = mPrev; + + // Tell the user... + logprintf("%s disconnected", getNetAddress().toString()); + } + + /// Adds this connection to the doubly linked list of clients. + void linkToClientList() + { + mNext = gClientList.mNext; + mPrev = gClientList.mNext->mPrev; + mNext->mPrev = this; + mPrev->mNext = this; + } + + void onConnectionEstablished() + { + logprintf("connection to %s - %s established.", isInitiator() ? "server" : "client", getNetAddress().toString()); + + // If we're a server (ie, being connected to by the client) add this new connection to + // our list of clients. + if(!isInitiator()) + linkToClientList(); + } + + static void checkGameTimeouts() + { + // Look for people who have been connected longer than the threshold and + // disconnect them. + + U32 currentTime = Platform::getRealMilliseconds(); + for(GameConnection *walk = gClientList.mNext; walk != &gClientList; walk = walk->mNext) + { + if(currentTime - walk->mCreateTime > 15000) + { + walk->disconnect("You're done!"); + break; + } + } + } + + // Various things that should trigger us to try another server... + + void onConnectTerminated(NetConnection::TerminationReason, const char *) + { + GameConnectionDone(); + } + + void onConnectionTerminated(NetConnection::TerminationReason, const char *reason) + { + logprintf("Connection to remote host terminated - %s", reason); + GameConnectionDone(); + } + + TNL_DECLARE_NETCONNECTION(GameConnection); +}; + +// Global list of clients (if we're a server). +GameConnection GameConnection::gClientList; + +TNL_IMPLEMENT_NETCONNECTION(GameConnection, NetClassGroupGame, false); + +//------------------------------------------------------------------------ + +class MasterServerConnection : public MasterServerInterface +{ + typedef MasterServerInterface Parent; + + // ID of our current query. + U32 mCurrentQueryId; + + // List of game servers from our last query. + Vector mIPList; + +public: + MasterServerConnection() + { + mCurrentQueryId = 0; + setIsConnectionToServer(); + } + + void startGameTypesQuery() + { + // Kick off a game types query. + mCurrentQueryId++; + c2mQueryGameTypes(mCurrentQueryId); + } + + TNL_DECLARE_RPC_OVERRIDE(m2cQueryGameTypesResponse, (U32 queryId, Vector gameTypes, Vector missionTypes)) + { + // Ignore old queries... + if(queryId != mCurrentQueryId) + return; + + // Inform the user of the results... + logprintf("Got game types response - %d game types, %d mission types", gameTypes.size(), missionTypes.size()); + for(S32 i = 0; i < gameTypes.size(); i++) + logprintf("G(%d): %s", i, gameTypes[i].getString()); + for(S32 i = 0; i < missionTypes.size(); i++) + logprintf("M(%d): %s", i, missionTypes[i].getString()); + + // when we receive the final list of mission and game types, + // query for servers: + if(gameTypes.size() == 0 && missionTypes.size() == 0) + { + // Invalidate old queries + mCurrentQueryId++; + mIPList.clear(); + + // And automatically do a server query as well - you may not want to do things + // in this order in your own clients. + c2mQueryServers(mCurrentQueryId, 0xFFFFFFFF, 0, 128, 0, 128, 0, "", ""); + } + } + + TNL_DECLARE_RPC_OVERRIDE(m2cQueryServersResponse, (U32 queryId, Vector ipList)) + { + // Only process results from current query... + if(queryId != mCurrentQueryId) + return; + + // Add the new results to our master result list... + for(S32 i = 0; i < ipList.size(); i++) + mIPList.push_back(ipList[i]); + + // if this was the last response, then echo out the list of servers, + // and attempt to connect to one of them: + if(ipList.size() == 0) + { + // Display the results... + logprintf("got a list of servers from the master: %d servers", mIPList.size()); + for(S32 i = 0; i < mIPList.size(); i++) + logprintf(" %s", Address(mIPList[i]).toString()); + + // If we got anything... + if(mIPList.size()) + { + // pick a random server to connect to: + U32 index = Random::readI(0, mIPList.size() - 1); + + // Invalidate the query... + mCurrentQueryId++; + + // And request an arranged connnection (notice gratuitous hardcoded payload) + c2mRequestArrangedConnection(mCurrentQueryId, mIPList[index], + getInterface()->getFirstBoundInterfaceAddress().toIPAddress(), + new ByteBuffer((U8 *) "Hello World!", 13)); + + logprintf("Requesting arranged connection with %s", Address(mIPList[index]).toString()); + } + else + { + logprintf("No game servers available... exiting."); + gQuit = true; + } + } + } + + TNL_DECLARE_RPC_OVERRIDE(m2cClientRequestedArrangedConnection, (U32 requestId, Vector possibleAddresses, + ByteBufferPtr connectionParameters)) + { + if(!gIsServer || Random::readF() > 0.75) + { + // We reject connections about 75% of the time... + + logprintf("Rejecting arranged connection from %s", Address(possibleAddresses[0]).toString()); + c2mRejectArrangedConnection(requestId, connectionParameters); + } + else + { + // Ok, let's do the arranged connection! + + U8 data[Nonce::NonceSize * 2 + SymmetricCipher::KeySize * 2]; + Random::read(data, sizeof(data)); + IPAddress localAddress = getInterface()->getFirstBoundInterfaceAddress().toIPAddress(); + + ByteBufferPtr b = new ByteBuffer(data, sizeof(data)); + b->takeOwnership(); + c2mAcceptArrangedConnection(requestId, localAddress, b); + GameConnection *conn = new GameConnection(); + + Vector

fullPossibleAddresses; + for(S32 i = 0; i < possibleAddresses.size(); i++) + fullPossibleAddresses.push_back(Address(possibleAddresses[i])); + + logprintf("Accepting arranged connection from %s", Address(fullPossibleAddresses[0]).toString()); + + logprintf(" Generated shared secret data: %s", b->encodeBase64()->getBuffer()); + + ByteBufferPtr theSharedData = new ByteBuffer(data + 2 * Nonce::NonceSize, sizeof(data) - 2 * Nonce::NonceSize); + theSharedData->takeOwnership(); + Nonce nonce(data); + Nonce serverNonce(data + Nonce::NonceSize); + + conn->connectArranged(getInterface(), fullPossibleAddresses, + nonce, serverNonce, theSharedData,false); + } + } + + TNL_DECLARE_RPC_OVERRIDE(m2cArrangedConnectionAccepted, (U32 requestId, Vector possibleAddresses, ByteBufferPtr connectionData)) + { + if(!gIsServer && requestId == mCurrentQueryId && connectionData->getBufferSize() >= Nonce::NonceSize * 2 + SymmetricCipher::KeySize * 2) + { + logprintf("Remote host accepted arranged connection."); + logprintf(" Shared secret data: %s", connectionData->encodeBase64()->getBuffer()); + GameConnection *conn = new GameConnection(); + + Vector
fullPossibleAddresses; + for(S32 i = 0; i < possibleAddresses.size(); i++) + fullPossibleAddresses.push_back(Address(possibleAddresses[i])); + + ByteBufferPtr theSharedData = + new ByteBuffer( + (U8 *) connectionData->getBuffer() + Nonce::NonceSize * 2, + connectionData->getBufferSize() - Nonce::NonceSize * 2 + ); + theSharedData->takeOwnership(); + + Nonce nonce(connectionData->getBuffer()); + Nonce serverNonce(connectionData->getBuffer() + Nonce::NonceSize); + + conn->connectArranged(getInterface(), fullPossibleAddresses, + nonce, serverNonce, theSharedData,true); + } + } + + TNL_DECLARE_RPC_OVERRIDE(m2cArrangedConnectionRejected, (U32 requestId, ByteBufferPtr rejectData)) + { + if(!gIsServer && requestId == mCurrentQueryId) + { + logprintf("Remote host rejected arranged connection..."); + logprintf("Requesting new game types list."); + startGameTypesQuery(); + } + } + void writeConnectRequest(BitStream *bstream) + { + Parent::writeConnectRequest(bstream); + + bstream->writeString("MasterServerTestGame"); // Game Name + if(bstream->writeFlag(gIsServer)) + { + bstream->write((U32) 1000); // CPU speed + bstream->write((U32) 0xFFFFFFFF); // region code + bstream->write((U32) 5); // num bots + bstream->write((U32) 10); // num players + bstream->write((U32) 32); // max players + bstream->write((U32) 0); // info flags + + bstream->writeString(gCurrentGameType.getString()); // Game type + bstream->writeString(gCurrentMissionType.getString()); // Mission type + } + } + + void onConnectionEstablished() + { + if(!gIsServer) + startGameTypesQuery(); + } + + TNL_DECLARE_NETCONNECTION(MasterServerConnection); +}; + +TNL_IMPLEMENT_NETCONNECTION(MasterServerConnection, NetClassGroupMaster, false); + +//------------------------------------------------------------------------ + +// This is called when we lose our connection to a game server. +void GameConnectionDone() +{ + // If we're still talking to the master server... + if(gMasterServerConnection.isValid() && + gMasterServerConnection->getConnectionState() == NetConnection::Connected) + { + // Query again! + gMasterServerConnection->startGameTypesQuery(); + } + else + { + logprintf("GameConnectionDone: No connection to master server available - terminating!"); + gQuit = true; + } +} + +//------------------------------------------------------------------------ + +class StdoutLogConsumer : public LogConsumer +{ +public: + void logString(const char *string) + { + printf("%s\n", string); + } +} gStdoutLogConsumer; + +//------------------------------------------------------------------------ + +int main(int argc, const char **argv) +{ + + // Parse command line arguments... + if(argc < 2) + { + logprintf("Usage: masterclient [-client|-server] [port]"); + return 0; + } + + Address masterAddress(argv[1]); + if(argc > 2) + gIsServer = !stricmp(argv[2], "-server"); + U32 port = 0; + if(argc > 3) + port = atoi(argv[3]); + + // Announce master status. + logprintf("%s started - master is at %s.", gIsServer ? "Server" : "Client", masterAddress.toString()); + + // Initialize the random number generator. + U32 value = Platform::getRealMilliseconds(); + Random::addEntropy((U8 *) &value, sizeof(U32)); + Random::addEntropy((U8 *) &value, sizeof(U32)); + Random::addEntropy((U8 *) &value, sizeof(U32)); + Random::addEntropy((U8 *) &value, sizeof(U32)); + + // Open a network port... + NetInterface *theInterface = new NetInterface(Address(IPProtocol, Address::Any, port)); + + // And start processing. + while(!gQuit) + { + // If we don't have a connection to the master server, then + // create one and connect to it. + if(!gMasterServerConnection.isValid() || + (gMasterServerConnection->getConnectionState() == NetConnection::TimedOut || + gMasterServerConnection->getConnectionState() == NetConnection::Disconnected)) + { + logprintf("Connecting to master server at %s", masterAddress.toString()); + gMasterServerConnection = new MasterServerConnection; + gMasterServerConnection->connect(theInterface, masterAddress); + } + + // Make sure to process network traffic and connected clients... + theInterface->checkIncomingPackets(); + theInterface->processConnections(); + GameConnection::checkGameTimeouts(); + + // Sleep a bit so we don't saturate the system. + Platform::sleep(1); + } + + // All done! + return 0; +} diff --git a/tnl-1.5.0/tnl/masterclient/masterclient.vcproj b/tnl-1.5.0/tnl/masterclient/masterclient.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..90bae01407db3316393144feda4f38710324204d --- /dev/null +++ b/tnl-1.5.0/tnl/masterclient/masterclient.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/openal/ALut.lib b/tnl-1.5.0/tnl/openal/ALut.lib new file mode 100644 index 0000000000000000000000000000000000000000..67cde9f676b7dbead6771de243a29cdf1b73f6be Binary files /dev/null and b/tnl-1.5.0/tnl/openal/ALut.lib differ diff --git a/tnl-1.5.0/tnl/openal/OpenAL32.lib b/tnl-1.5.0/tnl/openal/OpenAL32.lib new file mode 100644 index 0000000000000000000000000000000000000000..86de42002459c4b3e4f37d9bfd092afa9f491dbb Binary files /dev/null and b/tnl-1.5.0/tnl/openal/OpenAL32.lib differ diff --git a/tnl-1.5.0/tnl/openal/al.h b/tnl-1.5.0/tnl/openal/al.h new file mode 100644 index 0000000000000000000000000000000000000000..f6c887fa23dc97871423a8d761ea7c049634ecac --- /dev/null +++ b/tnl-1.5.0/tnl/openal/al.h @@ -0,0 +1,499 @@ +#ifndef _AL_H_ +#define _AL_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ +#include "altypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + #ifdef _OPENAL32LIB + #define ALAPI __declspec(dllexport) + #else + #define ALAPI __declspec(dllimport) + #endif + #define ALAPIENTRY __cdecl + #define AL_CALLBACK +#else + #ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif + #endif + #define ALAPI + #define ALAPIENTRY __cdecl + #define AL_CALLBACK +#endif + +// JMQ: hack for linux. we really shouldn't be using the creative +// headers with the linux lib. +#if defined(__linux) +#undef ALAPIENTRY +#define ALAPIENTRY +typedef ALCvoid ALCdevice; +typedef ALCvoid ALCcontext; +#endif + +#define OPENAL + +#ifndef AL_NO_PROTOTYPES + +/** + * OpenAL Maintenance Functions + * Initialization and exiting. + * State Management and Query. + * Error Handling. + * Extension Support. + */ + +/** State management. */ +ALAPI ALvoid ALAPIENTRY alEnable( ALenum capability ); +ALAPI ALvoid ALAPIENTRY alDisable( ALenum capability ); +ALAPI ALboolean ALAPIENTRY alIsEnabled( ALenum capability ); + +/** Application preferences for driver performance choices. */ +ALAPI ALvoid ALAPIENTRY alHint( ALenum target, ALenum mode ); + +/** State retrieval. */ +ALAPI ALboolean ALAPIENTRY alGetBoolean( ALenum param ); +ALAPI ALint ALAPIENTRY alGetInteger( ALenum param ); +ALAPI ALfloat ALAPIENTRY alGetFloat( ALenum param ); +ALAPI ALdouble ALAPIENTRY alGetDouble( ALenum param ); +ALAPI ALvoid ALAPIENTRY alGetBooleanv( ALenum param, ALboolean* data ); +ALAPI ALvoid ALAPIENTRY alGetIntegerv( ALenum param, ALint* data ); +ALAPI ALvoid ALAPIENTRY alGetFloatv( ALenum param, ALfloat* data ); +ALAPI ALvoid ALAPIENTRY alGetDoublev( ALenum param, ALdouble* data ); +ALAPI ALubyte* ALAPIENTRY alGetString( ALenum param ); + +/** + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +ALAPI ALenum ALAPIENTRY alGetError( ALvoid ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALboolean ALAPIENTRY alIsExtensionPresent( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALvoid* ALAPIENTRY alGetProcAddress( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the integer value of an enumeration (usually an extension) with the name ename. + */ +ALAPI ALenum ALAPIENTRY alGetEnumValue( ALubyte* ename ); + + + + +/** + * LISTENER + * Listener is the sample position for a given context. + * The multi-channel (usually stereo) output stream generated + * by the mixer is parametrized by this Listener object: + * its position and velocity relative to Sources, within + * occluder and reflector geometry. + */ + + + +/** + * + * Listener Environment: default 0. + */ +ALAPI ALvoid ALAPIENTRY alListeneri( ALenum param, ALint value ); + + +/** + * + * Listener Gain: default 1.0f. + */ +ALAPI ALvoid ALAPIENTRY alListenerf( ALenum param, ALfloat value ); + + +/** + * + * Listener Position. + * Listener Velocity. + */ +ALAPI ALvoid ALAPIENTRY alListener3f( ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); + + +/** + * + * Listener Position: ALfloat[3] + * Listener Velocity: ALfloat[3] + * Listener Orientation: ALfloat[6] (forward and up vector). + */ +ALAPI ALvoid ALAPIENTRY alListenerfv( ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY alGetListeneri( ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetListenerf( ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY alGetListener3f( ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY alGetListenerfv( ALenum param, ALfloat* values ); + + +/** + * SOURCE + * Source objects are by default localized. Sources + * take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial + * arrangement etc. + */ + + + +/** Create Source objects. */ +ALAPI ALvoid ALAPIENTRY alGenSources( ALsizei n, ALuint* sources ); + +/** Delete Source objects. */ +ALAPI ALvoid ALAPIENTRY alDeleteSources( ALsizei n, ALuint* sources ); + +/** Verify a handle is a valid Source. */ +ALAPI ALboolean ALAPIENTRY alIsSource( ALuint id ); + +/** Set an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY alSourcei( ALuint source, ALenum param, ALint value ); +ALAPI ALvoid ALAPIENTRY alSourcef( ALuint source, ALenum param, ALfloat value ); +ALAPI ALvoid ALAPIENTRY alSource3f( ALuint source, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); +ALAPI ALvoid ALAPIENTRY alSourcefv( ALuint source, ALenum param, ALfloat* values ); + +/** Get an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY alGetSourcei( ALuint source, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetSourcef( ALuint source, ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY alGetSource3f( ALuint source, ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY alGetSourcefv( ALuint source, ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY alSourcePlayv( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourcePausev( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourceStopv( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY alSourceRewindv(ALsizei n,ALuint *sources); + +/** Activate a source, start replay. */ +ALAPI ALvoid ALAPIENTRY alSourcePlay( ALuint source ); + +/** + * Pause a source, + * temporarily remove it from the mixer list. + */ +ALAPI ALvoid ALAPIENTRY alSourcePause( ALuint source ); + +/** + * Stop a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + * To remove a Source completely, it has to be + * deleted following Stop, or before Play. + */ +ALAPI ALvoid ALAPIENTRY alSourceStop( ALuint source ); + +/** + * Rewinds a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + */ +ALAPI ALvoid ALAPIENTRY alSourceRewind( ALuint source ); + + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. There can be more than + * one Source using the same Buffer data. If Buffers have + * to be duplicated on a per-Source basis, the driver has to + * take care of allocation, copying, and deallocation as well + * as propagating buffer data changes. + */ + + + + +/** Buffer object generation. */ +ALAPI ALvoid ALAPIENTRY alGenBuffers( ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY alDeleteBuffers( ALsizei n, ALuint* buffers ); +ALAPI ALboolean ALAPIENTRY alIsBuffer( ALuint buffer ); + +/** + * Specify the data to be filled into a buffer. + */ +ALAPI ALvoid ALAPIENTRY alBufferData( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ); + + +ALAPI ALvoid ALAPIENTRY alGetBufferi( ALuint buffer, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY alGetBufferf( ALuint buffer, ALenum param, ALfloat* value ); + + + + +/** + * Queue stuff + */ + +ALAPI ALvoid ALAPIENTRY alSourceQueueBuffers( ALuint source, ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY alSourceUnqueueBuffers( ALuint source, ALsizei n, ALuint* buffers ); + +/** + * Knobs and dials + */ +ALAPI ALvoid ALAPIENTRY alDistanceModel( ALenum value ); +ALAPI ALvoid ALAPIENTRY alDopplerFactor( ALfloat value ); +ALAPI ALvoid ALAPIENTRY alDopplerVelocity( ALfloat value ); + +#else /* AL_NO_PROTOTYPES */ + +/** + * OpenAL Maintenance Functions + * Initialization and exiting. + * State Management and Query. + * Error Handling. + * Extension Support. + */ + +/** State management. */ +ALAPI ALvoid ALAPIENTRY (*alEnable)( ALenum capability ); +ALAPI ALvoid ALAPIENTRY (*alDisable)( ALenum capability ); +ALAPI ALboolean ALAPIENTRY (*alIsEnabled)( ALenum capability ); + +/** Application preferences for driver performance choices. */ +ALAPI ALvoid ALAPIENTRY (*alHint)( ALenum target, ALenum mode ); + +/** State retrieval. */ +ALAPI ALboolean ALAPIENTRY (*alGetBoolean)( ALenum param ); +ALAPI ALint ALAPIENTRY (*alGetInteger)( ALenum param ); +ALAPI ALfloat ALAPIENTRY (*alGetFloat)( ALenum param ); +ALAPI ALdouble ALAPIENTRY (*alGetDouble)( ALenum param ); +ALAPI ALvoid ALAPIENTRY (*alGetBooleanv)( ALenum param, ALboolean* data ); +ALAPI ALvoid ALAPIENTRY (*alGetIntegerv)( ALenum param, ALint* data ); +ALAPI ALvoid ALAPIENTRY (*alGetFloatv)( ALenum param, ALfloat* data ); +ALAPI ALvoid ALAPIENTRY (*alGetDoublev)( ALenum param, ALdouble* data ); +ALAPI ALubyte* ALAPIENTRY (*alGetString)( ALenum param ); + +/** + * Error support. + * Obtain the most recent error generated in the AL state machine. + */ +ALAPI ALenum ALAPIENTRY (*alGetError)( ALvoid ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALboolean ALAPIENTRY (*alIsExtensionPresent)( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the address of a function (usually an extension) + * with the name fname. All addresses are context-independent. + */ +ALAPI ALvoid* ALAPIENTRY (*alGetProcAddress)( ALubyte* fname ); + + +/** + * Extension support. + * Obtain the integer value of an enumeration (usually an extension) with the name ename. + */ +ALAPI ALenum ALAPIENTRY (*alGetEnumValue)( ALubyte* ename ); + + + + +/** + * LISTENER + * Listener is the sample position for a given context. + * The multi-channel (usually stereo) output stream generated + * by the mixer is parametrized by this Listener object: + * its position and velocity relative to Sources, within + * occluder and reflector geometry. + */ + + + +/** + * + * Listener Environment: default 0. + */ +ALAPI ALvoid ALAPIENTRY (*alListeneri)( ALenum param, ALint value ); + + +/** + * + * Listener Gain: default 1.0f. + */ +ALAPI ALvoid ALAPIENTRY (*alListenerf)( ALenum param, ALfloat value ); + + +/** + * + * Listener Position. + * Listener Velocity. + */ +ALAPI ALvoid ALAPIENTRY (*alListener3f)( ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); + + +/** + * + * Listener Position: ALfloat[3] + * Listener Velocity: ALfloat[3] + * Listener Orientation: ALfloat[6] (forward and up vector). + */ +ALAPI ALvoid ALAPIENTRY (*alListenerfv)( ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY (*alGetListeneri)( ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetListenerf)( ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY (*alGetListener3f)( ALenum param, ALfloat* v1, ALfloat* v2, ALfloat* v3 ); +ALAPI ALvoid ALAPIENTRY (*alGetListenerfv)( ALenum param, ALfloat* values ); + + +/** + * SOURCE + * Source objects are by default localized. Sources + * take the PCM data provided in the specified Buffer, + * apply Source-specific modifications, and then + * submit them to be mixed according to spatial + * arrangement etc. + */ + + + +/** Create Source objects. */ +ALAPI ALvoid ALAPIENTRY (*alGenSources)( ALsizei n, ALuint* sources ); + +/** Delete Source objects. */ +ALAPI ALvoid ALAPIENTRY (*alDeleteSources)( ALsizei n, ALuint* sources ); + +/** Verify a handle is a valid Source. */ +ALAPI ALboolean ALAPIENTRY (*alIsSource)( ALuint id ); + +/** Set an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY (*alSourcei)( ALuint source, ALenum param, ALint value ); +ALAPI ALvoid ALAPIENTRY (*alSourcef)( ALuint source, ALenum param, ALfloat value ); +ALAPI ALvoid ALAPIENTRY (*alSource3f)( ALuint source, ALenum param, ALfloat v1, ALfloat v2, ALfloat v3 ); +ALAPI ALvoid ALAPIENTRY (*alSourcefv)( ALuint source, ALenum param, ALfloat* values ); + +/** Get an integer parameter for a Source object. */ +ALAPI ALvoid ALAPIENTRY (*alGetSourcei)( ALuint source, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetSourcef)( ALuint source, ALenum param, ALfloat* value ); +ALAPI ALvoid ALAPIENTRY (*alGetSourcefv)( ALuint source, ALenum param, ALfloat* values ); + +ALAPI ALvoid ALAPIENTRY (*alSourcePlayv)( ALsizei n, ALuint *sources ); +ALAPI ALvoid ALAPIENTRY (*alSourceStopv)( ALsizei n, ALuint *sources ); + +/** Activate a source, start replay. */ +ALAPI ALvoid ALAPIENTRY (*alSourcePlay)( ALuint source ); + +/** + * Pause a source, + * temporarily remove it from the mixer list. + */ +ALAPI ALvoid ALAPIENTRY (*alSourcePause)( ALuint source ); + +/** + * Stop a source, + * temporarily remove it from the mixer list, + * and reset its internal state to pre-Play. + * To remove a Source completely, it has to be + * deleted following Stop, or before Play. + */ +ALAPI ALvoid ALAPIENTRY (*alSourceStop)( ALuint source ); + + + +/** + * BUFFER + * Buffer objects are storage space for sample data. + * Buffers are referred to by Sources. There can be more than + * one Source using the same Buffer data. If Buffers have + * to be duplicated on a per-Source basis, the driver has to + * take care of allocation, copying, and deallocation as well + * as propagating buffer data changes. + */ + + + + +/** Buffer object generation. */ +ALAPI ALvoid ALAPIENTRY (*alGenBuffers)( ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY (*alDeleteBuffers)( ALsizei n, ALuint* buffers ); +ALAPI ALboolean ALAPIENTRY (*alIsBuffer)( ALuint buffer ); + +/** + * Specify the data to be filled into a buffer. + */ +ALAPI ALvoid ALAPIENTRY (*alBufferData)( ALuint buffer, + ALenum format, + ALvoid* data, + ALsizei size, + ALsizei freq ); + +ALAPI ALvoid ALAPIENTRY (*alGetBufferi)( ALuint buffer, ALenum param, ALint* value ); +ALAPI ALvoid ALAPIENTRY (*alGetBufferf)( ALuint buffer, ALenum param, ALfloat* value ); + + + + +/** + * Queue stuff + */ +ALAPI ALvoid ALAPIENTRY (*alSourceQueueBuffers)( ALuint source, ALsizei n, ALuint* buffers ); +ALAPI ALvoid ALAPIENTRY (*alSourceUnqueueBuffers)( ALuint source, ALsizei n, ALuint* buffers ); + +/** + * Knobs and dials + */ +ALAPI ALvoid ALAPIENTRY (*alDistanceModel)( ALenum value ); +ALAPI ALvoid ALAPIENTRY (*alDopplerFactor)( ALfloat value ); +ALAPI ALvoid ALAPIENTRY (*alDopplerVelocity)( ALfloat value ); + +#endif /* AL_NO_PROTOTYPES */ + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tnl-1.5.0/tnl/openal/alInclude.h b/tnl-1.5.0/tnl/openal/alInclude.h new file mode 100644 index 0000000000000000000000000000000000000000..634d723b9c3a3470c3cbbd02c7d8df708a76ccce --- /dev/null +++ b/tnl-1.5.0/tnl/openal/alInclude.h @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - Cross-platform OpenAL include file +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _ALINCLUDE_H_ +#define _ALINCLUDE_H_ + +#ifdef TNL_OS_MAC_OSX +#include +#include +#else +#include +#include +#endif + +#endif diff --git a/tnl-1.5.0/tnl/openal/alc.h b/tnl-1.5.0/tnl/openal/alc.h new file mode 100644 index 0000000000000000000000000000000000000000..bbca6c372847c4d7ef1c2fb91d6b8d660d7bdbc6 --- /dev/null +++ b/tnl-1.5.0/tnl/openal/alc.h @@ -0,0 +1,97 @@ +#ifndef _ALC_H_ +#define _ALC_H_ + +#include "altypes.h" +#include "alctypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + #ifdef _OPENAL32LIB + #define ALCAPI __declspec(dllexport) + #else + #define ALCAPI __declspec(dllimport) + #endif + + typedef struct ALCdevice_struct ALCdevice; + typedef struct ALCcontext_struct ALCcontext; + + #define ALCAPIENTRY __cdecl +#else + #ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export on + #endif + #endif + #define ALCAPI + #define ALCAPIENTRY __cdecl +#endif + +// JMQ: hack for linux. we really shouldn't be using the creative +// headers with the linux lib. +#if defined(__linux) +#undef ALCAPIENTRY +#define ALCAPIENTRY +typedef ALCvoid ALCdevice; +typedef ALCvoid ALCcontext; +#endif + +#ifndef ALC_NO_PROTOTYPES + +ALCAPI ALCubyte* ALCAPIENTRY alcGetString(ALCdevice *device,ALCenum param); +ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALCsizei size,ALCint *data); + +ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(ALCubyte *deviceName); +ALCAPI ALCvoid ALCAPIENTRY alcCloseDevice(ALCdevice *device); + +ALCAPI ALCcontext*ALCAPIENTRY alcCreateContext(ALCdevice *device,ALCint *attrList); +ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcProcessContext(ALCcontext *context); +ALCAPI ALCcontext*ALCAPIENTRY alcGetCurrentContext(ALCvoid); +ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcSuspendContext(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context); + +ALCAPI ALCenum ALCAPIENTRY alcGetError(ALCdevice *device); + +ALCAPI ALCboolean ALCAPIENTRY alcIsExtensionPresent(ALCdevice *device,ALCubyte *extName); +ALCAPI ALCvoid * ALCAPIENTRY alcGetProcAddress(ALCdevice *device,ALCubyte *funcName); +ALCAPI ALCenum ALCAPIENTRY alcGetEnumValue(ALCdevice *device,ALCubyte *enumName); + +#else /* AL_NO_PROTOTYPES */ + +ALCAPI ALCubyte* ALCAPIENTRY (*alcGetString)(ALCdevice *device,ALCenum param); +ALCAPI ALCvoid ALCAPIENTRY (*alcGetIntegerv)(ALCdevice * device,ALCenum param,ALCsizei size,ALCint *data); + +ALCAPI ALCdevice* ALCAPIENTRY (*alcOpenDevice)(ALubyte *deviceName); +ALCAPI ALCvoid ALCAPIENTRY (*alcCloseDevice)(ALCdevice *device); + +ALCAPI ALCcontext*ALCAPIENTRY (*alcCreateContext)(ALCdevice *device,ALCint *attrList); +ALCAPI ALCboolean ALCAPIENTRY (*alcMakeContextCurrent)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcProcessContext)(ALCcontext *context); +ALCAPI ALCcontext*ALCAPIENTRY (*alcGetCurrentContext)(ALCvoid); +ALCAPI ALCdevice* ALCAPIENTRY (*alcGetContextsDevice)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcSuspendContext)(ALCcontext *context); +ALCAPI ALCvoid ALCAPIENTRY (*alcDestroyContext)(ALCcontext *context); + +ALCAPI ALCenum ALCAPIENTRY (*alcGetError)(ALCdevice *device); + +ALCAPI ALCboolean ALCAPIENTRY (*alcIsExtensionPresent)(ALCdevice *device,ALCubyte *extName); +ALCAPI ALCvoid * ALCAPIENTRY (*alcGetProcAddress)(ALCdevice *device,ALCubyte *funcName); +ALCAPI ALCenum ALCAPIENTRY (*alcGetEnumValue)(ALCdevice *device,ALCubyte *enumName); + +#endif /* AL_NO_PROTOTYPES */ + +#ifdef TARGET_OS_MAC + #if TARGET_OS_MAC + #pragma export off + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tnl-1.5.0/tnl/openal/alctypes.h b/tnl-1.5.0/tnl/openal/alctypes.h new file mode 100644 index 0000000000000000000000000000000000000000..436fcfacc392eca058a5f6cb04871e5714703d6d --- /dev/null +++ b/tnl-1.5.0/tnl/openal/alctypes.h @@ -0,0 +1,125 @@ +#ifndef _ALCTYPES_H_ +#define _ALCTYPES_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** ALC boolean type. */ +typedef char ALCboolean; + +/** ALC 8bit signed byte. */ +typedef char ALCbyte; + +/** ALC 8bit unsigned byte. */ +typedef unsigned char ALCubyte; + +/** ALC 16bit signed short integer type. */ +typedef short ALCshort; + +/** ALC 16bit unsigned short integer type. */ +typedef unsigned short ALCushort; + +/** ALC 32bit unsigned integer type. */ +typedef unsigned ALCuint; + +/** ALC 32bit signed integer type. */ +typedef int ALCint; + +/** ALC 32bit floating point type. */ +typedef float ALCfloat; + +/** ALC 64bit double point type. */ +typedef double ALCdouble; + +/** ALC 32bit type. */ +typedef unsigned int ALCsizei; + +/** ALC void type */ +typedef void ALCvoid; + +/** ALC enumerations. */ +typedef int ALCenum; + +/* Bad value. */ +#define ALC_INVALID (-1) + +/* Boolean False. */ +#define ALC_FALSE 0 + +/* Boolean True. */ +#define ALC_TRUE 1 + +/** Errors: No Error. */ +#define ALC_NO_ERROR ALC_FALSE + +#define ALC_MAJOR_VERSION 0x1000 +#define ALC_MINOR_VERSION 0x1001 +#define ALC_ATTRIBUTES_SIZE 0x1002 +#define ALC_ALL_ATTRIBUTES 0x1003 + +#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 +#define ALC_DEVICE_SPECIFIER 0x1005 +#define ALC_EXTENSIONS 0x1006 + +#define ALC_FREQUENCY 0x1007 +#define ALC_REFRESH 0x1008 +#define ALC_SYNC 0x1009 + +/** + * The device argument does not name a valid dvice. + */ +#define ALC_INVALID_DEVICE 0xA001 + +/** + * The context argument does not name a valid context. + */ +#define ALC_INVALID_CONTEXT 0xA002 + +/** + * A function was called at inappropriate time, + * or in an inappropriate way, causing an illegal state. + * This can be an incompatible ALenum, object ID, + * and/or function. + */ +#define ALC_INVALID_ENUM 0xA003 + +/** + * Illegal value passed as an argument to an AL call. + * Applies to parameter values, but not to enumerations. + */ +#define ALC_INVALID_VALUE 0xA004 + +/** + * A function could not be completed, + * because there is not enough memory available. + */ +#define ALC_OUT_OF_MEMORY 0xA005 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/tnl-1.5.0/tnl/openal/altypes.h b/tnl-1.5.0/tnl/openal/altypes.h new file mode 100644 index 0000000000000000000000000000000000000000..8aa99c6086a7b2662a6d72910e5cdf0f8fbb922a --- /dev/null +++ b/tnl-1.5.0/tnl/openal/altypes.h @@ -0,0 +1,332 @@ +#ifndef _ALTYPES_H_ +#define _ALTYPES_H_ + +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2000 by authors. + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** OpenAL boolean type. */ +typedef char ALboolean; + +/** OpenAL 8bit signed byte. */ +typedef char ALbyte; + +/** OpenAL 8bit unsigned byte. */ +typedef unsigned char ALubyte; + +/** OpenAL 16bit signed short integer type. */ +typedef short ALshort; + +/** OpenAL 16bit unsigned short integer type. */ +typedef unsigned short ALushort; + +/** OpenAL 32bit unsigned integer type. */ +typedef unsigned ALuint; + +/** OpenAL 32bit signed integer type. */ +typedef int ALint; + +/** OpenAL 32bit floating point type. */ +typedef float ALfloat; + +/** OpenAL 64bit double point type. */ +typedef double ALdouble; + +/** OpenAL 32bit type. */ +typedef unsigned int ALsizei; + +/** OpenAL void type */ +typedef void ALvoid; + +/** OpenAL enumerations. */ +typedef int ALenum; + +/* Bad value. */ +#define AL_INVALID (-1) + +/* Disable value. */ +#define AL_NONE 0 + +/* Boolean False. */ +#define AL_FALSE 0 + +/* Boolean True. */ +#define AL_TRUE 1 + +/** + * Indicate the type of AL_SOURCE. + * Sources can be spatialized + */ +#define AL_SOURCE_TYPE 0x200 + +/** Indicate source has absolute coordinates. */ +#define AL_SOURCE_ABSOLUTE 0x201 + +/** Indicate Source has listener relative coordinates. */ +#define AL_SOURCE_RELATIVE 0x202 + +/** + * Directional source, inner cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_INNER_ANGLE 0x1001 + +/** + * Directional source, outer cone angle, in degrees. + * Range: [0-360] + * Default: 360 + */ +#define AL_CONE_OUTER_ANGLE 0x1002 + +/** + * Specify the pitch to be applied, either at source, + * or on mixer results, at listener. + * Range: [0.5-2.0] + * Default: 1.0 + */ +#define AL_PITCH 0x1003 + +/** + * Specify the current location in three dimensional space. + * OpenAL, like OpenGL, uses a right handed coordinate system, + * where in a frontal default view X (thumb) points right, + * Y points up (index finger), and Z points towards the + * viewer/camera (middle finger). + * To switch from a left handed coordinate system, flip the + * sign on the Z coordinate. + * Listener position is always in the world coordinate system. + */ +#define AL_POSITION 0x1004 + +/** Specify the current direction as forward vector. */ +#define AL_DIRECTION 0x1005 + +/** Specify the current velocity in three dimensional space. */ +#define AL_VELOCITY 0x1006 + +/** + * Indicate whether source has to loop infinite. + * Type: ALboolean + * Range: [AL_TRUE, AL_FALSE] + * Default: AL_FALSE + */ +#define AL_LOOPING 0x1007 + +/** + * Indicate the buffer to provide sound samples. + * Type: ALuint. + * Range: any valid Buffer id. + */ +#define AL_BUFFER 0x1009 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_GAIN 0x100A + +/** + * Indicate minimum source attenuation. + * Type: ALfloat + * Range: [0.0 - 1.0] + */ +#define AL_MIN_GAIN 0x100D + +/** + * Indicate maximum source attenuation. + * Type: ALfloat + * Range: [0.0 - 1.0] + */ +#define AL_MAX_GAIN 0x100E + +/** + * Specify the current orientation. + * Type: ALfv6 (at/up) + * Range: N/A + */ +#define AL_ORIENTATION 0x100F + +/* byte offset into source (in canon format). -1 if source + * is not playing. Don't set this, get this. + * + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + */ +#define AL_REFERENCE_DISTANCE 0x1020 + + /** + * Indicate the rolloff factor for the source. + * Type: ALfloat + * Range: [0.0 - ] + * Default: 1.0 + */ +#define AL_ROLLOFF_FACTOR 0x1021 + +/** + * Indicate the gain (volume amplification) applied. + * Type: ALfloat. + * Range: ]0.0- ] + * A value of 1.0 means un-attenuated/unchanged. + * Each division by 2 equals an attenuation of -6dB. + * Each multiplicaton with 2 equals an amplification of +6dB. + * A value of 0.0 is meaningless with respect to a logarithmic + * scale; it is interpreted as zero volume - the channel + * is effectively disabled. + */ +#define AL_CONE_OUTER_GAIN 0x1022 + +/** + * Specify the maximum distance. + * Type: ALfloat + * Range: [0.0 - ] + */ +#define AL_MAX_DISTANCE 0x1023 + +/** + * Specify the channel mask. (Creative) + * Type: ALuint + * Range: [0 - 255] + */ +#define AL_CHANNEL_MASK 0x3000 + +/** + * Source state information + */ +#define AL_SOURCE_STATE 0x1010 +#define AL_INITIAL 0x1011 +#define AL_PLAYING 0x1012 +#define AL_PAUSED 0x1013 +#define AL_STOPPED 0x1014 + +/** + * Buffer Queue params + */ +#define AL_BUFFERS_QUEUED 0x1015 +#define AL_BUFFERS_PROCESSED 0x1016 + +/** Sound buffers: format specifier. */ +#define AL_FORMAT_MONO8 0x1100 +#define AL_FORMAT_MONO16 0x1101 +#define AL_FORMAT_STEREO8 0x1102 +#define AL_FORMAT_STEREO16 0x1103 + +/** + * Sound buffers: frequency, in units of Hertz [Hz]. + * This is the number of samples per second. Half of the + * sample frequency marks the maximum significant + * frequency component. + */ +#define AL_FREQUENCY 0x2001 +#define AL_BITS 0x2002 +#define AL_CHANNELS 0x2003 +#define AL_SIZE 0x2004 +#define AL_DATA 0x2005 + +/** + * Buffer state. + * + * Not supported for public use (yet). + */ +#define AL_UNUSED 0x2010 +#define AL_PENDING 0x2011 +#define AL_PROCESSED 0x2012 + +/** Errors: No Error. */ +#define AL_NO_ERROR AL_FALSE + +/** + * Illegal name passed as an argument to an AL call. + */ +#define AL_INVALID_NAME 0xA001 + +/** + * Illegal enum passed as an argument to an AL call. + */ +#define AL_INVALID_ENUM 0xA002 +/** + * Illegal value passed as an argument to an AL call. + * Applies to parameter values, but not to enumerations. + */ +#define AL_INVALID_VALUE 0xA003 + +/** + * A function was called at inappropriate time, + * or in an inappropriate way, causing an illegal state. + * This can be an incompatible ALenum, object ID, + * and/or function. + */ +#define AL_INVALID_OPERATION 0xA004 + +/** + * A function could not be completed, + * because there is not enough memory available. + */ +#define AL_OUT_OF_MEMORY 0xA005 + +/** Context strings: Vendor Name. */ +#define AL_VENDOR 0xB001 +#define AL_VERSION 0xB002 +#define AL_RENDERER 0xB003 +#define AL_EXTENSIONS 0xB004 + +/** Global tweakage. */ + +/** + * Doppler scale. Default 1.0 + */ +#define AL_DOPPLER_FACTOR 0xC000 + +/** + * Doppler velocity. Default 1.0 + */ +#define AL_DOPPLER_VELOCITY 0xC001 + +/** + * Distance model. Default AL_INVERSE_DISTANCE_CLAMPED + */ +#define AL_DISTANCE_MODEL 0xD000 + +/** Distance models. */ + +#define AL_INVERSE_DISTANCE 0xD001 +#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 + + /** + * enables + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tnl-1.5.0/tnl/openal/alu.h b/tnl-1.5.0/tnl/openal/alu.h new file mode 100644 index 0000000000000000000000000000000000000000..5a746bb97c9de319d739ee44c19bbd4e9e1b6511 --- /dev/null +++ b/tnl-1.5.0/tnl/openal/alu.h @@ -0,0 +1,41 @@ +#ifndef _ALU_H_ +#define _ALU_H_ + +#define ALUAPI +#define ALUAPIENTRY __cdecl + +#if defined(__linux) +#undef ALUAPIENTRY +#define ALUAPIENTRY +typedef ALCvoid ALCdevice; +typedef ALCvoid ALCcontext; +#endif + +#define BUFFERSIZE 48000 +#define FRACTIONBITS 14 +#define FRACTIONMASK ((1L< + + + + IBDocumentLocation + 68 68 356 240 0 0 1024 746 + IBEditorPositions + + 29 + 116 253 341 44 0 0 1024 746 + + IBFramework Version + 349.0 + IBOpenObjects + + 21 + 29 + + IBSystem Version + 7D24 + + diff --git a/tnl-1.5.0/tnl/osx/English.lproj/MainMenu.nib/keyedobjects.nib b/tnl-1.5.0/tnl/osx/English.lproj/MainMenu.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..174c3922a7949c33e36825ce607450d345670962 Binary files /dev/null and b/tnl-1.5.0/tnl/osx/English.lproj/MainMenu.nib/keyedobjects.nib differ diff --git a/tnl-1.5.0/tnl/osx/Info.plist b/tnl-1.5.0/tnl/osx/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..0ddc1e805efd1a99a981de06cd19c14e9475ef5b --- /dev/null +++ b/tnl-1.5.0/tnl/osx/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + TNLTest + CFBundleIconFile + + CFBundleIdentifier + com.apple.myCocoaApp + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 0.1 + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/tnl-1.5.0/tnl/osx/MyOpenGLView.h b/tnl-1.5.0/tnl/osx/MyOpenGLView.h new file mode 100644 index 0000000000000000000000000000000000000000..63920d0fd5e5ed0382b0d8902d95a08ff152e62d --- /dev/null +++ b/tnl-1.5.0/tnl/osx/MyOpenGLView.h @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#import + +@interface MyOpenGLView : NSOpenGLView +{ + id textWindow; +} + +- (void) tick; +- (void)mouseDown:(NSEvent *)theEvent; +- (void)insertLogText: (const char *) text; + +@end diff --git a/tnl-1.5.0/tnl/osx/MyOpenGLView.mm b/tnl-1.5.0/tnl/osx/MyOpenGLView.mm new file mode 100644 index 0000000000000000000000000000000000000000..f1c2966cb99d049ce23a57db03fe9aca8404726c --- /dev/null +++ b/tnl-1.5.0/tnl/osx/MyOpenGLView.mm @@ -0,0 +1,166 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include + +#import "MyOpenGLView.h" +#include "testGame.h" + +class TestGameLog : public LogConsumer +{ + id myView; +public: + TestGameLog(id aView) { myView = aView; } + void logString(const char *string) + { + printf("%s\n", string); //[myView insertLogText: avar("%s\n", string)]; + } +}; + +TestGameLog *theLog; + +@implementation MyOpenGLView + +/* + Override NSView's initWithFrame: to specify our pixel format: +*/ + + +- (id) initWithFrame: (NSRect) frame +{ + GLuint attribs[] = + { + NSOpenGLPFANoRecovery, + NSOpenGLPFAWindow, + NSOpenGLPFAAccelerated, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAColorSize, 24, + NSOpenGLPFAAlphaSize, 8, + NSOpenGLPFADepthSize, 24, + NSOpenGLPFAStencilSize, 8, + NSOpenGLPFAAccumSize, 0, + 0 + }; + [NSTimer scheduledTimerWithTimeInterval: 0.02 target: self selector:@selector(tick) userInfo:NULL repeats: true]; + + NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) attribs]; + + if (!fmt) + NSLog(@"No OpenGL pixel format"); + + theLog = new TestGameLog(self); + [self restartAsClient:self]; + return self = [super initWithFrame:frame pixelFormat: [fmt autorelease]]; +} + +- (void) tick +{ + if(clientGame) + clientGame->tick(); + if(serverGame) + serverGame->tick(); + [self setNeedsDisplay: YES]; +} + +- (void) awakeFromNib +{ + +} + +/* + Override the view's drawRect: to draw our GL content. +*/ + +- (void) drawRect: (NSRect) rect +{ + if(clientGame) + clientGame->renderFrame((U32) rect.size.width, (U32) rect.size.height); + else if(serverGame) + serverGame->renderFrame((U32) rect.size.width, (U32) rect.size.height); + + [[self openGLContext] flushBuffer]; +} + +- (void)insertLogText: (const char *) text +{ + [textWindow insertText: [NSString stringWithCString:text]]; +} + +- (void)mouseDown:(NSEvent *)theEvent +{ + NSPoint mouseLoc; + mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSRect tempRect = [self bounds]; + Position p; + p.x = mouseLoc.x / NSWidth(tempRect); + p.y = 1.0f - mouseLoc.y / NSHeight(tempRect); + if(clientGame) + clientGame->moveMyPlayerTo(p); + else if(serverGame) + serverGame->moveMyPlayerTo(p); +} + +- (void)restartAsServer:sender +{ + delete serverGame; + delete clientGame; + + serverGame = new TestGame(true, Address(IPProtocol, Address::Any, 28999), + Address("IP:Broadcast:28999")); + clientGame = NULL; +} + +- (void)restartAsClientPingingLocalhost:sender +{ + delete serverGame; + delete clientGame; + serverGame = NULL; + clientGame = new TestGame(false, Address(IPProtocol, Address::Any, 0), + Address("IP:localhost:28999")); +} + +- (void)restartAsClient:sender +{ + delete serverGame; + delete clientGame; + serverGame = NULL; + clientGame = new TestGame(false, Address(IPProtocol, Address::Any, 0), + Address("IP:broadcast:28999")); +} + +- (void)restartAsClientAndServer:sender +{ + delete serverGame; + delete clientGame; + serverGame = new TestGame(true, Address(IPProtocol, Address::Any, 28999), + Address("IP:Broadcast:28999")); + clientGame = new TestGame(false, Address(IPProtocol, Address::Any, 0), + Address("IP:broadcast:28999")); + + clientGame->createLocalConnection(serverGame); +} + +@end \ No newline at end of file diff --git a/tnl-1.5.0/tnl/osx/main.mm b/tnl-1.5.0/tnl/osx/main.mm new file mode 100644 index 0000000000000000000000000000000000000000..911a0217e05aa416a3b45981532c2e7c4c8d7b9a --- /dev/null +++ b/tnl-1.5.0/tnl/osx/main.mm @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#import + +int main(int argc, const char *argv[]) +{ + return NSApplicationMain(argc, argv); +} diff --git a/tnl-1.5.0/tnl/osx/tnl.xcode/project.pbxproj b/tnl-1.5.0/tnl/osx/tnl.xcode/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..a95a461429b6907d1ae4775d39ac09f2ed86b543 --- /dev/null +++ b/tnl-1.5.0/tnl/osx/tnl.xcode/project.pbxproj @@ -0,0 +1,4879 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + 089C165CFE840E0CC02AAC07 = { + children = ( + 089C165DFE840E0CC02AAC07, + ); + isa = PBXVariantGroup; + name = InfoPlist.strings; + refType = 4; + sourceTree = ""; + }; + 089C165DFE840E0CC02AAC07 = { + fileEncoding = 10; + isa = PBXFileReference; + lastKnownFileType = text.plist.strings; + name = English; + path = English.lproj/InfoPlist.strings; + refType = 4; + sourceTree = ""; + }; +//080 +//081 +//082 +//083 +//084 +//100 +//101 +//102 +//103 +//104 + 1058C7A0FEA54F0111CA2CBB = { + children = ( + 1058C7A1FEA54F0111CA2CBB, + ); + isa = PBXGroup; + name = "Linked Frameworks"; + refType = 4; + sourceTree = ""; + }; + 1058C7A1FEA54F0111CA2CBB = { + fallbackIsa = PBXFileReference; + isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; + name = Cocoa.framework; + path = /System/Library/Frameworks/Cocoa.framework; + refType = 0; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB = { + children = ( + 29B97325FDCFA39411CA2CEA, + 29B97324FDCFA39411CA2CEA, + ); + isa = PBXGroup; + name = "Other Frameworks"; + refType = 4; + sourceTree = ""; + }; +//100 +//101 +//102 +//103 +//104 +//190 +//191 +//192 +//193 +//194 + 19C28FACFE9D520D11CA2CBB = { + children = ( + 8D1107320486CEB800E47090, + 66D85E1905ACBA97008DC9C1, + 66D85EDE05ACCC36008DC9C1, + 6649E0D605FD01D700B3DD8B, + 66BA0E5C05FD467E00D882FA, + 66BA0E8905FD473200D882FA, + 6692C08806247BE000D5ADFE, + ); + isa = PBXGroup; + name = Products; + path = ../exe; + refType = 2; + sourceTree = SOURCE_ROOT; + }; +//190 +//191 +//192 +//193 +//194 +//1D0 +//1D1 +//1D2 +//1D3 +//1D4 + 1D3CACC90694D76300313D6F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = goalZone.cpp; + path = ../zap/goalZone.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3CACCA0694D76300313D6F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = goalZone.h; + path = ../zap/goalZone.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3CACCB0694D76300313D6F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = retrieveGame.cpp; + path = ../zap/retrieveGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3CACCC0694D76300313D6F = { + fileRef = 1D3CACC90694D76300313D6F; + isa = PBXBuildFile; + settings = { + }; + }; + 1D3CACCD0694D76300313D6F = { + fileRef = 1D3CACCA0694D76300313D6F; + isa = PBXBuildFile; + settings = { + }; + }; + 1D3CACCE0694D76300313D6F = { + fileRef = 1D3CACCB0694D76300313D6F; + isa = PBXBuildFile; + settings = { + }; + }; + 1D3E3EE90666A7EE005D645B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = loadoutSelect.cpp; + path = ../zap/loadoutSelect.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3E3EEA0666A7EE005D645B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = loadoutSelect.h; + path = ../zap/loadoutSelect.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3E3EEB0666A7EE005D645B = { + fileRef = 1D3E3EE90666A7EE005D645B; + isa = PBXBuildFile; + settings = { + }; + }; + 1D3E3EEC0666A7EE005D645B = { + fileRef = 1D3E3EEA0666A7EE005D645B; + isa = PBXBuildFile; + settings = { + }; + }; + 1D3E3EED0666A871005D645B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UIEditor.cpp; + path = ../zap/UIEditor.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3E3EEE0666A871005D645B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UIEditor.h; + path = ../zap/UIEditor.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D3E3EEF0666A871005D645B = { + fileRef = 1D3E3EED0666A871005D645B; + isa = PBXBuildFile; + settings = { + }; + }; + 1D3E3EF00666A871005D645B = { + fileRef = 1D3E3EEE0666A871005D645B; + isa = PBXBuildFile; + settings = { + }; + }; + 1D49BD0C0691F71200643C72 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = IOKit.framework; + path = /System/Library/Frameworks/IOKit.framework; + refType = 0; + sourceTree = ""; + }; + 1D49BD0D0691F71200643C72 = { + fileRef = 1D49BD0C0691F71200643C72; + isa = PBXBuildFile; + settings = { + }; + }; + 1D49BDC50691F8E000643C72 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = input.cpp; + path = ../zap/input.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D49BDC60691F8E000643C72 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = input.h; + path = ../zap/input.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D49BDC70691F8E000643C72 = { + fileRef = 1D49BDC50691F8E000643C72; + isa = PBXBuildFile; + settings = { + }; + }; + 1D49BDC80691F8E000643C72 = { + fileRef = 1D49BDC60691F8E000643C72; + isa = PBXBuildFile; + settings = { + }; + }; + 1D8DCBB606557E6D00BC4809 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = controlObjectConnection.cpp; + path = ../zap/controlObjectConnection.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D8DCBB706557E6D00BC4809 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = controlObjectConnection.h; + path = ../zap/controlObjectConnection.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1D8DCBB806557E6D00BC4809 = { + fileRef = 1D8DCBB606557E6D00BC4809; + isa = PBXBuildFile; + settings = { + }; + }; + 1D8DCBB906557E6D00BC4809 = { + fileRef = 1D8DCBB706557E6D00BC4809; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED430652D22A00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = journal.cpp; + path = ../tnl/journal.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED440652D22A00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlJournal.h; + path = ../tnl/tnlJournal.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED450652D22A00BDEE0B = { + fileRef = 1DC6ED430652D22A00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED460652D22A00BDEE0B = { + fileRef = 1DC6ED440652D22A00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED470652D24B00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = gsm_decode.c; + path = ../zap/gsm_decode.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED480652D24B00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = gsm_encode.c; + path = ../zap/gsm_encode.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED490652D24B00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = gsm_state.c; + path = ../zap/gsm_state.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED4A0652D24B00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gsm.h; + path = ../zap/gsm.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED4B0652D24B00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = voiceCodec.cpp; + path = ../zap/voiceCodec.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED4C0652D24B00BDEE0B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = voiceCodec.h; + path = ../zap/voiceCodec.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC6ED4D0652D24B00BDEE0B = { + fileRef = 1DC6ED470652D24B00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED4E0652D24B00BDEE0B = { + fileRef = 1DC6ED480652D24B00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED4F0652D24B00BDEE0B = { + fileRef = 1DC6ED490652D24B00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED500652D24B00BDEE0B = { + fileRef = 1DC6ED4A0652D24B00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED510652D24B00BDEE0B = { + fileRef = 1DC6ED4B0652D24B00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC6ED520652D24B00BDEE0B = { + fileRef = 1DC6ED4C0652D24B00BDEE0B; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC82046064C5C9000F61B0E = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = tnlMethodDispatch.cpp; + path = ../tnl/tnlMethodDispatch.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC82047064C5C9000F61B0E = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlMethodDispatch.h; + path = ../tnl/tnlMethodDispatch.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC82048064C5C9000F61B0E = { + fileRef = 1DC82046064C5C9000F61B0E; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC82049064C5C9000F61B0E = { + fileRef = 1DC82047064C5C9000F61B0E; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC8204A064C5CBC00F61B0E = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = lpc10.h; + path = ../zap/lpc10.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC8204B064C5CBC00F61B0E = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = lpc10dec.c; + path = ../zap/lpc10dec.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC8204C064C5CBC00F61B0E = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = lpc10enc.c; + path = ../zap/lpc10enc.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DC8204D064C5CBC00F61B0E = { + fileRef = 1DC8204A064C5CBC00F61B0E; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC8204E064C5CBC00F61B0E = { + fileRef = 1DC8204B064C5CBC00F61B0E; + isa = PBXBuildFile; + settings = { + }; + }; + 1DC8204F064C5CBC00F61B0E = { + fileRef = 1DC8204C064C5CBC00F61B0E; + isa = PBXBuildFile; + settings = { + }; + }; + 1DD229E2070B4A02000DFF1F = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = HTFGame.cpp; + path = ../zap/HTFGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DD229E3070B4A02000DFF1F = { + fileRef = 1DD229E2070B4A02000DFF1F; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC6906909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = engineeredObjects.cpp; + path = ../zap/engineeredObjects.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC6A06909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = engineeredObjects.h; + path = ../zap/engineeredObjects.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC6B06909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = flagItem.cpp; + path = ../zap/flagItem.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC6C06909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = footballGame.cpp; + path = ../zap/footballGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC6D06909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameObjectRender.cpp; + path = ../zap/gameObjectRender.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC6E06909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameObjectRender.h; + path = ../zap/gameObjectRender.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC6F06909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = huntersGame.cpp; + path = ../zap/huntersGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7006909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = huntersGame.h; + path = ../zap/huntersGame.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7106909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = LoadoutZone.cpp; + path = ../zap/LoadoutZone.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7206909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = rabbitGame.cpp; + path = ../zap/rabbitGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7306909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = rabbitGame.h; + path = ../zap/rabbitGame.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7406909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UIInstructions.cpp; + path = ../zap/UIInstructions.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7506909AB400D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UIInstructions.h; + path = ../zap/UIInstructions.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EC7606909AB400D93C76 = { + fileRef = 1DE1EC6906909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7706909AB400D93C76 = { + fileRef = 1DE1EC6A06909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7806909AB400D93C76 = { + fileRef = 1DE1EC6B06909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7906909AB400D93C76 = { + fileRef = 1DE1EC6C06909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7A06909AB400D93C76 = { + fileRef = 1DE1EC6D06909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7B06909AB400D93C76 = { + fileRef = 1DE1EC6E06909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7C06909AB400D93C76 = { + fileRef = 1DE1EC6F06909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7D06909AB400D93C76 = { + fileRef = 1DE1EC7006909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7E06909AB400D93C76 = { + fileRef = 1DE1EC7106909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC7F06909AB400D93C76 = { + fileRef = 1DE1EC7206909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC8006909AB400D93C76 = { + fileRef = 1DE1EC7306909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC8106909AB400D93C76 = { + fileRef = 1DE1EC7406909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EC8206909AB400D93C76 = { + fileRef = 1DE1EC7506909AB400D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1ED0B06909D0A00D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameWeapons.cpp; + path = ../zap/gameWeapons.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1ED0C06909D0A00D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameWeapons.h; + path = ../zap/gameWeapons.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1ED0D06909D0A00D93C76 = { + fileRef = 1DE1ED0B06909D0A00D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1ED0E06909D0A00D93C76 = { + fileRef = 1DE1ED0C06909D0A00D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1ED3306909FA300D93C76 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Carbon.framework; + path = /System/Library/Frameworks/Carbon.framework; + refType = 0; + sourceTree = ""; + }; + 1DE1ED3406909FA300D93C76 = { + fileRef = 1DE1ED3306909FA300D93C76; + isa = PBXBuildFile; + settings = { + }; + }; + 1DE1EDF40690BA1600D93C76 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = osxInput.cpp; + path = ../zap/osxInput.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 1DE1EDF50690BA1600D93C76 = { + fileRef = 1DE1EDF40690BA1600D93C76; + isa = PBXBuildFile; + settings = { + }; + }; +//1D0 +//1D1 +//1D2 +//1D3 +//1D4 +//290 +//291 +//292 +//293 +//294 + 29B97313FDCFA39411CA2CEA = { + buildSettings = { + }; + buildStyles = ( + 4A9504CCFFE6A4B311CA0CBA, + 4A9504CDFFE6A4B311CA0CBA, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = 29B97314FDCFA39411CA2CEA; + projectDirPath = ""; + targets = ( + 8D1107260486CEB800E47090, + 66D85E1805ACBA97008DC9C1, + 66D85EDD05ACCC36008DC9C1, + 6649E0D505FD01D700B3DD8B, + 66BA0E5B05FD467E00D882FA, + 66BA0E8805FD473200D882FA, + 6692C08706247BE000D5ADFE, + ); + }; + 29B97314FDCFA39411CA2CEA = { + children = ( + 29B97315FDCFA39411CA2CEA, + 29B97317FDCFA39411CA2CEA, + 29B97323FDCFA39411CA2CEA, + 19C28FACFE9D520D11CA2CBB, + ); + isa = PBXGroup; + name = TNLTest; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA = { + children = ( + 6692C0E606247C3B00D5ADFE, + 66BA0EA905FD479700D882FA, + 6649E0F805FD023500B3DD8B, + 6649E0F305FD022D00B3DD8B, + 6649E0EE05FD022100B3DD8B, + 6649E0E705FD020E00B3DD8B, + ); + isa = PBXGroup; + name = "Source Files"; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA = { + children = ( + 8D1107310486CEB800E47090, + 089C165CFE840E0CC02AAC07, + 29B97318FDCFA39411CA2CEA, + ); + isa = PBXGroup; + name = Resources; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97318FDCFA39411CA2CEA = { + children = ( + 29B97319FDCFA39411CA2CEA, + ); + isa = PBXVariantGroup; + name = MainMenu.nib; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97319FDCFA39411CA2CEA = { + isa = PBXFileReference; + lastKnownFileType = wrapper.nib; + name = English; + path = English.lproj/MainMenu.nib; + refType = 4; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA = { + children = ( + 1D49BD0C0691F71200643C72, + 1DE1ED3306909FA300D93C76, + DB9525CF0636109800B8795E, + 6656DD9B0635C8EF00E30126, + 6692C11906247CF900D5ADFE, + 1058C7A0FEA54F0111CA2CBB, + 1058C7A2FEA54F0111CA2CBB, + ); + isa = PBXGroup; + name = Frameworks; + path = ""; + refType = 4; + sourceTree = ""; + }; + 29B97324FDCFA39411CA2CEA = { + fallbackIsa = PBXFileReference; + isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; + name = AppKit.framework; + path = /System/Library/Frameworks/AppKit.framework; + refType = 0; + sourceTree = ""; + }; + 29B97325FDCFA39411CA2CEA = { + fallbackIsa = PBXFileReference; + isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; + name = Foundation.framework; + path = /System/Library/Frameworks/Foundation.framework; + refType = 0; + sourceTree = ""; + }; +//290 +//291 +//292 +//293 +//294 +//4A0 +//4A1 +//4A2 +//4A3 +//4A4 + 4A9504CCFFE6A4B311CA0CBA = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OPTIMIZATION_CFLAGS = "-O0"; + ZERO_LINK = YES; + }; + isa = PBXBuildStyle; + name = Development; + }; + 4A9504CDFFE6A4B311CA0CBA = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + ZERO_LINK = NO; + }; + isa = PBXBuildStyle; + name = Deployment; + }; +//4A0 +//4A1 +//4A2 +//4A3 +//4A4 +//660 +//661 +//662 +//663 +//664 + 6645D4C305ACD81600EFFB5D = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.objcpp; + path = main.mm; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6645D4C405ACD81600EFFB5D = { + fileRef = 6645D4C305ACD81600EFFB5D; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E0D305FD01D700B3DD8B = { + buildActionMask = 2147483647; + files = ( + 6649E1A005FD02BA00B3DD8B, + 6649E1A105FD02BA00B3DD8B, + 6649E1A205FD02BA00B3DD8B, + 6649E1A305FD02BA00B3DD8B, + 6649E1A405FD02BA00B3DD8B, + 6649E1A505FD02BA00B3DD8B, + 6649E1A605FD02BA00B3DD8B, + 6649E1A705FD02BA00B3DD8B, + 6649E1A805FD02BA00B3DD8B, + 6649E1A905FD02BA00B3DD8B, + 6649E1AA05FD02BA00B3DD8B, + 6649E1AB05FD02BA00B3DD8B, + 6649E1C505FD02BA00B3DD8B, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6649E0D405FD01D700B3DD8B = { + buildActionMask = 2147483647; + files = ( + 6649E18705FD02BA00B3DD8B, + 6649E18805FD02BA00B3DD8B, + 6649E18905FD02BA00B3DD8B, + 6649E18A05FD02BA00B3DD8B, + 6649E18B05FD02BA00B3DD8B, + 6649E18C05FD02BA00B3DD8B, + 6649E18D05FD02BA00B3DD8B, + 6649E18E05FD02BA00B3DD8B, + 6649E18F05FD02BA00B3DD8B, + 6649E19005FD02BA00B3DD8B, + 6649E19205FD02BA00B3DD8B, + 6649E19305FD02BA00B3DD8B, + 6649E19405FD02BA00B3DD8B, + 6649E19605FD02BA00B3DD8B, + 6649E19705FD02BA00B3DD8B, + 6649E19805FD02BA00B3DD8B, + 6649E19905FD02BA00B3DD8B, + 6649E19A05FD02BA00B3DD8B, + 6649E19B05FD02BA00B3DD8B, + 6649E19C05FD02BA00B3DD8B, + 6649E19D05FD02BA00B3DD8B, + 6649E19E05FD02BA00B3DD8B, + 6649E19F05FD02BA00B3DD8B, + 6649E1AC05FD02BA00B3DD8B, + 6649E1AD05FD02BA00B3DD8B, + 6649E1AE05FD02BA00B3DD8B, + 6649E1AF05FD02BA00B3DD8B, + 6649E1B005FD02BA00B3DD8B, + 6649E1B105FD02BA00B3DD8B, + 6649E1B205FD02BA00B3DD8B, + 6649E1B305FD02BA00B3DD8B, + 6649E1B405FD02BA00B3DD8B, + 6649E1B505FD02BA00B3DD8B, + 6649E1B605FD02BA00B3DD8B, + 6649E1B805FD02BA00B3DD8B, + 6649E1B905FD02BA00B3DD8B, + 6649E1BA05FD02BA00B3DD8B, + 6649E1BB05FD02BA00B3DD8B, + 6649E1BC05FD02BA00B3DD8B, + 6649E1BE05FD02BA00B3DD8B, + 6649E1C005FD02BA00B3DD8B, + 6649E1C105FD02BA00B3DD8B, + 6649E1C205FD02BA00B3DD8B, + 6649E1C305FD02BA00B3DD8B, + 6649E1C405FD02BA00B3DD8B, + 6649E1C705FD02BA00B3DD8B, + 6649E1C805FD02BA00B3DD8B, + 6649E1C905FD02BA00B3DD8B, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6649E0D505FD01D700B3DD8B = { + buildPhases = ( + 6649E0D305FD01D700B3DD8B, + 6649E0D405FD01D700B3DD8B, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = /usr/include; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = libtomcrypt; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = libtomcrypt; + productName = libtomcrypt; + productReference = 6649E0D605FD01D700B3DD8B; + productType = "com.apple.product-type.library.static"; + }; + 6649E0D605FD01D700B3DD8B = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = liblibtomcrypt.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6649E0E705FD020E00B3DD8B = { + children = ( + 6649E14205FD02BA00B3DD8B, + 6649E14305FD02BA00B3DD8B, + 6649E14405FD02BA00B3DD8B, + 6649E14505FD02BA00B3DD8B, + 6649E14605FD02BA00B3DD8B, + 6649E14705FD02BA00B3DD8B, + 6649E14805FD02BA00B3DD8B, + 6649E14905FD02BA00B3DD8B, + 6649E14A05FD02BA00B3DD8B, + 6649E14B05FD02BA00B3DD8B, + 6649E14C05FD02BA00B3DD8B, + 6649E14D05FD02BA00B3DD8B, + 6649E14E05FD02BA00B3DD8B, + 6649E14F05FD02BA00B3DD8B, + 6649E15005FD02BA00B3DD8B, + 6649E15105FD02BA00B3DD8B, + 6649E15205FD02BA00B3DD8B, + 6649E15305FD02BA00B3DD8B, + 6649E15405FD02BA00B3DD8B, + 6649E15505FD02BA00B3DD8B, + 6649E15605FD02BA00B3DD8B, + 6649E15705FD02BA00B3DD8B, + 6649E15805FD02BA00B3DD8B, + 6649E15905FD02BA00B3DD8B, + 6649E15A05FD02BA00B3DD8B, + 6649E15B05FD02BA00B3DD8B, + 6649E15C05FD02BA00B3DD8B, + 6649E15D05FD02BA00B3DD8B, + 6649E15E05FD02BA00B3DD8B, + 6649E15F05FD02BA00B3DD8B, + 6649E16005FD02BA00B3DD8B, + 6649E16105FD02BA00B3DD8B, + 6649E16205FD02BA00B3DD8B, + 6649E16305FD02BA00B3DD8B, + 6649E16405FD02BA00B3DD8B, + 6649E16505FD02BA00B3DD8B, + 6649E16605FD02BA00B3DD8B, + 6649E16705FD02BA00B3DD8B, + 6649E16805FD02BA00B3DD8B, + 6649E16905FD02BA00B3DD8B, + 6649E16A05FD02BA00B3DD8B, + 6649E16B05FD02BA00B3DD8B, + 6649E16C05FD02BA00B3DD8B, + 6649E16D05FD02BA00B3DD8B, + 6649E16E05FD02BA00B3DD8B, + 6649E16F05FD02BA00B3DD8B, + 6649E17005FD02BA00B3DD8B, + 6649E17105FD02BA00B3DD8B, + 6649E17205FD02BA00B3DD8B, + 6649E17305FD02BA00B3DD8B, + 6649E17405FD02BA00B3DD8B, + 6649E17505FD02BA00B3DD8B, + 6649E17605FD02BA00B3DD8B, + 6649E17705FD02BA00B3DD8B, + 6649E17805FD02BA00B3DD8B, + 6649E17905FD02BA00B3DD8B, + 6649E17A05FD02BA00B3DD8B, + 6649E17B05FD02BA00B3DD8B, + 6649E17C05FD02BA00B3DD8B, + 6649E17D05FD02BA00B3DD8B, + 6649E17E05FD02BA00B3DD8B, + 6649E17F05FD02BA00B3DD8B, + 6649E18005FD02BA00B3DD8B, + 6649E18105FD02BA00B3DD8B, + 6649E18205FD02BA00B3DD8B, + 6649E18305FD02BA00B3DD8B, + 6649E18405FD02BA00B3DD8B, + 6649E18505FD02BA00B3DD8B, + ); + isa = PBXGroup; + name = libtomcrypt; + refType = 4; + sourceTree = ""; + }; + 6649E0EE05FD022100B3DD8B = { + children = ( + 1DC6ED430652D22A00BDEE0B, + 1DC6ED440652D22A00BDEE0B, + 1DC82046064C5C9000F61B0E, + 1DC82047064C5C9000F61B0E, + DB9525E3063610C200B8795E, + 66BA0CE005FD17F600D882FA, + 66BA0CE105FD17F600D882FA, + 66BA0CE205FD17F600D882FA, + 66BA0CE305FD17F600D882FA, + 66BA0C4A05FD107700D882FA, + 66BA0C4B05FD107700D882FA, + 66BA0C4C05FD107700D882FA, + 66BA0C4D05FD107700D882FA, + 66BA0C4E05FD107700D882FA, + 66BA0C4F05FD107700D882FA, + 66BA0C5005FD107700D882FA, + 66BA0C5105FD107700D882FA, + 66BA0C5205FD107700D882FA, + 66BA0C5305FD107700D882FA, + 66BA0C5405FD107700D882FA, + 66BA0C5505FD107700D882FA, + 66BA0C5605FD107700D882FA, + 66BA0C5705FD107700D882FA, + 66BA0C5805FD107700D882FA, + 66BA0C5905FD107700D882FA, + 66BA0C5A05FD107700D882FA, + 66BA0C5B05FD107700D882FA, + 66BA0C5C05FD107700D882FA, + 66BA0C5D05FD107700D882FA, + 66BA0C5E05FD107700D882FA, + 66BA0C5F05FD107700D882FA, + 66BA0C6005FD107700D882FA, + 66BA0C6105FD107700D882FA, + 66BA0C6205FD107700D882FA, + 66BA0C6305FD107700D882FA, + 66BA0C6405FD107700D882FA, + 66BA0C6505FD107700D882FA, + 6661401905B3966700320653, + 66D85E5C05ACCB91008DC9C1, + 6661401205B3965A00320653, + 66D85E9305ACCBBA008DC9C1, + 66D85E9405ACCBBA008DC9C1, + 66D85E9505ACCBBA008DC9C1, + 66D85E9605ACCBBA008DC9C1, + 66D85E9705ACCBBA008DC9C1, + 66D85E9905ACCBBA008DC9C1, + 66D85E9C05ACCBBA008DC9C1, + 66D85E9D05ACCBBA008DC9C1, + 66D85E9E05ACCBBA008DC9C1, + 66D85E9F05ACCBBA008DC9C1, + 66D85EA005ACCBBA008DC9C1, + 66D85EA105ACCBBA008DC9C1, + 66D85EA205ACCBBA008DC9C1, + 66D85EA305ACCBBA008DC9C1, + 66D85EA405ACCBBA008DC9C1, + 66D85EA505ACCBBA008DC9C1, + ); + isa = PBXGroup; + name = tnl; + refType = 4; + sourceTree = ""; + }; + 6649E0F305FD022D00B3DD8B = { + children = ( + 66BA0E7705FD46F600D882FA, + 66BA0E7805FD46F600D882FA, + 66BA0E7905FD46F600D882FA, + ); + isa = PBXGroup; + name = master; + refType = 4; + sourceTree = ""; + }; + 6649E0F805FD023500B3DD8B = { + children = ( + 6645D4C305ACD81600EFFB5D, + 66D85EE605ACCC6A008DC9C1, + 66D85DB705ACA1F0008DC9C1, + 66D85C9105AC8DC7008DC9C1, + 66D85C1E05AC8772008DC9C1, + 66D85C1F05AC8772008DC9C1, + 66D85C2005AC8772008DC9C1, + ); + isa = PBXGroup; + name = test; + refType = 4; + sourceTree = ""; + }; + 6649E14205FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = aes_tab.c; + path = ../libtomcrypt/aes_tab.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14305FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = aes.c; + path = ../libtomcrypt/aes.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14405FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = base64.c; + path = ../libtomcrypt/base64.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14505FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = bits.c; + path = ../libtomcrypt/bits.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14605FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = blowfish.c; + path = ../libtomcrypt/blowfish.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14705FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = cast5.c; + path = ../libtomcrypt/cast5.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14805FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = cbc.c; + path = ../libtomcrypt/cbc.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14905FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = cfb.c; + path = ../libtomcrypt/cfb.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14A05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = crypt.c; + path = ../libtomcrypt/crypt.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14B05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = ctr.c; + path = ../libtomcrypt/ctr.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14C05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = des.c; + path = ../libtomcrypt/des.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14D05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = dh_sys.c; + path = ../libtomcrypt/dh_sys.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14E05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = dh.c; + path = ../libtomcrypt/dh.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E14F05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = dsa.c; + path = ../libtomcrypt/dsa.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15005FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = ecb.c; + path = ../libtomcrypt/ecb.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15105FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = ecc_sys.c; + path = ../libtomcrypt/ecc_sys.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15205FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = ecc.c; + path = ../libtomcrypt/ecc.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15305FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = gf.c; + path = ../libtomcrypt/gf.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15405FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = hash.c; + path = ../libtomcrypt/hash.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15505FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = hmac.c; + path = ../libtomcrypt/hmac.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15605FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = keyring.c; + path = ../libtomcrypt/keyring.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15705FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = md2.c; + path = ../libtomcrypt/md2.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15805FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = md4.c; + path = ../libtomcrypt/md4.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15905FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = md5.c; + path = ../libtomcrypt/md5.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15A05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = mem.c; + path = ../libtomcrypt/mem.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15B05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = mpi.c; + path = ../libtomcrypt/mpi.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15C05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_argchk.h; + path = ../libtomcrypt/mycrypt_argchk.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15D05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_cfg.h; + path = ../libtomcrypt/mycrypt_cfg.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15E05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_cipher.h; + path = ../libtomcrypt/mycrypt_cipher.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E15F05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_custom.h; + path = ../libtomcrypt/mycrypt_custom.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16005FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_gf.h; + path = ../libtomcrypt/mycrypt_gf.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16105FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_hash.h; + path = ../libtomcrypt/mycrypt_hash.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16205FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_kr.h; + path = ../libtomcrypt/mycrypt_kr.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16305FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_macros.h; + path = ../libtomcrypt/mycrypt_macros.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16405FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_misc.h; + path = ../libtomcrypt/mycrypt_misc.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16505FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_pk.h; + path = ../libtomcrypt/mycrypt_pk.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16605FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt_prng.h; + path = ../libtomcrypt/mycrypt_prng.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16705FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = mycrypt.h; + path = ../libtomcrypt/mycrypt.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16805FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = noekeon.c; + path = ../libtomcrypt/noekeon.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16905FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = ofb.c; + path = ../libtomcrypt/ofb.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16A05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = omac.c; + path = ../libtomcrypt/omac.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16B05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = packet.c; + path = ../libtomcrypt/packet.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16C05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = prime.c; + path = ../libtomcrypt/prime.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16D05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rc2.c; + path = ../libtomcrypt/rc2.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16E05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rc4.c; + path = ../libtomcrypt/rc4.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E16F05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rc5.c; + path = ../libtomcrypt/rc5.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17005FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rc6.c; + path = ../libtomcrypt/rc6.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17105FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rmd128.c; + path = ../libtomcrypt/rmd128.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17205FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rmd160.c; + path = ../libtomcrypt/rmd160.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17305FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rsa_sys.c; + path = ../libtomcrypt/rsa_sys.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17405FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rsa.c; + path = ../libtomcrypt/rsa.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17505FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = safer_tab.c; + path = ../libtomcrypt/safer_tab.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17605FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = safer.c; + path = ../libtomcrypt/safer.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17705FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = "safer+.c"; + path = "../libtomcrypt/safer+.c"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17805FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sha1.c; + path = ../libtomcrypt/sha1.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17905FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sha224.c; + path = ../libtomcrypt/sha224.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17A05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sha256.c; + path = ../libtomcrypt/sha256.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17B05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sha384.c; + path = ../libtomcrypt/sha384.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17C05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sha512.c; + path = ../libtomcrypt/sha512.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17D05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = skipjack.c; + path = ../libtomcrypt/skipjack.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17E05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = sprng.c; + path = ../libtomcrypt/sprng.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E17F05FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = strings.c; + path = ../libtomcrypt/strings.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18005FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tiger.c; + path = ../libtomcrypt/tiger.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18105FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tommath.h; + path = ../libtomcrypt/tommath.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18205FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = twofish_tab.c; + path = ../libtomcrypt/twofish_tab.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18305FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = twofish.c; + path = ../libtomcrypt/twofish.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18405FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = xtea.c; + path = ../libtomcrypt/xtea.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18505FD02BA00B3DD8B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = yarrow.c; + path = ../libtomcrypt/yarrow.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6649E18705FD02BA00B3DD8B = { + fileRef = 6649E14305FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18805FD02BA00B3DD8B = { + fileRef = 6649E14405FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18905FD02BA00B3DD8B = { + fileRef = 6649E14505FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18A05FD02BA00B3DD8B = { + fileRef = 6649E14605FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18B05FD02BA00B3DD8B = { + fileRef = 6649E14705FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18C05FD02BA00B3DD8B = { + fileRef = 6649E14805FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18D05FD02BA00B3DD8B = { + fileRef = 6649E14905FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18E05FD02BA00B3DD8B = { + fileRef = 6649E14A05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E18F05FD02BA00B3DD8B = { + fileRef = 6649E14B05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19005FD02BA00B3DD8B = { + fileRef = 6649E14C05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19205FD02BA00B3DD8B = { + fileRef = 6649E14E05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19305FD02BA00B3DD8B = { + fileRef = 6649E14F05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19405FD02BA00B3DD8B = { + fileRef = 6649E15005FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19605FD02BA00B3DD8B = { + fileRef = 6649E15205FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19705FD02BA00B3DD8B = { + fileRef = 6649E15305FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19805FD02BA00B3DD8B = { + fileRef = 6649E15405FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19905FD02BA00B3DD8B = { + fileRef = 6649E15505FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19A05FD02BA00B3DD8B = { + fileRef = 6649E15605FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19B05FD02BA00B3DD8B = { + fileRef = 6649E15705FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19C05FD02BA00B3DD8B = { + fileRef = 6649E15805FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19D05FD02BA00B3DD8B = { + fileRef = 6649E15905FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19E05FD02BA00B3DD8B = { + fileRef = 6649E15A05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E19F05FD02BA00B3DD8B = { + fileRef = 6649E15B05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A005FD02BA00B3DD8B = { + fileRef = 6649E15C05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + ); + }; + }; + 6649E1A105FD02BA00B3DD8B = { + fileRef = 6649E15D05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A205FD02BA00B3DD8B = { + fileRef = 6649E15E05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A305FD02BA00B3DD8B = { + fileRef = 6649E15F05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A405FD02BA00B3DD8B = { + fileRef = 6649E16005FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A505FD02BA00B3DD8B = { + fileRef = 6649E16105FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A605FD02BA00B3DD8B = { + fileRef = 6649E16205FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A705FD02BA00B3DD8B = { + fileRef = 6649E16305FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A805FD02BA00B3DD8B = { + fileRef = 6649E16405FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1A905FD02BA00B3DD8B = { + fileRef = 6649E16505FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1AA05FD02BA00B3DD8B = { + fileRef = 6649E16605FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1AB05FD02BA00B3DD8B = { + fileRef = 6649E16705FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1AC05FD02BA00B3DD8B = { + fileRef = 6649E16805FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1AD05FD02BA00B3DD8B = { + fileRef = 6649E16905FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1AE05FD02BA00B3DD8B = { + fileRef = 6649E16A05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1AF05FD02BA00B3DD8B = { + fileRef = 6649E16B05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B005FD02BA00B3DD8B = { + fileRef = 6649E16C05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B105FD02BA00B3DD8B = { + fileRef = 6649E16D05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B205FD02BA00B3DD8B = { + fileRef = 6649E16E05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B305FD02BA00B3DD8B = { + fileRef = 6649E16F05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B405FD02BA00B3DD8B = { + fileRef = 6649E17005FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B505FD02BA00B3DD8B = { + fileRef = 6649E17105FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B605FD02BA00B3DD8B = { + fileRef = 6649E17205FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B805FD02BA00B3DD8B = { + fileRef = 6649E17405FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1B905FD02BA00B3DD8B = { + fileRef = 6649E17505FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1BA05FD02BA00B3DD8B = { + fileRef = 6649E17605FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1BB05FD02BA00B3DD8B = { + fileRef = 6649E17705FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1BC05FD02BA00B3DD8B = { + fileRef = 6649E17805FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1BE05FD02BA00B3DD8B = { + fileRef = 6649E17A05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C005FD02BA00B3DD8B = { + fileRef = 6649E17C05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C105FD02BA00B3DD8B = { + fileRef = 6649E17D05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C205FD02BA00B3DD8B = { + fileRef = 6649E17E05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C305FD02BA00B3DD8B = { + fileRef = 6649E17F05FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C405FD02BA00B3DD8B = { + fileRef = 6649E18005FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C505FD02BA00B3DD8B = { + fileRef = 6649E18105FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C705FD02BA00B3DD8B = { + fileRef = 6649E18305FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C805FD02BA00B3DD8B = { + fileRef = 6649E18405FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6649E1C905FD02BA00B3DD8B = { + fileRef = 6649E18505FD02BA00B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DD850635C66F00E30126 = { + fileRef = 66D85E1905ACBA97008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DD9B0635C8EF00E30126 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = OpenAL.framework; + path = /Library/Frameworks/OpenAL.framework; + refType = 0; + sourceTree = ""; + }; + 6656DD9C0635C8EF00E30126 = { + fileRef = 6656DD9B0635C8EF00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDCA0635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = CTFGame.cpp; + path = ../zap/CTFGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDCB0635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = CTFGame.h; + path = ../zap/CTFGame.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDCC0635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameType.cpp; + path = ../zap/gameType.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDCD0635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameType.h; + path = ../zap/gameType.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDCE0635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = item.cpp; + path = ../zap/item.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDCF0635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = item.h; + path = ../zap/item.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDD00635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = moveObject.cpp; + path = ../zap/moveObject.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDD10635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = moveObject.h; + path = ../zap/moveObject.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDD20635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = sfx.cpp; + path = ../zap/sfx.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDD30635C95C00E30126 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = sfx.h; + path = ../zap/sfx.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6656DDD40635C95C00E30126 = { + fileRef = 6656DDCA0635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDD50635C95C00E30126 = { + fileRef = 6656DDCB0635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDD60635C95C00E30126 = { + fileRef = 6656DDCC0635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDD70635C95C00E30126 = { + fileRef = 6656DDCD0635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDD80635C95C00E30126 = { + fileRef = 6656DDCE0635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDD90635C95C00E30126 = { + fileRef = 6656DDCF0635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDDA0635C95C00E30126 = { + fileRef = 6656DDD00635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDDB0635C95C00E30126 = { + fileRef = 6656DDD10635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDDC0635C95C00E30126 = { + fileRef = 6656DDD20635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6656DDDD0635C95C00E30126 = { + fileRef = 6656DDD30635C95C00E30126; + isa = PBXBuildFile; + settings = { + }; + }; + 6661401205B3965A00320653 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = udp.cpp; + path = ../tnl/udp.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6661401405B3965A00320653 = { + fileRef = 6661401205B3965A00320653; + isa = PBXBuildFile; + settings = { + }; + }; + 6661401905B3966700320653 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = platform.cpp; + path = ../tnl/platform.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6661401A05B3966700320653 = { + fileRef = 6661401905B3966700320653; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C08506247BE000D5ADFE = { + buildActionMask = 2147483647; + files = ( + 6692C0AB06247C2300D5ADFE, + 6692C0AD06247C2300D5ADFE, + 6692C0B206247C2300D5ADFE, + 6692C0B306247C2300D5ADFE, + 6692C0B506247C2300D5ADFE, + 6692C0B706247C2300D5ADFE, + 6692C0B906247C2300D5ADFE, + 6692C0BB06247C2300D5ADFE, + 6692C0BD06247C2300D5ADFE, + 6692C0BF06247C2300D5ADFE, + 6692C0C106247C2300D5ADFE, + 6692C0C306247C2300D5ADFE, + 6692C0C506247C2300D5ADFE, + 6692C18B06247DB900D5ADFE, + 6692C23A0625E7E800D5ADFE, + 6692C23C0625E7E800D5ADFE, + 6692C23E0625E7E800D5ADFE, + 6692C2400625E7E800D5ADFE, + 6692C2420625E7E800D5ADFE, + 6692C2440625E7E800D5ADFE, + 6656DDD50635C95C00E30126, + 6656DDD70635C95C00E30126, + 6656DDD90635C95C00E30126, + 6656DDDB0635C95C00E30126, + 6656DDDD0635C95C00E30126, + DB997D2C0638AFC1002745B0, + DBAFF49C06471A4200683BA4, + DBAFF4AA06471AAE00683BA4, + 1DC8204D064C5CBC00F61B0E, + 1DC6ED500652D24B00BDEE0B, + 1DC6ED520652D24B00BDEE0B, + 1D8DCBB906557E6D00BC4809, + 1D3E3EEC0666A7EE005D645B, + 1D3E3EF00666A871005D645B, + 1DE1EC7706909AB400D93C76, + 1DE1EC7B06909AB400D93C76, + 1DE1EC7D06909AB400D93C76, + 1DE1EC8006909AB400D93C76, + 1DE1EC8206909AB400D93C76, + 1DE1ED0E06909D0A00D93C76, + 1D49BDC80691F8E000643C72, + 1D3CACCD0694D76300313D6F, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6692C08606247BE000D5ADFE = { + buildActionMask = 2147483647; + files = ( + 6692C0AA06247C2300D5ADFE, + 6692C0AC06247C2300D5ADFE, + 6692C0B006247C2300D5ADFE, + 6692C0B106247C2300D5ADFE, + 6692C0B406247C2300D5ADFE, + 6692C0B606247C2300D5ADFE, + 6692C0B806247C2300D5ADFE, + 6692C0BA06247C2300D5ADFE, + 6692C0BC06247C2300D5ADFE, + 6692C0BE06247C2300D5ADFE, + 6692C0C006247C2300D5ADFE, + 6692C0C206247C2300D5ADFE, + 6692C0C406247C2300D5ADFE, + 6692C1FA06247F2000D5ADFE, + 6692C2390625E7E800D5ADFE, + 6692C23B0625E7E800D5ADFE, + 6692C23D0625E7E800D5ADFE, + 6692C23F0625E7E800D5ADFE, + 6692C2410625E7E800D5ADFE, + 6692C2430625E7E800D5ADFE, + 6656DDD40635C95C00E30126, + 6656DDD60635C95C00E30126, + 6656DDD80635C95C00E30126, + 6656DDDA0635C95C00E30126, + 6656DDDC0635C95C00E30126, + DB997D2A0638AFC1002745B0, + DB997D2B0638AFC1002745B0, + DBAFF49B06471A4200683BA4, + DBAFF4A906471AAE00683BA4, + 1DC8204E064C5CBC00F61B0E, + 1DC8204F064C5CBC00F61B0E, + 1DC6ED4D0652D24B00BDEE0B, + 1DC6ED4E0652D24B00BDEE0B, + 1DC6ED4F0652D24B00BDEE0B, + 1DC6ED510652D24B00BDEE0B, + 1D8DCBB806557E6D00BC4809, + 1D3E3EEB0666A7EE005D645B, + 1D3E3EEF0666A871005D645B, + 1DE1EC7606909AB400D93C76, + 1DE1EC7806909AB400D93C76, + 1DE1EC7906909AB400D93C76, + 1DE1EC7A06909AB400D93C76, + 1DE1EC7C06909AB400D93C76, + 1DE1EC7E06909AB400D93C76, + 1DE1EC7F06909AB400D93C76, + 1DE1EC8106909AB400D93C76, + 1DE1ED0D06909D0A00D93C76, + 1DE1EDF50690BA1600D93C76, + 1D49BDC70691F8E000643C72, + 1D3CACCC0694D76300313D6F, + 1D3CACCE0694D76300313D6F, + 1DD229E3070B4A02000DFF1F, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6692C08706247BE000D5ADFE = { + buildPhases = ( + 6692C08506247BE000D5ADFE, + 6692C08606247BE000D5ADFE, + 6692C15706247D1800D5ADFE, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = "../glut ../openal"; + INSTALL_PATH = ""; + MACOSX_DEPLOYMENT_TARGET = 10.2; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = "-lobjc"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = ZAP; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = ZAP; + productName = ZAP; + productReference = 6692C08806247BE000D5ADFE; + productType = "com.apple.product-type.tool"; + }; + 6692C08806247BE000D5ADFE = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = ZAP; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 6692C08E06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameConnection.cpp; + path = ../zap/gameConnection.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C08F06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameConnection.h; + path = ../zap/gameConnection.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09006247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameNetInterface.cpp; + path = ../zap/gameNetInterface.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09106247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameNetInterface.h; + path = ../zap/gameNetInterface.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09406247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = main.cpp; + path = ../zap/main.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09506247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = masterConnection.cpp; + path = ../zap/masterConnection.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09606247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = masterConnection.h; + path = ../zap/masterConnection.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09706247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = point.h; + path = ../zap/point.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09806247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = projectile.cpp; + path = ../zap/projectile.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09906247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = projectile.h; + path = ../zap/projectile.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09A06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ship.cpp; + path = ../zap/ship.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09B06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = ship.h; + path = ../zap/ship.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09C06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = sparkManager.cpp; + path = ../zap/sparkManager.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09D06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = sparkManager.h; + path = ../zap/sparkManager.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09E06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = SweptEllipsoid.cpp; + path = ../zap/SweptEllipsoid.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C09F06247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = SweptEllipsoid.h; + path = ../zap/SweptEllipsoid.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A006247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UI.cpp; + path = ../zap/UI.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A106247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UI.h; + path = ../zap/UI.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A206247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UIGame.cpp; + path = ../zap/UIGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A306247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UIGame.h; + path = ../zap/UIGame.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A406247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UIMenus.cpp; + path = ../zap/UIMenus.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A506247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UIMenus.h; + path = ../zap/UIMenus.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A606247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UINameEntry.cpp; + path = ../zap/UINameEntry.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A706247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UINameEntry.h; + path = ../zap/UINameEntry.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A806247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UIQueryServers.cpp; + path = ../zap/UIQueryServers.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0A906247C2300D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UIQueryServers.h; + path = ../zap/UIQueryServers.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C0AA06247C2300D5ADFE = { + fileRef = 6692C08E06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0AB06247C2300D5ADFE = { + fileRef = 6692C08F06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0AC06247C2300D5ADFE = { + fileRef = 6692C09006247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0AD06247C2300D5ADFE = { + fileRef = 6692C09106247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B006247C2300D5ADFE = { + fileRef = 6692C09406247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B106247C2300D5ADFE = { + fileRef = 6692C09506247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B206247C2300D5ADFE = { + fileRef = 6692C09606247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B306247C2300D5ADFE = { + fileRef = 6692C09706247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B406247C2300D5ADFE = { + fileRef = 6692C09806247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B506247C2300D5ADFE = { + fileRef = 6692C09906247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B606247C2300D5ADFE = { + fileRef = 6692C09A06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B706247C2300D5ADFE = { + fileRef = 6692C09B06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B806247C2300D5ADFE = { + fileRef = 6692C09C06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0B906247C2300D5ADFE = { + fileRef = 6692C09D06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0BA06247C2300D5ADFE = { + fileRef = 6692C09E06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0BB06247C2300D5ADFE = { + fileRef = 6692C09F06247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0BC06247C2300D5ADFE = { + fileRef = 6692C0A006247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0BD06247C2300D5ADFE = { + fileRef = 6692C0A106247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0BE06247C2300D5ADFE = { + fileRef = 6692C0A206247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0BF06247C2300D5ADFE = { + fileRef = 6692C0A306247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0C006247C2300D5ADFE = { + fileRef = 6692C0A406247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0C106247C2300D5ADFE = { + fileRef = 6692C0A506247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0C206247C2300D5ADFE = { + fileRef = 6692C0A606247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0C306247C2300D5ADFE = { + fileRef = 6692C0A706247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0C406247C2300D5ADFE = { + fileRef = 6692C0A806247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0C506247C2300D5ADFE = { + fileRef = 6692C0A906247C2300D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C0E606247C3B00D5ADFE = { + children = ( + 1DD229E2070B4A02000DFF1F, + 1D3CACC90694D76300313D6F, + 1D3CACCA0694D76300313D6F, + 1D3CACCB0694D76300313D6F, + 1D49BDC50691F8E000643C72, + 1D49BDC60691F8E000643C72, + 1DE1EDF40690BA1600D93C76, + 1DE1ED0B06909D0A00D93C76, + 1DE1ED0C06909D0A00D93C76, + 1DE1EC6906909AB400D93C76, + 1DE1EC6A06909AB400D93C76, + 1DE1EC6B06909AB400D93C76, + 1DE1EC6C06909AB400D93C76, + 1DE1EC6D06909AB400D93C76, + 1DE1EC6E06909AB400D93C76, + 1DE1EC6F06909AB400D93C76, + 1DE1EC7006909AB400D93C76, + 1DE1EC7106909AB400D93C76, + 1DE1EC7206909AB400D93C76, + 1DE1EC7306909AB400D93C76, + 1DE1EC7406909AB400D93C76, + 1DE1EC7506909AB400D93C76, + 1D3E3EED0666A871005D645B, + 1D3E3EEE0666A871005D645B, + 1D3E3EE90666A7EE005D645B, + 1D3E3EEA0666A7EE005D645B, + 1D8DCBB606557E6D00BC4809, + 1D8DCBB706557E6D00BC4809, + 1DC6ED470652D24B00BDEE0B, + 1DC6ED480652D24B00BDEE0B, + 1DC6ED490652D24B00BDEE0B, + 1DC6ED4A0652D24B00BDEE0B, + 1DC6ED4B0652D24B00BDEE0B, + 1DC6ED4C0652D24B00BDEE0B, + 1DC8204A064C5CBC00F61B0E, + 1DC8204B064C5CBC00F61B0E, + 1DC8204C064C5CBC00F61B0E, + DBAFF4A706471AAE00683BA4, + DBAFF4A806471AAE00683BA4, + DBAFF49906471A4200683BA4, + DBAFF49A06471A4200683BA4, + DB997D270638AFC1002745B0, + DB997D280638AFC1002745B0, + DB997D290638AFC1002745B0, + 6656DDCA0635C95C00E30126, + 6656DDCB0635C95C00E30126, + 6656DDCC0635C95C00E30126, + 6656DDCD0635C95C00E30126, + 6656DDCE0635C95C00E30126, + 6656DDCF0635C95C00E30126, + 6656DDD00635C95C00E30126, + 6656DDD10635C95C00E30126, + 6656DDD20635C95C00E30126, + 6656DDD30635C95C00E30126, + 6692C22D0625E7E800D5ADFE, + 6692C22E0625E7E800D5ADFE, + 6692C22F0625E7E800D5ADFE, + 6692C2300625E7E800D5ADFE, + 6692C2310625E7E800D5ADFE, + 6692C2320625E7E800D5ADFE, + 6692C2330625E7E800D5ADFE, + 6692C2340625E7E800D5ADFE, + 6692C2350625E7E800D5ADFE, + 6692C2360625E7E800D5ADFE, + 6692C2370625E7E800D5ADFE, + 6692C2380625E7E800D5ADFE, + 6692C08E06247C2300D5ADFE, + 6692C08F06247C2300D5ADFE, + 6692C09006247C2300D5ADFE, + 6692C09106247C2300D5ADFE, + 6692C09406247C2300D5ADFE, + 6692C09506247C2300D5ADFE, + 6692C09606247C2300D5ADFE, + 6692C09706247C2300D5ADFE, + 6692C09806247C2300D5ADFE, + 6692C09906247C2300D5ADFE, + 6692C09A06247C2300D5ADFE, + 6692C09B06247C2300D5ADFE, + 6692C09C06247C2300D5ADFE, + 6692C09D06247C2300D5ADFE, + 6692C09E06247C2300D5ADFE, + 6692C09F06247C2300D5ADFE, + 6692C0A006247C2300D5ADFE, + 6692C0A106247C2300D5ADFE, + 6692C0A206247C2300D5ADFE, + 6692C0A306247C2300D5ADFE, + 6692C0A406247C2300D5ADFE, + 6692C0A506247C2300D5ADFE, + 6692C0A606247C2300D5ADFE, + 6692C0A706247C2300D5ADFE, + 6692C0A806247C2300D5ADFE, + 6692C0A906247C2300D5ADFE, + 6692C18A06247DB900D5ADFE, + ); + isa = PBXGroup; + name = ZAP; + refType = 4; + sourceTree = ""; + }; + 6692C11906247CF900D5ADFE = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = GLUT.framework; + path = /System/Library/Frameworks/GLUT.framework; + refType = 0; + sourceTree = ""; + }; + 6692C15706247D1800D5ADFE = { + buildActionMask = 2147483647; + files = ( + 6692C15E06247D2000D5ADFE, + 6692C15F06247D2500D5ADFE, + 6692C16106247D2700D5ADFE, + 6656DD9C0635C8EF00E30126, + DB9525D00636109800B8795E, + 1DE1ED3406909FA300D93C76, + 1D49BD0D0691F71200643C72, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 6692C15E06247D2000D5ADFE = { + fileRef = 6692C11906247CF900D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C15F06247D2500D5ADFE = { + fileRef = 66D85E1905ACBA97008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C16106247D2700D5ADFE = { + fileRef = 6649E0D605FD01D700B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C18A06247DB900D5ADFE = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = glutInclude.h; + path = ../glut/glutInclude.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C18B06247DB900D5ADFE = { + fileRef = 6692C18A06247DB900D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C1FA06247F2000D5ADFE = { + fileRef = 66BA0E7805FD46F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C22D0625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = barrier.cpp; + path = ../zap/barrier.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C22E0625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = barrier.h; + path = ../zap/barrier.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C22F0625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = game.cpp; + path = ../zap/game.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2300625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = game.h; + path = ../zap/game.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2310625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameLoader.cpp; + path = ../zap/gameLoader.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2320625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameLoader.h; + path = ../zap/gameLoader.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2330625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameObject.cpp; + path = ../zap/gameObject.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2340625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gameObject.h; + path = ../zap/gameObject.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2350625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gridDB.cpp; + path = ../zap/gridDB.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2360625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = gridDB.h; + path = ../zap/gridDB.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2370625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = teleporter.cpp; + path = ../zap/teleporter.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2380625E7E800D5ADFE = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = teleporter.h; + path = ../zap/teleporter.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 6692C2390625E7E800D5ADFE = { + fileRef = 6692C22D0625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C23A0625E7E800D5ADFE = { + fileRef = 6692C22E0625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C23B0625E7E800D5ADFE = { + fileRef = 6692C22F0625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C23C0625E7E800D5ADFE = { + fileRef = 6692C2300625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C23D0625E7E800D5ADFE = { + fileRef = 6692C2310625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C23E0625E7E800D5ADFE = { + fileRef = 6692C2320625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C23F0625E7E800D5ADFE = { + fileRef = 6692C2330625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C2400625E7E800D5ADFE = { + fileRef = 6692C2340625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C2410625E7E800D5ADFE = { + fileRef = 6692C2350625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C2420625E7E800D5ADFE = { + fileRef = 6692C2360625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C2430625E7E800D5ADFE = { + fileRef = 6692C2370625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 6692C2440625E7E800D5ADFE = { + fileRef = 6692C2380625E7E800D5ADFE; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C3605FD0E5B00D882FA = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; + remoteInfo = libtomcrypt; + }; + 66BA0C3705FD0E5B00D882FA = { + isa = PBXTargetDependency; + target = 6649E0D505FD01D700B3DD8B; + targetProxy = 66BA0C3605FD0E5B00D882FA; + }; + 66BA0C4A05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlAssert.h; + path = ../tnl/tnlAssert.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C4B05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlAsymmetricKey.h; + path = ../tnl/tnlAsymmetricKey.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C4C05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlBitSet.h; + path = ../tnl/tnlBitSet.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C4D05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlBitStream.h; + path = ../tnl/tnlBitStream.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C4E05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlByteBuffer.h; + path = ../tnl/tnlByteBuffer.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C4F05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlCertificate.h; + path = ../tnl/tnlCertificate.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5005FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlClientPuzzle.h; + path = ../tnl/tnlClientPuzzle.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5105FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlConnectionStringTable.h; + path = ../tnl/tnlConnectionStringTable.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5205FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlDataChunker.h; + path = ../tnl/tnlDataChunker.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5305FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlEndian.h; + path = ../tnl/tnlEndian.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5405FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlEventConnection.h; + path = ../tnl/tnlEventConnection.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5505FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlGhostConnection.h; + path = ../tnl/tnlGhostConnection.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5605FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlHuffmanStringProcessor.h; + path = ../tnl/tnlHuffmanStringProcessor.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5705FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlLog.h; + path = ../tnl/tnlLog.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5805FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNetBase.h; + path = ../tnl/tnlNetBase.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5905FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNetConnection.h; + path = ../tnl/tnlNetConnection.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5A05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNetEvent.h; + path = ../tnl/tnlNetEvent.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5B05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNetInterface.h; + path = ../tnl/tnlNetInterface.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5C05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNetObject.h; + path = ../tnl/tnlNetObject.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5D05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNetStringTable.h; + path = ../tnl/tnlNetStringTable.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5E05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlNonce.h; + path = ../tnl/tnlNonce.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C5F05FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlPlatform.h; + path = ../tnl/tnlPlatform.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6005FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlRandom.h; + path = ../tnl/tnlRandom.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6105FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlRPC.h; + path = ../tnl/tnlRPC.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6205FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlSymmetricCipher.h; + path = ../tnl/tnlSymmetricCipher.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6305FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlTypes.h; + path = ../tnl/tnlTypes.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6405FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlUDP.h; + path = ../tnl/tnlUDP.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6505FD107700D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnlVector.h; + path = ../tnl/tnlVector.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0C6605FD107700D882FA = { + fileRef = 66BA0C4A05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6705FD107700D882FA = { + fileRef = 66BA0C4B05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6805FD107700D882FA = { + fileRef = 66BA0C4C05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6905FD107700D882FA = { + fileRef = 66BA0C4D05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6A05FD107700D882FA = { + fileRef = 66BA0C4E05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6B05FD107700D882FA = { + fileRef = 66BA0C4F05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6C05FD107700D882FA = { + fileRef = 66BA0C5005FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6D05FD107700D882FA = { + fileRef = 66BA0C5105FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6E05FD107700D882FA = { + fileRef = 66BA0C5205FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C6F05FD107700D882FA = { + fileRef = 66BA0C5305FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7005FD107700D882FA = { + fileRef = 66BA0C5405FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7105FD107700D882FA = { + fileRef = 66BA0C5505FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7205FD107700D882FA = { + fileRef = 66BA0C5605FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7305FD107700D882FA = { + fileRef = 66BA0C5705FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7405FD107700D882FA = { + fileRef = 66BA0C5805FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7505FD107700D882FA = { + fileRef = 66BA0C5905FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7605FD107700D882FA = { + fileRef = 66BA0C5A05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7705FD107700D882FA = { + fileRef = 66BA0C5B05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7805FD107700D882FA = { + fileRef = 66BA0C5C05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7905FD107700D882FA = { + fileRef = 66BA0C5D05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7A05FD107700D882FA = { + fileRef = 66BA0C5E05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7B05FD107700D882FA = { + fileRef = 66BA0C5F05FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7C05FD107700D882FA = { + fileRef = 66BA0C6005FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7D05FD107700D882FA = { + fileRef = 66BA0C6105FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7E05FD107700D882FA = { + fileRef = 66BA0C6205FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C7F05FD107700D882FA = { + fileRef = 66BA0C6305FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C8005FD107700D882FA = { + fileRef = 66BA0C6405FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0C8105FD107700D882FA = { + fileRef = 66BA0C6505FD107700D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0CE005FD17F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = asymmetricKey.cpp; + path = ../tnl/asymmetricKey.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0CE105FD17F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = byteBuffer.cpp; + path = ../tnl/byteBuffer.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0CE205FD17F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = clientPuzzle.cpp; + path = ../tnl/clientPuzzle.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0CE305FD17F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = symmetricCipher.cpp; + path = ../tnl/symmetricCipher.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0CE405FD17F600D882FA = { + fileRef = 66BA0CE005FD17F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0CE505FD17F600D882FA = { + fileRef = 66BA0CE105FD17F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0CE605FD17F600D882FA = { + fileRef = 66BA0CE205FD17F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0CE705FD17F600D882FA = { + fileRef = 66BA0CE305FD17F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0CF605FD182100D882FA = { + fileRef = 6649E0D605FD01D700B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0D1005FD195C00D882FA = { + fileRef = 6649E0D605FD01D700B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0E5905FD467E00D882FA = { + buildActionMask = 2147483647; + files = ( + 66BA0E7C05FD46F600D882FA, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66BA0E5A05FD467E00D882FA = { + buildActionMask = 2147483647; + files = ( + 66BA0E7A05FD46F600D882FA, + 66BA0E7B05FD46F600D882FA, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66BA0E5B05FD467E00D882FA = { + buildPhases = ( + 66BA0E5905FD467E00D882FA, + 66BA0E5A05FD467E00D882FA, + 66BA0E6605FD469900D882FA, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = master; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + 66BA0E6105FD468600D882FA, + 66BA0E6305FD468B00D882FA, + ); + isa = PBXNativeTarget; + name = master; + productName = master; + productReference = 66BA0E5C05FD467E00D882FA; + productType = "com.apple.product-type.tool"; + }; + 66BA0E5C05FD467E00D882FA = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = master; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 66BA0E6005FD468600D882FA = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; + remoteInfo = tnl; + }; + 66BA0E6105FD468600D882FA = { + isa = PBXTargetDependency; + target = 66D85E1805ACBA97008DC9C1; + targetProxy = 66BA0E6005FD468600D882FA; + }; + 66BA0E6205FD468B00D882FA = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; + remoteInfo = libtomcrypt; + }; + 66BA0E6305FD468B00D882FA = { + isa = PBXTargetDependency; + target = 6649E0D505FD01D700B3DD8B; + targetProxy = 66BA0E6205FD468B00D882FA; + }; + 66BA0E6605FD469900D882FA = { + buildActionMask = 2147483647; + files = ( + 66BA0E6E05FD46C300D882FA, + 66BA0E6B05FD46C000D882FA, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66BA0E6B05FD46C000D882FA = { + fileRef = 6649E0D605FD01D700B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0E6E05FD46C300D882FA = { + fileRef = 66D85E1905ACBA97008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0E7705FD46F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = main.cpp; + path = ../master/main.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0E7805FD46F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = masterInterface.cpp; + path = ../master/masterInterface.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0E7905FD46F600D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = masterInterface.h; + path = ../master/masterInterface.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0E7A05FD46F600D882FA = { + fileRef = 66BA0E7705FD46F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0E7B05FD46F600D882FA = { + fileRef = 66BA0E7805FD46F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0E7C05FD46F600D882FA = { + fileRef = 66BA0E7905FD46F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0E8605FD473200D882FA = { + buildActionMask = 2147483647; + files = ( + 66BA0EBC05FD47B100D882FA, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66BA0E8705FD473200D882FA = { + buildActionMask = 2147483647; + files = ( + 66BA0EB905FD47A900D882FA, + 66BA0EA405FD478900D882FA, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66BA0E8805FD473200D882FA = { + buildPhases = ( + 66BA0E8605FD473200D882FA, + 66BA0E8705FD473200D882FA, + 66BA0E9905FD476D00D882FA, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + INSTALL_PATH = /usr/local/bin; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = masterclient; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + 66BA0E8E05FD473A00D882FA, + 66BA0E9005FD474000D882FA, + ); + isa = PBXNativeTarget; + name = masterclient; + productName = masterclient; + productReference = 66BA0E8905FD473200D882FA; + productType = "com.apple.product-type.tool"; + }; + 66BA0E8905FD473200D882FA = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = masterclient; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 66BA0E8D05FD473A00D882FA = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; + remoteInfo = tnl; + }; + 66BA0E8E05FD473A00D882FA = { + isa = PBXTargetDependency; + target = 66D85E1805ACBA97008DC9C1; + targetProxy = 66BA0E8D05FD473A00D882FA; + }; + 66BA0E8F05FD474000D882FA = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; + remoteInfo = libtomcrypt; + }; + 66BA0E9005FD474000D882FA = { + isa = PBXTargetDependency; + target = 6649E0D505FD01D700B3DD8B; + targetProxy = 66BA0E8F05FD474000D882FA; + }; + 66BA0E9305FD475500D882FA = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; + remoteInfo = libtomcrypt; + }; + 66BA0E9405FD475500D882FA = { + isa = PBXTargetDependency; + target = 6649E0D505FD01D700B3DD8B; + targetProxy = 66BA0E9305FD475500D882FA; + }; + 66BA0E9905FD476D00D882FA = { + buildActionMask = 2147483647; + files = ( + 66BA0EA005FD477500D882FA, + 66BA0EA105FD477500D882FA, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66BA0EA005FD477500D882FA = { + fileRef = 66D85E1905ACBA97008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0EA105FD477500D882FA = { + fileRef = 6649E0D605FD01D700B3DD8B; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0EA305FD478900D882FA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = main.cpp; + path = ../masterclient/main.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66BA0EA405FD478900D882FA = { + fileRef = 66BA0EA305FD478900D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0EA905FD479700D882FA = { + children = ( + 66BA0EA305FD478900D882FA, + ); + isa = PBXGroup; + name = masterclient; + refType = 4; + sourceTree = ""; + }; + 66BA0EB905FD47A900D882FA = { + fileRef = 66BA0E7805FD46F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66BA0EBC05FD47B100D882FA = { + fileRef = 66BA0E7905FD46F600D882FA; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85C1E05AC8772008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = testGame.cpp; + path = ../test/testGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85C1F05AC8772008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = testGame.h; + path = ../test/testGame.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85C2005AC8772008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = testGameRender.cpp; + path = ../test/testGameRender.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85C2105AC8772008DC9C1 = { + fileRef = 66D85C1E05AC8772008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85C2205AC8772008DC9C1 = { + fileRef = 66D85C1F05AC8772008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85C2305AC8772008DC9C1 = { + fileRef = 66D85C2005AC8772008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85C9105AC8DC7008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = MyOpenGLView.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85C9305AC8DC7008DC9C1 = { + fileRef = 66D85C9105AC8DC7008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85DB705ACA1F0008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.objcpp; + path = MyOpenGLView.mm; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85DB805ACA1F0008DC9C1 = { + fileRef = 66D85DB705ACA1F0008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85E1605ACBA97008DC9C1 = { + buildActionMask = 2147483647; + files = ( + 66D85E7305ACCB91008DC9C1, + 66BA0C6605FD107700D882FA, + 66BA0C6705FD107700D882FA, + 66BA0C6805FD107700D882FA, + 66BA0C6905FD107700D882FA, + 66BA0C6A05FD107700D882FA, + 66BA0C6B05FD107700D882FA, + 66BA0C6C05FD107700D882FA, + 66BA0C6D05FD107700D882FA, + 66BA0C6E05FD107700D882FA, + 66BA0C6F05FD107700D882FA, + 66BA0C7005FD107700D882FA, + 66BA0C7105FD107700D882FA, + 66BA0C7205FD107700D882FA, + 66BA0C7305FD107700D882FA, + 66BA0C7405FD107700D882FA, + 66BA0C7505FD107700D882FA, + 66BA0C7605FD107700D882FA, + 66BA0C7705FD107700D882FA, + 66BA0C7805FD107700D882FA, + 66BA0C7905FD107700D882FA, + 66BA0C7A05FD107700D882FA, + 66BA0C7B05FD107700D882FA, + 66BA0C7C05FD107700D882FA, + 66BA0C7D05FD107700D882FA, + 66BA0C7E05FD107700D882FA, + 66BA0C7F05FD107700D882FA, + 66BA0C8005FD107700D882FA, + 66BA0C8105FD107700D882FA, + 1DC82049064C5C9000F61B0E, + 1DC6ED460652D22A00BDEE0B, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66D85E1705ACBA97008DC9C1 = { + buildActionMask = 2147483647; + files = ( + 66D85EA605ACCBBA008DC9C1, + 66D85EA705ACCBBA008DC9C1, + 66D85EA805ACCBBA008DC9C1, + 66D85EA905ACCBBA008DC9C1, + 66D85EAA05ACCBBA008DC9C1, + 66D85EAC05ACCBBA008DC9C1, + 66D85EAF05ACCBBA008DC9C1, + 66D85EB005ACCBBA008DC9C1, + 66D85EB105ACCBBA008DC9C1, + 66D85EB205ACCBBA008DC9C1, + 66D85EB305ACCBBA008DC9C1, + 66D85EB405ACCBBA008DC9C1, + 66D85EB505ACCBBA008DC9C1, + 66D85EB605ACCBBA008DC9C1, + 66D85EB705ACCBBA008DC9C1, + 66D85EB805ACCBBA008DC9C1, + 6661401405B3965A00320653, + 6661401A05B3966700320653, + 66BA0CE405FD17F600D882FA, + 66BA0CE505FD17F600D882FA, + 66BA0CE605FD17F600D882FA, + 66BA0CE705FD17F600D882FA, + DB9525E4063610C200B8795E, + 1DC82048064C5C9000F61B0E, + 1DC6ED450652D22A00BDEE0B, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66D85E1805ACBA97008DC9C1 = { + buildPhases = ( + 66D85E1605ACBA97008DC9C1, + 66D85E1705ACBA97008DC9C1, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + INSTALL_PATH = /usr/local/lib; + LIBRARY_STYLE = STATIC; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = tnl; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = tnl; + productName = tnl; + productReference = 66D85E1905ACBA97008DC9C1; + productType = "com.apple.product-type.library.static"; + }; + 66D85E1905ACBA97008DC9C1 = { + explicitFileType = archive.ar; + includeInIndex = 0; + isa = PBXFileReference; + path = libtnl.a; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 66D85E5C05ACCB91008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tnl.h; + path = ../tnl/tnl.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E7305ACCB91008DC9C1 = { + fileRef = 66D85E5C05ACCB91008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85E9305ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = huffmanStringProcessor.cpp; + path = ../tnl/huffmanStringProcessor.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9405ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = assert.cpp; + path = ../tnl/assert.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9505ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = dataChunker.cpp; + path = ../tnl/dataChunker.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9605ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = netStringTable.cpp; + path = ../tnl/netStringTable.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9705ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = ghostConnection.cpp; + path = ../tnl/ghostConnection.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9905ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = netConnection.cpp; + path = ../tnl/netConnection.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9C05ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = log.cpp; + path = ../tnl/log.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9D05ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = random.cpp; + path = ../tnl/random.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9E05ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = netObject.cpp; + path = ../tnl/netObject.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85E9F05ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = connectionStringTable.cpp; + path = ../tnl/connectionStringTable.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA005ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = rpc.cpp; + path = ../tnl/rpc.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA105ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = netInterface.cpp; + path = ../tnl/netInterface.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA205ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = netBase.cpp; + path = ../tnl/netBase.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA305ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = eventConnection.cpp; + path = ../tnl/eventConnection.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA405ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = vector.cpp; + path = ../tnl/vector.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA505ACCBBA008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = bitStream.cpp; + path = ../tnl/bitStream.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EA605ACCBBA008DC9C1 = { + fileRef = 66D85E9305ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EA705ACCBBA008DC9C1 = { + fileRef = 66D85E9405ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EA805ACCBBA008DC9C1 = { + fileRef = 66D85E9505ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EA905ACCBBA008DC9C1 = { + fileRef = 66D85E9605ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EAA05ACCBBA008DC9C1 = { + fileRef = 66D85E9705ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EAC05ACCBBA008DC9C1 = { + fileRef = 66D85E9905ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EAF05ACCBBA008DC9C1 = { + fileRef = 66D85E9C05ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB005ACCBBA008DC9C1 = { + fileRef = 66D85E9D05ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB105ACCBBA008DC9C1 = { + fileRef = 66D85E9E05ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB205ACCBBA008DC9C1 = { + fileRef = 66D85E9F05ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB305ACCBBA008DC9C1 = { + fileRef = 66D85EA005ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB405ACCBBA008DC9C1 = { + fileRef = 66D85EA105ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB505ACCBBA008DC9C1 = { + fileRef = 66D85EA205ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB605ACCBBA008DC9C1 = { + fileRef = 66D85EA305ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB705ACCBBA008DC9C1 = { + fileRef = 66D85EA405ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EB805ACCBBA008DC9C1 = { + fileRef = 66D85EA505ACCBBA008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85ED805ACCC15008DC9C1 = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; + remoteInfo = tnl; + }; + 66D85ED905ACCC15008DC9C1 = { + isa = PBXTargetDependency; + target = 66D85E1805ACBA97008DC9C1; + targetProxy = 66D85ED805ACCC15008DC9C1; + }; + 66D85EDB05ACCC36008DC9C1 = { + buildActionMask = 2147483647; + files = ( + 66D85EF305ACCC8D008DC9C1, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66D85EDC05ACCC36008DC9C1 = { + buildActionMask = 2147483647; + files = ( + 66D85EE705ACCC6A008DC9C1, + 66D85EF005ACCC8D008DC9C1, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 66D85EDD05ACCC36008DC9C1 = { + buildPhases = ( + 66D85EDB05ACCC36008DC9C1, + 66D85EDC05ACCC36008DC9C1, + 66D85F2E05ACCD61008DC9C1, + ); + buildRules = ( + ); + buildSettings = { + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + INSTALL_PATH = /usr/local/bin; + LIBRARY_SEARCH_PATHS = ../osx/build; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = testserver; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + 66D85EE305ACCC3C008DC9C1, + 66BA0E9405FD475500D882FA, + ); + isa = PBXNativeTarget; + name = testserver; + productName = testserver; + productReference = 66D85EDE05ACCC36008DC9C1; + productType = "com.apple.product-type.tool"; + }; + 66D85EDE05ACCC36008DC9C1 = { + explicitFileType = "compiled.mach-o.executable"; + includeInIndex = 0; + isa = PBXFileReference; + path = testserver; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 66D85EE205ACCC3C008DC9C1 = { + containerPortal = 29B97313FDCFA39411CA2CEA; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; + remoteInfo = tnl; + }; + 66D85EE305ACCC3C008DC9C1 = { + isa = PBXTargetDependency; + target = 66D85E1805ACBA97008DC9C1; + targetProxy = 66D85EE205ACCC3C008DC9C1; + }; + 66D85EE605ACCC6A008DC9C1 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = server.cpp; + path = ../test/server.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + 66D85EE705ACCC6A008DC9C1 = { + fileRef = 66D85EE605ACCC6A008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EF005ACCC8D008DC9C1 = { + fileRef = 66D85C1E05AC8772008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85EF305ACCC8D008DC9C1 = { + fileRef = 66D85C1F05AC8772008DC9C1; + isa = PBXBuildFile; + settings = { + }; + }; + 66D85F2E05ACCD61008DC9C1 = { + buildActionMask = 2147483647; + files = ( + 66BA0D1005FD195C00D882FA, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; +//660 +//661 +//662 +//663 +//664 +//8D0 +//8D1 +//8D2 +//8D3 +//8D4 + 8D1107260486CEB800E47090 = { + buildPhases = ( + 8D1107270486CEB800E47090, + 8D1107290486CEB800E47090, + 8D11072C0486CEB800E47090, + 8D11072E0486CEB800E47090, + ); + buildRules = ( + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_TRIGRAPHS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ../osx/build; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = TNLTest; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + 66D85ED905ACCC15008DC9C1, + 66BA0C3705FD0E5B00D882FA, + ); + isa = PBXNativeTarget; + name = TNLTest; + productInstallPath = "$(HOME)/Applications"; + productName = TNLTest; + productReference = 8D1107320486CEB800E47090; + productType = "com.apple.product-type.application"; + }; + 8D1107270486CEB800E47090 = { + buildActionMask = 2147483647; + files = ( + 66D85C2205AC8772008DC9C1, + 66D85C9305AC8DC7008DC9C1, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D1107290486CEB800E47090 = { + buildActionMask = 2147483647; + files = ( + 8D11072A0486CEB800E47090, + 8D11072B0486CEB800E47090, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D11072A0486CEB800E47090 = { + fileRef = 29B97318FDCFA39411CA2CEA; + isa = PBXBuildFile; + settings = { + }; + }; + 8D11072B0486CEB800E47090 = { + fileRef = 089C165CFE840E0CC02AAC07; + isa = PBXBuildFile; + settings = { + }; + }; + 8D11072C0486CEB800E47090 = { + buildActionMask = 2147483647; + files = ( + 66D85C2105AC8772008DC9C1, + 66D85C2305AC8772008DC9C1, + 66D85DB805ACA1F0008DC9C1, + 6645D4C405ACD81600EFFB5D, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D11072E0486CEB800E47090 = { + buildActionMask = 2147483647; + files = ( + 6656DD850635C66F00E30126, + 66BA0CF605FD182100D882FA, + 8D11072F0486CEB800E47090, + DB9525D10636109800B8795E, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D11072F0486CEB800E47090 = { + fileRef = 1058C7A1FEA54F0111CA2CBB; + isa = PBXBuildFile; + settings = { + }; + }; + 8D1107310486CEB800E47090 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text.plist; + path = Info.plist; + refType = 4; + sourceTree = ""; + }; + 8D1107320486CEB800E47090 = { + explicitFileType = wrapper.application; + includeInIndex = 0; + isa = PBXFileReference; + path = TNLTest.app; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; +//8D0 +//8D1 +//8D2 +//8D3 +//8D4 +//DB0 +//DB1 +//DB2 +//DB3 +//DB4 + DB9525CF0636109800B8795E = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = OpenGL.framework; + path = /System/Library/Frameworks/OpenGL.framework; + refType = 0; + sourceTree = ""; + }; + DB9525D00636109800B8795E = { + fileRef = DB9525CF0636109800B8795E; + isa = PBXBuildFile; + settings = { + }; + }; + DB9525D10636109800B8795E = { + fileRef = DB9525CF0636109800B8795E; + isa = PBXBuildFile; + settings = { + }; + }; + DB9525E3063610C200B8795E = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = certificate.cpp; + path = ../tnl/certificate.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DB9525E4063610C200B8795E = { + fileRef = DB9525E3063610C200B8795E; + isa = PBXBuildFile; + settings = { + }; + }; + DB997D270638AFC1002745B0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = gameItems.cpp; + path = ../zap/gameItems.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DB997D280638AFC1002745B0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = quickChat.cpp; + path = ../zap/quickChat.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DB997D290638AFC1002745B0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = quickChat.h; + path = ../zap/quickChat.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DB997D2A0638AFC1002745B0 = { + fileRef = DB997D270638AFC1002745B0; + isa = PBXBuildFile; + settings = { + }; + }; + DB997D2B0638AFC1002745B0 = { + fileRef = DB997D280638AFC1002745B0; + isa = PBXBuildFile; + settings = { + }; + }; + DB997D2C0638AFC1002745B0 = { + fileRef = DB997D290638AFC1002745B0; + isa = PBXBuildFile; + settings = { + }; + }; + DBAFF49906471A4200683BA4 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = soccerGame.cpp; + path = ../zap/soccerGame.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DBAFF49A06471A4200683BA4 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = soccerGame.h; + path = ../zap/soccerGame.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DBAFF49B06471A4200683BA4 = { + fileRef = DBAFF49906471A4200683BA4; + isa = PBXBuildFile; + settings = { + }; + }; + DBAFF49C06471A4200683BA4 = { + fileRef = DBAFF49A06471A4200683BA4; + isa = PBXBuildFile; + settings = { + }; + }; + DBAFF4A706471AAE00683BA4 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.cpp.cpp; + name = UICredits.cpp; + path = ../zap/UICredits.cpp; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DBAFF4A806471AAE00683BA4 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = UICredits.h; + path = ../zap/UICredits.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + DBAFF4A906471AAE00683BA4 = { + fileRef = DBAFF4A706471AAE00683BA4; + isa = PBXBuildFile; + settings = { + }; + }; + DBAFF4AA06471AAE00683BA4 = { + fileRef = DBAFF4A806471AAE00683BA4; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = 29B97313FDCFA39411CA2CEA; +} diff --git a/tnl-1.5.0/tnl/osx/version.plist b/tnl-1.5.0/tnl/osx/version.plist new file mode 100644 index 0000000000000000000000000000000000000000..a293201869bcde9ff4371910ffa0994d67ffcb71 --- /dev/null +++ b/tnl-1.5.0/tnl/osx/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 17 + CFBundleShortVersionString + 0.1 + CFBundleVersion + 0.1 + ProjectName + NibPBTemplates + SourceVersion + 1150000 + + diff --git a/tnl-1.5.0/tnl/test/Makefile b/tnl-1.5.0/tnl/test/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..83ca2eb6b7d540f5217b5883317f3e01bc365639 --- /dev/null +++ b/tnl-1.5.0/tnl/test/Makefile @@ -0,0 +1,34 @@ +# TNL Makefile +# (c) 2003 GarageGames +# +# This makefile is for Linux atm. + + +# +# Configuration +# +CC=g++ -g #-O2 + +OBJECTS_SERVER=\ + testGame.o\ + server.o + +OBJECTS_TNLTEST=\ + testGame.o\ + testWindow.o \ + testGameRender.o \ + +CFLAGS= + +.cpp.o : + $(CC) -c $(CFLAGS) $< + +default: $(OBJECTS_SERVER) $(OBJECTS_CLIENT) + @echo Building linux dedicated server... + $(CC) -o server $(OBJECTS_SERVER) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a -lstdc++ -lm + +tnltest: $(OBJECTS_TNLTEST) + @echo Building TNLTest gui... + $(CC) -o tnltest $(OBJECTS_TNLTEST) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a -lGL -lGLU -lglut -lm +clean: + rm -f $(OBJECTS_SERVER) $(OBJECTS_CLIENT) $(OBJECTS_TNLTEST) server client tnltest diff --git a/tnl-1.5.0/tnl/test/TNLTest.def b/tnl-1.5.0/tnl/test/TNLTest.def new file mode 100644 index 0000000000000000000000000000000000000000..91a8060615bd77e96c43f9ed581e406913fe398d --- /dev/null +++ b/tnl-1.5.0/tnl/test/TNLTest.def @@ -0,0 +1,9 @@ +NAME TNLTest +DESCRIPTION 'TNLTest' +EXETYPE WINDOWS +STUB 'WINSTUB.EXE' +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +HEAPSIZE 1024 +STACKSIZE 16192 + diff --git a/tnl-1.5.0/tnl/test/TNLTest.suo b/tnl-1.5.0/tnl/test/TNLTest.suo new file mode 100644 index 0000000000000000000000000000000000000000..a38118c4a4bd7c3f2e54c7cebd790fa1d23bbc74 Binary files /dev/null and b/tnl-1.5.0/tnl/test/TNLTest.suo differ diff --git a/tnl-1.5.0/tnl/test/TNLTest.vcproj b/tnl-1.5.0/tnl/test/TNLTest.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..cd6685a762e026d769a9aa701249438032c61117 --- /dev/null +++ b/tnl-1.5.0/tnl/test/TNLTest.vcproj @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/test/client.cpp b/tnl-1.5.0/tnl/test/client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f706a865c1c162ded4a561ffabce4e8aa4596b22 --- /dev/null +++ b/tnl-1.5.0/tnl/test/client.cpp @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------------- +// Torque Network Library Test Program (Dedicated Server) +// +// Copyright (c) 2004 GarageGames.Com +//----------------------------------------------------------------------------- + +#include "testGame.h" +#include +#include + +class DedicatedServerLogConsumer : public LogConsumer +{ +public: + void logString(const char *string) + { + printf("%s\n", string); + } +} gDedicatedServerLogConsumer; + +int main(int argc, const char **argv) +{ + const char *localBroadcastAddress = "IP:broadcast:28999"; + + S32 port = 28999; + if(argc == 2) + port = atoi(argv[1]); + TestGame* theGame = new TestGame(false, Address(IPProtocol, Address::Any, port),Address(localBroadcastAddress)); + for(;;) + theGame->tick(); +} diff --git a/tnl-1.5.0/tnl/test/fractal.suo b/tnl-1.5.0/tnl/test/fractal.suo new file mode 100644 index 0000000000000000000000000000000000000000..85fc01ffe454a59503fee92bb924c8ec58818d71 Binary files /dev/null and b/tnl-1.5.0/tnl/test/fractal.suo differ diff --git a/tnl-1.5.0/tnl/test/mondrian.ico b/tnl-1.5.0/tnl/test/mondrian.ico new file mode 100644 index 0000000000000000000000000000000000000000..2310c5d275a87af295d5ea8dc79ea417a5e74c53 Binary files /dev/null and b/tnl-1.5.0/tnl/test/mondrian.ico differ diff --git a/tnl-1.5.0/tnl/test/server.cpp b/tnl-1.5.0/tnl/test/server.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c9acff450cff2339217d414a6be38ef8d98234d --- /dev/null +++ b/tnl-1.5.0/tnl/test/server.cpp @@ -0,0 +1,359 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - TNLTest dedicated server and unit tests +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "testGame.h" +#include +#include "../tnl/tnlSymmetricCipher.h" +#include "../tnl/tnlAsymmetricKey.h" +#include "../tnl/tnlCertificate.h" +#include "../tnl/tnlBitStream.h" + +using namespace TNL; + +//#define TNLTest_SERVER +#define TNL_TEST_RPC +//#define TNL_TEST_PROTOCOL +//#define TNL_TEST_RPC +//#define TNL_TEST_NETINTERFACE +//#define TNL_TEST_CERTIFICATE + +// server.cpp +// +// This file contains several different test programs, one of which +// can be enabled by uncommenting one of the previous #define'd macros. +// +// All of the test programs use the following LogConsumer to write +// output from the TNL to the standard output console. + +class DedicatedServerLogConsumer : public LogConsumer +{ +public: + void logString(const char *string) + { + printf("%s\n", string); + } +} gDedicatedServerLogConsumer; + + +#if defined(TNLTest_SERVER) + +// The TNLTest_SERVER test is an example dedicated server for the +// TNLTest application. + +int main(int argc, const char **argv) +{ + const char *localBroadcastAddress = "IP:broadcast:28999"; + + S32 port = 28999; + if(argc == 2) + port = atoi(argv[1]); + serverGame = new TestGame(true, Address(IPProtocol, Address::Any, port), Address(localBroadcastAddress)); + for(;;) + serverGame->tick(); + return 0; +} + +#elif defined(TNL_TEST_RPC) + +// The TNL_TEST_RPC exercises the RPC functionality of TNL. The RPC +// code is the only code that is challenging to port to new platforms +// because of its reliance on platform specific stack structure and +// function invocation guidelines. +// +// All RPC methods are declared to be virtual and are invoked using a +// virtual member function pointer. The assembly language output of the +// VFTester calls below can be used to determine how to invoke virtual member +// functions on different platforms and compilers. + +class RPCTestConnection : public EventConnection +{ +public: + + /// Test RPC function for long argument lists, especially useful in debugging architectures that pass some arguments in registers, and some on the stack. + TNL_DECLARE_RPC(rpcLongArgChainTest, (Float<7> i1, Float<6> i2, F32 i3, F32 i4, RangedU32<0,40> i5, F32 i6, U32 i7, F32 i8, U32 i9)); + + TNL_DECLARE_RPC(rpcVectorTest, (IPAddress theIP, ByteBufferPtr buf, Vector v0, Vector v1, Vector v2)); + TNL_DECLARE_RPC(rpcVectorTest2, (Vector v, F32 v2)); + TNL_DECLARE_RPC(rpcSTETest, (StringTableEntry e1, Vector v2)); + +}; + +TNL_IMPLEMENT_RPC(RPCTestConnection, rpcLongArgChainTest, (Float<7> i1, Float<6> i2, F32 i3, F32 i4, RangedU32<0,40> i5, F32 i6, U32 i7, F32 i8, U32 i9), + (i1, i2, i3, i4, i5, i6, i7, i8, i9), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + F32 fi1 = i1; + F32 fi2 = i2; + logprintf( "%g %g %g %g %d %g %d %g %d", + fi1, fi2, i3, i4, U32(i5), i6, i7, i8, i9); +} + +TNL_IMPLEMENT_RPC(RPCTestConnection, rpcVectorTest2, (Vector floatVec, F32 floatVal), (floatVec, floatVal), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + logprintf("val = %g", floatVal); + for(S32 i = 0; i < floatVec.size(); i++) + logprintf("floatVec[%d] = %g", i, floatVec[i]); +} + +TNL_IMPLEMENT_RPC(RPCTestConnection, rpcVectorTest, + (IPAddress theIP, ByteBufferPtr buf, Vector v0, Vector v1, Vector v2), + (theIP, buf, v0, v1, v2), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + logprintf("Vector 0 size: %d, Vector 1 size: %d, Vector 2 size: %d", v0.size(), v1.size(), v2.size()); + Address anAddress(theIP); + logprintf("BB: %d - %s", buf->getBufferSize(), buf->getBuffer()); + logprintf("IPAddress = %s", anAddress.toString()); + for(S32 i = 0; i < v0.size(); i++) + logprintf("Addr: %s", Address(v0[i]).toString()); + for(S32 i = 0; i < v1.size(); i++) + logprintf("%s", v1[i].getString()); + for(S32 i = 0; i < v2.size(); i++) + logprintf("%g", v2[i]); +} + +TNL_IMPLEMENT_RPC(RPCTestConnection, rpcSTETest, + (StringTableEntry e1, Vector v2), + (e1, v2), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + logprintf("e1 = %s", e1.getString()); + for(S32 i = 0; i < v2.size(); i++) + { + logprintf("%d - %s", i, v2[i].getString()); + } +} + +class VFTester +{ +public: + U32 someValue; + VFTester() { someValue = 100; } + virtual void doSomething(U32 newValue); +}; + +void VFTester::doSomething(U32 newValue) +{ + someValue = newValue; +} + +typedef void (VFTester::*fptr)(U32 newValue); + +struct U32Struct +{ + U32 value; +}; + +int main(int argc, const char **argv) +{ + // The assembly output of the following lines is used to determine + // how the RPC executor should dispatch RPC calls. + VFTester *newTester = new VFTester; + fptr thePtr = &VFTester::doSomething; + (newTester->*thePtr)(50); + + RPCTestConnection *tc = new RPCTestConnection; + + printf("sizeof RangedU32 = %d\n", sizeof(RangedU32<0,U32_MAX>)); + printf("sizeof Float<> = %d\nSizeof Int<>=%d\n",sizeof(Float<12>),sizeof(Int<12>)); + printf("sizeof U32Struct = %d\n", sizeof(U32Struct)); + fflush(stdout); + + tc->rpcLongArgChainTest_test(0.25, 0.5, 3, 4, 5, 6, 7, 8, 9); + Vector v1; + Vector v0; + v0.push_back(Address("IP:192.168.0.1:1").toIPAddress()); + v0.push_back(Address("IP:192.168.0.2:3").toIPAddress()); + v0.push_back(Address("IP:192.168.0.4:5").toIPAddress()); + v0.push_back(Address("IP:192.168.0.6:7").toIPAddress()); + v1.push_back("Hello World"); + v1.push_back("Foo bar"); + v1.push_back("what's up dood?"); + v1.push_back("whoziwhatsit"); + Vector v2; + v2.push_back(1.5); + v2.push_back(2.5); + v2.push_back(3.5); + v2.push_back(4.5); + v2.push_back(5.5); + + tc->rpcVectorTest2_test(v2, 50); + Address theAddress("IP:192.168.0.23:6969"); + ByteBufferPtr buf = new ByteBuffer((U8 *) "Simple test buffer.", 20); + + Vector v3; + v3.push_back("Foo Bar!"); + v3.push_back("Testing 1 2 3"); + + tc->rpcSTETest_test("Hello World!!!", v3); + tc->rpcVectorTest_test(theAddress.toIPAddress(), buf, v0, v1, v2); + delete tc; +} + +#elif defined(TNL_TEST_PROTOCOL) + +// The TNL_TEST_PROTOCOL section is used to test the underlying NetConnection +// Notify Protocol. This section is not generally useful, but can help +// debug changes to the underlying protocol. + +const U32 testValue = 0xF0F1BAAD; + +class ProtocolTestConnection : public NetConnection +{ + U32 sequence; + U32 mConNum; +public: + ProtocolTestConnection(U32 conNum = 0) + { + mConNum = conNum; sequence = 0; + U8 symmetricKey[16] = { 127, 31, 79, 202, 251, 81, 179, 67, + 90, 151, 216, 10, 171, 243, 1, 0 }; + + U8 initVector[16] = { 117, 42, 81, 222, 211, 85, 189, 17, + 92, 159, 6, 102, 179, 2, 100, 0 }; + + setSymmetricCipher(new SymmetricCipher(symmetricKey, initVector)); + } + + void writePacket(BitStream *bstream, PacketNotify *note) + { + logprintf("%d: sending packet - sequence = %d", mConNum, sequence); + bstream->write(testValue); + bstream->write(sequence++); + } + void readPacket(BitStream *bstream) + { + U32 val; + bstream->read(&val); + U32 seq; + bstream->read(&seq); + if(val != testValue) + logprintf("%d: ERROR - read bad test value.", mConNum); + //logprintf("%d: received packet - sequence = %d", mConNum, seq); + } +}; + +int main(int argc, const char **argv) +{ + TNLLogEnable(LogConnectionProtocol, true); + + ProtocolTestConnection *t1 = new ProtocolTestConnection(1); + ProtocolTestConnection *t2 = new ProtocolTestConnection(2); + t1->setRemoteConnectionObject(t2); + t2->setRemoteConnectionObject(t1); + + t1->setInitialRecvSequence(t2->getInitialSendSequence()); + t2->setInitialRecvSequence(t1->getInitialSendSequence()); + + t1->checkPacketSend(true,0); + t2->checkPacketSend(true,0); + + for(U32 i = 0; i < 15; i++) + t1->checkPacketSend(true,0); + for(U32 i = 0; i < 3; i++) + t2->checkPacketSend(true,0); + for(U32 i = 0; i < 72; i++) + t1->checkPacketSend(true,0); + for(U32 i = 0; i < 41; i++) + t2->checkPacketSend(true,0); + for(U32 i = 0; i < 15; i++) + t1->checkPacketSend(true,0); + for(U32 i = 0; i < 3; i++) + t2->checkPacketSend(true,0); + for(U32 i = 0; i < 15; i++) + t1->checkPacketSend(true,0); + for(U32 i = 0; i < 3; i++) + t2->checkPacketSend(true,0); +} + +#elif defined(TNL_TEST_NETINTERFACE) + +// The TNL_TEST_NETINTERFACE section is used to test the connection +// handshaking process in NetInterface, including key exchange and +// encryption. + +class NetInterfaceTestConnection : public NetConnection +{ + public: + TNL_DECLARE_NETCONNECTION(NetInterfaceTestConnection); +}; + +TNL_IMPLEMENT_NETCONNECTION(NetInterfaceTestConnection, NetClassGroupGame, true); + +int main(int argc, const char **argv) +{ + TNLLogEnable(LogNetInterface, true); + + NetInterface *clientInterface = new NetInterface(25000); + NetInterface *serverInterface = new NetInterface(25001); + + serverInterface->setAllowsConnections(true); + serverInterface->setRequiresKeyExchange(true); + + serverInterface->setPrivateKey(new AsymmetricKey(32)); + NetInterfaceTestConnection *clientConnection = new NetInterfaceTestConnection; + + Address addr("IP:127.0.0.1:25001"); + clientConnection->connect(clientInterface, &addr, true, false); + + for(;;) + { + serverInterface->checkIncomingPackets(); + serverInterface->processConnections(); + clientInterface->checkIncomingPackets(); + clientInterface->processConnections(); + } +} + +#elif defined(TNL_TEST_CERTIFICATE) + +int main(int argc, const char **argv) +{ + RefPtr signatoryKey = new AsymmetricKey(32); + RefPtr certificateKey = new AsymmetricKey(32); + + U8 *certificateString = (U8 *) "This is a sample certificate payload."; + ByteBuffer thePayload(certificateString, strlen((const char *) certificateString) + 1); + + RefPtr theCertificate = new Certificate(thePayload, certificateKey, signatoryKey); + + PacketStream streamTest; + + streamTest.write(theCertificate); + streamTest.setBytePosition(0); + + RefPtr readCert = new Certificate(&streamTest); + + logprintf("Read certificate: %s", readCert->getPayload()->getBuffer()); + + logprintf("Checking certificate signature validity..."); + bool isvalid = readCert->validate(signatoryKey); + + logprintf("Certificate %s valid.", isvalid ? "IS" : "IS NOT"); +} + +#endif diff --git a/tnl-1.5.0/tnl/test/server.vcproj b/tnl-1.5.0/tnl/test/server.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..4966d335ee8226b553a84c2491c00de3d4b58350 --- /dev/null +++ b/tnl-1.5.0/tnl/test/server.vcproj @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/test/test.rc b/tnl-1.5.0/tnl/test/test.rc new file mode 100644 index 0000000000000000000000000000000000000000..e3b11b011641a08a81cfab23022303315f79f2fd --- /dev/null +++ b/tnl-1.5.0/tnl/test/test.rc @@ -0,0 +1,4 @@ +wxSTD_FRAME ICON "mondrian.ico" + +#include "wx/msw/wx.rc" + diff --git a/tnl-1.5.0/tnl/test/test.suo b/tnl-1.5.0/tnl/test/test.suo new file mode 100644 index 0000000000000000000000000000000000000000..7a9b35a890257ba318ff95f1ee9e8e68d7ff7194 Binary files /dev/null and b/tnl-1.5.0/tnl/test/test.suo differ diff --git a/tnl-1.5.0/tnl/test/testGame.cpp b/tnl-1.5.0/tnl/test/testGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a8e4bcd0f8d1a17dfcfdbfb56c0b8d110228536 --- /dev/null +++ b/tnl-1.5.0/tnl/test/testGame.cpp @@ -0,0 +1,636 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - TNLTest example program +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include + +#include "testGame.h" +#include "../tnl/tnlBitStream.h" +#include "../tnl/tnlNetConnection.h" +#include "../tnl/tnlRandom.h" +#include "../tnl/tnlSymmetricCipher.h" +#include "../tnl/tnlAsymmetricKey.h" + +namespace TNLTest { + +TestGame *clientGame = NULL; +TestGame *serverGame = NULL; + +//--------------------------------------------------------------------------------- +TNL_IMPLEMENT_NETOBJECT(Player); + +// Player constructor +Player::Player(Player::PlayerType pt) +{ + // assign a random starting position for the player. + startPos.x = TNL::Random::readF(); + startPos.y = TNL::Random::readF(); + endPos.x = startPos.x; + endPos.y = startPos.y; + renderPos = startPos; + + // preset the movement parameter for the player to the end of + // the path + t = 1.0; + + tDelta = 0; + myPlayerType = pt; + + mNetFlags.set(Ghostable); + game = NULL; +} + +Player::~Player() +{ + if(!game) + return; + + // remove the player from the list of players in the game. + for( TNL::S32 i = 0; i < game->players.size(); i++) + { + if(game->players[i] == this) + { + game->players.erase_fast(i); + return; + } + } +} + +void Player::addToGame(TestGame *theGame) +{ + // add the player to the list of players in the game. + theGame->players.push_back(this); + game = theGame; + + if(myPlayerType == PlayerTypeMyClient) + { + // set the client player for the game for drawing the + // scoping radius circle. + game->clientPlayer = this; + } +} + +bool Player::onGhostAdd(TNL::GhostConnection *theConnection) +{ + addToGame(((TestNetInterface *) theConnection->getInterface())->game); + return true; +} + +void Player::performScopeQuery(TNL::GhostConnection *connection) +{ + // find all the objects that are "in scope" - for the purposes + // of this test program, all buildings are considered to be in + // scope always, as well as all "players" in a circle of radius + // 0.25 around the scope object, or a radius squared of 0.0625 + + for(TNL::S32 i = 0; i < game->buildings.size(); i++) + connection->objectInScope(game->buildings[i]); + + for(TNL::S32 i = 0; i < game->players.size(); i++) + { + Position playerP = game->players[i]->renderPos; + TNL::F32 dx = playerP.x - renderPos.x; + TNL::F32 dy = playerP.y - renderPos.y; + TNL::F32 distSquared = dx * dx + dy * dy; + if(distSquared < 0.0625) + connection->objectInScope(game->players[i]); + } +} + +TNL::U32 Player::packUpdate(TNL::GhostConnection *connection, TNL::U32 updateMask, TNL::BitStream *stream) +{ + // if this is the initial update, write out some static + // information about this player. Since we never call + // setMaskBits(InitialMask), we're guaranteed that this state + // will only be updated on the first update for this object. + if(stream->writeFlag(updateMask & InitialMask)) + { + // write one bit if it's not an AI + if(stream->writeFlag(myPlayerType != PlayerTypeAI)) + { + // write a flag to the client if this is the player that + // that client controls. + stream->writeFlag(connection->getScopeObject() == this); + } + } + + // see if we need to write out the position data + // we must write a bit to let the unpackUpdate know whether to + // read the position data out of the stream. + + if(stream->writeFlag(updateMask & PositionMask)) + { + // since the position data is all 0 to 1, we can use + // the bit stream's writeFloat method to write it out. + // 12 bits should be sufficient precision + stream->writeFloat(startPos.x, 12); + stream->writeFloat(startPos.y, 12); + stream->writeFloat(endPos.x, 12); + stream->writeFloat(endPos.y, 12); + stream->write(t); // fully precise t and tDelta + stream->write(tDelta); + } + + + // if I had other states on the player that changed independently + // of position, I could test for and update them here. + // ... + + // the return value from packUpdate is the update mask for this + // object on this client _AFTER_ this update has been sent. + // Normally this will be zero, but it could be nonzero if this + // object has a state that depends on some other object that + // hasn't yet been ghosted. + return 0; +} + +void Player::unpackUpdate(TNL::GhostConnection *connection, TNL::BitStream *stream) +{ + // see if the initial packet data was written: + if(stream->readFlag()) + { + // check to see if it's not an AI player. + if(stream->readFlag()) + { + if(stream->readFlag()) + myPlayerType = PlayerTypeMyClient; + else + myPlayerType = PlayerTypeClient; + } + else + myPlayerType = PlayerTypeAIDummy; + } + // see if the player's position has been updated: + if(stream->readFlag()) + { + startPos.x = stream->readFloat(12); + startPos.y = stream->readFloat(12); + endPos.x = stream->readFloat(12); + endPos.y = stream->readFloat(12); + stream->read(&t); + stream->read(&tDelta); + // update the render position + update(0); + } +} + +void Player::serverSetPosition(Position inStartPos, Position inEndPos, TNL::F32 inT, TNL::F32 inTDelta) +{ + // update the instance variables of the object + startPos = inStartPos; + endPos = inEndPos; + t = inT; + tDelta = inTDelta; + + // notify the network system that the position state of this object has changed: + setMaskBits(PositionMask); + + // call a quick RPC to all the connections that have this object in scope + rpcPlayerDidMove(inEndPos.x, inEndPos.y); +} + +void Player::update(TNL::F32 timeDelta) +{ + t += tDelta * timeDelta; + if(t >= 1.0) + { + t = 1.0; + tDelta = 0; + renderPos = endPos; + // if this is an AI player on the server, + if(myPlayerType == PlayerTypeAI) + { + startPos = renderPos; + t = 0; + endPos.x = TNL::Random::readF(); + endPos.y = TNL::Random::readF(); + tDelta = 0.2f + TNL::Random::readF() * 0.1f; + setMaskBits(PositionMask); // notify the network system that the network state has been updated + } + } + renderPos.x = startPos.x + (endPos.x - startPos.x) * t; + renderPos.y = startPos.y + (endPos.y - startPos.y) * t; +} + +void Player::onGhostAvailable(TNL::GhostConnection *theConnection) +{ + // this function is called every time a ghost of this object is known + // to be available on a given client. + // we'll use this to demonstrate targeting a NetObject RPC + // to a specific connection. Normally a RPC method marked as + // RPCToGhost will be broadcast to ALL ghosts of the object currently in + // scope. + + // first we construct an event that will represent the RPC call... + // the RPC macros create a RPCNAME_construct function that returns + // a NetEvent that encapsulates the RPC. + TNL::NetEvent *theRPCEvent = TNL_RPC_CONSTRUCT_NETEVENT(this, rpcPlayerIsInScope, (renderPos.x, renderPos.y)); + + // then we can just post the event to whatever connections we want to have + // receive the message. + // In the case of NetObject RPCs, if the source object is not ghosted, + // the RPC will just be silently dropped. + theConnection->postNetEvent(theRPCEvent); +} + +/* +class RPCEV_Player_rpcPlayerIsInScope : + public TNL::NetObjectRPCEvent +{ +public: TNL::FunctorDecl x, TNL::Float<6> y)> mFunctorDecl; + RPCEV_Player_rpcPlayerIsInScope() : + mFunctorDecl(Player::rpcPlayerIsInScope_remote), + RPCEvent(TNL::RPCGuaranteedOrdered, TNL::RPCToGhost) + { mFunctor = &mFunctorDecl; } + static TNL::NetClassRepInstance dynClassRep; + virtual TNL::NetClassRep* getClassRep() const; + bool checkClassType(TNL::Object *theObject) + { return dynamic_cast(theObject) != __null; } +}; +TNL::NetClassRep* RPCEV_Player_rpcPlayerIsInScope::getClassRep() +const { return &RPCEV_Player_rpcPlayerIsInScope::dynClassRep; } +TNL::NetClassRepInstance RPCEV_Player_rpcPlayerIsInScope::dynClassRep("RPCEV_Player_rpcPlayerIsInScope",TNL::NetClassGroupGameMask, TNL::NetClassTypeEvent, 0); +void Player::rpcPlayerIsInScope (TNL::Float<6> x, TNL::Float<6> y) +{ + RPCEV_Player_rpcPlayerIsInScope *theEvent = new RPCEV_Player_rpcPlayerIsInScope; + theEvent->mFunctorDecl.set (x, y) ; + postNetEvent(theEvent); +} + +TNL::NetEvent * Player::rpcPlayerIsInScope_construct (TNL::Float<6> x, TNL::Float<6> y) { RPCEV_Player_rpcPlayerIsInScope *theEvent = new RPCEV_Player_rpcPlayerIsInScope; theEvent->mFunctorDecl.set (x, y) ; return theEvent; } void Player::rpcPlayerIsInScope_test (TNL::Float<6> x, TNL::Float<6> y) { RPCEV_Player_rpcPlayerIsInScope *theEvent = new RPCEV_Player_rpcPlayerIsInScope; theEvent->mFunctorDecl.set (x, y) ; TNL::PacketStream ps; theEvent->pack(this, &ps); ps.setBytePosition(0); theEvent->unpack(this, &ps); theEvent->process(this); } void Player::rpcPlayerIsInScope_remote (TNL::Float<6> x, TNL::Float<6> y) + + +{ + TNL::F32 fx = x, fy = y; + TNL::logprintf("A player is now in scope at %g, %g", fx, fy); +} + +*/ +TNL_IMPLEMENT_NETOBJECT_RPC(Player, rpcPlayerIsInScope, + (TNL::Float<6> x, TNL::Float<6> y), (x, y), + TNL::NetClassGroupGameMask, TNL::RPCGuaranteedOrdered, TNL::RPCToGhost, 0) +{ + TNL::F32 fx = x, fy = y; + TNL::logprintf("A player is now in scope at %g, %g", fx, fy); +} + +TNL_IMPLEMENT_NETOBJECT_RPC(Player, rpcPlayerWillMove, + (TNL::StringPtr testString), (testString), + TNL::NetClassGroupGameMask, TNL::RPCGuaranteedOrdered, TNL::RPCToGhostParent, 0) +{ + TNL::logprintf("Expecting a player move from the connection: %s", testString); +} + +TNL_IMPLEMENT_NETOBJECT_RPC(Player, rpcPlayerDidMove, + (TNL::Float<6> x, TNL::Float<6> y), (x, y), + TNL::NetClassGroupGameMask, TNL::RPCGuaranteedOrdered, TNL::RPCToGhost, 0) +{ + TNL::F32 fx = x, fy = y; + TNL::logprintf("A player moved to %g, %g", fx, fy); +} + +//--------------------------------------------------------------------------------- +TNL_IMPLEMENT_NETOBJECT(Building); + +Building::Building() +{ + // place the "building" in a random position on the screen + upperLeft.x = TNL::Random::readF(); + upperLeft.y = TNL::Random::readF(); + + lowerRight.x = upperLeft.x + TNL::Random::readF() * 0.1f + 0.025f; + lowerRight.y = upperLeft.y + TNL::Random::readF() * 0.1f + 0.025f; + + game = NULL; + + // always scope the buildings to the clients + mNetFlags.set(Ghostable); +} + +Building::~Building() +{ + if(!game) + return; + + // remove the building from the list of buildings in the game. + for( TNL::S32 i = 0; i < game->buildings.size(); i++) + { + if(game->buildings[i] == this) + { + game->buildings.erase_fast(i); + return; + } + } +} + +void Building::addToGame(TestGame *theGame) +{ + // add it to the list of buildings in the game + theGame->buildings.push_back(this); + game = theGame; +} + +bool Building::onGhostAdd(TNL::GhostConnection *theConnection) +{ + addToGame(((TestNetInterface *) theConnection->getInterface())->game); + return true; +} + +TNL::U32 Building::packUpdate(TNL::GhostConnection *connection, TNL::U32 updateMask, TNL::BitStream *stream) +{ + if(stream->writeFlag(updateMask & InitialMask)) + { + // we know all the positions are 0 to 1. + // since this object is scope always, we don't care quite as much + // how efficient the initial state updating is, since we're only + // ever going to send this data when the client first connects + // to this mission. + stream->write(upperLeft.x); + stream->write(upperLeft.y); + stream->write(lowerRight.x); + stream->write(lowerRight.y); + } + // for later - add a "color" field to the buildings that can change + // when AIs or players move over them. + + return 0; +} + +void Building::unpackUpdate(TNL::GhostConnection *connection, TNL::BitStream *stream) +{ + if(stream->readFlag()) + { + stream->read(&upperLeft.x); + stream->read(&upperLeft.y); + stream->read(&lowerRight.x); + stream->read(&lowerRight.y); + } +} + +//--------------------------------------------------------------------------------- + +TNL_IMPLEMENT_NETCONNECTION(TestConnection, TNL::NetClassGroupGame, true); + +TNL_IMPLEMENT_RPC(TestConnection, rpcGotPlayerPos, + (bool b1, bool b2, TNL::StringTableEntry string, TNL::Float x, TNL::Float y), (b1, b2, string, x, y), + TNL::NetClassGroupGameMask, TNL::RPCGuaranteedOrdered, TNL::RPCDirAny, 0) +{ + TNL::F32 xv = x, yv = y; + TNL::logprintf("Server acknowledged position update - %d %d %s %g %g", b1, b2, string.getString(), xv, yv); +} + +TNL_IMPLEMENT_RPC(TestConnection, rpcSetPlayerPos, + (TNL::F32 x, TNL::F32 y), (x, y), + TNL::NetClassGroupGameMask, TNL::RPCGuaranteedOrdered, TNL::RPCDirClientToServer, 0) +{ + Position newPosition; + newPosition.x = x; + newPosition.y = y; + + TNL::logprintf("%s - received new position (%g, %g) from client", + getNetAddressString(), + newPosition.x, newPosition.y); + + myPlayer->serverSetPosition(myPlayer->renderPos, newPosition, 0, 0.2f); + + // send an RPC back the other way! + TNL::StringTableEntry helloString("Hello World!!"); + rpcGotPlayerPos(true, false, helloString, x, y); +}; + +TestConnection::TestConnection() +{ + // every connection class instance must have a net class group set + // before it is used. + + //setIsAdaptive(); // <-- Uncomment me if you want to use adaptive rate instead of fixed rate... +} + +bool TestConnection::isDataToTransmit() +{ + // we always want packets to be sent. + return true; +} + +void TestConnection::onConnectTerminated(NetConnection::TerminationReason reason, const char *string) +{ + ((TestNetInterface *) getInterface())->pingingServers = true; +} + +void TestConnection::onConnectionTerminated(NetConnection::TerminationReason reason, const char *edString) +{ + logprintf("%s - %s connection terminated - reason %d.", getNetAddressString(), isConnectionToServer() ? "server" : "client", reason); + + if(isConnectionToServer()) + ((TestNetInterface *) getInterface())->pingingServers = true; + else + delete (Player*)myPlayer; +} + +void TestConnection::onConnectionEstablished() +{ + // call the parent's onConnectionEstablished. + // by default this will set the initiator to be a connection + // to "server" and the non-initiator to be a connection to "client" + Parent::onConnectionEstablished(); + + // To see how this program performs with 50% packet loss, + // Try uncommenting the next line :) + //setSimulatedNetParams(0.5, 0); + + if(isInitiator()) + { + setGhostFrom(false); + setGhostTo(true); + TNL::logprintf("%s - connected to server.", getNetAddressString()); + ((TestNetInterface *) getInterface())->connectionToServer = this; + } + else + { + // on the server, we create a player object that will be the scope object + // for this client. + Player *player = new Player; + myPlayer = player; + myPlayer->addToGame(((TestNetInterface *) getInterface())->game); + setScopeObject(myPlayer); + setGhostFrom(true); + setGhostTo(false); + activateGhosting(); + TNL::logprintf("%s - client connected.", getNetAddressString()); + } +} + +//--------------------------------------------------------------------------------- + +TestNetInterface::TestNetInterface(TestGame *theGame, bool server, const TNL::Address &bindAddress, const TNL::Address &pingAddr) : NetInterface(bindAddress) +{ + game = theGame; + isServer = server; + pingingServers = !server; + lastPingTime = 0; + pingAddress = pingAddr; +} + +void TestNetInterface::sendPing() +{ + TNL::PacketStream writeStream; + + // the ping packet right now just has one byte for packet type + writeStream.write(TNL::U8(GamePingRequest)); + + writeStream.sendto(mSocket, pingAddress); + + TNL::logprintf("%s - sending ping.", pingAddress.toString()); +} + +void TestNetInterface::tick() +{ + TNL::U32 currentTime = TNL::Platform::getRealMilliseconds(); + + if(pingingServers && (lastPingTime + PingDelayTime < currentTime)) + { + lastPingTime = currentTime; + sendPing(); + } + checkIncomingPackets(); + processConnections(); +} + +// handleInfoPacket for the test game is very simple - if this instance +// is a client, it pings for servers until one is found to connect to. +// If this instance is a server, it responds to ping packets from clients. +// More complicated games could maintain server lists, request game information +// and more. + +void TestNetInterface::handleInfoPacket(const TNL::Address &address, TNL::U8 packetType, TNL::BitStream *stream) +{ + TNL::PacketStream writeStream; + if(packetType == GamePingRequest && isServer) + { + TNL::logprintf("%s - received ping.", address.toString()); + // we're a server, and we got a ping packet from a client, + // so send back a GamePingResponse to let the client know it + // has found a server. + writeStream.write(TNL::U8(GamePingResponse)); + writeStream.sendto(mSocket, address); + + TNL::logprintf("%s - sending ping response.", address.toString()); + } + else if(packetType == GamePingResponse && pingingServers) + { + // we were pinging servers and we got a response. Stop the server + // pinging, and try to connect to the server. + + TNL::logprintf("%s - received ping response.", address.toString()); + + TestConnection *connection = new TestConnection; + connection->connect(this, address); // connect to the server through the game's network interface + + TNL::logprintf("Connecting to server: %s", address.toString()); + + pingingServers = false; + } +} + +//--------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------- + +TestGame::TestGame(bool server, const TNL::Address &interfaceBindAddr, const TNL::Address &pingAddress) +{ + isServer = server; + myNetInterface = new TestNetInterface(this, isServer, interfaceBindAddr, pingAddress); + TNL::AsymmetricKey *theKey = new TNL::AsymmetricKey(32); + myNetInterface->setPrivateKey(theKey); + myNetInterface->setRequiresKeyExchange(true); + + lastTime = TNL::Platform::getRealMilliseconds(); + + if(isServer) + { + // generate some buildings and AIs: + for(TNL::S32 i = 0; i < 50; i ++) + { + Building *building = new Building; + building->addToGame(this); + } + for(TNL::S32 i = 0; i < 15; i ++) + { + Player *aiPlayer = new Player(Player::PlayerTypeAI); + aiPlayer->addToGame(this); + } + serverPlayer = new Player(Player::PlayerTypeMyClient); + serverPlayer->addToGame(this); + } + + TNL::logprintf("Created a %s...", (server ? "server" : "client")); +} + +TestGame::~TestGame() +{ + delete myNetInterface; + for(TNL::S32 i = 0; i < buildings.size(); i++) + delete buildings[i]; + for(TNL::S32 i = 0; i < players.size(); i++) + delete players[i]; + + TNL::logprintf("Destroyed a %s...", (this->isServer ? "server" : "client")); +} + +void TestGame::createLocalConnection(TestGame *serverGame) +{ + myNetInterface->pingingServers = false; + TestConnection *theConnection = new TestConnection; + theConnection->connectLocal(myNetInterface, serverGame->myNetInterface); +} + +void TestGame::tick() +{ + TNL::U32 currentTime = TNL::Platform::getRealMilliseconds(); + if(currentTime == lastTime) + return; + + TNL::F32 timeDelta = (currentTime - lastTime) / 1000.0f; + for(TNL::S32 i = 0; i < players.size(); i++) + players[i]->update(timeDelta); + myNetInterface->tick(); + lastTime = currentTime; +} + +void TestGame::moveMyPlayerTo(Position newPosition) +{ + if(isServer) + { + serverPlayer->serverSetPosition(serverPlayer->renderPos, newPosition, 0, 0.2f); + } + else if(!myNetInterface->connectionToServer.isNull()) + { + TNL::logprintf("posting new position (%g, %g) to server", newPosition.x, newPosition.y); + if(!clientPlayer.isNull()) + clientPlayer->rpcPlayerWillMove("Whee! Foo!"); + myNetInterface->connectionToServer->rpcSetPlayerPos(newPosition.x, newPosition.y); + } +} + +}; diff --git a/tnl-1.5.0/tnl/test/testGame.h b/tnl-1.5.0/tnl/test/testGame.h new file mode 100644 index 0000000000000000000000000000000000000000..d37b8eaf7cf8056fc70e364aa4b067df55534387 --- /dev/null +++ b/tnl-1.5.0/tnl/test/testGame.h @@ -0,0 +1,369 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - TNLTest example program +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "../tnl/tnl.h" +#include "../tnl/tnlNetBase.h" +#include "../tnl/tnlGhostConnection.h" +#include "../tnl/tnlNetInterface.h" +#include "../tnl/tnlNetObject.h" +#include "../tnl/tnlLog.h" +#include "../tnl/tnlRPC.h" +#include "../tnl/tnlString.h" + +/// TNL Graphical Test Application. +/// +/// The TNLTest application demonstrates some of the more useful +/// features of the Torque Network Library. The application presents +/// a single window, representing an abstract simulation area. Red +/// rectangles are used to represent "buildings" that small squares +/// representing players move over. +/// +/// On the linux and Win32 platforms, TNLTest uses the wxWindows user +/// interface API. On Mac OSX TNLTest uses the native Cocoa application +/// framework to render. +/// +/// Each instance of TNLTest can run in one of four modes: as a server, +/// able to host multiple clients; as a client, which searches for and then +/// connects to a server for game data; a client pinging the localhost for +/// connecting to a server on the local machine, and as a combined server +/// and client. +namespace TNLTest +{ + +class TestGame; + +/// Position structure used for positions of objects in the test game. +struct Position +{ + TNL::F32 x; ///< X position of the object, from 0 ... 1 + TNL::F32 y; ///< Y position of the object, from 0 ... 1 +}; + +/// The Player is an example of an object that can move around and update its +/// position to clients in the system. Each client in the server controls +/// a Player instance constructed for it upon joining the game. +/// Client users click on the game window, which generates an event to the server to +/// move that client's player to the desired point. +class Player : public TNL::NetObject +{ + typedef TNL::NetObject Parent; +public: + Position startPos, endPos; ///< All players move along a line from startPos to endPos. + Position renderPos; ///< Position at which to render the player - computed during update(). + TNL::F32 t; ///< Parameter of how far the player is along the line from startPos to endPos. + TNL::F32 tDelta; ///< Change in t per second (ie, velocity). + TestGame *game; ///< The game object this player is associated with + + /// Enumeration of possible player types in the game. + enum PlayerType { + PlayerTypeAI, ///< The player is an AI controlled player on the server. + PlayerTypeAIDummy, ///< The player is the ghost of an AI controlled player on the server. + PlayerTypeClient, ///< The player is owned by a client. If this is a ghost, it is owned by a user other than this client. + PlayerTypeMyClient, ///< The player controlled by this client. + }; + + PlayerType myPlayerType; ///< What type of player is this? + + /// Player constructor, assigns a random position in the playing field to the player, and + /// if it is AI controlled will pick a first destination point. + Player(PlayerType pt = PlayerTypeClient); + + /// Player destructor removes the player from the game. + ~Player(); + + /// Mask bits used for determining which object states need to be updated + /// to all the clients. + enum MaskBits { + InitialMask = (1 << 0), ///< This mask bit is never set explicitly, so it can be used for initialization data. + PositionMask = (1 << 1), ///< This mask bit is set when the position information changes on the server. + }; + + /// performScopeQuery is called to determine which objects are "in scope" for the client + /// that controls this Player instance. In the TNLTest program, all objects in a circle + /// of radius 0.25 around the scope object are considered to be in scope. + void performScopeQuery(TNL::GhostConnection *connection); + + /// packUpdate writes the Player's ghost update from the server to the client. + /// This function takes advantage of the fact that the InitialMask is only ever set + /// for the first update of the object to send once-only state to the client. + TNL::U32 packUpdate(TNL::GhostConnection *connection, TNL::U32 updateMask, TNL::BitStream *stream); + + /// unpackUpdate reads the data the server wrote in packUpdate from the packet. + void unpackUpdate(TNL::GhostConnection *connection, TNL::BitStream *stream); + + /// serverSetPosition is called on the server when it receives notice from a client + /// to change the position of the player it controls. serverSetPosition will call + /// setMaskBits(PositionMask) to notify the network system that this object has + /// changed state. + void serverSetPosition(Position startPos, Position endPos, TNL::F32 t, TNL::F32 tDelta); + + /// Move this object along its path. + /// + /// If it hits the end point, and it's an AI, it will generate a new destination. + void update(TNL::F32 timeDelta); + + /// onGhostAvailable is called on the server when it knows that this Player has been + /// constructed on the specified client as a result of being "in scope". In TNLTest + /// this method call is used to test the per-ghost targeted RPC functionality of + /// NetObject subclasses by calling rpcPlayerIsInScope on the Player ghost on + /// the specified connection. + void onGhostAvailable(TNL::GhostConnection *theConnection); + + /// onGhostAdd is called for every NetObject on the client after the ghost has + /// been constructed and its initial unpackUpdate is called. A return value of + /// false from this function would indicate than an error had occured, notifying the + /// network system that the connection should be terminated. + bool onGhostAdd(TNL::GhostConnection *theConnection); + + /// Adds this Player to the list of Player instances in the specified game. + void addToGame(TestGame *theGame); + + /// rpcPlayerWillMove is used in TNLTest to demonstrate ghost->parent NetObject RPCs. + TNL_DECLARE_RPC(rpcPlayerWillMove, (TNL::StringPtr testString)); + + /// rpcPlayerDidMove is used in TNLTest to demostrate a broadcast RPC from the server + /// to all of the ghosts on clients scoping this object. It also demonstrates the + /// usage of the Float<> template argument, in this case using 6 bits for each X and + /// Y position. Float arguments to RPCs are between 0 and 1. + TNL_DECLARE_RPC(rpcPlayerDidMove, (TNL::Float<6> x, TNL::Float<6> y)); + + /// rpcPlayerIsInScope is the RPC method called by onGhostAvailable to demonstrate + /// targeted NetObject RPCs. onGhostAvailable uses the TNL_RPC_CONSTRUCT_NETEVENT + /// macro to construct a NetEvent from the RPC invocation and then posts it only + /// to the client for which the object just came into scope. + TNL_DECLARE_RPC(rpcPlayerIsInScope, (TNL::Float<6> x, TNL::Float<6> y)); + + /// This macro invocation declares the Player class to be known + /// to the TNL class management system. + TNL_DECLARE_CLASS(Player); +}; + +/// The Building class is an example of a NetObject that is ScopeAlways. +/// ScopeAlways objects are transmitted to all clients that are currently +/// ghosting, regardless of whether or not the scope object calls GhostConnection::objectInScope +/// for them or not. The "buildings" are represented by red rectangles on the +/// playing field, and are constructed with random position and extents. +class Building : public TNL::NetObject +{ + typedef TNL::NetObject Parent; +public: + /// Mask bits used to determine what states are out of date for this + /// object and what then represent. + enum MaskBits { + InitialMask = (1 << 0), ///< Building's only mask bit is the initial mask, as no other states are ever set. + }; + TestGame *game; ///< The game object this building is associated with + Position upperLeft; ///< Upper left corner of the building rectangle on the screen. + Position lowerRight; ///< Lower right corner of the building rectangle on the screen. + + /// The Building constructor creates a random position and extent for the building, and marks it as scopeAlways. + Building(); + + /// The Building destructor removes the Building from the game, if it is associated with a game object. + ~Building(); + + /// Called on the client when this Building object has been ghosted to the + /// client and its first unpackUpdate has been called. onGhostAdd adds + /// the building to the client game. + bool onGhostAdd(TNL::GhostConnection *theConnection); + + /// addToGame is a helper function called by onGhostAdd and on the server + /// to add the building to the specified game. + void addToGame(TestGame *game); + + /// packUpdate is called on the server Building object to update any out-of-date network + /// state information to the client. Since the Building object only declares an initial + /// mask bit state and never calls setMaskBits, this method will only be invoked when + /// the ghost is being created on the client. + TNL::U32 packUpdate(TNL::GhostConnection *connection, TNL::U32 updateMask, TNL::BitStream *stream); + + /// Reads the update information about the building from the specified packet BitStream. + void unpackUpdate(TNL::GhostConnection *connection, TNL::BitStream *stream); + + /// This macro declares Building to be a part of the TNL network class management system. + TNL_DECLARE_CLASS(Building); +}; + +/// TestConnection is the TNLTest connection class. +/// +/// The TestConnection class overrides particular methods for +/// connection housekeeping, and for connected clients manages +/// the transmission of client inputs to the server for player +/// position updates. +/// +/// When a client's connection to the server is lost, the +/// TestConnection notifies the network interface that it should begin +/// searching for a new server to join. +class TestConnection : public TNL::GhostConnection +{ + typedef TNL::GhostConnection Parent; +public: + + /// The TestConnection constructor. This method contains a line that can be + /// uncommented to put the TestConnection into adaptive communications mode. + TestConnection(); + + /// The player object associated with this connection. + TNL::SafePtr myPlayer; + + /// onConnectTerminated is called when the connection request to the server + /// is unable to complete due to server rejection, timeout or other error. + /// When a TestConnection connect request to a server is terminated, the client's network interface + /// is notified so it can begin searching for another server to connect to. + void onConnectTerminated(TNL::NetConnection::TerminationReason reason, const char *rejectionString); + + /// onConnectionTerminated is called when an established connection is terminated, whether + /// from the local or remote hosts explicitly disconnecting, timing out or network error. + /// When a TestConnection to a server is disconnected, the client's network interface + /// is notified so it can begin searching for another server to connect to. + void onConnectionTerminated(TNL::NetConnection::TerminationReason reason, const char *string); + + /// onConnectionEstablished is called on both ends of a connection when the connection is established. + /// On the server this will create a player for this client, and set it as the client's + /// scope object. On both sides this will set the proper ghosting behavior for the connection (ie server to client). + void onConnectionEstablished(); + + /// isDataToTransmit is called each time the connection is ready to send a packet. If + /// the NetConnection subclass has data to send it should return true. In the case of a simulation, + /// this should always return true. + bool isDataToTransmit(); + + /// Remote function that client calls to set the position of the player on the server. + TNL_DECLARE_RPC(rpcSetPlayerPos, (TNL::F32 x, TNL::F32 y)); + + /// Enumeration constant used to specify the size field of Float<> parameters in the rpcGotPlayerPos method. + enum RPCEnumerationValues { + PlayerPosReplyBitSize = 6, ///< Size, in bits of the floats the server sends to the client to acknowledge position updates. + }; + + /// Remote function the server sends back to the client when it gets a player position. + /// We only use 6 bits of precision on each float to illustrate the float compression + /// that's possible using TNL's RPC. This RPC also sends bool and StringTableEntry data, + /// as well as showing the use of the TNL_DECLARE_RPC_ENUM macro. + TNL_DECLARE_RPC(rpcGotPlayerPos, (bool b1, bool b2, TNL::StringTableEntry string, TNL::Float x, TNL::Float y)); + + /// TNL_DECLARE_NETCONNECTION is used to declare that TestConnection is a valid connection class to the + /// TNL network system. + TNL_DECLARE_NETCONNECTION(TestConnection); +}; + +/// TestNetInterface - the NetInterface subclass used in TNLTest. +/// TestNetInterface subclasses TNLTest to provide server pinging and response +/// info packets. +/// When a client TestNetInterface starts, it begins sending ping +/// packets to the pingAddr address specified in the constructor. When a server +/// receives a GamePingRequest packet, it sends a GamePingResponse packet to the +/// source address of the GamePingRequest. Upon receipt of this response packet, +/// the client attempts to connect to the server that returned the response. +/// When the connection or connection attempt to that server is terminated, the +/// TestNetInterface resumes pinging for available TNLTest servers. +class TestNetInterface : public TNL::NetInterface +{ + typedef TNL::NetInterface Parent; +public: + /// Constants used in this NetInterface + enum Constants { + PingDelayTime = 2000, ///< Milliseconds to wait between sending GamePingRequest packets. + GamePingRequest = FirstValidInfoPacketId, ///< Byte value of the first byte of a GamePingRequest packet. + GamePingResponse, ///< Byte value of the first byte of a GamePingResponse packet. + }; + + bool pingingServers; ///< True if this is a client that is pinging for active servers. + TNL::U32 lastPingTime; ///< The last platform time that a GamePingRequest was sent from this network interface. + bool isServer; ///< True if this network interface is a server, false if it is a client. + + TNL::SafePtr connectionToServer; ///< A safe pointer to the current connection to the server, if this is a client. + TNL::Address pingAddress; ///< Network address to ping in searching for a server. This can be a specific host address or it can be a LAN broadcast address. + TestGame *game; ///< The game object associated with this network interface. + + /// Constructor for this network interface, called from the constructor for TestGame. + /// The constructor initializes and binds the network interface, as well as sets + /// parameters for the associated game and whether or not it is a server. + TestNetInterface(TestGame *theGame, bool server, const TNL::Address &bindAddress, const TNL::Address &pingAddr); + + /// handleInfoPacket overrides the method in the NetInterface class to handle processing + /// of the GamePingRequest and GamePingResponse packet types. + void handleInfoPacket(const TNL::Address &address, TNL::U8 packetType, TNL::BitStream *stream); + + /// sendPing sends a GamePingRequest packet to pingAddress of this TestNetInterface. + void sendPing(); + + /// Tick checks to see if it is an appropriate time to send a ping packet, in addition + /// to checking for incoming packets and processing connections. + void tick(); +}; + +/// The TestGame class manages a TNLTest client or server instance. +/// TestGame maintains a list of all the Player and Building objects in the +/// playing area, and interfaces with the specific platform's windowing +/// system to respond to user input and render the current game display. +class TestGame { +public: + TNL::Vector players; ///< vector of player objects in the game + TNL::Vector buildings; ///< vector of buildings in the game + bool isServer; ///< was this game created to be a server? + TestNetInterface *myNetInterface; ///< network interface for this game + TNL::U32 lastTime; ///< last time that tick() was called + TNL::SafePtr serverPlayer; ///< the player that the server controls + TNL::SafePtr clientPlayer; ///< the player that this client controls, if this game is a client + + /// Constructor for TestGame, determines whether this game will be a client + /// or a server, and what addresses to bind to and ping. If this game is a + /// server, it will construct 50 random buildings and 15 random AI players to + /// populate the "world" with. TestGame also constructs an AsymmetricKey to + /// demonstrate establishing secure connections with clients and servers. + TestGame(bool server, const TNL::Address &bindAddress, const TNL::Address &pingAddress); + + /// Destroys a game, freeing all Player and Building objects associated with it. + ~TestGame(); + + /// createLocalConnection demonstrates the use of so-called "short circuit" connections + /// for connecting to a server NetInterface in the same process as this client game. + void createLocalConnection(TestGame *serverGame); + + /// Called periodically by the platform windowing code, tick will update + /// all the players in the simulation as well as tick() the game's + /// network interface. + void tick(); + + /// renderFrame is called by the platform windowing code to notify the game + /// that it should render the current world using the specified window area. + void renderFrame(int width, int height); + + /// moveMyPlayerTo is called by the platform windowing code in response to + /// user input. + void moveMyPlayerTo(Position newPosition); +}; + +/// The instance of the client game, if there is a client currently running. +extern TestGame *clientGame; + +/// The instance of the server game, if there is a server currently running. +extern TestGame *serverGame; + +}; + +using namespace TNLTest; diff --git a/tnl-1.5.0/tnl/test/testGameRender.cpp b/tnl-1.5.0/tnl/test/testGameRender.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a0ff091732ac6de399b732c9aeb7d0b633144c4 --- /dev/null +++ b/tnl-1.5.0/tnl/test/testGameRender.cpp @@ -0,0 +1,121 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - TNLTest example program +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#if defined(_WIN32) +#include + + +#include +#elif defined (__APPLE__) +#include +#else +#include +#endif +#include "testGame.h" +#include + +namespace TNLTest { + +void TestGame::renderFrame(int width, int height) +{ + glClearColor(1, 1, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 1, 1, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + + // first, render the alpha blended circle around the player, + // to show the scoping range. + + if(clientPlayer) + { + Position p = clientPlayer->renderPos; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBegin(GL_POLYGON); + glColor4f(0.5f, 0.5f, 0.5f, 0.65f); + for(TNL::F32 r = 0; r < 3.1415 * 2; r += 0.1f) + { + glVertex2f(p.x + 0.25f * cos(r), p.y + 0.25f * sin(r)); + } + + glEnd(); + glDisable(GL_BLEND); + } + + // then draw all the buildings. + for(TNL::S32 i = 0; i < buildings.size(); i++) + { + Building *b = buildings[i]; + glBegin(GL_POLYGON); + glColor3f(1, 0, 0); + glVertex2f(b->upperLeft.x, b->upperLeft.y); + glVertex2f(b->lowerRight.x, b->upperLeft.y); + glVertex2f(b->lowerRight.x, b->lowerRight.y); + glVertex2f(b->upperLeft.x, b->lowerRight.y); + glEnd(); + } + + // last, draw all the players in the game. + for(TNL::S32 i = 0; i < players.size(); i++) + { + Player *p = players[i]; + glBegin(GL_POLYGON); + glColor3f(0,0,0); + + glVertex2f(p->renderPos.x - 0.012f, p->renderPos.y - 0.012f); + glVertex2f(p->renderPos.x + 0.012f, p->renderPos.y - 0.012f); + glVertex2f(p->renderPos.x + 0.012f, p->renderPos.y + 0.012f); + glVertex2f(p->renderPos.x - 0.012f, p->renderPos.y + 0.012f); + glEnd(); + + glBegin(GL_POLYGON); + switch(p->myPlayerType) + { + case Player::PlayerTypeAI: + case Player::PlayerTypeAIDummy: + glColor3f(0, 0, 1); + break; + case Player::PlayerTypeClient: + glColor3f(0.5, 0.5, 1); + break; + case Player::PlayerTypeMyClient: + glColor3f(1, 1, 1); + break; + } + glVertex2f(p->renderPos.x - 0.01f, p->renderPos.y - 0.01f); + glVertex2f(p->renderPos.x + 0.01f, p->renderPos.y - 0.01f); + glVertex2f(p->renderPos.x + 0.01f, p->renderPos.y + 0.01f); + glVertex2f(p->renderPos.x - 0.01f, p->renderPos.y + 0.01f); + + glEnd(); + } +} + +}; diff --git a/tnl-1.5.0/tnl/test/testWindow.cpp b/tnl-1.5.0/tnl/test/testWindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e35916120bfa496f1d2ff134546c9bae498d6bb5 --- /dev/null +++ b/tnl-1.5.0/tnl/test/testWindow.cpp @@ -0,0 +1,182 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - TNLTest example program +// Copyright (C) 2004 GarageGames.com, Inc. +// Portions of this file (c) 1994 Andrew Davison +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + + +#include +#include +#include +#include "testGame.h" +#include "../tnl/tnlLog.h" + +#include "../glut/glutInclude.h" + +static const char *localBroadcastAddress = "IP:broadcast:28999"; +static const char *localHostAddress = "IP:localhost:28999"; + +void createGameClient(bool pingLocalHost = false) +{ + delete clientGame; + delete serverGame; + + // create a client, by default pinging the LAN broadcast on port 28999 + clientGame = new TestGame(false,TNL::Address(TNL::IPProtocol, TNL::Address::Any, 0),TNL::Address(pingLocalHost ? localHostAddress : localBroadcastAddress)); + serverGame = NULL; +} + +void createGameServer() +{ + delete clientGame; + delete serverGame; + + clientGame = NULL; + // create a server, listening on port 28999. + serverGame = new TestGame(true,TNL::Address(TNL::IPProtocol,TNL::Address::Any, 28999),TNL::Address(localBroadcastAddress)); +} + +void createGameClientServer() +{ + delete clientGame; + delete serverGame; + + // construct two local games, one client and one server, and have the client game ping the localhost + // loopback address. + clientGame = new TestGame(false,TNL::Address(TNL::IPProtocol, TNL::Address::Any, 0),TNL::Address(localHostAddress)); + serverGame = new TestGame(true,TNL::Address(TNL::IPProtocol,TNL::Address::Any, 28999),TNL::Address(localBroadcastAddress)); + + // If the following line is commented out, the local games will create a normal (network) connection. + // the createLocalConnection call constructs a short-circuit connection that works without + // network access at all. + clientGame->createLocalConnection(serverGame); +} + +void onExit() +{ + delete clientGame; + delete serverGame; +} + + +int gWindowWidth = 400; +int gWindowHeight = 400; + +void reshape(int nw, int nh) +{ + gWindowWidth = nw; + gWindowHeight = nh; +} + +void mouse(int button, int state, int x, int y) +{ + static int mouseState=0; + + if(!state) // mouse up + { + Position p; + p.x = x / TNL::F32(gWindowWidth); + p.y = y / TNL::F32(gWindowHeight); + + if(clientGame) + clientGame->moveMyPlayerTo(p); + else if(serverGame) + serverGame->moveMyPlayerTo(p); + } +} + + +void idle() +{ + if(clientGame) + clientGame->tick(); + if(serverGame) + serverGame->tick(); + glutPostRedisplay(); +} + +void display() +{ + if(clientGame) + clientGame->renderFrame(gWindowWidth, gWindowHeight); + else if(serverGame) + serverGame->renderFrame(gWindowWidth, gWindowHeight); + glFlush(); + glutSwapBuffers(); +} + +void menu(int value) +{ + switch(value) + { + case 1: + createGameClient(false); + break; + case 2: + createGameServer(); + break; + case 3: + createGameClientServer(); + break; + case 4: + createGameClient(true); + break; + } +} + +#include +class StdoutLogConsumer : public TNL::LogConsumer +{ +public: + void logString(const char *string) + { + printf("%s\r\n", string); + } +} gStdoutLogConsumer; + +int main(int argc, char **argv) +{ + TNLLogEnable(LogGhostConnection, true); + createGameClient(); + glutInitWindowSize(gWindowWidth, gWindowHeight); + glutInit(&argc, argv); + + glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB); + glutCreateWindow("TNLTest - Right Button for Menu"); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutMouseFunc(mouse); + glutIdleFunc(idle); + atexit(onExit); + + glutCreateMenu(menu); + glutAddMenuEntry("Restart as client", 1); + glutAddMenuEntry("Restart as server", 2); + glutAddMenuEntry("Restart as client/server", 3); + glutAddMenuEntry("Restart as client pinging localhost", 4); + glutAttachMenu( GLUT_RIGHT_BUTTON ); + + glutMainLoop(); +} + diff --git a/tnl-1.5.0/tnl/tnl.mcp b/tnl-1.5.0/tnl/tnl.mcp new file mode 100644 index 0000000000000000000000000000000000000000..962f1f90c5313e7ec7939b65b14425d68c8115bc Binary files /dev/null and b/tnl-1.5.0/tnl/tnl.mcp differ diff --git a/tnl-1.5.0/tnl/tnl.sln b/tnl-1.5.0/tnl/tnl.sln new file mode 100644 index 0000000000000000000000000000000000000000..ba6e34917df65a6a8775c26554aae9c8a1212c17 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl.sln @@ -0,0 +1,134 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tnl", "tnl\tnl.vcproj", "{5FAF4911-1DA7-44FE-9DA1-49AE25B11250}" + ProjectSection(ProjectDependencies) = postProject + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} = {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TNLTest", "test\TNLTest.vcproj", "{2BF337F1-B812-4324-A9BA-E4D580C8CFF1}" + ProjectSection(ProjectDependencies) = postProject + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} = {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} = {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "test\server.vcproj", "{2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}" + ProjectSection(ProjectDependencies) = postProject + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} = {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} = {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtomcrypt", "libtomcrypt\libtomcrypt.vcproj", "{3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "master", "master\master.vcproj", "{CE4F0113-8119-491D-BCBE-20F5C3A555FC}" + ProjectSection(ProjectDependencies) = postProject + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} = {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} = {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "masterclient", "masterclient\masterclient.vcproj", "{F931A5FA-FF37-4977-8493-786AFD5D71EC}" + ProjectSection(ProjectDependencies) = postProject + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} = {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} = {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAP", "zap\ZAP.vcproj", "{F1A0916C-3232-4C2E-B52B-368955AA4C62}" + ProjectSection(ProjectDependencies) = postProject + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} = {5FAF4911-1DA7-44FE-9DA1-49AE25B11250} + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} = {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Debug Win32 = Debug Win32 + Debug Xbox = Debug Xbox + Release = Release + Release Win32 = Release Win32 + Release Xbox = Release Xbox + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Debug.ActiveCfg = Debug|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Debug.Build.0 = Debug|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Debug Win32.ActiveCfg = Debug|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Debug Win32.Build.0 = Debug|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Debug Xbox.ActiveCfg = Debug|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Debug Xbox.Build.0 = Debug|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Release.ActiveCfg = Release|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Release.Build.0 = Release|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Release Win32.ActiveCfg = Release|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Release Win32.Build.0 = Release|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Release Xbox.ActiveCfg = Release|Win32 + {5FAF4911-1DA7-44FE-9DA1-49AE25B11250}.Release Xbox.Build.0 = Release|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Debug.ActiveCfg = Debug|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Debug.Build.0 = Debug|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Debug Win32.ActiveCfg = Debug|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Debug Xbox.ActiveCfg = Debug|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Debug Xbox.Build.0 = Debug|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Release.ActiveCfg = Release|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Release.Build.0 = Release|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Release Win32.ActiveCfg = Release|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Release Win32.Build.0 = Release|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Release Xbox.ActiveCfg = Release|Win32 + {2BF337F1-B812-4324-A9BA-E4D580C8CFF1}.Release Xbox.Build.0 = Release|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Debug.ActiveCfg = Debug|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Debug.Build.0 = Debug|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Debug Win32.ActiveCfg = Debug|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Debug Xbox.ActiveCfg = Debug|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Debug Xbox.Build.0 = Debug|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Release.ActiveCfg = Release|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Release Win32.ActiveCfg = Release|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Release Win32.Build.0 = Release|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Release Xbox.ActiveCfg = Release|Win32 + {2BC8A06B-B9E6-4C92-9E10-6B5E37CBFF96}.Release Xbox.Build.0 = Release|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Debug.ActiveCfg = Debug|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Debug.Build.0 = Debug|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Debug Win32.ActiveCfg = Debug|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Debug Win32.Build.0 = Debug|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Debug Xbox.ActiveCfg = Debug|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Debug Xbox.Build.0 = Debug|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Release.ActiveCfg = Release|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Release.Build.0 = Release|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Release Win32.ActiveCfg = Release|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Release Win32.Build.0 = Release|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Release Xbox.ActiveCfg = Release|Win32 + {3F7F7B79-4473-4CAB-A54E-4274A9F1A01A}.Release Xbox.Build.0 = Release|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Debug.ActiveCfg = Debug|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Debug.Build.0 = Debug|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Debug Win32.ActiveCfg = Debug|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Debug Xbox.ActiveCfg = Debug|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Debug Xbox.Build.0 = Debug|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Release.ActiveCfg = Release|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Release.Build.0 = Release|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Release Win32.ActiveCfg = Release|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Release Win32.Build.0 = Release|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Release Xbox.ActiveCfg = Release|Win32 + {CE4F0113-8119-491D-BCBE-20F5C3A555FC}.Release Xbox.Build.0 = Release|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Debug.ActiveCfg = Debug|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Debug.Build.0 = Debug|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Debug Win32.ActiveCfg = Debug|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Debug Xbox.ActiveCfg = Debug|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Debug Xbox.Build.0 = Debug|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Release.ActiveCfg = Release|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Release Win32.ActiveCfg = Release|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Release Win32.Build.0 = Release|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Release Xbox.ActiveCfg = Release|Win32 + {F931A5FA-FF37-4977-8493-786AFD5D71EC}.Release Xbox.Build.0 = Release|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Debug.ActiveCfg = Debug|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Debug.Build.0 = Debug|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Debug Win32.ActiveCfg = Debug|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Debug Win32.Build.0 = Debug|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Debug Xbox.ActiveCfg = Debug|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Debug Xbox.Build.0 = Debug|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Release.ActiveCfg = Release|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Release.Build.0 = Release|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Release Win32.ActiveCfg = Release|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Release Win32.Build.0 = Release|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Release Xbox.ActiveCfg = Release|Win32 + {F1A0916C-3232-4C2E-B52B-368955AA4C62}.Release Xbox.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/tnl-1.5.0/tnl/tnl/Makefile b/tnl-1.5.0/tnl/tnl/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6dad149f3f9f21e622636fced3cc1589d5a2facc --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/Makefile @@ -0,0 +1,49 @@ +# TNL Makefile +# (c) 2003 GarageGames +# +# This makefile is for gcc-based projects, at the moment. + + +# +# Configuration +# +CC=g++ -g -DTNL_DEBUG -DTNL_ENABLE_LOGGING -I../libtomcrypt # -O2 + +OBJECTS=\ + assert.o\ + asymmetricKey.o\ + bitStream.o\ + byteBuffer.o\ + certificate.o\ + clientPuzzle.o\ + connectionStringTable.o\ + dataChunker.o\ + eventConnection.o\ + ghostConnection.o\ + huffmanStringProcessor.o\ + log.o\ + netBase.o\ + netConnection.o\ + netInterface.o\ + netObject.o\ + netStringTable.o\ + platform.o\ + random.o\ + rpc.o\ + symmetricCipher.o\ + tnlMethodDispatch.o\ + journal.o\ + udp.o\ + vector.o\ + +CFLAGS= + +.cpp.o : + $(CC) -c $(CFLAGS) $< + +default: $(OBJECTS) + @echo Building libtnl.a ... + ar rcv libtnl.a $(OBJECTS) + +clean: + rm -f $(OBJECTS) libtnl.a diff --git a/tnl-1.5.0/tnl/tnl/assert.cpp b/tnl-1.5.0/tnl/tnl/assert.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a94f13c824360d7e9b1400ced0b2efbdb1af5aae --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/assert.cpp @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlAssert.h" +#include +#include "tnlLog.h" + +namespace TNL { + +#ifdef TNL_ENABLE_ASSERTS + +//-------------------------------------- STATIC Declaration +static bool processing = false; + +//-------------------------------------- +static bool displayMessageBox(const char *title, const char *message, bool retry) +{ + if (retry) + return Platform::AlertRetry(title, message); + + Platform::AlertOK(title, message); + return false; +} + +//-------------------------------------- +void Assert::processAssert(const char *filename, U32 lineNumber, const char *message) +{ + processing = true; + + char buffer[2048]; + dSprintf(buffer, sizeof(buffer), "Fatal: (%s: %ld)", filename, lineNumber); +#ifdef TNL_DEBUG + // In debug versions, allow a retry even for ISVs... + bool retry = displayMessageBox(buffer, message, true); +#else + bool retry = displayMessageBox(buffer, message, ((assertType == Fatal) ? true : false) ); +#endif + if (!retry) + Platform::forceQuit(); + + processing = false; +} + +bool Assert::processingAssert() +{ + return processing; +} + +#endif + +//-------------------------------------- +const char* avar(const char *message, ...) +{ + static char buffer[4096]; + va_list args; + va_start(args, message); + dVsprintf(buffer, sizeof(buffer), message, args); + return( buffer ); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/asymmetricKey.cpp b/tnl-1.5.0/tnl/tnl/asymmetricKey.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3bbba4c99db6ca32ea113b9c019615f6b1f6e168 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/asymmetricKey.cpp @@ -0,0 +1,200 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlAsymmetricKey.h" +#include "tnlRandom.h" +#include +#include "tnlLog.h" + +#define crypto_key ecc_key +#define crypto_make_key ecc_make_key +#define crypto_free ecc_free +#define crypto_import ecc_import +#define crypto_export ecc_export +#define crypto_shared_secret ecc_shared_secret + +namespace TNL +{ + +enum { + StaticCryptoBufferSize = 2048, +}; + +static U8 staticCryptoBuffer[StaticCryptoBufferSize]; + +AsymmetricKey::AsymmetricKey(U32 keySize) +{ + mIsValid = false; + + int descriptorIndex = register_prng ( &yarrow_desc ); + crypto_key *theKey = (crypto_key *) malloc(sizeof(crypto_key)); + + if( crypto_make_key((prng_state *) Random::getState(), descriptorIndex, + keySize, theKey) != CRYPT_OK ) + return; + + mKeyData = theKey; + mKeySize = keySize; + + unsigned long bufferLen = sizeof(staticCryptoBuffer) - sizeof(U32) - 1; + + staticCryptoBuffer[0] = KeyTypePrivate; + writeU32ToBuffer(mKeySize, staticCryptoBuffer + 1); + + crypto_export(staticCryptoBuffer + sizeof(U32) + 1, &bufferLen, PK_PRIVATE, theKey); + bufferLen += sizeof(U32) + 1; + + mPrivateKey = new ByteBuffer(staticCryptoBuffer, bufferLen); + mPrivateKey->takeOwnership(); + + bufferLen = sizeof(staticCryptoBuffer) - sizeof(U32) - 1; + + staticCryptoBuffer[0] = KeyTypePublic; + writeU32ToBuffer(mKeySize, staticCryptoBuffer + 1); + + crypto_export(staticCryptoBuffer + sizeof(U32) + 1, &bufferLen, PK_PUBLIC, theKey); + bufferLen += sizeof(U32) + 1; + + mPublicKey = new ByteBuffer(staticCryptoBuffer, bufferLen); + mPublicKey->takeOwnership(); + + mHasPrivateKey = true; + mIsValid = true; +} + +AsymmetricKey::~AsymmetricKey() +{ + if(mKeyData) + { + crypto_free((crypto_key *) mKeyData); + free(mKeyData); + } +} + +void AsymmetricKey::load(const ByteBuffer &theBuffer) +{ + mIsValid = false; + + crypto_key *theKey = (crypto_key *) malloc(sizeof(crypto_key)); + const U8 *bufferPtr = theBuffer.getBuffer(); + + mHasPrivateKey = bufferPtr[0] == KeyTypePrivate; + + U32 bufferSize = theBuffer.getBufferSize(); + if(bufferSize < sizeof(U32) + 1) + return; + + mKeySize = readU32FromBuffer(bufferPtr + 1); + + if( crypto_import(bufferPtr + sizeof(U32) + 1, bufferSize - sizeof(U32) - 1, theKey) + != CRYPT_OK) + return; + + mKeyData = theKey; + + if(mHasPrivateKey) + { + unsigned long bufferLen = sizeof(staticCryptoBuffer) - sizeof(U32) - 1; + staticCryptoBuffer[0] = KeyTypePublic; + + writeU32ToBuffer(mKeySize, staticCryptoBuffer); + + if( crypto_export(staticCryptoBuffer + sizeof(U32) + 1, &bufferLen, PK_PUBLIC, theKey) + != CRYPT_OK ) + return; + + bufferLen += sizeof(U32) + 1; + + mPublicKey = new ByteBuffer(staticCryptoBuffer, bufferLen); + mPublicKey->takeOwnership(); + mPrivateKey = new ByteBuffer(theBuffer); + mPrivateKey->takeOwnership(); + } + else + { + mPublicKey = new ByteBuffer(theBuffer); + mPublicKey->takeOwnership(); + } + mIsValid = true; +} + +ByteBufferPtr AsymmetricKey::computeSharedSecretKey(AsymmetricKey *publicKey) +{ + if(publicKey->getKeySize() != getKeySize() || !mHasPrivateKey) + return NULL; + + U8 hash[32]; + unsigned long outLen = sizeof(staticCryptoBuffer); + + TIME_BLOCK(secretSubKeyGen, + crypto_shared_secret((crypto_key *) mKeyData, (crypto_key *) publicKey->mKeyData, + staticCryptoBuffer, &outLen); + ) + hash_state hashState; + sha256_init(&hashState); + sha256_process(&hashState, staticCryptoBuffer, outLen); + sha256_done(&hashState, hash); + ByteBuffer *ret = new ByteBuffer(hash, 32); + ret->takeOwnership(); + return ret; +} + +ByteBufferPtr AsymmetricKey::hashAndSign(const ByteBuffer &theByteBuffer) +{ + int descriptorIndex = register_prng ( &yarrow_desc ); + + U8 hash[32]; + hash_state hashState; + + sha256_init(&hashState); + sha256_process(&hashState, theByteBuffer.getBuffer(), theByteBuffer.getBufferSize()); + sha256_done(&hashState, hash); + + unsigned long outlen = sizeof(staticCryptoBuffer); + + ecc_sign_hash(hash, 32, + staticCryptoBuffer, &outlen, + (prng_state *) Random::getState(), descriptorIndex, (crypto_key *) mKeyData); + + return new ByteBuffer(staticCryptoBuffer, (U32) outlen); +} + +bool AsymmetricKey::verifySignature(const ByteBuffer &theByteBuffer, const ByteBuffer &theSignature) +{ + U8 hash[32]; + hash_state hashState; + + sha256_init(&hashState); + sha256_process(&hashState, theByteBuffer.getBuffer(), theByteBuffer.getBufferSize()); + sha256_done(&hashState, hash); + + int stat; + + ecc_verify_hash(theSignature.getBuffer(), theSignature.getBufferSize(), hash, 32, &stat, (crypto_key *) mKeyData); + return stat != 0; +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/bitStream.cpp b/tnl-1.5.0/tnl/tnl/bitStream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91429d664c71e49375c0d85f8a1238d03fffb226 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/bitStream.cpp @@ -0,0 +1,591 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlBitStream.h" +#include "tnlVector.h" +#include "tnlNetBase.h" +#include "tnlHuffmanStringProcessor.h" +#include "tnlSymmetricCipher.h" +#include + +#include + +namespace TNL { + +void BitStream::setMaxSizes(U32 maxReadSize, U32 maxWriteSize) +{ + maxReadBitNum = maxReadSize << 3; + maxWriteBitNum = maxWriteSize << 3; +} + +void BitStream::setMaxBitSizes(U32 maxReadSize, U32 maxWriteSize) +{ + maxReadBitNum = maxReadSize; + maxWriteBitNum = maxWriteSize; +} + +void BitStream::reset() +{ + bitNum = 0; + error = false; + mCompressRelative = false; + mStringBuffer[0] = 0; + mStringTable = NULL; +} + +U8 *BitStream::getBytePtr() +{ + return getBuffer() + getBytePosition(); +} + +void BitStream::writeClassId(U32 classId, U32 classType, U32 classGroup) +{ + TNLAssert(classType < NetClassTypeCount, "Out of range class type."); + TNLAssert(classId < NetClassRep::getNetClassCount(classGroup, classType), "Out of range class id."); + writeInt(classId, NetClassRep::getNetClassBitSize(classGroup, classType)); +} + +U32 BitStream::readClassId(U32 classType, U32 classGroup) +{ + TNLAssert(classType < NetClassTypeCount, "Out of range class type."); + U32 ret = readInt(NetClassRep::getNetClassBitSize(classGroup, classType)); + if(ret >= NetClassRep::getNetClassCount(classGroup, classType)) + return 0xFFFFFFFF; + return ret; +} + +bool BitStream::resizeBits(U32 newBits) +{ + U32 newSize = ((maxWriteBitNum + newBits + 7) >> 3) + ResizePad; + if(!resize(newSize)) + { + error = true; + return false; + } + maxReadBitNum = newSize << 3; + maxWriteBitNum = newSize << 3; + return true; +} + +bool BitStream::writeBits(U32 bitCount, const void *bitPtr) +{ + if(!bitCount) + return true; + + if(bitCount + bitNum > maxWriteBitNum) + if(!resizeBits(bitCount + bitNum - maxWriteBitNum)) + return false; + + U32 upShift = bitNum & 0x7; + U32 downShift= 8 - upShift; + + const U8 *sourcePtr = (U8 *) bitPtr; + U8 *destPtr = getBuffer() + (bitNum >> 3); + + // if this write is for <= 1 byte, and it will all fit in the + // first dest byte, then do some special masking. + if(downShift >= bitCount) + { + U8 mask = ((1 << bitCount) - 1) << upShift; + *destPtr = (*destPtr & ~mask) | ((*sourcePtr << upShift) & mask); + bitNum += bitCount; + return true; + } + + // check for byte aligned writes -- this will be + // much faster than the shifting writes. + if(!upShift) + { + bitNum += bitCount; + for(; bitCount >= 8; bitCount -= 8) + *destPtr++ = *sourcePtr++; + if(bitCount) + { + U8 mask = (1 << bitCount) - 1; + *destPtr = (*sourcePtr & mask) | (*destPtr & ~mask); + } + return true; + } + + // the write destination is not byte aligned. + U8 sourceByte; + U8 destByte = *destPtr & (0xFF >> downShift); + U8 lastMask = 0xFF >> (7 - ((bitNum + bitCount - 1) & 0x7)); + + bitNum += bitCount; + + for(;bitCount >= 8; bitCount -= 8) + { + sourceByte = *sourcePtr++; + *destPtr++ = destByte | (sourceByte << upShift); + destByte = sourceByte >> downShift; + } + if(bitCount == 0) + { + *destPtr = (*destPtr & ~lastMask) | (destByte & lastMask); + return true; + } + if(bitCount <= downShift) + { + *destPtr = (*destPtr & ~lastMask) | ((destByte | (*sourcePtr << upShift)) & lastMask); + return true; + } + sourceByte = *sourcePtr; + + *destPtr++ = destByte | (sourceByte << upShift); + *destPtr = (*destPtr & ~lastMask) | ((sourceByte >> downShift) & lastMask); + return true; +} + +bool BitStream::readBits(U32 bitCount, void *bitPtr) +{ + if(!bitCount) + return true; + if(bitCount + bitNum > maxReadBitNum) + { + error = true; + return false; + } + + U8 *sourcePtr = getBuffer() + (bitNum >> 3); + U32 byteCount = (bitCount + 7) >> 3; + + U8 *destPtr = (U8 *) bitPtr; + + U32 downShift = bitNum & 0x7; + U32 upShift = 8 - downShift; + + if(!downShift) + { + while(byteCount--) + *destPtr++ = *sourcePtr++; + bitNum += bitCount; + return true; + } + + U8 sourceByte = *sourcePtr >> downShift; + bitNum += bitCount; + + for(; bitCount >= 8; bitCount -= 8) + { + U8 nextByte = *++sourcePtr; + *destPtr++ = sourceByte | (nextByte << upShift); + sourceByte = nextByte >> downShift; + } + if(bitCount) + { + if(bitCount <= upShift) + { + *destPtr = sourceByte; + return true; + } + *destPtr = sourceByte | ( (*++sourcePtr) << upShift); + } + return true; +} + +bool BitStream::setBit(U32 bitCount, bool set) +{ + if(bitCount >= maxWriteBitNum) + if(!resizeBits(bitCount - maxWriteBitNum + 1)) + return false; + if(set) + *(getBuffer() + (bitCount >> 3)) |= (1 << (bitCount & 0x7)); + else + *(getBuffer() + (bitCount >> 3)) &= ~(1 << (bitCount & 0x7)); + return true; +} + +bool BitStream::testBit(U32 bitCount) +{ + return (*(getBuffer() + (bitCount >> 3)) & (1 << (bitCount & 0x7))) != 0; +} + +bool BitStream::writeFlag(bool val) +{ + if(bitNum + 1 > maxWriteBitNum) + if(!resizeBits(1)) + return false; + if(val) + *(getBuffer() + (bitNum >> 3)) |= (1 << (bitNum & 0x7)); + else + *(getBuffer() + (bitNum >> 3)) &= ~(1 << (bitNum & 0x7)); + bitNum++; + return (val); +} + +bool BitStream::write(const ByteBuffer *theBuffer) +{ + U32 size = theBuffer->getBufferSize(); + if(size > 1023) + return false; + + writeInt(size, 10); + return write(size, theBuffer->getBuffer()); +} + +bool BitStream::read(ByteBuffer *theBuffer) +{ + U32 size = readInt(10); + theBuffer->takeOwnership(); + theBuffer->resize(size); + return read(size, theBuffer->getBuffer()); +} + +U32 BitStream::readInt(U8 bitCount) +{ + U32 ret = 0; + readBits(bitCount, &ret); + ret = convertLEndianToHost(ret); + + // Clear bits that we didn't read. + if(bitCount == 32) + return ret; + else + ret &= (1 << bitCount) - 1; + + return ret; +} + +void BitStream::writeInt(U32 val, U8 bitCount) +{ + val = convertHostToLEndian(val); + writeBits(bitCount, &val); +} + +void BitStream::writeFloat(F32 f, U8 bitCount) +{ + writeInt(U32(f * ((1 << bitCount) - 1)), bitCount); +} + +F32 BitStream::readFloat(U8 bitCount) +{ + return readInt(bitCount) / F32((1 << bitCount) - 1); +} + +void BitStream::writeSignedFloat(F32 f, U8 bitCount) +{ + writeSignedInt(S32(f * ((1 << (bitCount - 1)) - 1)), bitCount); +} + +F32 BitStream::readSignedFloat(U8 bitCount) +{ + return readSignedInt(bitCount) / F32((1 << (bitCount - 1)) - 1); +} + +void BitStream::writeSignedInt(S32 value, U8 bitCount) +{ + if(writeFlag(value < 0)) + writeInt(-value, bitCount - 1); + else + writeInt(value, bitCount - 1); +} + +S32 BitStream::readSignedInt(U8 bitCount) +{ + if(readFlag()) + return -(S32)readInt(bitCount - 1); + else + return (S32)readInt(bitCount - 1); +} + +void BitStream::writeNormalVector(const Point3F& vec, U8 bitCount) +{ + F32 phi = F32(atan2(vec.x, vec.y) * FloatInversePi ); + F32 theta = F32(atan2(vec.z, sqrt(vec.x*vec.x + vec.y*vec.y)) * Float2InversePi); + + writeSignedFloat(phi, bitCount+1); + writeSignedFloat(theta, bitCount); +} + +void BitStream::readNormalVector(Point3F *vec, U8 bitCount) +{ + F32 phi = readSignedFloat(bitCount+1) * FloatPi; + F32 theta = readSignedFloat(bitCount) * FloatHalfPi; + + vec->x = sin(phi)*cos(theta); + vec->y = cos(phi)*cos(theta); + vec->z = sin(theta); +} + +Point3F BitStream::dumbDownNormal(const Point3F& vec, U8 bitCount) +{ + U8 buffer[128]; + BitStream temp(buffer, 128); + + temp.writeNormalVector(vec, bitCount); + temp.setBitPosition(0); + + Point3F ret; + temp.readNormalVector(&ret, bitCount); + return ret; +} + +void BitStream::writeNormalVector(const Point3F& vec, U8 angleBitCount, U8 zBitCount) +{ + // if this is a z up or down vector, just write out a couple of bits + // if z is -1 or 1, x and y must both be 0 + + // FIXME: this should test if the vec.z is within zBitCount precision of 1 + // BJG - fixed, but may be inefficient. Lookup table? + if(writeFlag(fabs(vec.z) >= (1.0f-(1.0f/zBitCount)))) + writeFlag(vec.z < 0); + else + { + // write out the z value and the angle that x and y make around the z axis + writeSignedFloat( vec.z, zBitCount ); + writeSignedFloat( atan2(vec.x,vec.y) * FloatInverse2Pi, angleBitCount ); + } +} + +void BitStream::readNormalVector(Point3F * vec, U8 angleBitCount, U8 zBitCount) +{ + if(readFlag()) + { + vec->z = readFlag() ? -1.0f : 1.0f; + vec->x = 0; + vec->y = 0; + } + else + { + vec->z = readSignedFloat(zBitCount); + + F32 angle = Float2Pi * readSignedFloat(angleBitCount); + + F32 mult = (F32) sqrt(1.0f - vec->z * vec->z); + vec->x = mult * cos(angle); + vec->y = mult * sin(angle); + } +} + +//---------------------------------------------------------------------------- + +void BitStream::clearPointCompression() +{ + mCompressRelative = false; +} + +void BitStream::setPointCompression(const Point3F& p) +{ + mCompressRelative = true; + mCompressPoint = p; +} + +static U32 gBitCounts[4] = { + 16, 18, 20, 32 +}; + +void BitStream::writePointCompressed(const Point3F& p,F32 scale) +{ + // Same # of bits for all axis + Point3F vec; + F32 invScale = 1 / scale; + U32 type; + if(mCompressRelative) + { + vec.x = p.x - mCompressPoint.x; + vec.y = p.y - mCompressPoint.y; + vec.z = p.z - mCompressPoint.z; + + F32 dist = (F32) sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) * invScale; + if(dist < (1 << 15)) + type = 0; + else if(dist < (1 << 17)) + type = 1; + else if(dist < (1 << 19)) + type = 2; + else + type = 3; + } + else + type = 3; + + writeInt(type, 2); + + if (type != 3) + { + type = gBitCounts[type]; + writeSignedInt(S32(vec.x * invScale),type); + writeSignedInt(S32(vec.y * invScale),type); + writeSignedInt(S32(vec.z * invScale),type); + } + else + { + write(p.x); + write(p.y); + write(p.z); + } +} + +void BitStream::readPointCompressed(Point3F* p,F32 scale) +{ + // Same # of bits for all axis + U32 type = readInt(2); + + if(type == 3) + { + read(&p->x); + read(&p->y); + read(&p->z); + } + else + { + type = gBitCounts[type]; + p->x = (F32) readSignedInt(type); + p->y = (F32) readSignedInt(type); + p->z = (F32) readSignedInt(type); + + p->x = mCompressPoint.x + p->x * scale; + p->y = mCompressPoint.y + p->y * scale; + p->z = mCompressPoint.z + p->z * scale; + } +} + +void BitStream::readString(char buf[256]) +{ + if(readFlag()) + { + S32 offset = readInt(8); + HuffmanStringProcessor::readHuffBuffer(this, mStringBuffer + offset); + strcpy(buf, mStringBuffer); + } + else + { + HuffmanStringProcessor::readHuffBuffer(this, buf); + strcpy(mStringBuffer, buf); + } +} + +void BitStream::writeString(const char *string, U8 maxLen) +{ + if(!string) + string = ""; + U8 j; + for(j = 0; j < maxLen && mStringBuffer[j] == string[j] && string[j];j++) + ; + strncpy(mStringBuffer + j, string + j, maxLen - j); + mStringBuffer[maxLen] = 0; + + if(writeFlag(j > 2)) + { + writeInt(j, 8); + HuffmanStringProcessor::writeHuffBuffer(this, string + j, maxLen - j); + } + else + HuffmanStringProcessor::writeHuffBuffer(this, string, maxLen); +} + +//-------------------------------------------------------------------- +//-------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void BitStream::readStringTableEntry(StringTableEntry *ste) +{ + if(mStringTable) + *ste = mStringTable->readStringTableEntry(this); + else + { + char buf[256]; + readString(buf); + ste->set(buf); + } +} + +void BitStream::writeStringTableEntry(const StringTableEntry &ste) +{ + if(mStringTable) + mStringTable->writeStringTableEntry(this, ste); + else + writeString(ste.getString()); +} +//------------------------------------------------------------------------------ + +void BitStream::hashAndEncrypt(U32 hashDigestSize, U32 encryptStartOffset, SymmetricCipher *theCipher) +{ + U32 digestStart = getBytePosition(); + setBytePosition(digestStart); + hash_state hashState; + + U8 hash[32]; + + // do a sha256 hash of the BitStream: + sha256_init(&hashState); + sha256_process(&hashState, getBuffer(), digestStart); + sha256_done(&hashState, hash); + + // write the hash into the BitStream: + write(hashDigestSize, hash); + + theCipher->encrypt(getBuffer() + encryptStartOffset, + getBuffer() + encryptStartOffset, + getBytePosition() - encryptStartOffset); +} + +bool BitStream::decryptAndCheckHash(U32 hashDigestSize, U32 decryptStartOffset, SymmetricCipher *theCipher) +{ + U32 bufferSize = getBufferSize(); + U8 *buffer = getBuffer(); + + if(bufferSize < decryptStartOffset + hashDigestSize) + return false; + + theCipher->decrypt(buffer + decryptStartOffset, + buffer + decryptStartOffset, + bufferSize - decryptStartOffset); + + hash_state hashState; + U8 hash[32]; + + sha256_init(&hashState); + sha256_process(&hashState, buffer, bufferSize - hashDigestSize); + sha256_done(&hashState, hash); + + bool ret = !memcmp(buffer + bufferSize - hashDigestSize, hash, hashDigestSize); + if(ret) + resize(bufferSize - hashDigestSize); + return ret; +} + +//------------------------------------------------------------------------------ + +NetError PacketStream::sendto(Socket &outgoingSocket, const Address &addr) +{ + return outgoingSocket.sendto(addr, buffer, getBytePosition()); +} + +NetError PacketStream::recvfrom(Socket &incomingSocket, Address *recvAddress) +{ + NetError error; + S32 dataSize; + error = incomingSocket.recvfrom(recvAddress, buffer, sizeof(buffer), &dataSize); + setBuffer(buffer, dataSize); + setMaxSizes(dataSize, 0); + reset(); + return error; +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/byteBuffer.cpp b/tnl-1.5.0/tnl/tnl/byteBuffer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1d6786c67d001348b956d65edf9f15139d32d77f --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/byteBuffer.cpp @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlByteBuffer.h" +#include + +namespace TNL { + +RefPtr ByteBuffer::encodeBase64() const +{ + unsigned long outLen = ((getBufferSize() / 3) + 1) * 4 + 4 + 1; + ByteBuffer *ret = new ByteBuffer(outLen); + base64_encode(getBuffer(), getBufferSize(), ret->getBuffer(), &outLen); + ret->resize(outLen+1); + ret->getBuffer()[outLen] = 0; + return ret; +} + +RefPtr ByteBuffer::decodeBase64() const +{ + unsigned long outLen = getBufferSize(); + ByteBuffer *ret = new ByteBuffer(outLen); + base64_decode(getBuffer(), getBufferSize(), ret->getBuffer(), &outLen); + ret->resize(outLen); + return ret; +} + +RefPtr ByteBuffer::encodeBase16() const +{ + U32 outLen = getBufferSize() * 2 + 1; + ByteBuffer *ret = new ByteBuffer(outLen); + const U8 *buffer = getBuffer(); + U8 *outBuffer = ret->getBuffer(); + + S32 size = getBufferSize(); + for(S32 i = 0; i < size; i++) + { + U8 b = *buffer++; + U32 nib1 = b >> 4; + U32 nib2 = b & 0xF; + if(nib1 > 9) + *outBuffer++ = 'a' + nib1 - 10; + else + *outBuffer++ = '0' + nib1; + if(nib2 > 9) + *outBuffer++ = 'a' + nib2 - 10; + else + *outBuffer++ = '0' + nib2; + } + *outBuffer = 0; + return ret; +} + +RefPtr ByteBuffer::decodeBase16() const +{ + U32 outLen = getBufferSize() >> 1; + ByteBuffer *ret = new ByteBuffer(outLen); + const U8 *src = getBuffer(); + U8 *dst = ret->getBuffer(); + for(U32 i = 0; i < outLen; i++) + { + U8 out = 0; + U8 nib1 = *src++; + U8 nib2 = *src++; + if(nib1 >= '0' && nib1 <= '9') + out = (nib1 - '0') << 4; + else if(nib1 >= 'a' && nib1 <= 'f') + out = (nib1 - 'a' + 10) << 4; + else if(nib1 >= 'A' && nib1 <= 'A') + out = (nib1 - 'A' + 10) << 4; + if(nib2 >= '0' && nib2 <= '9') + out |= nib2 - '0'; + else if(nib2 >= 'a' && nib2 <= 'f') + out |= nib2 - 'a' + 10; + else if(nib2 >= 'A' && nib2 <= 'A') + out |= nib2 - 'A' + 10; + *dst++ = out; + } + return ret; +} + +RefPtr ByteBuffer::computeMD5Hash(U32 len) const +{ + if(!len) + len = getBufferSize(); + + ByteBuffer *ret = new ByteBuffer(16); + hash_state md; + md5_init(&md); + md5_process(&md, (unsigned char *) getBuffer(), len); + md5_done(&md, ret->getBuffer()); + return ret; +} + +U32 ByteBuffer::calculateCRC(U32 start, U32 end, U32 crcVal) const +{ + static U32 crcTable[256]; + static bool crcTableValid = false; + + if(!crcTableValid) + { + U32 val; + + for(S32 i = 0; i < 256; i++) + { + val = i; + for(S32 j = 0; j < 8; j++) + { + if(val & 0x01) + val = 0xedb88320 ^ (val >> 1); + else + val = val >> 1; + } + crcTable[i] = val; + } + crcTableValid = true; + } + + if(start >= mBufSize) + return 0; + if(end > mBufSize) + end = mBufSize; + + // now calculate the crc + const U8 * buf = getBuffer(); + for(U32 i = start; i < end; i++) + crcVal = crcTable[(crcVal ^ buf[i]) & 0xff] ^ (crcVal >> 8); + return(crcVal); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/certificate.cpp b/tnl-1.5.0/tnl/tnl/certificate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f073c310fb889312e9eed71e457c299faa52b0ca --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/certificate.cpp @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlCertificate.h" + +namespace TNL { + +void Certificate::parse() +{ + BitStream aStream(getBuffer(), getBufferSize()); + + mPayload = new ByteBuffer(0); + aStream.read(mPayload); + mPublicKey = new AsymmetricKey(&aStream); + mSignature = new ByteBuffer(0); + + mSignatureByteSize = aStream.getBytePosition(); + + // advance the bit stream to the next byte: + aStream.setBytePosition(aStream.getBytePosition()); + + aStream.read(mSignature); + + if(aStream.isValid() && getBufferSize() == aStream.getBytePosition() && mPublicKey->isValid()) + mIsValid = true; +} + +bool Certificate::validate(RefPtr signatoryPublicKey) +{ + if(!mIsValid) + return false; + + ByteBuffer signedBytes(getBuffer(), mSignatureByteSize); + + return signatoryPublicKey->verifySignature(signedBytes, *mSignature); +} + +Certificate::Certificate(const ByteBuffer &payload, RefPtr publicKey, RefPtr theCAPrivateKey) +{ + mIsValid = false; + mSignatureByteSize = 0; + + if(payload.getBufferSize() > MaxPayloadSize || !publicKey->isValid()) + return; + + ByteBufferPtr thePublicKey = publicKey->getPublicKey(); + PacketStream packet; + + packet.write(&payload); + packet.write(thePublicKey); + mSignatureByteSize = packet.getBytePosition(); + packet.setBytePosition(mSignatureByteSize); + + ByteBuffer theSignedBytes(packet.getBuffer(), packet.getBytePosition()); + + mSignature = theCAPrivateKey->hashAndSign(theSignedBytes); + packet.write(mSignature); + + setBuffer(packet.getBuffer(), packet.getBytePosition()); + takeOwnership(); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/clientPuzzle.cpp b/tnl-1.5.0/tnl/tnl/clientPuzzle.cpp new file mode 100644 index 0000000000000000000000000000000000000000..662f29b2f31a83ad7579a6bfb310f15990e3e5d1 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/clientPuzzle.cpp @@ -0,0 +1,179 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlClientPuzzle.h" +#include "tnlRandom.h" + +#include + +namespace TNL { + +void ClientPuzzleManager::NonceTable::reset() +{ + mChunker.freeBlocks(); + mHashTableSize = Random::readI(MinHashTableSize, MaxHashTableSize) * 2 + 1; + mHashTable = (Entry **) mChunker.alloc(sizeof(Entry *) * mHashTableSize); + for(U32 i = 0; i < mHashTableSize; i++) + mHashTable[i] = NULL; +} + +bool ClientPuzzleManager::NonceTable::checkAdd(Nonce &theNonce) +{ + U32 nonce1 = readU32FromBuffer(theNonce.data); + U32 nonce2 = readU32FromBuffer(theNonce.data + 4); + + U64 fullNonce = (U64(nonce1) << 32) | nonce2; + + U32 hashIndex = U32(fullNonce % mHashTableSize); + for(Entry *walk = mHashTable[hashIndex]; walk; walk = walk->mHashNext) + if(walk->mNonce == theNonce) + return false; + Entry *newEntry = (Entry *) mChunker.alloc(sizeof(Entry)); + newEntry->mNonce = theNonce; + newEntry->mHashNext = mHashTable[hashIndex]; + mHashTable[hashIndex] = newEntry; + return true; +} + +ClientPuzzleManager::ClientPuzzleManager() +{ + mCurrentDifficulty = InitialPuzzleDifficulty; + mLastUpdateTime = 0; + mLastTickTime = 0; + Random::read(mCurrentNonce.data, Nonce::NonceSize); + Random::read(mLastNonce.data, Nonce::NonceSize); + + mCurrentNonceTable = new NonceTable; + mLastNonceTable = new NonceTable; +} + +ClientPuzzleManager::~ClientPuzzleManager() +{ + delete mCurrentNonceTable; + delete mLastNonceTable; +} + +void ClientPuzzleManager::tick(U32 currentTime) +{ + if(!mLastTickTime) + mLastTickTime = currentTime; + + // use delta of last tick time and current time to manage puzzle + // difficulty. + + // not yet implemented. + + + // see if it's time to refresh the current puzzle: + U32 timeDelta = currentTime - mLastUpdateTime; + if(timeDelta > PuzzleRefreshTime) + { + mLastUpdateTime = currentTime; + mLastNonce = mCurrentNonce; + NonceTable *tempTable = mLastNonceTable; + mLastNonceTable = mCurrentNonceTable; + mCurrentNonceTable = tempTable; + + mLastNonce = mCurrentNonce; + mCurrentNonceTable->reset(); + Random::read(mCurrentNonce.data, Nonce::NonceSize); + } +} + +bool ClientPuzzleManager::checkOneSolution(U32 solution, Nonce &clientNonce, Nonce &serverNonce, U32 puzzleDifficulty, U32 clientIdentity) +{ + U8 buffer[8]; + writeU32ToBuffer(solution, buffer); + writeU32ToBuffer(clientIdentity, buffer + 4); + + hash_state hashState; + U8 hash[32]; + + sha256_init(&hashState); + sha256_process(&hashState, buffer, sizeof(buffer)); + sha256_process(&hashState, clientNonce.data, Nonce::NonceSize); + sha256_process(&hashState, serverNonce.data, Nonce::NonceSize); + sha256_done(&hashState, hash); + + U32 index = 0; + while(puzzleDifficulty > 8) + { + if(hash[index]) + return false; + index++; + puzzleDifficulty -= 8; + } + U8 mask = 0xFF << (8 - puzzleDifficulty); + return (mask & hash[index]) == 0; +} + +ClientPuzzleManager::ErrorCode ClientPuzzleManager::checkSolution(U32 solution, Nonce &clientNonce, Nonce &serverNonce, U32 puzzleDifficulty, U32 clientIdentity) +{ + if(puzzleDifficulty != mCurrentDifficulty) + return InvalidPuzzleDifficulty; + NonceTable *theTable = NULL; + if(serverNonce == mCurrentNonce) + theTable = mCurrentNonceTable; + else if(serverNonce == mLastNonce) + theTable = mLastNonceTable; + if(!theTable) + return InvalidServerNonce; + if(!checkOneSolution(solution, clientNonce, serverNonce, puzzleDifficulty, clientIdentity)) + return InvalidSolution; + if(!theTable->checkAdd(clientNonce)) + return InvalidClientNonce; + return Success; +} + +bool ClientPuzzleManager::solvePuzzle(U32 *solution, Nonce &clientNonce, Nonce &serverNonce, U32 puzzleDifficulty, U32 clientIdentity) +{ + U32 startTime = Platform::getRealMilliseconds(); + U32 startValue = *solution; + + // Until we're done... + for(;;) + { + U32 nextValue = startValue + SolutionFragmentIterations; + for(;startValue < nextValue; startValue++) + { + if(checkOneSolution(startValue, clientNonce, serverNonce, puzzleDifficulty, clientIdentity)) + { + *solution = startValue; + return true; + } + } + + // Then we check to see if we're out of time... + if(Platform::getRealMilliseconds() - startTime > MaxSolutionComputeFragment) + { + *solution = startValue; + return false; + } + } +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/connectionStringTable.cpp b/tnl-1.5.0/tnl/tnl/connectionStringTable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1601893009d8fe8357395d6b0d782ac5520f0e83 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/connectionStringTable.cpp @@ -0,0 +1,152 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" + +#include "tnlEventConnection.h" +#include "tnlBitStream.h" + +namespace TNL { + +//-------------------------------------------------------------------- +static ClassChunker packetEntryFreeList(4096); + +ConnectionStringTable::ConnectionStringTable(NetConnection *parent) +{ + mParent = parent; + for(U32 i = 0; i < EntryCount; i++) + { + mEntryTable[i].nextHash = NULL; + mEntryTable[i].nextLink = &mEntryTable[i+1]; + mEntryTable[i].prevLink = &mEntryTable[i-1]; + mEntryTable[i].index = i; + mHashTable[i] = NULL; + } + mLRUHead.nextLink = &mEntryTable[0]; + mEntryTable[0].prevLink = &mLRUHead; + mLRUTail.prevLink = &mEntryTable[EntryCount-1]; + mEntryTable[EntryCount-1].nextLink = &mLRUTail; +} + +void ConnectionStringTable::writeStringTableEntry(BitStream *stream, StringTableEntryRef string) +{ + // see if the entry is in the hash table right now + U32 hashIndex = string.getIndex() % EntryCount; + Entry *sendEntry = NULL; + for(Entry *walk = mHashTable[hashIndex]; walk; walk = walk->nextHash) + { + if(walk->string == string) + { + // it's in the table + // first, push it to the back of the LRU list. + pushBack(walk); + sendEntry = walk; + break; + } + } + if(!sendEntry) + { + // not in the hash table, means we have to add it + // pull the new entry from the LRU list. + sendEntry = mLRUHead.nextLink; + + // push it to the end of the LRU list + pushBack(sendEntry); + + // remove the string from the hash table + Entry **hashWalk; + for (hashWalk = &mHashTable[sendEntry->string.getIndex() % EntryCount]; *hashWalk; hashWalk = &((*hashWalk)->nextHash)) + { + if(*hashWalk == sendEntry) + { + *hashWalk = sendEntry->nextHash; + break; + } + } + + sendEntry->string = string; + sendEntry->receiveConfirmed = false; + sendEntry->nextHash = mHashTable[hashIndex]; + mHashTable[hashIndex] = sendEntry; + } + stream->writeInt(sendEntry->index, EntryBitSize); + if(!stream->writeFlag(sendEntry->receiveConfirmed)) + { + stream->writeString(sendEntry->string.getString()); + PacketEntry *entry = packetEntryFreeList.alloc(); + + entry->stringTableEntry = sendEntry; + entry->string = sendEntry->string; + entry->nextInPacket = NULL; + + PacketList *note = &mParent->getCurrentWritePacketNotify()->stringList; + + if(!note->stringHead) + note->stringHead = entry; + else + note->stringTail->nextInPacket = entry; + note->stringTail = entry; + } +} + +StringTableEntry ConnectionStringTable::readStringTableEntry(BitStream *stream) +{ + U32 index = stream->readInt(EntryBitSize); + + char buf[256]; + if(!stream->readFlag()) + { + stream->readString(buf); + mRemoteStringTable[index].set(buf); + } + return mRemoteStringTable[index]; +} + +void ConnectionStringTable::packetReceived(PacketList *note) +{ + PacketEntry *walk = note->stringHead; + while(walk) + { + PacketEntry *next = walk->nextInPacket; + if(walk->stringTableEntry->string == walk->string) + walk->stringTableEntry->receiveConfirmed = true; + packetEntryFreeList.free(walk); + walk = next; + } +} + +void ConnectionStringTable::packetDropped(PacketList *note) +{ + PacketEntry *walk = note->stringHead; + while(walk) + { + PacketEntry *next = walk->nextInPacket; + packetEntryFreeList.free(walk); + walk = next; + } +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/dataChunker.cpp b/tnl-1.5.0/tnl/tnl/dataChunker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc6919e87810ff80e97db9f88b94ea6c54d7da7d --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/dataChunker.cpp @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlDataChunker.h" + + +//---------------------------------------------------------------------------- + +namespace TNL { + +DataChunker::DataChunker(S32 size) +{ + chunkSize = size; + curBlock = new DataBlock(size); + curBlock->next = NULL; + curBlock->curIndex = 0; +} + +DataChunker::~DataChunker() +{ + freeBlocks(); +} + +void *DataChunker::alloc(S32 size) +{ + TNLAssert(size <= chunkSize, "Data chunk too large."); + if(!curBlock || size + curBlock->curIndex > chunkSize) + { + DataBlock *temp = new DataBlock(chunkSize); + temp->next = curBlock; + temp->curIndex = 0; + curBlock = temp; + } + void *ret = curBlock->data + curBlock->curIndex; + curBlock->curIndex += (size + 3) & ~3; // dword align + return ret; +} + +DataChunker::DataBlock::DataBlock(S32 size) +{ + data = new U8[size]; +} + +DataChunker::DataBlock::~DataBlock() +{ + delete[] data; +} + +void DataChunker::freeBlocks() +{ + while(curBlock) + { + DataBlock *temp = curBlock->next; + delete curBlock; + curBlock = temp; + } +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/eventConnection.cpp b/tnl-1.5.0/tnl/tnl/eventConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fba2c9592df87a558fc1b8e6903c62048ca06c6e --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/eventConnection.cpp @@ -0,0 +1,494 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlEventConnection.h" +#include "tnlBitStream.h" +#include "tnlLog.h" +#include "tnlNetInterface.h" + +namespace TNL { + +ClassChunker EventConnection::mEventNoteChunker; + +EventConnection::EventConnection() +{ + // event management data: + + mNotifyEventList = NULL; + mSendEventQueueHead = NULL; + mSendEventQueueTail = NULL; + mUnorderedSendEventQueueHead = NULL; + mUnorderedSendEventQueueTail = NULL; + mWaitSeqEvents = NULL; + + mNextSendEventSeq = FirstValidSendEventSeq; + mNextRecvEventSeq = FirstValidSendEventSeq; + mLastAckedEventSeq = -1; + mEventClassCount = 0; + mEventClassBitSize = 0; +} + +EventConnection::~EventConnection() +{ + + while(mNotifyEventList) + { + EventNote *temp = mNotifyEventList; + mNotifyEventList = temp->mNextEvent; + + temp->mEvent->notifyDelivered(this, true); + mEventNoteChunker.free(temp); + } + while(mUnorderedSendEventQueueHead) + { + EventNote *temp = mUnorderedSendEventQueueHead; + mUnorderedSendEventQueueHead = temp->mNextEvent; + + temp->mEvent->notifyDelivered(this, true); + mEventNoteChunker.free(temp); + } + while(mSendEventQueueHead) + { + EventNote *temp = mSendEventQueueHead; + mSendEventQueueHead = temp->mNextEvent; + + temp->mEvent->notifyDelivered(this, true); + mEventNoteChunker.free(temp); + } +} + +void EventConnection::writeConnectRequest(BitStream *stream) +{ + Parent::writeConnectRequest(stream); + stream->write(NetClassRep::getNetClassCount(getNetClassGroup(), NetClassTypeEvent)); +} + +bool EventConnection::readConnectRequest(BitStream *stream, const char **errorString) +{ + if(!Parent::readConnectRequest(stream, errorString)) + return false; + + U32 classCount; + stream->read(&classCount); + + U32 myCount = NetClassRep::getNetClassCount(getNetClassGroup(), NetClassTypeEvent); + if(myCount <= classCount) + mEventClassCount = myCount; + else + { + mEventClassCount = classCount; + if(!NetClassRep::isVersionBorderCount(getNetClassGroup(), NetClassTypeEvent, mEventClassCount)) + return false; + } + mEventClassVersion = NetClassRep::getClass(getNetClassGroup(), NetClassTypeEvent, mEventClassCount-1)->getClassVersion(); + mEventClassBitSize = getNextBinLog2(mEventClassCount); + return true; +} + +void EventConnection::writeConnectAccept(BitStream *stream) +{ + Parent::writeConnectAccept(stream); + stream->write(mEventClassCount); +} + +bool EventConnection::readConnectAccept(BitStream *stream, const char **errorString) +{ + if(!Parent::readConnectAccept(stream, errorString)) + return false; + + stream->read(&mEventClassCount); + U32 myCount = NetClassRep::getNetClassCount(getNetClassGroup(), NetClassTypeEvent); + + if(mEventClassCount > myCount) + return false; + + if(!NetClassRep::isVersionBorderCount(getNetClassGroup(), NetClassTypeEvent, mEventClassCount)) + return false; + + mEventClassBitSize = getNextBinLog2(mEventClassCount); + return true; +} + +void EventConnection::processEvent(NetEvent *theEvent) +{ + if(getConnectionState() == NetConnection::Connected) + theEvent->process(this); +} + +void EventConnection::packetDropped(PacketNotify *pnotify) +{ + Parent::packetDropped(pnotify); + EventPacketNotify *notify = static_cast(pnotify); + + EventNote *walk = notify->eventList; + EventNote **insertList = &mSendEventQueueHead; + EventNote *temp; + + while(walk) + { + switch(walk->mEvent->mGuaranteeType) + { + case NetEvent::GuaranteedOrdered: + // It was a guaranteed ordered packet, reinsert it back into + // mSendEventQueueHead in the right place (based on seq numbers) + + TNLLogMessageV(LogEventConnection, ("EventConnection %s: DroppedGuaranteed - %d", getNetAddressString(), walk->mSeqCount)); + while(*insertList && (*insertList)->mSeqCount < walk->mSeqCount) + insertList = &((*insertList)->mNextEvent); + + temp = walk->mNextEvent; + walk->mNextEvent = *insertList; + if(!walk->mNextEvent) + mSendEventQueueTail = walk; + *insertList = walk; + insertList = &(walk->mNextEvent); + walk = temp; + break; + case NetEvent::Guaranteed: + // It was a guaranteed packet, put it at the top of + // mUnorderedSendEventQueueHead. + temp = walk->mNextEvent; + walk->mNextEvent = mUnorderedSendEventQueueHead; + mUnorderedSendEventQueueHead = walk; + if(!walk->mNextEvent) + mUnorderedSendEventQueueTail = walk; + walk = temp; + break; + case NetEvent::Unguaranteed: + // Or else it was an unguaranteed packet, notify that + // it was _not_ delivered and blast it. + walk->mEvent->notifyDelivered(this, false); + temp = walk->mNextEvent; + mEventNoteChunker.free(walk); + walk = temp; + } + } +} + +void EventConnection::packetReceived(PacketNotify *pnotify) +{ + Parent::packetReceived(pnotify); + + EventPacketNotify *notify = static_cast(pnotify); + + EventNote *walk = notify->eventList; + EventNote **noteList = &mNotifyEventList; + + while(walk) + { + EventNote *next = walk->mNextEvent; + if(walk->mEvent->mGuaranteeType != NetEvent::GuaranteedOrdered) + { + walk->mEvent->notifyDelivered(this, true); + mEventNoteChunker.free(walk); + walk = next; + } + else + { + while(*noteList && (*noteList)->mSeqCount < walk->mSeqCount) + noteList = &((*noteList)->mNextEvent); + + walk->mNextEvent = *noteList; + *noteList = walk; + noteList = &walk->mNextEvent; + walk = next; + } + } + while(mNotifyEventList && mNotifyEventList->mSeqCount == mLastAckedEventSeq + 1) + { + mLastAckedEventSeq++; + EventNote *next = mNotifyEventList->mNextEvent; + TNLLogMessageV(LogEventConnection, ("EventConnection %s: NotifyDelivered - %d", getNetAddressString(), mNotifyEventList->mSeqCount)); + mNotifyEventList->mEvent->notifyDelivered(this, true); + mEventNoteChunker.free(mNotifyEventList); + mNotifyEventList = next; + } +} + +void EventConnection::writePacket(BitStream *bstream, PacketNotify *pnotify) +{ + Parent::writePacket(bstream, pnotify); + EventPacketNotify *notify = static_cast(pnotify); + + if(mConnectionParameters.mDebugObjectSizes) + bstream->writeInt(DebugChecksum, 32); + + EventNote *packQueueHead = NULL, *packQueueTail = NULL; + + while(mUnorderedSendEventQueueHead) + { + if(bstream->isFull()) + break; + // get the first event + EventNote *ev = mUnorderedSendEventQueueHead; + + bstream->writeFlag(true); + S32 start = bstream->getBitPosition(); + + if(mConnectionParameters.mDebugObjectSizes) + bstream->advanceBitPosition(BitStreamPosBitSize); + + S32 classId = ev->mEvent->getClassId(getNetClassGroup()); + bstream->writeInt(classId, mEventClassBitSize); + + ev->mEvent->pack(this, bstream); + TNLLogMessageV(LogEventConnection, ("EventConnection %s: WroteEvent %s - %d bits", getNetAddressString(), ev->mEvent->getDebugName(), bstream->getBitPosition() - start)); + + if(mConnectionParameters.mDebugObjectSizes) + bstream->writeIntAt(bstream->getBitPosition(), BitStreamPosBitSize, start); + + if(bstream->getBitSpaceAvailable() < MinimumPaddingBits) + { + // rewind to before the event, and break out of the loop: + bstream->setBitPosition(start - 1); + bstream->clearError(); + break; + } + + // dequeue the event and add this event onto the packet queue + mUnorderedSendEventQueueHead = ev->mNextEvent; + ev->mNextEvent = NULL; + + if(!packQueueHead) + packQueueHead = ev; + else + packQueueTail->mNextEvent = ev; + packQueueTail = ev; + } + + bstream->writeFlag(false); + S32 prevSeq = -2; + + while(mSendEventQueueHead) + { + if(bstream->isFull()) + break; + + // if the event window is full, stop processing + if(mSendEventQueueHead->mSeqCount > mLastAckedEventSeq + 126) + break; + + // get the first event + EventNote *ev = mSendEventQueueHead; + S32 eventStart = bstream->getBitPosition(); + + bstream->writeFlag(true); + + if(!bstream->writeFlag(ev->mSeqCount == prevSeq + 1)) + bstream->writeInt(ev->mSeqCount, 7); + prevSeq = ev->mSeqCount; + + if(mConnectionParameters.mDebugObjectSizes) + bstream->advanceBitPosition(BitStreamPosBitSize); + + S32 start = bstream->getBitPosition(); + + S32 classId = ev->mEvent->getClassId(getNetClassGroup()); + bstream->writeInt(classId, mEventClassBitSize); + ev->mEvent->pack(this, bstream); + + ev->mEvent->getClassRep()->addInitialUpdate(bstream->getBitPosition() - start); + TNLLogMessageV(LogEventConnection, ("EventConnection %s: WroteEvent %s - %d bits", getNetAddressString(), ev->mEvent->getDebugName(), bstream->getBitPosition() - start)); + + if(mConnectionParameters.mDebugObjectSizes) + bstream->writeIntAt(bstream->getBitPosition(), BitStreamPosBitSize, start - BitStreamPosBitSize); + + if(bstream->getBitSpaceAvailable() < MinimumPaddingBits) + { + // rewind to before the event, and break out of the loop: + bstream->setBitPosition(eventStart); + bstream->clearError(); + break; + } + + // dequeue the event: + mSendEventQueueHead = ev->mNextEvent; + ev->mNextEvent = NULL; + if(!packQueueHead) + packQueueHead = ev; + else + packQueueTail->mNextEvent = ev; + packQueueTail = ev; + } + for(EventNote *ev = packQueueHead; ev; ev = ev->mNextEvent) + ev->mEvent->notifySent(this); + + notify->eventList = packQueueHead; + bstream->writeFlag(0); +} + +void EventConnection::readPacket(BitStream *bstream) +{ + Parent::readPacket(bstream); + + if(mConnectionParameters.mDebugObjectSizes) + { + U32 sum = bstream->readInt(32); + TNLAssert(sum == DebugChecksum, "Invalid checksum."); + } + + S32 prevSeq = -2; + EventNote **waitInsert = &mWaitSeqEvents; + bool unguaranteedPhase = true; + + while(true) + { + bool bit = bstream->readFlag(); + if(unguaranteedPhase && !bit) + { + unguaranteedPhase = false; + bit = bstream->readFlag(); + } + if(!unguaranteedPhase && !bit) + break; + + S32 seq = -1; + + if(!unguaranteedPhase) // get the sequence + { + if(bstream->readFlag()) + seq = (prevSeq + 1) & 0x7f; + else + seq = bstream->readInt(7); + prevSeq = seq; + } + + U32 endingPosition; + if(mConnectionParameters.mDebugObjectSizes) + endingPosition = bstream->readInt(BitStreamPosBitSize); + + U32 classId = bstream->readInt(mEventClassBitSize); + if(classId >= mEventClassCount) + { + setLastError("Invalid packet."); + return; + } + NetEvent *evt = (NetEvent *) Object::create(getNetClassGroup(), NetClassTypeEvent, classId); + if(!evt) + { + setLastError("Invalid packet."); + return; + } + + // check if the direction this event moves is a valid direction. + if( (evt->getEventDirection() == NetEvent::DirUnset) + || (evt->getEventDirection() == NetEvent::DirServerToClient && isConnectionToClient()) + || (evt->getEventDirection() == NetEvent::DirClientToServer && isConnectionToServer()) ) + { + setLastError("Invalid Packet."); + return; + } + + + evt->unpack(this, bstream); + if(mErrorBuffer[0]) + return; + + if(mConnectionParameters.mDebugObjectSizes) + { + TNLAssert(endingPosition == bstream->getBitPosition(), + avar("unpack did not match pack for event of class %s.", + evt->getClassName()) ); + } + + if(unguaranteedPhase) + { + processEvent(evt); + delete evt; + if(mErrorBuffer[0]) + return; + continue; + } + seq |= (mNextRecvEventSeq & ~0x7F); + if(seq < mNextRecvEventSeq) + seq += 128; + + EventNote *note = mEventNoteChunker.alloc(); + note->mEvent = evt; + note->mSeqCount = seq; + TNLLogMessageV(LogEventConnection, ("EventConnection %s: RecvdGuaranteed %d", getNetAddressString(), seq)); + + while(*waitInsert && (*waitInsert)->mSeqCount < seq) + waitInsert = &((*waitInsert)->mNextEvent); + + note->mNextEvent = *waitInsert; + *waitInsert = note; + waitInsert = &(note->mNextEvent); + } + while(mWaitSeqEvents && mWaitSeqEvents->mSeqCount == mNextRecvEventSeq) + { + mNextRecvEventSeq++; + EventNote *temp = mWaitSeqEvents; + mWaitSeqEvents = temp->mNextEvent; + + TNLLogMessageV(LogEventConnection, ("EventConnection %s: ProcessGuaranteed %d", getNetAddressString(), temp->mSeqCount)); + processEvent(temp->mEvent); + mEventNoteChunker.free(temp); + if(mErrorBuffer[0]) + return; + } +} + +bool EventConnection::postNetEvent(NetEvent *theEvent) +{ + S32 classId = theEvent->getClassId(getNetClassGroup()); + if(U32(classId) >= mEventClassCount && getConnectionState() == Connected) + return false; + + theEvent->notifyPosted(this); + + EventNote *event = mEventNoteChunker.alloc(); + event->mEvent = theEvent; + event->mNextEvent = NULL; + + if(event->mEvent->mGuaranteeType == NetEvent::GuaranteedOrdered) + { + event->mSeqCount = mNextSendEventSeq++; + if(!mSendEventQueueHead) + mSendEventQueueHead = event; + else + mSendEventQueueTail->mNextEvent = event; + mSendEventQueueTail = event; + } + else + { + event->mSeqCount = InvalidSendEventSeq; + if(!mUnorderedSendEventQueueHead) + mUnorderedSendEventQueueHead = event; + else + mUnorderedSendEventQueueTail->mNextEvent = event; + mUnorderedSendEventQueueTail = event; + } + return true; +} + +bool EventConnection::isDataToTransmit() +{ + return mUnorderedSendEventQueueHead || mSendEventQueueHead || Parent::isDataToTransmit(); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/ghostConnection.cpp b/tnl-1.5.0/tnl/tnl/ghostConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e94435795389d976e2f13970fbd5231633da577c --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/ghostConnection.cpp @@ -0,0 +1,840 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlGhostConnection.h" +#include "tnlBitStream.h" +#include "tnlNetBase.h" +#include "tnlNetObject.h" +#include "tnlNetInterface.h" + +namespace TNL { + +GhostConnection::GhostConnection() +{ + // ghost management data: + mScopeObject = NULL; + mGhostingSequence = 0; + mGhosting = false; + mScoping = false; + mGhostArray = NULL; + mGhostRefs = NULL; + mGhostLookupTable = NULL; + mLocalGhosts = NULL; + mGhostZeroUpdateIndex = 0; +} + +GhostConnection::~GhostConnection() +{ + clearAllPacketNotifies(); + + // delete any ghosts that may exist for this connection, but aren't added + if(mGhostArray) + clearGhostInfo(); + deleteLocalGhosts(); + delete[] mLocalGhosts; + delete[] mGhostLookupTable; + delete[] mGhostRefs; + delete[] mGhostArray; +} + +void GhostConnection::setGhostTo(bool ghostTo) +{ + if(mLocalGhosts) // if ghosting to this is already enabled, silently return + return; + + if(ghostTo) + { + mLocalGhosts = new NetObject *[MaxGhostCount]; + for(S32 i = 0; i < MaxGhostCount; i++) + mLocalGhosts[i] = NULL; + } +} + +void GhostConnection::setGhostFrom(bool ghostFrom) +{ + if(mGhostArray) + return; + + if(ghostFrom) + { + mGhostFreeIndex = mGhostZeroUpdateIndex = 0; + mGhostArray = new GhostInfo *[MaxGhostCount]; + mGhostRefs = new GhostInfo[MaxGhostCount]; + S32 i; + for(i = 0; i < MaxGhostCount; i++) + { + mGhostRefs[i].obj = NULL; + mGhostRefs[i].index = i; + mGhostRefs[i].updateMask = 0; + } + mGhostLookupTable = new GhostInfo *[GhostLookupTableSize]; + for(i = 0; i < GhostLookupTableSize; i++) + mGhostLookupTable[i] = 0; + } +} + +void GhostConnection::packetDropped(PacketNotify *pnotify) +{ + Parent::packetDropped(pnotify); + GhostPacketNotify *notify = static_cast(pnotify); + + GhostRef *packRef = notify->ghostList; + // loop through all the packRefs in the packet + + while(packRef) + { + GhostRef *temp = packRef->nextRef; + + U32 updateFlags = packRef->mask; + + // figure out which flags need to be updated on the object + for(GhostRef *walk = packRef->updateChain; walk && updateFlags; walk = walk->updateChain) + updateFlags &= ~walk->mask; + + // for any flags we haven't updated since this (dropped) packet + // or them into the mask so they'll get updated soon + + if(updateFlags) + { + if(!packRef->ghost->updateMask) + { + packRef->ghost->updateMask = updateFlags; + ghostPushNonZero(packRef->ghost); + } + else + packRef->ghost->updateMask |= updateFlags; + } + + // make sure this packRef isn't the last one on the GhostInfo + if(packRef->ghost->lastUpdateChain == packRef) + packRef->ghost->lastUpdateChain = NULL; + + // if this packet was ghosting an object, set it + // to re ghost at it's earliest convenience + + if(packRef->ghostInfoFlags & GhostInfo::Ghosting) + { + packRef->ghost->flags |= GhostInfo::NotYetGhosted; + packRef->ghost->flags &= ~GhostInfo::Ghosting; + } + + // otherwise, if it was being deleted, + // set it to re-delete + + else if(packRef->ghostInfoFlags & GhostInfo::KillingGhost) + { + packRef->ghost->flags |= GhostInfo::KillGhost; + packRef->ghost->flags &= ~GhostInfo::KillingGhost; + } + + delete packRef; + packRef = temp; + } +} + +void GhostConnection::packetReceived(PacketNotify *pnotify) +{ + Parent::packetReceived(pnotify); + GhostPacketNotify *notify = static_cast(pnotify); + + GhostRef *packRef = notify->ghostList; + + // loop through all the notifies in this packet + + while(packRef) + { + // make sure this packRef isn't the last one on the GhostInfo + if(packRef->ghost->lastUpdateChain == packRef) + packRef->ghost->lastUpdateChain = NULL; + + GhostRef *temp = packRef->nextRef; + // if this object was ghosting , it is now ghosted + + if(packRef->ghostInfoFlags & GhostInfo::Ghosting) + { + packRef->ghost->flags &= ~GhostInfo::Ghosting; + if(packRef->ghost->obj) + packRef->ghost->obj->onGhostAvailable(this); + } + // otherwise, if it was dieing, free the ghost + + else if(packRef->ghostInfoFlags & GhostInfo::KillingGhost) + freeGhostInfo(packRef->ghost); + + delete packRef; + packRef = temp; + } +} + +static S32 QSORT_CALLBACK UQECompare(const void *a,const void *b) +{ + GhostInfo *ga = *((GhostInfo **) a); + GhostInfo *gb = *((GhostInfo **) b); + + F32 ret = ga->priority - gb->priority; + return (ret < 0) ? -1 : ((ret > 0) ? 1 : 0); +} + +void GhostConnection::prepareWritePacket() +{ + Parent::prepareWritePacket(); + + if(!doesGhostFrom() && !mGhosting) + return; + // first step is to check all our polled ghosts: + + // 1. Scope query - find if any new objects have come into + // scope and if any have gone out. + + // Each packet we loop through all the objects with non-zero masks and + // mark them as "out of scope" before the scope query runs. + // if the object has a zero update mask, we wait to remove it until it requests + // an update + + for(S32 i = 0; i < mGhostZeroUpdateIndex; i++) + { + // increment the updateSkip for everyone... it's all good + GhostInfo *walk = mGhostArray[i]; + walk->updateSkipCount++; + if(!(walk->flags & (GhostInfo::ScopeLocalAlways))) + walk->flags &= ~GhostInfo::InScope; + } + + if(mScopeObject) + mScopeObject->performScopeQuery(this); +} + +bool GhostConnection::isDataToTransmit() +{ + // once we've run the scope query - if there are no objects that need to be updated, + // we return false + return Parent::isDataToTransmit() || mGhostZeroUpdateIndex != 0; +} + +void GhostConnection::writePacket(BitStream *bstream, PacketNotify *pnotify) +{ + Parent::writePacket(bstream, pnotify); + GhostPacketNotify *notify = static_cast(pnotify); + + if(mConnectionParameters.mDebugObjectSizes) + bstream->writeInt(DebugChecksum, 32); + + notify->ghostList = NULL; + + if(!doesGhostFrom()) + return; + + if(!bstream->writeFlag(mGhosting && mScopeObject.isValid())) + return; + + // fill a packet (or two) with ghosting data + + // 2. call scoped objects' priority functions if the flag set is nonzero + // A removed ghost is assumed to have a high priority + // 3. call updates based on sorted priority until the packet is + // full. set flags to zero for all updated objects + + GhostInfo *walk; + + for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0; i--) + { + if(!(mGhostArray[i]->flags & GhostInfo::InScope)) + detachObject(mGhostArray[i]); + } + + U32 maxIndex = 0; + for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0; i--) + { + walk = mGhostArray[i]; + if(walk->index > maxIndex) + maxIndex = walk->index; + + // clear out any kill objects that haven't been ghosted yet + if((walk->flags & GhostInfo::KillGhost) && (walk->flags & GhostInfo::NotYetGhosted)) + { + freeGhostInfo(walk); + continue; + } + // don't do any ghost processing on objects that are being killed + // or in the process of ghosting + else if(!(walk->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting))) + { + if(walk->flags & GhostInfo::KillGhost) + walk->priority = 10000; + else + walk->priority = walk->obj->getUpdatePriority(mScopeObject, walk->updateMask, walk->updateSkipCount); + } + else + walk->priority = 0; + } + GhostRef *updateList = NULL; + qsort(mGhostArray, mGhostZeroUpdateIndex, sizeof(GhostInfo *), UQECompare); + // reset the array indices... + for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0; i--) + mGhostArray[i]->arrayIndex = i; + + S32 sendSize = 1; + while(maxIndex >>= 1) + sendSize++; + + if(sendSize < 3) + sendSize = 3; + + bstream->writeInt(sendSize - 3, 3); // 0-7 3 bit number + + U32 count = 0; + // + for(S32 i = mGhostZeroUpdateIndex - 1; i >= 0 && !bstream->isFull(); i--) + { + GhostInfo *walk = mGhostArray[i]; + if(walk->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting)) + continue; + + U32 updateStart = bstream->getBitPosition(); + U32 updateMask = walk->updateMask; + U32 retMask; + + bstream->writeFlag(true); + bstream->writeInt(walk->index, sendSize); + if(!bstream->writeFlag(walk->flags & GhostInfo::KillGhost)) + { + // this is an update of some kind: + if(mConnectionParameters.mDebugObjectSizes) + bstream->advanceBitPosition(BitStreamPosBitSize); + + S32 startPos = bstream->getBitPosition(); + + if(walk->flags & GhostInfo::NotYetGhosted) + { + S32 classId = walk->obj->getClassId(getNetClassGroup()); + bstream->writeClassId(classId, NetClassTypeObject, getNetClassGroup()); + NetObject::mIsInitialUpdate = true; + } + + // update the object + retMask = walk->obj->packUpdate(this, updateMask, bstream); + + if(NetObject::mIsInitialUpdate) + { + NetObject::mIsInitialUpdate = false; + walk->obj->getClassRep()->addInitialUpdate(bstream->getBitPosition() - startPos); + } + else + walk->obj->getClassRep()->addPartialUpdate(bstream->getBitPosition() - startPos); + + if(mConnectionParameters.mDebugObjectSizes) + bstream->writeIntAt(bstream->getBitPosition(), BitStreamPosBitSize, startPos - BitStreamPosBitSize); + + TNLLogMessageV(LogGhostConnection, ("GhostConnection %s GHOST %d", walk->obj->getClassName(), bstream->getBitPosition() - 16 - startPos)); + + TNLAssert((retMask & (~updateMask)) == 0, "Cannot set new bits in packUpdate return"); + } + + // check for packet overrun, and rewind this update if there + // was one: + if(bstream->getBitSpaceAvailable() < MinimumPaddingBits) + { + bstream->setBitPosition(updateStart); + bstream->clearError(); + break; + } + + // otherwise, create a record of this ghost update and + // attach it to the packet. + GhostRef *upd = new GhostRef; + + upd->nextRef = updateList; + updateList = upd; + + if(walk->lastUpdateChain) + walk->lastUpdateChain->updateChain = upd; + walk->lastUpdateChain = upd; + + upd->ghost = walk; + upd->ghostInfoFlags = 0; + upd->updateChain = NULL; + + if(walk->flags & GhostInfo::KillGhost) + { + walk->flags &= ~GhostInfo::KillGhost; + walk->flags |= GhostInfo::KillingGhost; + walk->updateMask = 0; + upd->mask = updateMask; + ghostPushToZero(walk); + upd->ghostInfoFlags = GhostInfo::KillingGhost; + } + else + { + if(walk->flags & GhostInfo::NotYetGhosted) + { + walk->flags &= ~GhostInfo::NotYetGhosted; + walk->flags |= GhostInfo::Ghosting; + upd->ghostInfoFlags = GhostInfo::Ghosting; + } + walk->updateMask = retMask; + if(!retMask) + ghostPushToZero(walk); + upd->mask = updateMask & ~retMask; + walk->updateSkipCount = 0; + count++; + } + } + // count # of ghosts have been updated, + // mGhostZeroUpdateIndex # of ghosts remain to be updated. + // no more objects... + bstream->writeFlag(false); + notify->ghostList = updateList; +} + +void GhostConnection::readPacket(BitStream *bstream) +{ + Parent::readPacket(bstream); + + if(mConnectionParameters.mDebugObjectSizes) + { + U32 sum = bstream->readInt(32); + TNLAssert(sum == DebugChecksum, "Invalid checksum."); + } + + if(!doesGhostTo()) + return; + if(!bstream->readFlag()) + return; + + S32 idSize; + idSize = bstream->readInt( 3 ); + idSize += 3; + + // while there's an object waiting... + + while(bstream->readFlag()) + { + U32 index; + //S32 startPos = bstream->getCurPos(); + index = (U32) bstream->readInt(idSize); + if(bstream->readFlag()) // is this ghost being deleted? + { + TNLAssert(mLocalGhosts[index] != NULL, "Error, NULL ghost encountered."); + if(mLocalGhosts[index]) + { + mLocalGhosts[index]->onGhostRemove(); + delete mLocalGhosts[index]; + mLocalGhosts[index] = NULL; + } + } + else + { + U32 endPosition = 0; + if(mConnectionParameters.mDebugObjectSizes) + endPosition = bstream->readInt(BitStreamPosBitSize); + + if(!mLocalGhosts[index]) // it's a new ghost... cool + { + S32 classId = bstream->readClassId(NetClassTypeObject, getNetClassGroup()); + if(classId == -1) + { + setLastError("Invalid packet."); + return; + } + + NetObject *obj = (NetObject *) Object::create(getNetClassGroup(), NetClassTypeObject, classId); + if(!obj) + { + setLastError("Invalid packet."); + return; + } + obj->mOwningConnection = this; + obj->mNetFlags = NetObject::IsGhost; + + // object gets initial update before adding to the manager + + obj->mNetIndex = index; + mLocalGhosts[index] = obj; + + NetObject::mIsInitialUpdate = true; + mLocalGhosts[index]->unpackUpdate(this, bstream); + NetObject::mIsInitialUpdate = false; + + if(!obj->onGhostAdd(this)) + { + if(!mErrorBuffer[0]) + setLastError("Invalid packet."); + return; + } + if(mRemoteConnection) + { + GhostConnection *gc = static_cast(mRemoteConnection.getPointer()); + obj->mServerObject = gc->resolveGhostParent(index); + } + } + else + { + mLocalGhosts[index]->unpackUpdate(this, bstream); + } + + if(mConnectionParameters.mDebugObjectSizes) + { + TNLAssert(bstream->getBitPosition() == endPosition, + avar("unpackUpdate did not match packUpdate for object of class %s. Expected %d bits, got %d bits.", + mLocalGhosts[index]->getClassName(), endPosition, bstream->getBitPosition()) ); + } + + if(mErrorBuffer[0]) + return; + } + } +} + +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- + +void GhostConnection::setScopeObject(NetObject *obj) +{ + if(((NetObject *) mScopeObject) == obj) + return; + mScopeObject = obj; +} + +void GhostConnection::detachObject(GhostInfo *info) +{ + // mark it for ghost killin' + info->flags |= GhostInfo::KillGhost; + + // if the mask is in the zero range, we've got to move it up... + if(!info->updateMask) + { + info->updateMask = 0xFFFFFFFF; + ghostPushNonZero(info); + } + if(info->obj) + { + if(info->prevObjectRef) + info->prevObjectRef->nextObjectRef = info->nextObjectRef; + else + info->obj->mFirstObjectRef = info->nextObjectRef; + if(info->nextObjectRef) + info->nextObjectRef->prevObjectRef = info->prevObjectRef; + // remove it from the lookup table + + U32 id = info->obj->getHashId(); + for(GhostInfo **walk = &mGhostLookupTable[id & GhostLookupTableMask]; *walk; walk = &((*walk)->nextLookupInfo)) + { + GhostInfo *temp = *walk; + if(temp == info) + { + *walk = temp->nextLookupInfo; + break; + } + } + info->prevObjectRef = info->nextObjectRef = NULL; + info->obj = NULL; + } +} + +void GhostConnection::freeGhostInfo(GhostInfo *ghost) +{ + TNLAssert(ghost->arrayIndex < mGhostFreeIndex, "Ghost already freed."); + if(ghost->arrayIndex < mGhostZeroUpdateIndex) + { + TNLAssert(ghost->updateMask != 0, "Invalid ghost mask."); + ghost->updateMask = 0; + ghostPushToZero(ghost); + } + ghostPushZeroToFree(ghost); + TNLAssert(ghost->lastUpdateChain == NULL, "Ack!"); +} + +//----------------------------------------------------------------------------- + +void GhostConnection::objectLocalScopeAlways(NetObject *obj) +{ + if(!doesGhostFrom()) + return; + objectInScope(obj); + for(GhostInfo *walk = mGhostLookupTable[obj->getHashId() & GhostLookupTableMask]; walk; walk = walk->nextLookupInfo) + { + if(walk->obj != obj) + continue; + walk->flags |= GhostInfo::ScopeLocalAlways; + return; + } +} + +void GhostConnection::objectLocalClearAlways(NetObject *obj) +{ + if(!doesGhostFrom()) + return; + for(GhostInfo *walk = mGhostLookupTable[obj->getHashId() & GhostLookupTableMask]; walk; walk = walk->nextLookupInfo) + { + if(walk->obj != obj) + continue; + walk->flags &= ~GhostInfo::ScopeLocalAlways; + return; + } +} + +bool GhostConnection::validateGhostArray() +{ + TNLAssert(mGhostZeroUpdateIndex >= 0 && mGhostZeroUpdateIndex <= mGhostFreeIndex, "Invalid update index range."); + TNLAssert(mGhostFreeIndex <= MaxGhostCount, "Invalid free index range."); + S32 i; + for(i = 0; i < mGhostZeroUpdateIndex; i ++) + { + TNLAssert(mGhostArray[i]->arrayIndex == i, "Invalid array index."); + TNLAssert(mGhostArray[i]->updateMask != 0, "Invalid ghost mask."); + } + for(; i < mGhostFreeIndex; i ++) + { + TNLAssert(mGhostArray[i]->arrayIndex == i, "Invalid array index."); + TNLAssert(mGhostArray[i]->updateMask == 0, "Invalid ghost mask."); + } + for(; i < MaxGhostCount; i++) + { + TNLAssert(mGhostArray[i]->arrayIndex == i, "Invalid array index."); + } + return true; +} + +void GhostConnection::objectInScope(NetObject *obj) +{ + if (!mScoping || !doesGhostFrom()) + return; + if (!obj->isGhostable() || (obj->isScopeLocal() && !isLocalConnection())) + return; + S32 index = obj->getHashId() & GhostLookupTableMask; + + // check if it's already in scope + // the object may have been cleared out without the lookupTable being cleared + // so validate that the object pointers are the same. + + for(GhostInfo *walk = mGhostLookupTable[index ]; walk; walk = walk->nextLookupInfo) + { + if(walk->obj != obj) + continue; + walk->flags |= GhostInfo::InScope; + return; + } + + if (mGhostFreeIndex == MaxGhostCount) + return; + + GhostInfo *giptr = mGhostArray[mGhostFreeIndex]; + ghostPushFreeToZero(giptr); + giptr->updateMask = 0xFFFFFFFF; + ghostPushNonZero(giptr); + + giptr->flags = GhostInfo::NotYetGhosted | GhostInfo::InScope; + + giptr->obj = obj; + giptr->lastUpdateChain = NULL; + giptr->updateSkipCount = 0; + + giptr->connection = this; + + giptr->nextObjectRef = obj->mFirstObjectRef; + if(obj->mFirstObjectRef) + obj->mFirstObjectRef->prevObjectRef = giptr; + giptr->prevObjectRef = NULL; + obj->mFirstObjectRef = giptr; + + giptr->nextLookupInfo = mGhostLookupTable[index]; + mGhostLookupTable[index] = giptr; + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +//----------------------------------------------------------------------------- + +void GhostConnection::activateGhosting() +{ + if(!doesGhostFrom()) + return; + + mGhostingSequence++; + TNLLogMessageV(LogGhostConnection, ("Ghosting activated - %d", mGhostingSequence)); + + TNLAssert((mGhostFreeIndex == 0) && (mGhostZeroUpdateIndex == 0), "Error: ghosts in the ghost list before activate."); + + // iterate through the ghost always objects and InScope them... + // also post em all to the other side. + + S32 j; + for(j = 0; j < MaxGhostCount; j++) + { + mGhostArray[j] = mGhostRefs + j; + mGhostArray[j]->arrayIndex = j; + } + mScoping = true; // so that objectInScope will work + + rpcStartGhosting(mGhostingSequence); + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +TNL_IMPLEMENT_RPC(GhostConnection, rpcStartGhosting, + (U32 sequence), (sequence), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + TNLLogMessageV(LogGhostConnection, ("Got GhostingStarting %d", sequence)); + + if(!doesGhostTo()) + { + setLastError("Invalid packet."); + return; + } + onStartGhosting(); + rpcReadyForNormalGhosts(sequence); +} + +TNL_IMPLEMENT_RPC(GhostConnection, rpcReadyForNormalGhosts, + (U32 sequence), (sequence), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + TNLLogMessageV(LogGhostConnection, ("Got ready for normal ghosts %d %d", sequence, mGhostingSequence)); + if(!doesGhostFrom()) + { + setLastError("Invalid packet."); + return; + } + if(sequence != mGhostingSequence) + return; + mGhosting = true; +} + +TNL_IMPLEMENT_RPC(GhostConnection, rpcEndGhosting, (), (), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + if(!doesGhostTo()) + { + setLastError("Invalid packet."); + return; + } + deleteLocalGhosts(); + onEndGhosting(); +} + +void GhostConnection::deleteLocalGhosts() +{ + if(!mLocalGhosts) + return; + // just delete all the local ghosts, + // and delete all the ghosts in the current save list + for(S32 i = 0; i < MaxGhostCount; i++) + { + if(mLocalGhosts[i]) + { + mLocalGhosts[i]->onGhostRemove(); + delete mLocalGhosts[i]; + mLocalGhosts[i] = NULL; + } + } +} + +void GhostConnection::clearGhostInfo() +{ + // gotta clear out the ghosts... + for(PacketNotify *walk = mNotifyQueueHead; walk; walk = walk->nextPacket) + { + GhostPacketNotify *note = static_cast(walk); + GhostRef *delWalk = note->ghostList; + note->ghostList = NULL; + while(delWalk) + { + GhostRef *next = delWalk->nextRef; + delete delWalk; + delWalk = next; + } + } + for(S32 i = 0; i < MaxGhostCount; i++) + { + if(mGhostRefs[i].arrayIndex < mGhostFreeIndex) + { + detachObject(&mGhostRefs[i]); + mGhostRefs[i].lastUpdateChain = NULL; + freeGhostInfo(&mGhostRefs[i]); + } + } + TNLAssert((mGhostFreeIndex == 0) && (mGhostZeroUpdateIndex == 0), "Invalid indices."); +} + +void GhostConnection::resetGhosting() +{ + if(!doesGhostFrom()) + return; + // stop all ghosting activity + // send a message to the other side notifying of this + + mGhosting = false; + mScoping = false; + rpcEndGhosting(); + mGhostingSequence++; + clearGhostInfo(); + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +//----------------------------------------------------------------------------- + +NetObject *GhostConnection::resolveGhost(S32 id) +{ + if(id == -1) + return NULL; + + return mLocalGhosts[id]; +} + +NetObject *GhostConnection::resolveGhostParent(S32 id) +{ + return mGhostRefs[id].obj; +} + +S32 GhostConnection::getGhostIndex(NetObject *obj) +{ + if(!obj) + return -1; + if(!doesGhostFrom()) + return obj->mNetIndex; + S32 index = obj->getHashId() & GhostLookupTableMask; + + for(GhostInfo *gptr = mGhostLookupTable[index]; gptr; gptr = gptr->nextLookupInfo) + { + if(gptr->obj == obj && (gptr->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting | GhostInfo::NotYetGhosted | GhostInfo::KillGhost)) == 0) + return gptr->index; + } + return -1; +} + +//----------------------------------------------------------------------------- + +void GhostConnection::onEndGhosting() +{ +} + +void GhostConnection::onStartGhosting() +{ +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/huffmanStringProcessor.cpp b/tnl-1.5.0/tnl/tnl/huffmanStringProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47a198c59c4995e92cc3da6fe3cf9ac45b6bd070 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/huffmanStringProcessor.cpp @@ -0,0 +1,524 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlBitStream.h" +#include "tnlVector.h" +#include "tnlHuffmanStringProcessor.h" + +namespace TNL { + +namespace HuffmanStringProcessor { + // This is extern so we can keep our huge hairy table definition at the end of the file. + extern const U32 mCharFreqs[256]; + bool mTablesBuilt = false; + + struct HuffNode { + U32 pop; + + S16 index0; + S16 index1; + }; + struct HuffLeaf { + U32 pop; + + U8 numBits; + U8 symbol; + U32 code; // no code should be longer than 32 bits. + }; + + Vector mHuffNodes; + Vector mHuffLeaves; + + void buildTables(); + + // We have to be a bit careful with these, since they are pointers... + struct HuffWrap { + HuffNode* pNode; + HuffLeaf* pLeaf; + + public: + HuffWrap() : pNode(NULL), pLeaf(NULL) { } + + void set(HuffLeaf* in_leaf) { pNode = NULL; pLeaf = in_leaf; } + void set(HuffNode* in_node) { pLeaf = NULL; pNode = in_node; } + + U32 getPop() { if (pNode) return pNode->pop; else return pLeaf->pop; } + }; + + + S16 determineIndex(HuffWrap&); + + void generateCodes(BitStream&, S32, S32); +}; + +//bool HuffmanStringProcessor::mTablesBuilt = false; +//Vector HuffmanStringProcessor::mHuffNodes; +//Vector HuffmanStringProcessor::mHuffLeaves; + + +void HuffmanStringProcessor::buildTables() +{ + TNLAssert(mTablesBuilt == false, "Cannot build tables twice!"); + mTablesBuilt = true; + + S32 i; + + // First, construct the array of wraps... + // + mHuffLeaves.setSize(256); + mHuffNodes.reserve(256); + mHuffNodes.setSize(mHuffNodes.size() + 1); + for (i = 0; i < 256; i++) { + HuffLeaf& rLeaf = mHuffLeaves[i]; + + rLeaf.pop = mCharFreqs[i] + 1; + rLeaf.symbol = U8(i); + + memset(&rLeaf.code, 0, sizeof(rLeaf.code)); + rLeaf.numBits = 0; + } + + S32 currWraps = 256; + HuffWrap* pWrap = new HuffWrap[256]; + for (i = 0; i < 256; i++) { + pWrap[i].set(&mHuffLeaves[i]); + } + + while (currWraps != 1) { + U32 min1 = 0xfffffffe, min2 = 0xffffffff; + S32 index1 = -1, index2 = -1; + + for (i = 0; i < currWraps; i++) { + if (pWrap[i].getPop() < min1) { + min2 = min1; + index2 = index1; + + min1 = pWrap[i].getPop(); + index1 = i; + } else if (pWrap[i].getPop() < min2) { + min2 = pWrap[i].getPop(); + index2 = i; + } + } + TNLAssert(index1 != -1 && index2 != -1 && index1 != index2, "hrph"); + + // Create a node for this... + mHuffNodes.setSize(mHuffNodes.size() + 1); + HuffNode& rNode = mHuffNodes.last(); + rNode.pop = pWrap[index1].getPop() + pWrap[index2].getPop(); + rNode.index0 = determineIndex(pWrap[index1]); + rNode.index1 = determineIndex(pWrap[index2]); + + S32 mergeIndex = index1 > index2 ? index2 : index1; + S32 nukeIndex = index1 > index2 ? index1 : index2; + pWrap[mergeIndex].set(&rNode); + + if (index2 != (currWraps - 1)) { + pWrap[nukeIndex] = pWrap[currWraps - 1]; + } + currWraps--; + } + TNLAssert(currWraps == 1, "wrong wraps?"); + TNLAssert(pWrap[0].pNode != NULL && pWrap[0].pLeaf == NULL, "Wrong wrap type!"); + + // Ok, now we have one wrap, which is a node. we need to make sure that this + // is the first node in the node list. + mHuffNodes[0] = *(pWrap[0].pNode); + delete [] pWrap; + + U32 code = 0; + BitStream bs((U8 *) &code, 4); + + generateCodes(bs, 0, 0); +} + +void HuffmanStringProcessor::generateCodes(BitStream& rBS, S32 index, S32 depth) +{ + if (index < 0) { + // leaf node, copy the code in, and back out... + HuffLeaf& rLeaf = mHuffLeaves[-(index + 1)]; + + memcpy(&rLeaf.code, rBS.getBuffer(), sizeof(rLeaf.code)); + rLeaf.numBits = depth; + } else { + HuffNode& rNode = mHuffNodes[index]; + + S32 pos = rBS.getBitPosition(); + + rBS.writeFlag(false); + generateCodes(rBS, rNode.index0, depth + 1); + + rBS.setBitPosition(pos); + rBS.writeFlag(true); + generateCodes(rBS, rNode.index1, depth + 1); + + rBS.setBitPosition(pos); + } +} + +S16 HuffmanStringProcessor::determineIndex(HuffWrap& rWrap) +{ + if (rWrap.pLeaf != NULL) { + TNLAssert(rWrap.pNode == NULL, "um, never."); + + return -((rWrap.pLeaf - mHuffLeaves.address()) + 1); + } else { + TNLAssert(rWrap.pNode != NULL, "um, never."); + + return rWrap.pNode - mHuffNodes.address(); + } +} + +bool HuffmanStringProcessor::readHuffBuffer(BitStream* pStream, char* out_pBuffer) +{ + if (mTablesBuilt == false) + buildTables(); + + if (pStream->readFlag()) { + U32 len = pStream->readInt(8); + for (U32 i = 0; i < len; i++) { + S32 index = 0; + while (true) { + if (index >= 0) { + if (pStream->readFlag() == true) { + index = mHuffNodes[index].index1; + } else { + index = mHuffNodes[index].index0; + } + } else { + out_pBuffer[i] = mHuffLeaves[-(index+1)].symbol; + break; + } + } + } + out_pBuffer[len] = '\0'; + return true; + } else { + // Uncompressed string... + U32 len = pStream->readInt(8); + pStream->read(len, out_pBuffer); + out_pBuffer[len] = '\0'; + return true; + } +} + +bool HuffmanStringProcessor::writeHuffBuffer(BitStream* pStream, const char* out_pBuffer, U32 maxLen) +{ + if (out_pBuffer == NULL) { + pStream->writeFlag(false); + pStream->writeInt(0, 8); + return true; + } + + if (mTablesBuilt == false) + buildTables(); + + U32 len = out_pBuffer ? strlen(out_pBuffer) : 0; + TNLAssertV(len <= 255, ("String \"%s\" TOO long for writeString", out_pBuffer)); + if (len > maxLen) + len = maxLen; + + U32 numBits = 0; + U32 i; + for (i = 0; i < len; i++) + numBits += mHuffLeaves[(unsigned char)out_pBuffer[i]].numBits; + + if (numBits >= (len * 8)) { + pStream->writeFlag(false); + pStream->writeInt(len, 8); + pStream->write(len, out_pBuffer); + } else { + pStream->writeFlag(true); + pStream->writeInt(len, 8); + for (i = 0; i < len; i++) { + HuffLeaf& rLeaf = mHuffLeaves[((unsigned char)out_pBuffer[i])]; + pStream->writeBits(rLeaf.numBits, &rLeaf.code); + } + } + + return true; +} + +const U32 HuffmanStringProcessor::mCharFreqs[256] = { +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +329 , +21 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +2809 , +68 , +0 , +27 , +0 , +58 , +3 , +62 , +4 , +7 , +0 , +0 , +15 , +65 , +554 , +3 , +394 , +404 , +189 , +117 , +30 , +51 , +27 , +15 , +34 , +32 , +80 , +1 , +142 , +3 , +142 , +39 , +0 , +144 , +125 , +44 , +122 , +275 , +70 , +135 , +61 , +127 , +8 , +12 , +113 , +246 , +122 , +36 , +185 , +1 , +149 , +309 , +335 , +12 , +11 , +14 , +54 , +151 , +0 , +0 , +2 , +0 , +0 , +211 , +0 , +2090 , +344 , +736 , +993 , +2872 , +701 , +605 , +646 , +1552 , +328 , +305 , +1240 , +735 , +1533 , +1713 , +562 , +3 , +1775 , +1149 , +1469 , +979 , +407 , +553 , +59 , +279 , +31 , +0 , +0 , +0 , +68 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 , +0 +}; + +}; diff --git a/tnl-1.5.0/tnl/tnl/journal.cpp b/tnl-1.5.0/tnl/tnl/journal.cpp new file mode 100644 index 0000000000000000000000000000000000000000..976848ae6831960fe8baf02458c823bf21f6fd9b --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/journal.cpp @@ -0,0 +1,330 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlJournal.h" +#include "tnlEndian.h" +#include "tnlLog.h" + +namespace TNL +{ + +Vector *JournalEntryRecord::mEntryVector; + +bool Journal::mInsideEntrypoint = false; +Journal::Mode Journal::mCurrentMode = Journal::Inactive; +U32 Journal::mReadBreakBitPos = 0; + +FILE *Journal::mJournalFile = NULL; +BitStream Journal::mWriteStream; +BitStream Journal::mReadStream; +Journal *Journal::mJournal = NULL; +U32 Journal::mWritePosition = 0; +U32 Journal::mBreakBlockIndex = 0; +U32 Journal::mBlockIndex = 0; + +JournalBlockTypeToken *JournalBlockTypeToken::mList = NULL; +bool JournalBlockTypeToken::mInitialized = false; + +JournalBlockTypeToken::JournalBlockTypeToken(const char *typeString) +{ + mString = typeString; + mValue = 0xFFFFFFFF; + mNext = mList; + mList = this; +} + +S32 QSORT_CALLBACK JBTTCompare(JournalBlockTypeToken **a, JournalBlockTypeToken **b) +{ + return strcmp((*a)->getString(), (*b)->getString()); +} + +U32 JournalBlockTypeToken::getValue() +{ + if(!mInitialized) + { + mInitialized = true; + Vector vec; + for(JournalBlockTypeToken *walk = mList; walk; walk = walk->mNext) + vec.push_back(walk); + + vec.sort(JBTTCompare); + U32 lastValue = 0; + const char *lastString = ""; + for(S32 i = 0; i < vec.size(); i++) + { + if(!strcmp(vec[i]->mString, lastString)) + vec[i]->mValue = lastValue; + else + { + lastValue++; + vec[i]->mValue = lastValue; + lastString = vec[i]->mString; + } + } + } + return mValue; +} + +const char *JournalBlockTypeToken::findName(U32 value) +{ + for(JournalBlockTypeToken *walk = mList; walk; walk = walk->mNext) + if(walk->mValue == value) + return walk->mString; + return "INVALID"; +} + +JournalEntryRecord::JournalEntryRecord(const char *functionName) +{ + S32 i; + if(!mEntryVector) + mEntryVector = new Vector; + + for(i = 0; i < mEntryVector->size(); i++) + { + if(strcmp((*mEntryVector)[i]->mFunctionName, functionName) < 0) + break; + } + mEntryVector->insert(i); + (*mEntryVector)[i] = this; + mFunctionName = functionName; + mEntryIndex = 0; +} + +JournalEntryRecord::~JournalEntryRecord() +{ + if(mEntryVector) + { + delete mEntryVector; + mEntryVector = NULL; + } +} + +Journal::Journal() +{ + TNLAssert(mJournal == NULL, "Cannot construct more than one Journal instance."); + mJournal = this; +} + +// the journal stream is written as a single continuous bit stream. +// the first four bytes of the stream are the total number of bits in +// the stream. As a block is written, the bits in the write stream are +// all erased except for those in the last byte, which are moved to the first. +void Journal::syncWriteStream() +{ + if(mWriteStream.getBytePosition() == 0) + return; + + U32 totalBits = (mWritePosition << 3) + mWriteStream.getBitPosition(); + + // seek back to the beginning + fseek(mJournalFile, 0, SEEK_SET); + + // write the new total bits + U32 writeBits = convertHostToLEndian(totalBits); + fwrite(&writeBits, 1, sizeof(U32), mJournalFile); + + // seek to the writing position + fseek(mJournalFile, mWritePosition, SEEK_SET); + + U32 bytesToWrite = mWriteStream.getBytePosition(); + // write the bytes to the file + fwrite(mWriteStream.getBuffer(), 1, bytesToWrite, mJournalFile); + fflush(mJournalFile); + + // adjust the write stream + if(totalBits & 7) + { + U8 *buffer = mWriteStream.getBuffer(); + buffer[0] = buffer[bytesToWrite - 1]; + mWriteStream.setBitPosition(totalBits & 7); + mWritePosition += bytesToWrite - 1; + } + else + { + mWritePosition += bytesToWrite; + mWriteStream.setBitPosition(0); + } +} + +void Journal::record(const char *fileName) +{ + mJournalFile = fopen(fileName, "wb"); + if(mJournalFile) + { + mCurrentMode = Record; + mWritePosition = sizeof(U32); + } +} + +void Journal::load(const char *fileName) +{ + FILE *theJournal = fopen(fileName, "rb"); + if(!theJournal) + return; + + fseek(theJournal, 0, SEEK_END); + U32 fileSize = ftell(theJournal); + fseek(theJournal, 0, SEEK_SET); + + mReadStream.resize(fileSize); + U32 bitCount; + fread(mReadStream.getBuffer(), 1, fileSize, theJournal); + mReadStream.read(&bitCount); + mReadStream.setMaxBitSizes(bitCount); + + if(!mReadBreakBitPos || mReadBreakBitPos > bitCount) + mReadBreakBitPos = bitCount; + + fclose(theJournal); + mCurrentMode = Playback; +} + +void Journal::callEntry(const char *funcName, Functor *theCall) +{ + if(mCurrentMode == Playback) + return; + + TNLAssert(mInsideEntrypoint == false, "Journal entries cannot be reentrant!"); + mInsideEntrypoint = true; + + S32 entryIndex; + for(entryIndex = 0; entryIndex < JournalEntryRecord::mEntryVector->size(); entryIndex++) + { + if(!strcmp((*JournalEntryRecord::mEntryVector)[entryIndex]->mFunctionName, funcName)) + break; + } + TNLAssert(entryIndex != JournalEntryRecord::mEntryVector->size(), "No entry point found!"); + + if(mCurrentMode == Record) + { +#ifdef TNL_ENABLE_BIG_JOURNALS + TNL_JOURNAL_WRITE( (U16(0x1234)) ); +#endif + mWriteStream.writeRangedU32(entryIndex, 0, JournalEntryRecord::mEntryVector->size() - 1); + theCall->write(mWriteStream); +#ifdef TNL_ENABLE_BIG_JOURNALS + TNL_JOURNAL_WRITE( (U16(0x5678)) ); +#endif + syncWriteStream(); + } + theCall->dispatch(this); + mInsideEntrypoint = false; +} + +void Journal::checkReadPosition() +{ + if(!mReadStream.isValid() || mReadStream.getBitPosition() >= mReadBreakBitPos) + TNL_DEBUGBREAK(); +} + +void Journal::beginBlock(U32 blockId, bool writeBlock) +{ + if(writeBlock) + { +#ifdef TNL_ENABLE_BIG_JOURNALS + TNL_JOURNAL_WRITE( (U16(0x1234 ^ blockId)) ); +#endif + } + else + { + mBlockIndex++; + if(mBreakBlockIndex && mBlockIndex >= mBreakBlockIndex) + TNL_DEBUGBREAK(); + +#ifdef TNL_ENABLE_BIG_JOURNALS + U16 startToken; + TNL_JOURNAL_READ( (&startToken) ); + if((startToken ^ 0x1234) != blockId) + { + logprintf("Expected token %s - got %s", JournalBlockTypeToken::findName(blockId), JournalBlockTypeToken::findName(startToken ^ 0x1234)); + TNL_DEBUGBREAK(); + } +#endif + } +} + +void Journal::endBlock(U32 blockId, bool writeBlock) +{ + if(writeBlock) + { +#ifdef TNL_ENABLE_BIG_JOURNALS + TNL_JOURNAL_WRITE( (U16(0x5678 ^ blockId)) ); +#endif + syncWriteStream(); + } + else + { +#ifdef TNL_ENABLE_BIG_JOURNALS + U16 endToken; + TNL_JOURNAL_READ( (&endToken) ); + if((endToken ^ 0x5678) != blockId) + { + logprintf("Expected token %s - got %s", JournalBlockTypeToken::findName(blockId), JournalBlockTypeToken::findName(endToken ^ 0x5678)); + TNL_DEBUGBREAK(); + } +#endif + checkReadPosition(); + } +} + +void Journal::processNextJournalEntry() +{ + if(mCurrentMode != Playback) + return; + +#ifdef TNL_ENABLE_BIG_JOURNALS + U16 token; + TNL_JOURNAL_READ( (&token) ); + if(token != 0x1234) + TNL_DEBUGBREAK(); +#endif + + U32 index = mReadStream.readRangedU32(0, JournalEntryRecord::mEntryVector->size()); + + JournalEntryRecord *theEntry = (*JournalEntryRecord::mEntryVector)[index]; + + // check for errors... + if(!theEntry) + { + TNLAssert(0, "blech!"); + } + theEntry->mFunctor->read(mReadStream); + +#ifdef TNL_ENABLE_BIG_JOURNALS + TNL_JOURNAL_READ( (&token) ); + if(token != 0x5678) + TNL_DEBUGBREAK(); +#endif + + checkReadPosition(); + + mInsideEntrypoint = true; + theEntry->mFunctor->dispatch(this); + mInsideEntrypoint = false; +} + +}; + diff --git a/tnl-1.5.0/tnl/tnl/log.cpp b/tnl-1.5.0/tnl/tnl/log.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f6b7de073b616090e4b10eafcd6a0543d719a1c --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/log.cpp @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlLog.h" +#include "tnlDataChunker.h" +#include + +namespace TNL +{ + +LogConsumer *LogConsumer::mLinkedList = NULL; + +LogConsumer::LogConsumer() +{ + mNextConsumer = mLinkedList; + if(mNextConsumer) + mNextConsumer->mPrevConsumer = this; + mPrevConsumer = NULL; + mLinkedList = this; +} + +LogConsumer::~LogConsumer() +{ + if(mNextConsumer) + mNextConsumer->mPrevConsumer = mPrevConsumer; + if(mPrevConsumer) + mPrevConsumer->mNextConsumer = mNextConsumer; + else + mLinkedList = mNextConsumer; +} + +LogType *LogType::linkedList = NULL; +LogType *LogType::current = NULL; + +#ifdef TNL_ENABLE_LOGGING + +LogType *LogType::find(const char *name) +{ + static ClassChunker logTypeChunker(4096); + + for(LogType *walk = linkedList; walk; walk = walk->next) + if(!strcmp(walk->typeName, name)) + return walk; + LogType *ret = logTypeChunker.alloc(); + ret->next = linkedList; + linkedList = ret; + ret->isEnabled = false; + ret->typeName = name; + return ret; +} +#endif + +void LogConsumer::logString(const char *string) +{ + // by default the LogConsumer will output to the platform debug + // string printer, but only if we're in debug mode +#ifdef TNL_DEBUG + Platform::outputDebugString(string); + Platform::outputDebugString("\n"); +#endif +} + +void logprintf(const char *format, ...) +{ + char buffer[4096]; + U32 bufferStart = 0; + if(LogType::current) + { + strcpy(buffer, LogType::current->typeName); + bufferStart = strlen(buffer); + + buffer[bufferStart] = ':'; + buffer[bufferStart+1] = ' '; + bufferStart += 2; + } + va_list s; + va_start( s, format ); + dVsprintf(buffer + bufferStart, sizeof(buffer) - bufferStart, format, s); + for(LogConsumer *walk = LogConsumer::getLinkedList(); walk; walk = walk->getNext()) + walk->logString(buffer); + va_end(s); + Platform::outputDebugString(buffer); + Platform::outputDebugString("\n"); +} + +}; + diff --git a/tnl-1.5.0/tnl/tnl/netBase.cpp b/tnl-1.5.0/tnl/tnl/netBase.cpp new file mode 100644 index 0000000000000000000000000000000000000000..168b23015ffc60076831ffbe8e3e3a6d01871cf6 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/netBase.cpp @@ -0,0 +1,173 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlNetBase.h" +#include "tnlVector.h" +#include "tnlLog.h" + +namespace TNL +{ + +#define INITIAL_CRC_VALUE 0xFFFFFFFF + +NetClassRep *NetClassRep::mClassLinkList = NULL; +U32 NetClassRep::mNetClassBitSize[NetClassGroupCount][NetClassTypeCount] = {{0, },}; +Vector NetClassRep::mClassTable[NetClassGroupCount][NetClassTypeCount]; +U32 NetClassRep::mClassCRC[NetClassGroupCount] = {INITIAL_CRC_VALUE, }; + +bool NetClassRep::mInitialized = false; + +NetClassRep::NetClassRep() +{ + mInitialUpdateCount = 0; + mInitialUpdateBitsUsed = 0; + mPartialUpdateCount = 0; + mPartialUpdateBitsUsed = 0; +} + +Object* NetClassRep::create(const char* className) +{ + TNLAssert(mInitialized, "creating an object before NetClassRep::initialize."); + + for (NetClassRep *walk = mClassLinkList; walk; walk = walk->mNextClass) + if (!strcmp(walk->getClassName(), className)) + return walk->create(); + + TNLAssertV(0,("Couldn't find class rep for dynamic class: %s", className)); + return NULL; +} + +//-------------------------------------- +Object* NetClassRep::create(const U32 groupId, const U32 typeId, const U32 classId) +{ + TNLAssert(mInitialized, "creating an object before NetClassRep::initialize."); + TNLAssert(classId < U32(mClassTable[groupId][typeId].size()), "Class id out of range."); + TNLAssert(mClassTable[groupId][typeId][classId] != NULL, "No class with declared id type."); + + if(mClassTable[groupId][typeId][classId]) + return mClassTable[groupId][typeId][classId]->create(); + return NULL; +} + +//-------------------------------------- + +static S32 QSORT_CALLBACK ACRCompare(const void *aptr, const void *bptr) +{ + const NetClassRep *a = *((const NetClassRep **) aptr); + const NetClassRep *b = *((const NetClassRep **) bptr); + + if(a->getClassVersion() != b->getClassVersion()) + return a->getClassVersion() - b->getClassVersion(); + return strcmp(a->getClassName(), b->getClassName()); +} + +void NetClassRep::initialize() +{ + if(mInitialized) + return; + Vector dynamicTable; + + NetClassRep *walk; + + for (U32 group = 0; group < NetClassGroupCount; group++) + { + U32 groupMask = 1 << group; + for(U32 type = 0; type < NetClassTypeCount; type++) + { + for (walk = mClassLinkList; walk; walk = walk->mNextClass) + { + if(walk->getClassType() == type && walk->mClassGroupMask & groupMask) + dynamicTable.push_back(walk); + } + if(!dynamicTable.size()) + continue; + + qsort((void *) &dynamicTable[0], dynamicTable.size(), sizeof(NetClassRep *), ACRCompare); + + TNLLogBlock(LogNetBase, + logprintf("Class Group: %d Class Type: %d count: %d", + group, type, dynamicTable.size()); + for(S32 i = 0; i < dynamicTable.size(); i++) + logprintf("%s", dynamicTable[i]->getClassName()); + ) + + mClassTable[group][type] = dynamicTable; + + for(U32 i = 0; i < mClassTable[group][type].size();i++) + mClassTable[group][type][i]->mClassId[group] = i; + + mNetClassBitSize[group][type] = + getBinLog2(getNextPow2(mClassTable[group][type].size() + 1)); + dynamicTable.clear(); + } + } + mInitialized = true; +} + +void NetClassRep::logBitUsage() +{ + logprintf("Net Class Bit Usage:"); + for(NetClassRep *walk = mClassLinkList; walk; walk = walk->mNextClass) + { + if(walk->mInitialUpdateCount) + logprintf("%s (Initial) - Count: %d Avg Size: %g", walk->mClassName, walk->mInitialUpdateCount, walk->mInitialUpdateBitsUsed / F32(walk->mInitialUpdateCount)); + if(walk->mPartialUpdateCount) + logprintf("%s (Partial) - Count: %d Avg Size: %g", walk->mClassName, walk->mPartialUpdateCount, walk->mPartialUpdateBitsUsed / F32(walk->mPartialUpdateCount)); + } +} + + +Object::Object() +{ + mFirstObjectRef = NULL; + mRefCount = 0; +} + +Object::~Object() +{ + TNLAssert(mRefCount == 0, "Error! Object deleted with non-zero reference count!"); + // loop through the linked list of object references and NULL + // out all pointers to this object. + + SafeObjectRef *walk = mFirstObjectRef; + while(walk) + { + SafeObjectRef *next = walk->mNextObjectRef; + walk->mObject = NULL; + walk->mPrevObjectRef = NULL; + walk->mNextObjectRef = NULL; + walk = next; + } +} + +//-------------------------------------- +NetClassRep* Object::getClassRep() const +{ + return NULL; +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/netConnection.cpp b/tnl-1.5.0/tnl/tnl/netConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..490e34f6769a7867a653d03bd8bb2334c7dabe5c --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/netConnection.cpp @@ -0,0 +1,918 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlNetBase.h" +#include "tnlNetConnection.h" +#include "tnlNetInterface.h" +#include "tnlLog.h" +#include "tnlRandom.h" +#include "tnlSymmetricCipher.h" +#include "tnlAsymmetricKey.h" +#include "tnlConnectionStringTable.h" + +#include + + +namespace TNL { + +NetConnectionRep *NetConnectionRep::mLinkedList = NULL; + +NetConnection *NetConnectionRep::create(const char *name) +{ + for(NetConnectionRep *walk = mLinkedList; walk; walk = walk->mNext) + if(walk->mCanRemoteCreate && !strcmp(name, walk->mClassRep->getClassName())) + { + Object *obj = walk->mClassRep->create(); + NetConnection *ret = dynamic_cast(obj); + TNLAssert(ret != NULL, "Invalid TNL_IMPLEMENT_NETCONNECTION"); + if(!ret) + delete obj; + return ret; + } + + return NULL; +} + +static const char *packetTypeNames[] = +{ + "DataPacket", + "PingPacket", + "AckPacket", +}; + +//----------------------------------------------------------------- + +NetConnection::NetConnection() +{ + mInitialSendSeq = Random::readI(); + Random::read(mConnectionParameters.mNonce.data, Nonce::NonceSize); + + mSimulatedLatency = 0; + mSimulatedPacketLoss = 0; + + mLastPacketRecvTime = 0; + mLastUpdateTime = 0; + mRoundTripTime = 0; + mSendDelayCredit = 0; + mConnectionState = NotConnected; + + mNotifyQueueHead = NULL; + mNotifyQueueTail = NULL; + + mLocalRate.maxRecvBandwidth = DefaultFixedBandwidth; + mLocalRate.maxSendBandwidth = DefaultFixedBandwidth; + mLocalRate.minPacketRecvPeriod = DefaultFixedSendPeriod; + mLocalRate.minPacketSendPeriod = DefaultFixedSendPeriod; + + mRemoteRate = mLocalRate; + mLocalRateChanged = true; + computeNegotiatedRate(); + + mPingSendCount = 0; + mLastPingSendTime = 0; + + mLastSeqRecvd = 0; + mHighestAckedSeq = mInitialSendSeq; + mLastSendSeq = mInitialSendSeq; // start sending at mInitialSendSeq + 1 + mAckMask[0] = 0; + mLastRecvAckAck = 0; + + // Adaptive + cwnd = 2; + ssthresh = 30; + mLastSeqRecvdAck = 0; + + mPingTimeout = DefaultPingTimeout; + mPingRetryCount = DefaultPingRetryCount; + mStringTable = NULL; +} + +void NetConnection::setInitialRecvSequence(U32 sequence) +{ + mInitialRecvSeq = mLastSeqRecvd = mLastRecvAckAck = sequence; +} + +void NetConnection::clearAllPacketNotifies() +{ + while(mNotifyQueueHead) + handleNotify(0, false); +} + +NetConnection::~NetConnection() +{ + clearAllPacketNotifies(); + delete mStringTable; + + TNLAssert(mNotifyQueueHead == NULL, "Uncleared notifies remain."); +} + +//-------------------------------------------------------------------- +void NetConnection::setNetAddress(const Address &addr) +{ + mNetAddress = addr; +} + +const Address &NetConnection::getNetAddress() +{ + return mNetAddress; +} + +NetConnection::PacketNotify::PacketNotify() +{ + rateChanged = false; + sendTime = 0; +} + +bool NetConnection::checkTimeout(U32 time) +{ + if(!isNetworkConnection()) + return false; + + if(!mLastPingSendTime) + mLastPingSendTime = time; + + U32 timeout = mPingTimeout; + U32 timeoutCount = mPingRetryCount; + + if(isAdaptive()) + { + if(hasUnackedSentPackets()) + { + timeout = AdaptiveUnackedSentPingTimeout; + } + else + { + timeoutCount = AdaptivePingRetryCount; + if(!mPingSendCount) + timeout = AdaptiveInitialPingTimeout; + } + } + if((time - mLastPingSendTime) > timeout) + { + if(mPingSendCount >= timeoutCount) + return true; + mLastPingSendTime = time; + mPingSendCount++; + sendPingPacket(); + } + return false; +} + +void NetConnection::keepAlive() +{ + mLastPingSendTime = 0; + mPingSendCount = 0; +} + +//-------------------------------------------------------------------- + +char NetConnection::mErrorBuffer[256]; + +void NetConnection::setLastError(const char *fmt, ...) +{ + va_list argptr; + va_start(argptr, fmt); + dVsprintf(mErrorBuffer, sizeof(mErrorBuffer), fmt, argptr); + // setLastErrors assert in debug builds + + TNLAssert(0, mErrorBuffer); + va_end(argptr); +} + +//-------------------------------------------------------------------- + +void NetConnection::writeRawPacket(BitStream *bstream, NetPacketType packetType) +{ + writePacketHeader(bstream, packetType); + if(packetType == DataPacket) + { + PacketNotify *note = allocNotify(); + if(!mNotifyQueueHead) + mNotifyQueueHead = note; + else + mNotifyQueueTail->nextPacket = note; + mNotifyQueueTail = note; + note->nextPacket = NULL; + note->sendTime = mInterface->getCurrentTime(); + + writePacketRateInfo(bstream, note); + S32 start = bstream->getBitPosition(); + bstream->setStringTable(mStringTable); + + TNLLogMessageV(LogNetConnection, ("NetConnection %s: START %s", mNetAddress.toString(), getClassName()) ); + writePacket(bstream, note); + TNLLogMessageV(LogNetConnection, ("NetConnection %s: END %s - %d bits", mNetAddress.toString(), getClassName(), bstream->getBitPosition() - start) ); + } + if(!mSymmetricCipher.isNull()) + { + mSymmetricCipher->setupCounter(mLastSendSeq, mLastSeqRecvd, packetType, 0); + bstream->hashAndEncrypt(MessageSignatureBytes, PacketHeaderByteSize, mSymmetricCipher); + } +} + +void NetConnection::readRawPacket(BitStream *bstream) +{ + if(mSimulatedPacketLoss && Random::readF() < mSimulatedPacketLoss) + { + TNLLogMessageV(LogNetConnection, ("NetConnection %s: RECVDROP - %d", mNetAddress.toString(), getLastSendSequence())); + return; + } + TNLLogMessageV(LogNetConnection, ("NetConnection %s: RECV- %d bytes", mNetAddress.toString(), bstream->getMaxReadBitPosition() >> 3)); + + mErrorBuffer[0] = 0; + if(readPacketHeader(bstream)) + { + mLastPacketRecvTime = mInterface->getCurrentTime(); + + readPacketRateInfo(bstream); + bstream->setStringTable(mStringTable); + readPacket(bstream); + + if(!bstream->isValid() && !mErrorBuffer[0]) + NetConnection::setLastError("Invalid Packet."); + if(mErrorBuffer[0]) + getInterface()->handleConnectionError(this, mErrorBuffer); + mErrorBuffer[0] = 0; + } +} + +//-------------------------------------------------------------------- + +void NetConnection::writePacketHeader(BitStream *stream, NetPacketType packetType) +{ + if(windowFull() && packetType == DataPacket) + TNL_DEBUGBREAK(); + + S32 ackByteCount = ((mLastSeqRecvd - mLastRecvAckAck + 7) >> 3); + TNLAssert(ackByteCount <= MaxAckByteCount, "ackByteCount exceeds MaxAckByteCount!"); + + if(packetType == DataPacket) + mLastSendSeq++; + + stream->writeInt(packetType, 2); + stream->writeInt(mLastSendSeq, 5); // write the first 5 bits of the send sequence + stream->writeFlag(true); // high bit of first byte indicates this is a data packet. + stream->writeInt(mLastSendSeq >> 5, SequenceNumberBitSize - 5); // write the rest of the send sequence + stream->writeInt(mLastSeqRecvd, AckSequenceNumberBitSize); + stream->writeInt(0, PacketHeaderPadBits); + + stream->writeRangedU32(ackByteCount, 0, MaxAckByteCount); + + U32 wordCount = (ackByteCount + 3) >> 2; + + for(U32 i = 0; i < wordCount; i++) + stream->writeInt(mAckMask[i], i == wordCount - 1 ? + (ackByteCount - (i * 4)) * 8 : 32); + + U32 sendDelay = mInterface->getCurrentTime() - mLastPacketRecvTime; + if(sendDelay > 2047) + sendDelay = 2047; + stream->writeInt(sendDelay >> 3, 8); + + // if we're resending this header, we can't advance the + // sequence recieved (in case this packet drops and the prev one + // goes through) + + if(packetType == DataPacket) + mLastSeqRecvdAtSend[mLastSendSeq & PacketWindowMask] = mLastSeqRecvd; + + //if(isNetworkConnection()) + //{ + // TNLLogMessageV(LogBlah, ("SND: mLSQ: %08x pkLS: %08x pt: %d abc: %d", + // mLastSendSeq, mLastSeqRecvd, packetType, ackByteCount)); + //} + + TNLLogMessageV(LogConnectionProtocol, ("build hdr %d %d", mLastSendSeq, packetType)); +} + +bool NetConnection::readPacketHeader(BitStream *pstream) +{ + // read in the packet header: + // + // 2 bits packet type + // low 5 bits of the packet sequence number + // 1 bit game packet + // SequenceNumberBitSize-5 bits (packet seq number >> 5) + // AckSequenceNumberBitSize bits ackstart seq number + // PacketHeaderPadBits = 0 - padding to byte boundary + // after this point, if this is an encrypted packet, all the rest of the data will be encrypted + + // rangedU32 - 0...MaxAckByteCount + // + // type is: + // 00 data packet + // 01 ping packet + // 02 ack packet + + // next 0...ackByteCount bytes are ack flags + // + // return value is true if this is a valid data packet + // or false if there is nothing more that should be read + + U32 pkPacketType = pstream->readInt(2); + U32 pkSequenceNumber = pstream->readInt(5); + bool pkDataPacketFlg = pstream->readFlag(); + pkSequenceNumber = pkSequenceNumber | (pstream->readInt(SequenceNumberBitSize - 5) << 5); + + U32 pkHighestAck = pstream->readInt(AckSequenceNumberBitSize); + U32 pkPadBits = pstream->readInt(PacketHeaderPadBits); + + if(pkPadBits != 0) + return false; + + TNLAssert(pkDataPacketFlg, "Invalid packet header in NetConnection::readPacketHeader!"); + + // verify packet ordering and acking and stuff + // check if the 9-bit sequence is within the packet window + // (within 31 packets of the last received sequence number). + + pkSequenceNumber |= (mLastSeqRecvd & SequenceNumberMask); + // account for wrap around + if(pkSequenceNumber < mLastSeqRecvd) + pkSequenceNumber += SequenceNumberWindowSize; + + // in the following test, account for wrap around from 0 + if(pkSequenceNumber - mLastSeqRecvd > (MaxPacketWindowSize - 1)) + { + // the sequence number is outside the window... must be out of order + // discard. + return false; + } + + pkHighestAck |= (mHighestAckedSeq & AckSequenceNumberMask); + // account for wrap around + + if(pkHighestAck < mHighestAckedSeq) + pkHighestAck += AckSequenceNumberWindowSize; + + if(pkHighestAck > mLastSendSeq) + { + // the ack number is outside the window... must be an out of order + // packet, discard. + return false; + } + + if(!mSymmetricCipher.isNull()) + { + mSymmetricCipher->setupCounter(pkSequenceNumber, pkHighestAck, pkPacketType, 0); + if(!pstream->decryptAndCheckHash(MessageSignatureBytes, PacketHeaderByteSize, mSymmetricCipher)) + { + TNLLogMessage(LogNetConnection, "Packet failed crypto"); + return false; + } + } + + U32 pkAckByteCount = pstream->readRangedU32(0, MaxAckByteCount); + if(pkAckByteCount > MaxAckByteCount || pkPacketType >= InvalidPacketType) + return false; + + U32 pkAckMask[MaxAckMaskSize]; + U32 pkAckWordCount = (pkAckByteCount + 3) >> 2; + + for(U32 i = 0; i < pkAckWordCount; i++) + pkAckMask[i] = pstream->readInt(i == pkAckWordCount - 1 ? + (pkAckByteCount - (i * 4)) * 8 : 32); + + //if(isNetworkConnection()) + //{ + // TNLLogMessageV(LogBlah, ("RCV: mHA: %08x pkHA: %08x mLSQ: %08x pkSN: %08x pkLS: %08x pkAM: %08x", + // mHighestAckedSeq, pkHighestAck, mLastSendSeq, pkSequenceNumber, mLastSeqRecvd, pkAckMask[0])); + //} + + U32 pkSendDelay = (pstream->readInt(8) << 3) + 4; + + TNLLogBlock(LogConnectionProtocol, + for(U32 i = mLastSeqRecvd+1; i < pkSequenceNumber; i++) + logprintf ("Not recv %d", i); + logprintf("Recv %d %s", pkSequenceNumber, packetTypeNames[pkPacketType]); + ); + + // shift up the ack mask by the packet difference + // this essentially nacks all the packets dropped + + U32 ackMaskShift = pkSequenceNumber - mLastSeqRecvd; + + // if we've missed more than a full word of packets, shift up by words + while(ackMaskShift > 32) + { + for(S32 i = MaxAckMaskSize - 1; i > 0; i--) + mAckMask[i] = mAckMask[i-1]; + mAckMask[0] = 0; + ackMaskShift -= 32; + } + + // the first word upshifts all NACKs, except for the low bit, which is a + // 1 if this is a data packet (i.e. not a ping packet or an ack packet) + U32 upShifted = (pkPacketType == DataPacket) ? 1 : 0; + + for(U32 i = 0; i < MaxAckMaskSize; i++) + { + U32 nextShift = mAckMask[i] >> (32 - ackMaskShift); + mAckMask[i] = (mAckMask[i] << ackMaskShift) | upShifted; + upShifted = nextShift; + } + + // do all the notifies... + U32 notifyCount = pkHighestAck - mHighestAckedSeq; + for(U32 i = 0; i < notifyCount; i++) + { + U32 notifyIndex = mHighestAckedSeq + i + 1; + + U32 ackMaskBit = (pkHighestAck - notifyIndex) & 0x1F; + U32 ackMaskWord = (pkHighestAck - notifyIndex) >> 5; + + bool packetTransmitSuccess = (pkAckMask[ackMaskWord] & (1 << ackMaskBit)) != 0; + TNLLogMessageV(LogConnectionProtocol, ("Ack %d %d", notifyIndex, packetTransmitSuccess)); + + mHighestAckedSendTime = 0; + handleNotify(notifyIndex, packetTransmitSuccess); + + // Running average of roundTrip time + if(mHighestAckedSendTime) + { + S32 roundTripDelta = mInterface->getCurrentTime() - (mHighestAckedSendTime + pkSendDelay); + mRoundTripTime = mRoundTripTime * 0.9f + roundTripDelta * 0.1f; + if(mRoundTripTime < 0) + mRoundTripTime = 0; + } + if(packetTransmitSuccess) + mLastRecvAckAck = mLastSeqRecvdAtSend[notifyIndex & PacketWindowMask]; + } + // the other side knows more about its window than we do. + if(pkSequenceNumber - mLastRecvAckAck > MaxPacketWindowSize) + mLastRecvAckAck = pkSequenceNumber - MaxPacketWindowSize; + + mHighestAckedSeq = pkHighestAck; + + // first things first... + // ackback any pings or half-full windows + + keepAlive(); // notification that the connection is ok + + U32 prevLastSequence = mLastSeqRecvd; + mLastSeqRecvd = pkSequenceNumber; + + if(pkPacketType == PingPacket || (pkSequenceNumber - mLastRecvAckAck > (MaxPacketWindowSize >> 1))) + { + // send an ack to the other side + // the ack will have the same packet sequence as our last sent packet + // if the last packet we sent was the connection accepted packet + // we must resend that packet + sendAckPacket(); + } + return prevLastSequence != pkSequenceNumber && pkPacketType == DataPacket; +} + +//-------------------------------------------------------------------- + +void NetConnection::writePacketRateInfo(BitStream *bstream, PacketNotify *note) +{ + note->rateChanged = mLocalRateChanged; + mLocalRateChanged = false; + if(bstream->writeFlag(note->rateChanged)) + { + if(!bstream->writeFlag(mTypeFlags.test(ConnectionAdaptive))) + { + bstream->writeRangedU32(mLocalRate.maxRecvBandwidth, 0, MaxFixedBandwidth); + bstream->writeRangedU32(mLocalRate.maxSendBandwidth, 0, MaxFixedBandwidth); + bstream->writeRangedU32(mLocalRate.minPacketRecvPeriod, 1, MaxFixedSendPeriod); + bstream->writeRangedU32(mLocalRate.minPacketSendPeriod, 1, MaxFixedSendPeriod); + } + } +} + +void NetConnection::readPacketRateInfo(BitStream *bstream) +{ + if(bstream->readFlag()) + { + if(bstream->readFlag()) + mTypeFlags.set(ConnectionRemoteAdaptive); + else + { + mRemoteRate.maxRecvBandwidth = bstream->readRangedU32(0, MaxFixedBandwidth); + mRemoteRate.maxSendBandwidth = bstream->readRangedU32(0, MaxFixedBandwidth); + mRemoteRate.minPacketRecvPeriod = bstream->readRangedU32(1, MaxFixedSendPeriod); + mRemoteRate.minPacketSendPeriod = bstream->readRangedU32(1, MaxFixedSendPeriod); + computeNegotiatedRate(); + } + } +} + +void NetConnection::computeNegotiatedRate() +{ + mCurrentPacketSendPeriod = getMax(mLocalRate.minPacketSendPeriod, mRemoteRate.minPacketRecvPeriod); + + U32 maxBandwidth = getMin(mLocalRate.maxSendBandwidth, mRemoteRate.maxRecvBandwidth); + mCurrentPacketSendSize = U32(maxBandwidth * mCurrentPacketSendPeriod * 0.001f); + + // make sure we don't try to overwrite the maximum packet size + if(mCurrentPacketSendSize > MaxPacketDataSize) + mCurrentPacketSendSize = MaxPacketDataSize; +} + +void NetConnection::setIsAdaptive() +{ + mTypeFlags.set(ConnectionAdaptive); + mLocalRateChanged = true; +} + +void NetConnection::setFixedRateParameters(U32 minPacketSendPeriod, U32 minPacketRecvPeriod, U32 maxSendBandwidth, U32 maxRecvBandwidth) +{ + mTypeFlags.clear(ConnectionAdaptive); + + mLocalRate.maxRecvBandwidth = maxRecvBandwidth; + mLocalRate.maxSendBandwidth = maxSendBandwidth; + mLocalRate.minPacketRecvPeriod = minPacketRecvPeriod; + mLocalRate.minPacketSendPeriod = minPacketSendPeriod; + mLocalRateChanged = true; + computeNegotiatedRate(); +} + +//-------------------------------------------------------------------- + +void NetConnection::sendPingPacket() +{ + PacketStream ps; + writeRawPacket(&ps, PingPacket); + TNLLogMessageV(LogConnectionProtocol, ("send ping %d", mLastSendSeq)); + + sendPacket(&ps); +} + +void NetConnection::sendAckPacket() +{ + PacketStream ps; + writeRawPacket(&ps, AckPacket); + TNLLogMessageV(LogConnectionProtocol, ("send ack %d", mLastSendSeq)); + + sendPacket(&ps); +} + +//-------------------------------------------------------------------- + +void NetConnection::handleNotify(U32 sequence, bool recvd) +{ + TNLLogMessageV(LogNetConnection, ("NetConnection %s: NOTIFY %d %s", mNetAddress.toString(), sequence, recvd ? "RECVD" : "DROPPED")); + + PacketNotify *note = mNotifyQueueHead; + TNLAssert(note != NULL, "Error: got a notify with a null notify head."); + mNotifyQueueHead = mNotifyQueueHead->nextPacket; + + if(note->rateChanged && !recvd) + mLocalRateChanged = true; + + if(recvd) + { + mHighestAckedSendTime = note->sendTime; + + if(isAdaptive()) + { + // Deal with updating our cwnd and ssthresh... + if(cwnd < ssthresh) + { + // Slow start strategy + cwnd++; + TNLLogMessageV(LogNetConnection, ("PKT SSOK - ssthresh = %f cwnd=%f", ssthresh, cwnd)); + + } else { + // We are in normal state.. + if(cwnd < MaxPacketWindowSize-2) + cwnd += 1/cwnd; + + TNLLogMessageV(LogNetConnection, ("PKT OK - ssthresh = %f cwnd=%f", ssthresh, cwnd)); + + } + } + + packetReceived(note); + } + else + { + if(isAdaptive()) + { + // Deal with updating our cwnd and ssthresh... + ssthresh = (0.5f * ssthresh < 2) ? 2 : (0.5f * ssthresh); + cwnd -= 1; + if(cwnd < 2) cwnd = 2; + +/* TNLLogMessageV(LogNetConnection, (" * ack=%f pktDt=%d time=%f (%d) seq=%d %d %d %d", + ack, + ackDelta, + deltaT / 1000.0f, + deltaT, + mLastSeqRecvd, + mLastRecvAckAck, + mLastSeqRecvdAck, + mHighestAckedSeq + )); */ + + } + + packetDropped(note); + } + delete note; +} + +//-------------------------------------------------------------------- + +void NetConnection::checkPacketSend(bool force, U32 curTime) +{ + U32 delay = mCurrentPacketSendPeriod; + + if(!force) + { + if(!isAdaptive()) + { + if(curTime - mLastUpdateTime + mSendDelayCredit < delay) + return; + + mSendDelayCredit = curTime - (mLastUpdateTime + delay - mSendDelayCredit); + if(mSendDelayCredit > 1000) + mSendDelayCredit = 1000; + } + } + prepareWritePacket(); + if(windowFull() || !isDataToTransmit()) + { + // there is nothing to transmit, or the window is full + if(isAdaptive()) + { + // Still, on an adaptive connection, we may need to send an ack here... + + // Check if we should ack. We use a heuristic to do this. (fuzzy logic!) + S32 ackDelta = (mLastSeqRecvd - mLastSeqRecvdAck); + F32 ack = ackDelta / 4.0f; + + // Multiply by the time since we've acked... + // If we're much below 200, we don't want to ack; if we're much over we do. + U32 deltaT = (curTime - mLastAckTime); + ack = ack * deltaT / 200.0f; + + if((ack > 1.0f || (ackDelta > (0.75*MaxPacketWindowSize))) && (mLastSeqRecvdAck != mLastSeqRecvd)) + { + mLastSeqRecvdAck = mLastSeqRecvd; + mLastAckTime = curTime; + sendAckPacket(); + } + } + return; + } + PacketStream stream(mCurrentPacketSendSize); + mLastUpdateTime = curTime; + + writeRawPacket(&stream, DataPacket); + + sendPacket(&stream); +} + +bool NetConnection::windowFull() +{ + if(mLastSendSeq - mHighestAckedSeq >= (MaxPacketWindowSize - 2)) + return true; + if(isAdaptive()) + return mLastSendSeq - mHighestAckedSeq >= cwnd; + return false; +} + +NetError NetConnection::sendPacket(BitStream *stream) +{ + if(mSimulatedPacketLoss && Random::readF() < mSimulatedPacketLoss) + { + TNLLogMessageV(LogNetConnection, ("NetConnection %s: SENDDROP - %d", mNetAddress.toString(), getLastSendSequence())); + return NoError; + } + + TNLLogMessageV(LogNetConnection, ("NetConnection %s: SEND - %d bytes", mNetAddress.toString(), stream->getBytePosition())); + + // do nothing on send if this is a demo replay. + if(isLocalConnection()) + { + // short circuit connection to the other side. + // handle the packet, then force a notify. + U32 size = stream->getBytePosition(); + + stream->reset(); + stream->setMaxSizes(size, 0); + + mRemoteConnection->readRawPacket(stream); + return NoError; + } + else + { + if(mSimulatedLatency) + { + mInterface->sendtoDelayed(getNetAddress(), stream, mSimulatedLatency); + return NoError; + } + else + return mInterface->sendto(getNetAddress(), stream); + } +} + +//-------------------------------------------------------------------- +//-------------------------------------------------------------------- + +// these are the virtual function defs for Connection - +// if your subclass has additional data to read / write / notify, add it in these functions. + +void NetConnection::readPacket(BitStream *bstream) +{ +} + +void NetConnection::prepareWritePacket() +{ +} + +void NetConnection::writePacket(BitStream *bstream, PacketNotify *note) +{ +} + +void NetConnection::packetReceived(PacketNotify *note) +{ + if(mStringTable) + mStringTable->packetReceived(¬e->stringList); +} + +void NetConnection::packetDropped(PacketNotify *note) +{ + if(mStringTable) + mStringTable->packetDropped(¬e->stringList); + +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +void NetConnection::setTranslatesStrings() +{ + if(!mStringTable) + mStringTable = new ConnectionStringTable(this); +} + +void NetConnection::setInterface(NetInterface *myInterface) +{ + mInterface = myInterface; +} + +NetInterface *NetConnection::getInterface() +{ + return mInterface; +} + +void NetConnection::setSymmetricCipher(SymmetricCipher *theCipher) +{ + mSymmetricCipher = theCipher; +} + +void NetConnection::connect(NetInterface *theInterface, const Address &address, bool requestKeyExchange, bool requestCertificate) +{ + mConnectionParameters.mRequestKeyExchange = requestKeyExchange; + mConnectionParameters.mRequestCertificate = requestCertificate; + mConnectionParameters.mIsInitiator = true; + + setNetAddress(address); + setInterface(theInterface); + mInterface->startConnection(this); +} + +void NetConnection::connectArranged(NetInterface *connectionInterface, const Vector
&possibleAddresses, Nonce &nonce, Nonce &serverNonce, ByteBufferPtr sharedSecret, bool isInitiator, bool requestsKeyExchange, bool requestsCertificate) +{ + mConnectionParameters.mRequestKeyExchange = requestsKeyExchange; + mConnectionParameters.mRequestCertificate = requestsCertificate; + mConnectionParameters.mPossibleAddresses = possibleAddresses; + mConnectionParameters.mIsInitiator = isInitiator; + mConnectionParameters.mIsArranged = true; + mConnectionParameters.mNonce = nonce; + mConnectionParameters.mServerNonce = serverNonce; + mConnectionParameters.mArrangedSecret = sharedSecret; + mConnectionParameters.mArrangedSecret->takeOwnership(); + + setInterface(connectionInterface); + mInterface->startArrangedConnection(this); +} + +void NetConnection::disconnect(const char *reason) +{ + mInterface->disconnect(this, ReasonSelfDisconnect, reason); +} + +void NetConnection::onConnectionEstablished() +{ + if(isInitiator()) + setIsConnectionToServer(); + else + setIsConnectionToClient(); +} + +void NetConnection::onConnectionTerminated(TerminationReason, const char *) +{ +} + +void NetConnection::onConnectTerminated(TerminationReason, const char *) +{ +} + +void NetConnection::writeConnectRequest(BitStream *stream) +{ + stream->write(U32(getNetClassGroup())); + stream->write(U32(NetClassRep::getClassGroupCRC(getNetClassGroup()))); +} + +bool NetConnection::readConnectRequest(BitStream *stream, const char **errorString) +{ + U32 classGroup, classCRC; + stream->read(&classGroup); + stream->read(&classCRC); + + if(classGroup == getNetClassGroup() && classCRC == NetClassRep::getClassGroupCRC(getNetClassGroup())) + return true; + + *errorString = "CHR_INVALID"; + return false; +} + +void NetConnection::writeConnectAccept(BitStream *stream) +{ + stream; +} + +bool NetConnection::readConnectAccept(BitStream *stream, const char **errorString) +{ + stream; + errorString; + return true; +} + +bool NetConnection::connectLocal(NetInterface *connectionInterface, NetInterface *serverInterface) +{ + Object *co = Object::create(getClassName()); + NetConnection *client = this; + NetConnection *server = dynamic_cast(co); + const char *error = NULL; + PacketStream stream; + + if(!server) + goto errorOut; + + client->setInterface(connectionInterface); + client->getConnectionParameters().mIsInitiator = true; + client->getConnectionParameters().mIsLocal = true; + server->getConnectionParameters().mIsLocal = true; + + server->setInterface(serverInterface); + + server->setInitialRecvSequence(client->getInitialSendSequence()); + client->setInitialRecvSequence(server->getInitialSendSequence()); + client->setRemoteConnectionObject(server); + server->setRemoteConnectionObject(client); + + stream.setBytePosition(0); + client->writeConnectRequest(&stream); + stream.setBytePosition(0); + if(!server->readConnectRequest(&stream, &error)) + goto errorOut; + + stream.setBytePosition(0); + server->writeConnectAccept(&stream); + stream.setBytePosition(0); + + if(!client->readConnectAccept(&stream, &error)) + goto errorOut; + + client->setConnectionState(NetConnection::Connected); + server->setConnectionState(NetConnection::Connected); + + client->onConnectionEstablished(); + server->onConnectionEstablished(); + connectionInterface->addConnection(client); + serverInterface->addConnection(server); + return true; +errorOut: + delete server; + return false; +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/netInterface.cpp b/tnl-1.5.0/tnl/tnl/netInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bad581b4569460693eb1c3d9fd5e1cbc237bcba5 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/netInterface.cpp @@ -0,0 +1,1312 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlAsymmetricKey.h" +#include "tnlNetConnection.h" +#include "tnlNetInterface.h" +#include "tnlBitStream.h" +#include "tnlRandom.h" +#include "tnlNetObject.h" +#include "tnlClientPuzzle.h" +#include "tnlCertificate.h" +#include + +namespace TNL { + +//----------------------------------------------------------------------------- +// NetInterface initialization/destruction +//----------------------------------------------------------------------------- + +NetInterface::NetInterface(const Address &bindAddress) : mSocket(bindAddress) +{ + NetClassRep::initialize(); // initialize the net class reps, if they haven't been initialized already. + + mLastTimeoutCheckTime = 0; + mAllowConnections = true; + mRequiresKeyExchange = false; + + Random::read(mRandomHashData, sizeof(mRandomHashData)); + + mConnectionHashTable.setSize(129); + for(S32 i = 0; i < mConnectionHashTable.size(); i++) + mConnectionHashTable[i] = NULL; + mSendPacketList = NULL; + mCurrentTime = Platform::getRealMilliseconds(); +} + +NetInterface::~NetInterface() +{ + // gracefully close all the connections on this NetInterface: + while(mConnectionList.size()) + { + NetConnection *c = mConnectionList[0]; + disconnect(c, NetConnection::ReasonSelfDisconnect, "Shutdown"); + } +} + +Address NetInterface::getFirstBoundInterfaceAddress() +{ + Address theAddress = mSocket.getBoundAddress(); + + if(theAddress.isEqualAddress(Address(IPProtocol, Address::Any, 0))) + { + Vector
interfaceAddresses; + Socket::getInterfaceAddresses(&interfaceAddresses); + U16 savePort = theAddress.port; + if(interfaceAddresses.size()) + { + theAddress = interfaceAddresses[0]; + theAddress.port = savePort; + } + } + return theAddress; +} + +void NetInterface::setPrivateKey(AsymmetricKey *theKey) +{ + mPrivateKey = theKey; +} + +//----------------------------------------------------------------------------- +// NetInterface packet sending functions +//----------------------------------------------------------------------------- + +NetError NetInterface::sendto(const Address &address, BitStream *stream) +{ + return mSocket.sendto(address, stream->getBuffer(), stream->getBytePosition()); +} + +void NetInterface::sendtoDelayed(const Address &address, BitStream *stream, U32 millisecondDelay) +{ + U32 dataSize = stream->getBytePosition(); + + // allocate the send packet, with the data size added on + DelaySendPacket *thePacket = (DelaySendPacket *) malloc(sizeof(DelaySendPacket) + dataSize); + thePacket->remoteAddress = address; + thePacket->sendTime = getCurrentTime() + millisecondDelay; + thePacket->packetSize = dataSize; + memcpy(thePacket->packetData, stream->getBuffer(), dataSize); + + // insert it into the DelaySendPacket list, sorted by time + DelaySendPacket **list; + for(list = &mSendPacketList; *list && ((*list)->sendTime < thePacket->sendTime); list = &((*list)->nextPacket)) + ; + thePacket->nextPacket = *list; + *list = thePacket; +} + +//----------------------------------------------------------------------------- +// NetInterface utility functions +//----------------------------------------------------------------------------- + +U32 NetInterface::computeClientIdentityToken(const Address &address, const Nonce &theNonce) +{ + hash_state hashState; + U32 hash[8]; + + sha256_init(&hashState); + sha256_process(&hashState, (const U8 *) &address, sizeof(Address)); + sha256_process(&hashState, theNonce.data, Nonce::NonceSize); + sha256_process(&hashState, mRandomHashData, sizeof(mRandomHashData)); + sha256_done(&hashState, (U8 *) hash); + + return hash[0]; +} + +//----------------------------------------------------------------------------- +// NetInterface pending connection list management +//----------------------------------------------------------------------------- + +void NetInterface::addPendingConnection(NetConnection *connection) +{ + // make sure we're not already connected to the host at the + // connection's Address + findAndRemovePendingConnection(connection->getNetAddress()); + NetConnection *temp = findConnection(connection->getNetAddress()); + if(temp) + disconnect(temp, NetConnection::ReasonSelfDisconnect, "Reconnecting"); + + // hang on to the connection and add it to the pending connection list + connection->incRef(); + mPendingConnections.push_back(connection); +} + +void NetInterface::removePendingConnection(NetConnection *connection) +{ + // search the pending connection list for the specified connection + // and remove it. + for(S32 i = 0; i < mPendingConnections.size(); i++) + if(mPendingConnections[i] == connection) + { + connection->decRef(); + mPendingConnections.erase(i); + return; + } +} + +NetConnection *NetInterface::findPendingConnection(const Address &address) +{ + // Loop through all the pending connections and compare the NetAddresses + for(S32 i = 0; i < mPendingConnections.size(); i++) + if(address == mPendingConnections[i]->getNetAddress()) + return mPendingConnections[i]; + return NULL; +} + +void NetInterface::findAndRemovePendingConnection(const Address &address) +{ + // Search through the list by Address and remove any connection + // that matches. + for(S32 i = 0; i < mPendingConnections.size(); i++) + if(address == mPendingConnections[i]->getNetAddress()) + { + mPendingConnections[i]->decRef(); + mPendingConnections.erase(i); + return; + } +} + +//----------------------------------------------------------------------------- +// NetInterface connection list management +//----------------------------------------------------------------------------- + +NetConnection *NetInterface::findConnection(const Address &addr) +{ + // The connection hash table is a single vector, with hash collisions + // resolved to the next open space in the table. + + // Compute the hash index based on the network address + U32 hashIndex = addr.hash() % mConnectionHashTable.size(); + + // Search through the table for an address that matches the source + // address. If the connection pointer is NULL, we've found an + // empty space and a connection with that address is not in the table + while(mConnectionHashTable[hashIndex] != NULL) + { + if(addr == mConnectionHashTable[hashIndex]->getNetAddress()) + return mConnectionHashTable[hashIndex]; + hashIndex++; + if(hashIndex >= (U32) mConnectionHashTable.size()) + hashIndex = 0; + } + return NULL; +} + +void NetInterface::removeConnection(NetConnection *conn) +{ + for(S32 i = 0; i < mConnectionList.size(); i++) + { + if(mConnectionList[i] == conn) + { + mConnectionList.erase_fast(i); + break; + } + } + U32 index = conn->getNetAddress().hash() % mConnectionHashTable.size(); + U32 startIndex = index; + + while(mConnectionHashTable[index] != conn) + { + index++; + if(index >= (U32) mConnectionHashTable.size()) + index = 0; + TNLAssert(index != startIndex, "Attempting to remove a connection that is not in the table.") // not in the table + if(index == startIndex) + return; + } + mConnectionHashTable[index] = NULL; + + // rehash all subsequent entries until we find a NULL entry: + for(;;) + { + index++; + if(index >= (U32) mConnectionHashTable.size()) + index = 0; + if(!mConnectionHashTable[index]) + break; + NetConnection *rehashConn = mConnectionHashTable[index]; + mConnectionHashTable[index] = NULL; + U32 realIndex = rehashConn->getNetAddress().hash() % mConnectionHashTable.size(); + while(mConnectionHashTable[realIndex] != NULL) + { + realIndex++; + if(realIndex >= (U32) mConnectionHashTable.size()) + realIndex = 0; + } + mConnectionHashTable[realIndex] = rehashConn; + } + conn->decRef(); +} + +void NetInterface::addConnection(NetConnection *conn) +{ + conn->incRef(); + mConnectionList.push_back(conn); + S32 numConnections = mConnectionList.size(); + if(numConnections > mConnectionHashTable.size() / 2) + { + mConnectionHashTable.setSize(numConnections * 4 - 1); + for(S32 i = 0; i < mConnectionHashTable.size(); i++) + mConnectionHashTable[i] = NULL; + for(S32 i = 0; i < numConnections; i++) + { + U32 index = mConnectionList[i]->getNetAddress().hash() % mConnectionHashTable.size(); + while(mConnectionHashTable[index] != NULL) + { + index++; + if(index >= (U32) mConnectionHashTable.size()) + index = 0; + } + mConnectionHashTable[index] = mConnectionList[i]; + } + } + else + { + U32 index = mConnectionList[numConnections - 1]->getNetAddress().hash() % mConnectionHashTable.size(); + while(mConnectionHashTable[index] != NULL) + { + index++; + if(index >= (U32) mConnectionHashTable.size()) + index = 0; + } + mConnectionHashTable[index] = mConnectionList[numConnections - 1]; + } +} + +//----------------------------------------------------------------------------- +// NetInterface timeout and packet send processing +//----------------------------------------------------------------------------- + +void NetInterface::processConnections() +{ + mCurrentTime = Platform::getRealMilliseconds(); + mPuzzleManager.tick(mCurrentTime); + + // first see if there are any delayed packets that need to be sent... + while(mSendPacketList && mSendPacketList->sendTime < getCurrentTime()) + { + DelaySendPacket *next = mSendPacketList->nextPacket; + mSocket.sendto(mSendPacketList->remoteAddress, + mSendPacketList->packetData, mSendPacketList->packetSize); + free(mSendPacketList); + mSendPacketList = next; + } + + NetObject::collapseDirtyList(); // collapse all the mask bits... + for(S32 i = 0; i < mConnectionList.size(); i++) + mConnectionList[i]->checkPacketSend(false, getCurrentTime()); + + if(getCurrentTime() > mLastTimeoutCheckTime + TimeoutCheckInterval) + { + for(S32 i = 0; i < mPendingConnections.size();) + { + NetConnection *pending = mPendingConnections[i]; + + if(pending->getConnectionState() == NetConnection::AwaitingChallengeResponse && + getCurrentTime() > pending->mConnectLastSendTime + ChallengeRetryTime) + { + if(pending->mConnectSendCount > ChallengeRetryCount) + { + pending->setConnectionState(NetConnection::ConnectTimedOut); + pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); + removePendingConnection(pending); + continue; + } + else + sendConnectChallengeRequest(pending); + } + else if(pending->getConnectionState() == NetConnection::AwaitingConnectResponse && + getCurrentTime() > pending->mConnectLastSendTime + ConnectRetryTime) + { + if(pending->mConnectSendCount > ConnectRetryCount) + { + pending->setConnectionState(NetConnection::ConnectTimedOut); + pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); + removePendingConnection(pending); + continue; + } + else + { + if(pending->getConnectionParameters().mIsArranged) + sendArrangedConnectRequest(pending); + else + sendConnectRequest(pending); + } + } + else if(pending->getConnectionState() == NetConnection::SendingPunchPackets && + getCurrentTime() > pending->mConnectLastSendTime + PunchRetryTime) + { + if(pending->mConnectSendCount > PunchRetryCount) + { + pending->setConnectionState(NetConnection::ConnectTimedOut); + pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); + removePendingConnection(pending); + continue; + } + else + sendPunchPackets(pending); + } + else if(pending->getConnectionState() == NetConnection::ComputingPuzzleSolution && + getCurrentTime() > pending->mConnectLastSendTime + PuzzleSolutionTimeout) + { + pending->setConnectionState(NetConnection::ConnectTimedOut); + pending->onConnectTerminated(NetConnection::ReasonTimedOut, "Timeout"); + removePendingConnection(pending); + } + i++; + } + mLastTimeoutCheckTime = getCurrentTime(); + + for(S32 i = 0; i < mConnectionList.size();) + { + if(mConnectionList[i]->checkTimeout(getCurrentTime())) + { + mConnectionList[i]->setConnectionState(NetConnection::TimedOut); + mConnectionList[i]->onConnectionTerminated(NetConnection::ReasonTimedOut, "Timeout"); + removeConnection(mConnectionList[i]); + } + else + i++; + } + } + + // check if we're trying to solve any client connection puzzles + for(S32 i = 0; i < mPendingConnections.size(); i++) + { + if(mPendingConnections[i]->getConnectionState() == NetConnection::ComputingPuzzleSolution) + { + continuePuzzleSolution(mPendingConnections[i]); + break; + } + } +} + +//----------------------------------------------------------------------------- +// NetInterface incoming packet dispatch +//----------------------------------------------------------------------------- + +void NetInterface::checkIncomingPackets() +{ + PacketStream stream; + NetError error; + Address sourceAddress; + + mCurrentTime = Platform::getRealMilliseconds(); + + // read out all the available packets: + while((error = stream.recvfrom(mSocket, &sourceAddress)) == NoError) + processPacket(sourceAddress, &stream); +} + +void NetInterface::processPacket(const Address &sourceAddress, BitStream *pStream) +{ + + // Determine what to do with this packet: + + if(pStream->getBuffer()[0] & 0x80) // it's a protocol packet... + { + // if the LSB of the first byte is set, it's a game data packet + // so pass it to the appropriate connection. + + // lookup the connection in the addressTable + // if this packet causes a disconnection, keep the conn around until this function exits + RefPtr conn = findConnection(sourceAddress); + if(conn) + conn->readRawPacket(pStream); + } + else + { + // Otherwise, it's either a game info packet or a + // connection handshake packet. + + U8 packetType; + pStream->read(&packetType); + + if(packetType >= FirstValidInfoPacketId) + handleInfoPacket(sourceAddress, packetType, pStream); + else + { + // check if there's a connection already: + switch(packetType) + { + case ConnectChallengeRequest: + handleConnectChallengeRequest(sourceAddress, pStream); + break; + case ConnectChallengeResponse: + handleConnectChallengeResponse(sourceAddress, pStream); + break; + case ConnectRequest: + handleConnectRequest(sourceAddress, pStream); + break; + case ConnectReject: + handleConnectReject(sourceAddress, pStream); + break; + case ConnectAccept: + handleConnectAccept(sourceAddress, pStream); + break; + case Disconnect: + handleDisconnect(sourceAddress, pStream); + break; + case Punch: + handlePunch(sourceAddress, pStream); + break; + case ArrangedConnectRequest: + handleArrangedConnectRequest(sourceAddress, pStream); + break; + } + } + } +} + +void NetInterface::handleInfoPacket(const Address &address, U8 packetType, BitStream *stream) +{ +} + +//----------------------------------------------------------------------------- +// NetInterface connection handshake initiaton and processing +//----------------------------------------------------------------------------- + +void NetInterface::startConnection(NetConnection *conn) +{ + TNLAssert(conn->getConnectionState() == NetConnection::NotConnected, + "Cannot start unless it is in the NotConnected state."); + + addPendingConnection(conn); + conn->mConnectSendCount = 0; + conn->setConnectionState(NetConnection::AwaitingChallengeResponse); + sendConnectChallengeRequest(conn); +} + +void NetInterface::sendConnectChallengeRequest(NetConnection *conn) +{ + TNLLogMessageV(LogNetInterface, ("Sending Connect Challenge Request to %s", conn->getNetAddress().toString())); + PacketStream out; + out.write(U8(ConnectChallengeRequest)); + ConnectionParameters ¶ms = conn->getConnectionParameters(); + params.mNonce.write(&out); + out.writeFlag(params.mRequestKeyExchange); + out.writeFlag(params.mRequestCertificate); + + conn->mConnectSendCount++; + conn->mConnectLastSendTime = getCurrentTime(); + out.sendto(mSocket, conn->getNetAddress()); +} + +void NetInterface::handleConnectChallengeRequest(const Address &addr, BitStream *stream) +{ + TNLLogMessageV(LogNetInterface, ("Received Connect Challenge Request from %s", addr.toString())); + + if(!mAllowConnections) + return; + Nonce clientNonce; + clientNonce.read(stream); + bool wantsKeyExchange = stream->readFlag(); + bool wantsCertificate = stream->readFlag(); + + sendConnectChallengeResponse(addr, clientNonce, wantsKeyExchange, wantsCertificate); +} + +void NetInterface::sendConnectChallengeResponse(const Address &addr, Nonce &clientNonce, bool wantsKeyExchange, bool wantsCertificate) +{ + PacketStream out; + out.write(U8(ConnectChallengeResponse)); + clientNonce.write(&out); + + U32 identityToken = computeClientIdentityToken(addr, clientNonce); + out.write(identityToken); + + // write out a client puzzle + Nonce serverNonce = mPuzzleManager.getCurrentNonce(); + U32 difficulty = mPuzzleManager.getCurrentDifficulty(); + serverNonce.write(&out); + out.write(difficulty); + + if(out.writeFlag(mRequiresKeyExchange || (wantsKeyExchange && !mPrivateKey.isNull()))) + { + if(out.writeFlag(wantsCertificate && !mCertificate.isNull())) + out.write(mCertificate); + else + out.write(mPrivateKey->getPublicKey()); + } + TNLLogMessageV(LogNetInterface, ("Sending Challenge Response: %8x", identityToken)); + + out.sendto(mSocket, addr); +} + +//----------------------------------------------------------------------------- + +void NetInterface::handleConnectChallengeResponse(const Address &address, BitStream *stream) +{ + NetConnection *conn = findPendingConnection(address); + if(!conn || conn->getConnectionState() != NetConnection::AwaitingChallengeResponse) + return; + + Nonce theNonce; + theNonce.read(stream); + + ConnectionParameters &theParams = conn->getConnectionParameters(); + if(theNonce != theParams.mNonce) + return; + + stream->read(&theParams.mClientIdentity); + + // see if the server wants us to solve a client puzzle + theParams.mServerNonce.read(stream); + stream->read(&theParams.mPuzzleDifficulty); + + if(theParams.mPuzzleDifficulty > ClientPuzzleManager::MaxPuzzleDifficulty) + return; + + // see if the connection needs to be authenticated or uses key exchange + if(stream->readFlag()) + { + if(stream->readFlag()) + { + theParams.mCertificate = new Certificate(stream); + if(!theParams.mCertificate->isValid() || !conn->validateCertficate(theParams.mCertificate, true)) + return; + theParams.mPublicKey = theParams.mCertificate->getPublicKey(); + } + else + { + theParams.mPublicKey = new AsymmetricKey(stream); + if(!theParams.mPublicKey->isValid() || !conn->validatePublicKey(theParams.mPublicKey, true)) + return; + } + if(mPrivateKey.isNull() || mPrivateKey->getKeySize() != theParams.mPublicKey->getKeySize()) + { + // we don't have a private key, so generate one for this connection + theParams.mPrivateKey = new AsymmetricKey(theParams.mPublicKey->getKeySize()); + } + else + theParams.mPrivateKey = mPrivateKey; + theParams.mSharedSecret = theParams.mPrivateKey->computeSharedSecretKey(theParams.mPublicKey); + //logprintf("shared secret (client) %s", theParams.mSharedSecret->encodeBase64()->getBuffer()); + Random::read(theParams.mSymmetricKey, SymmetricCipher::KeySize); + theParams.mUsingCrypto = true; + } + + TNLLogMessageV(LogNetInterface, ("Received Challenge Response: %8x", theParams.mClientIdentity )); + + conn->setConnectionState(NetConnection::ComputingPuzzleSolution); + conn->mConnectSendCount = 0; + + theParams.mPuzzleSolution = 0; + conn->mConnectLastSendTime = getCurrentTime(); + continuePuzzleSolution(conn); +} + +void NetInterface::continuePuzzleSolution(NetConnection *conn) +{ + ConnectionParameters &theParams = conn->getConnectionParameters(); + bool solved = ClientPuzzleManager::solvePuzzle(&theParams.mPuzzleSolution, theParams.mNonce, theParams.mServerNonce, theParams.mPuzzleDifficulty, theParams.mClientIdentity); + + if(solved) + { + logprintf("Client puzzle solved in %d ms.", Platform::getRealMilliseconds() - conn->mConnectLastSendTime); + conn->setConnectionState(NetConnection::AwaitingConnectResponse); + sendConnectRequest(conn); + } +} + +//----------------------------------------------------------------------------- +// NetInterface connect request +//----------------------------------------------------------------------------- + +void NetInterface::sendConnectRequest(NetConnection *conn) +{ + TNLLogMessageV(LogNetInterface, ("Sending Connect Request")); + PacketStream out; + ConnectionParameters &theParams = conn->getConnectionParameters(); + + out.write(U8(ConnectRequest)); + theParams.mNonce.write(&out); + theParams.mServerNonce.write(&out); + out.write(theParams.mClientIdentity); + out.write(theParams.mPuzzleDifficulty); + out.write(theParams.mPuzzleSolution); + + U32 encryptPos = 0; + + if(out.writeFlag(theParams.mUsingCrypto)) + { + out.write(theParams.mPrivateKey->getPublicKey()); + encryptPos = out.getBytePosition(); + out.setBytePosition(encryptPos); + out.write(SymmetricCipher::KeySize, theParams.mSymmetricKey); + } + out.writeFlag(theParams.mDebugObjectSizes); + out.write(conn->getInitialSendSequence()); + out.writeString(conn->getClassName()); + conn->writeConnectRequest(&out); + + if(encryptPos) + { + // if we're using crypto on this connection, + // then write a hash of everything we wrote into the packet + // key. Then we'll symmetrically encrypt the packet from + // the end of the public key to the end of the signature. + + SymmetricCipher theCipher(theParams.mSharedSecret); + out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); + } + + conn->mConnectSendCount++; + conn->mConnectLastSendTime = getCurrentTime(); + + out.sendto(mSocket, conn->getNetAddress()); +} + +void NetInterface::handleConnectRequest(const Address &address, BitStream *stream) +{ + if(!mAllowConnections) + return; + + ConnectionParameters theParams; + theParams.mNonce.read(stream); + theParams.mServerNonce.read(stream); + stream->read(&theParams.mClientIdentity); + + if(theParams.mClientIdentity != computeClientIdentityToken(address, theParams.mNonce)) + return; + + stream->read(&theParams.mPuzzleDifficulty); + stream->read(&theParams.mPuzzleSolution); + + // see if the connection is in the main connection table. + // If the connection is in the connection table and it has + // the same initiatorSequence, we'll just resend the connect + // acceptance packet, assuming that the last time we sent it + // it was dropped. + NetConnection *connect = findConnection(address); + if(connect) + { + ConnectionParameters &cp = connect->getConnectionParameters(); + if(cp.mNonce == theParams.mNonce && cp.mServerNonce == theParams.mServerNonce) + { + sendConnectAccept(connect); + return; + } + } + + // check the puzzle solution + ClientPuzzleManager::ErrorCode result = mPuzzleManager.checkSolution( + theParams.mPuzzleSolution, theParams.mNonce, theParams.mServerNonce, + theParams.mPuzzleDifficulty, theParams.mClientIdentity); + + if(result != ClientPuzzleManager::Success) + { + sendConnectReject(&theParams, address, "Puzzle"); + return; + } + + if(stream->readFlag()) + { + if(mPrivateKey.isNull()) + return; + + theParams.mUsingCrypto = true; + theParams.mPublicKey = new AsymmetricKey(stream); + theParams.mPrivateKey = mPrivateKey; + + U32 decryptPos = stream->getBytePosition(); + + stream->setBytePosition(decryptPos); + theParams.mSharedSecret = theParams.mPrivateKey->computeSharedSecretKey(theParams.mPublicKey); + //logprintf("shared secret (server) %s", theParams.mSharedSecret->encodeBase64()->getBuffer()); + + SymmetricCipher theCipher(theParams.mSharedSecret); + + if(!stream->decryptAndCheckHash(NetConnection::MessageSignatureBytes, decryptPos, &theCipher)) + return; + + // now read the first part of the connection's symmetric key + stream->read(SymmetricCipher::KeySize, theParams.mSymmetricKey); + Random::read(theParams.mInitVector, SymmetricCipher::KeySize); + } + + U32 connectSequence; + theParams.mDebugObjectSizes = stream->readFlag(); + stream->read(&connectSequence); + TNLLogMessageV(LogNetInterface, ("Received Connect Request %8x", theParams.mClientIdentity)); + + if(connect) + disconnect(connect, NetConnection::ReasonSelfDisconnect, "NewConnection"); + + char connectionClass[256]; + stream->readString(connectionClass); + + NetConnection *conn = NetConnectionRep::create(connectionClass); + + if(!conn) + return; + + RefPtr theConnection = conn; + conn->getConnectionParameters() = theParams; + + conn->setNetAddress(address); + conn->setInitialRecvSequence(connectSequence); + conn->setInterface(this); + + if(theParams.mUsingCrypto) + conn->setSymmetricCipher(new SymmetricCipher(theParams.mSymmetricKey, theParams.mInitVector)); + + const char *errorString = NULL; + if(!conn->readConnectRequest(stream, &errorString)) + { + sendConnectReject(&theParams, address, errorString); + return; + } + addConnection(conn); + conn->setConnectionState(NetConnection::Connected); + conn->onConnectionEstablished(); + sendConnectAccept(conn); +} + +//----------------------------------------------------------------------------- +// NetInterface connection acceptance and handling +//----------------------------------------------------------------------------- + +void NetInterface::sendConnectAccept(NetConnection *conn) +{ + TNLLogMessageV(LogNetInterface, ("Sending Connect Accept - connection established.")); + + PacketStream out; + out.write(U8(ConnectAccept)); + ConnectionParameters &theParams = conn->getConnectionParameters(); + + theParams.mNonce.write(&out); + theParams.mServerNonce.write(&out); + U32 encryptPos = out.getBytePosition(); + out.setBytePosition(encryptPos); + + out.write(conn->getInitialSendSequence()); + conn->writeConnectAccept(&out); + + if(theParams.mUsingCrypto) + { + out.write(SymmetricCipher::KeySize, theParams.mInitVector); + SymmetricCipher theCipher(theParams.mSharedSecret); + out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); + } + out.sendto(mSocket, conn->getNetAddress()); +} + +void NetInterface::handleConnectAccept(const Address &address, BitStream *stream) +{ + Nonce nonce, serverNonce; + + nonce.read(stream); + serverNonce.read(stream); + U32 decryptPos = stream->getBytePosition(); + stream->setBytePosition(decryptPos); + + NetConnection *conn = findPendingConnection(address); + if(!conn || conn->getConnectionState() != NetConnection::AwaitingConnectResponse) + return; + + ConnectionParameters &theParams = conn->getConnectionParameters(); + + if(theParams.mNonce != nonce || theParams.mServerNonce != serverNonce) + return; + + if(theParams.mUsingCrypto) + { + SymmetricCipher theCipher(theParams.mSharedSecret); + if(!stream->decryptAndCheckHash(NetConnection::MessageSignatureBytes, decryptPos, &theCipher)) + return; + } + U32 recvSequence; + stream->read(&recvSequence); + conn->setInitialRecvSequence(recvSequence); + + const char *errorString = NULL; + if(!conn->readConnectAccept(stream, &errorString)) + { + removePendingConnection(conn); + return; + } + if(theParams.mUsingCrypto) + { + stream->read(SymmetricCipher::KeySize, theParams.mInitVector); + conn->setSymmetricCipher(new SymmetricCipher(theParams.mSymmetricKey, theParams.mInitVector)); + } + + addConnection(conn); // first, add it as a regular connection + removePendingConnection(conn); // remove from the pending connection list + + conn->setConnectionState(NetConnection::Connected); + conn->onConnectionEstablished(); // notify the connection that it has been established + TNLLogMessageV(LogNetInterface, ("Received Connect Accept - connection established.")); +} + +//----------------------------------------------------------------------------- +// NetInterface connection rejection and handling +//----------------------------------------------------------------------------- + +void NetInterface::sendConnectReject(ConnectionParameters *conn, const Address &theAddress, const char *reason) +{ + if(!reason) + return; // if the stream is NULL, we reject silently + + PacketStream out; + out.write(U8(ConnectReject)); + conn->mNonce.write(&out); + conn->mServerNonce.write(&out); + out.writeString(reason); + out.sendto(mSocket, theAddress); +} + +void NetInterface::handleConnectReject(const Address &address, BitStream *stream) +{ + Nonce nonce; + Nonce serverNonce; + + nonce.read(stream); + serverNonce.read(stream); + + NetConnection *conn = findPendingConnection(address); + if(!conn || (conn->getConnectionState() != NetConnection::AwaitingChallengeResponse && + conn->getConnectionState() != NetConnection::AwaitingConnectResponse)) + return; + ConnectionParameters &p = conn->getConnectionParameters(); + if(p.mNonce != nonce || p.mServerNonce != serverNonce) + return; + + char reason[256]; + stream->readString(reason); + + TNLLogMessageV(LogNetInterface, ("Received Connect Reject - reason %s", reason)); + // if the reason is a bad puzzle solution, try once more with a + // new nonce. + if(!strcmp(reason, "Puzzle") && !p.mPuzzleRetried) + { + p.mPuzzleRetried = true; + conn->setConnectionState(NetConnection::AwaitingChallengeResponse); + conn->mConnectSendCount = 0; + p.mNonce.getRandom(); + sendConnectChallengeRequest(conn); + return; + } + + conn->setConnectionState(NetConnection::ConnectRejected); + conn->onConnectTerminated(NetConnection::ReasonRemoteHostRejectedConnection, reason); + removePendingConnection(conn); +} + +//----------------------------------------------------------------------------- +// NetInterface arranged connection process +//----------------------------------------------------------------------------- + +void NetInterface::startArrangedConnection(NetConnection *conn) +{ + + conn->setConnectionState(NetConnection::SendingPunchPackets); + addPendingConnection(conn); + conn->mConnectSendCount = 0; + conn->mConnectLastSendTime = getCurrentTime(); + sendPunchPackets(conn); +} + +void NetInterface::sendPunchPackets(NetConnection *conn) +{ + ConnectionParameters &theParams = conn->getConnectionParameters(); + PacketStream out; + out.write(U8(Punch)); + + if(theParams.mIsInitiator) + theParams.mNonce.write(&out); + else + theParams.mServerNonce.write(&out); + + U32 encryptPos = out.getBytePosition(); + out.setBytePosition(encryptPos); + + if(theParams.mIsInitiator) + theParams.mServerNonce.write(&out); + else + { + theParams.mNonce.write(&out); + if(out.writeFlag(mRequiresKeyExchange || (theParams.mRequestKeyExchange && !mPrivateKey.isNull()))) + { + if(out.writeFlag(theParams.mRequestCertificate && !mCertificate.isNull())) + out.write(mCertificate); + else + out.write(mPrivateKey->getPublicKey()); + } + } + SymmetricCipher theCipher(theParams.mArrangedSecret); + out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); + + for(S32 i = 0; i < theParams.mPossibleAddresses.size(); i++) + { + out.sendto(mSocket, theParams.mPossibleAddresses[i]); + + TNLLogMessageV(LogNetInterface, ("Sending punch packet (%s, %s) to %s", + ByteBuffer(theParams.mNonce.data, Nonce::NonceSize).encodeBase64()->getBuffer(), + ByteBuffer(theParams.mServerNonce.data, Nonce::NonceSize).encodeBase64()->getBuffer(), + theParams.mPossibleAddresses[i].toString())); + } + conn->mConnectSendCount++; + conn->mConnectLastSendTime = getCurrentTime(); +} + +void NetInterface::handlePunch(const Address &theAddress, BitStream *stream) +{ + S32 i, j; + NetConnection *conn; + + Nonce firstNonce; + firstNonce.read(stream); + + ByteBuffer b(firstNonce.data, Nonce::NonceSize); + + TNLLogMessageV(LogNetInterface, ("Received punch packet from %s - %s", theAddress.toString(), b.encodeBase64()->getBuffer())); + + for(i = 0; i < mPendingConnections.size(); i++) + { + conn = mPendingConnections[i]; + ConnectionParameters &theParams = conn->getConnectionParameters(); + + if(conn->getConnectionState() != NetConnection::SendingPunchPackets) + continue; + + if((theParams.mIsInitiator && firstNonce != theParams.mServerNonce) || + (!theParams.mIsInitiator && firstNonce != theParams.mNonce)) + continue; + + // first see if the address is in the possible addresses list: + + for(j = 0; j < theParams.mPossibleAddresses.size(); j++) + if(theAddress == theParams.mPossibleAddresses[j]) + break; + + // if there was an exact match, just exit the loop, or + // continue on to the next pending if this is not an initiator: + if(j != theParams.mPossibleAddresses.size()) + { + if(theParams.mIsInitiator) + break; + else + continue; + } + + // if there was no exact match, we may have a funny NAT in the + // middle. But since a packet got through from the remote host + // we'll want to send a punch to the address it came from, as long + // as only the port is not an exact match: + for(j = 0; j < theParams.mPossibleAddresses.size(); j++) + if(theAddress.isEqualAddress(theParams.mPossibleAddresses[j])) + break; + + // if the address wasn't even partially in the list, just exit out + if(j == theParams.mPossibleAddresses.size()) + continue; + + // otherwise, as long as we don't have too many ping addresses, + // add this one to the list: + if(theParams.mPossibleAddresses.size() < 5) + theParams.mPossibleAddresses.push_back(theAddress); + + // if this is the initiator of the arranged connection, then + // process the punch packet from the remote host by issueing a + // connection request. + if(theParams.mIsInitiator) + break; + } + if(i == mPendingConnections.size()) + return; + + ConnectionParameters &theParams = conn->getConnectionParameters(); + SymmetricCipher theCipher(theParams.mArrangedSecret); + if(!stream->decryptAndCheckHash(NetConnection::MessageSignatureBytes, stream->getBytePosition(), &theCipher)) + return; + + Nonce nextNonce; + nextNonce.read(stream); + + if(nextNonce != theParams.mNonce) + return; + + // see if the connection needs to be authenticated or uses key exchange + if(stream->readFlag()) + { + if(stream->readFlag()) + { + theParams.mCertificate = new Certificate(stream); + if(!theParams.mCertificate->isValid() || !conn->validateCertficate(theParams.mCertificate, true)) + return; + theParams.mPublicKey = theParams.mCertificate->getPublicKey(); + } + else + { + theParams.mPublicKey = new AsymmetricKey(stream); + if(!theParams.mPublicKey->isValid() || !conn->validatePublicKey(theParams.mPublicKey, true)) + return; + } + if(mPrivateKey.isNull() || mPrivateKey->getKeySize() != theParams.mPublicKey->getKeySize()) + { + // we don't have a private key, so generate one for this connection + theParams.mPrivateKey = new AsymmetricKey(theParams.mPublicKey->getKeySize()); + } + else + theParams.mPrivateKey = mPrivateKey; + theParams.mSharedSecret = theParams.mPrivateKey->computeSharedSecretKey(theParams.mPublicKey); + //logprintf("shared secret (client) %s", theParams.mSharedSecret->encodeBase64()->getBuffer()); + Random::read(theParams.mSymmetricKey, SymmetricCipher::KeySize); + theParams.mUsingCrypto = true; + } + conn->setNetAddress(theAddress); + TNLLogMessageV(LogNetInterface, ("Punch from %s matched nonces - connecting...", theAddress.toString())); + + conn->setConnectionState(NetConnection::AwaitingConnectResponse); + conn->mConnectSendCount = 0; + conn->mConnectLastSendTime = getCurrentTime(); + + sendArrangedConnectRequest(conn); +} + +void NetInterface::sendArrangedConnectRequest(NetConnection *conn) +{ + TNLLogMessageV(LogNetInterface, ("Sending Arranged Connect Request")); + PacketStream out; + + ConnectionParameters &theParams = conn->getConnectionParameters(); + + out.write(U8(ArrangedConnectRequest)); + theParams.mNonce.write(&out); + U32 encryptPos = out.getBytePosition(); + U32 innerEncryptPos = 0; + + out.setBytePosition(encryptPos); + + theParams.mServerNonce.write(&out); + if(out.writeFlag(theParams.mUsingCrypto)) + { + out.write(theParams.mPrivateKey->getPublicKey()); + innerEncryptPos = out.getBytePosition(); + out.setBytePosition(innerEncryptPos); + out.write(SymmetricCipher::KeySize, theParams.mSymmetricKey); + } + out.writeFlag(theParams.mDebugObjectSizes); + out.write(conn->getInitialSendSequence()); + conn->writeConnectRequest(&out); + + if(innerEncryptPos) + { + SymmetricCipher theCipher(theParams.mSharedSecret); + out.hashAndEncrypt(NetConnection::MessageSignatureBytes, innerEncryptPos, &theCipher); + } + SymmetricCipher theCipher(theParams.mArrangedSecret); + out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); + + conn->mConnectSendCount++; + conn->mConnectLastSendTime = getCurrentTime(); + + out.sendto(mSocket, conn->getNetAddress()); +} + +void NetInterface::handleArrangedConnectRequest(const Address &theAddress, BitStream *stream) +{ + S32 i, j; + NetConnection *conn; + Nonce nonce, serverNonce; + nonce.read(stream); + + // see if the connection is in the main connection table. + // If the connection is in the connection table and it has + // the same initiatorSequence, we'll just resend the connect + // acceptance packet, assuming that the last time we sent it + // it was dropped. + NetConnection *oldConnection = findConnection(theAddress); + if(oldConnection) + { + ConnectionParameters &cp = oldConnection->getConnectionParameters(); + if(cp.mNonce == nonce) + { + sendConnectAccept(oldConnection); + return; + } + } + + for(i = 0; i < mPendingConnections.size(); i++) + { + conn = mPendingConnections[i]; + ConnectionParameters &theParams = conn->getConnectionParameters(); + + if(conn->getConnectionState() != NetConnection::SendingPunchPackets || theParams.mIsInitiator) + continue; + + if(nonce != theParams.mNonce) + continue; + + for(j = 0; j < theParams.mPossibleAddresses.size(); j++) + if(theAddress.isEqualAddress(theParams.mPossibleAddresses[j])) + break; + if(j != theParams.mPossibleAddresses.size()) + break; + } + if(i == mPendingConnections.size()) + return; + + ConnectionParameters &theParams = conn->getConnectionParameters(); + SymmetricCipher theCipher(theParams.mArrangedSecret); + if(!stream->decryptAndCheckHash(NetConnection::MessageSignatureBytes, stream->getBytePosition(), &theCipher)) + return; + + stream->setBytePosition(stream->getBytePosition()); + + serverNonce.read(stream); + if(serverNonce != theParams.mServerNonce) + return; + + if(stream->readFlag()) + { + if(mPrivateKey.isNull()) + return; + theParams.mUsingCrypto = true; + theParams.mPublicKey = new AsymmetricKey(stream); + theParams.mPrivateKey = mPrivateKey; + + U32 decryptPos = stream->getBytePosition(); + stream->setBytePosition(decryptPos); + theParams.mSharedSecret = theParams.mPrivateKey->computeSharedSecretKey(theParams.mPublicKey); + SymmetricCipher theCipher(theParams.mSharedSecret); + + if(!stream->decryptAndCheckHash(NetConnection::MessageSignatureBytes, decryptPos, &theCipher)) + return; + + // now read the first part of the connection's session (symmetric) key + stream->read(SymmetricCipher::KeySize, theParams.mSymmetricKey); + Random::read(theParams.mInitVector, SymmetricCipher::KeySize); + } + + U32 connectSequence; + theParams.mDebugObjectSizes = stream->readFlag(); + stream->read(&connectSequence); + TNLLogMessageV(LogNetInterface, ("Received Arranged Connect Request")); + + if(oldConnection) + disconnect(oldConnection, NetConnection::ReasonSelfDisconnect, ""); + + conn->setNetAddress(theAddress); + conn->setInitialRecvSequence(connectSequence); + if(theParams.mUsingCrypto) + conn->setSymmetricCipher(new SymmetricCipher(theParams.mSymmetricKey, theParams.mInitVector)); + + const char *errorString = NULL; + if(!conn->readConnectRequest(stream, &errorString)) + { + sendConnectReject(&theParams, theAddress, errorString); + removePendingConnection(conn); + return; + } + addConnection(conn); + removePendingConnection(conn); + conn->setConnectionState(NetConnection::Connected); + conn->onConnectionEstablished(); + sendConnectAccept(conn); +} + +//----------------------------------------------------------------------------- +// NetInterface disconnection and handling +//----------------------------------------------------------------------------- + +void NetInterface::disconnect(NetConnection *conn, NetConnection::TerminationReason reason, const char *reasonString) +{ + if(conn->getConnectionState() == NetConnection::AwaitingChallengeResponse || + conn->getConnectionState() == NetConnection::AwaitingConnectResponse) + { + conn->onConnectTerminated(reason, reasonString); + removePendingConnection(conn); + } + else if(conn->getConnectionState() == NetConnection::Connected) + { + conn->setConnectionState(NetConnection::Disconnected); + conn->onConnectionTerminated(reason, reasonString); + if(conn->isNetworkConnection()) + { + // send a disconnect packet... + PacketStream out; + out.write(U8(Disconnect)); + ConnectionParameters &theParams = conn->getConnectionParameters(); + theParams.mNonce.write(&out); + theParams.mServerNonce.write(&out); + U32 encryptPos = out.getBytePosition(); + out.setBytePosition(encryptPos); + out.writeString(reasonString); + + if(theParams.mUsingCrypto) + { + SymmetricCipher theCipher(theParams.mSharedSecret); + out.hashAndEncrypt(NetConnection::MessageSignatureBytes, encryptPos, &theCipher); + } + out.sendto(mSocket, conn->getNetAddress()); + } + removeConnection(conn); + } +} + +void NetInterface::handleDisconnect(const Address &address, BitStream *stream) +{ + NetConnection *conn = findConnection(address); + if(!conn) + return; + + ConnectionParameters &theParams = conn->getConnectionParameters(); + + Nonce nonce, serverNonce; + char reason[256]; + + nonce.read(stream); + serverNonce.read(stream); + + if(nonce != theParams.mNonce || serverNonce != theParams.mServerNonce) + return; + + U32 decryptPos = stream->getBytePosition(); + stream->setBytePosition(decryptPos); + + if(theParams.mUsingCrypto) + { + SymmetricCipher theCipher(theParams.mSharedSecret); + if(!stream->decryptAndCheckHash(NetConnection::MessageSignatureBytes, decryptPos, &theCipher)) + return; + } + stream->readString(reason); + + conn->setConnectionState(NetConnection::Disconnected); + conn->onConnectionTerminated(NetConnection::ReasonRemoteDisconnectPacket, reason); + removeConnection(conn); +} + +void NetInterface::handleConnectionError(NetConnection *theConnection, const char *errorString) +{ + disconnect(theConnection, NetConnection::ReasonError, errorString); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/netObject.cpp b/tnl-1.5.0/tnl/tnl/netObject.cpp new file mode 100644 index 0000000000000000000000000000000000000000..412466ba42aef0389fb1f493df483b5ed8f9ba38 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/netObject.cpp @@ -0,0 +1,268 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlNetObject.h" +#include "tnlGhostConnection.h" +#include "tnlNetInterface.h" + +namespace TNL { + +GhostConnection *NetObject::mRPCSourceConnection = NULL; +GhostConnection *NetObject::mRPCDestConnection = NULL; +bool NetObject::mIsInitialUpdate = false; + +NetObject::NetObject() +{ + // netFlags will clear itself to 0 + mNetIndex = U32(-1); + mFirstObjectRef = NULL; + mPrevDirtyList = NULL; + mNextDirtyList = NULL; + mDirtyMaskBits = 0; +} + +NetObject::~NetObject() +{ + while(mFirstObjectRef) + mFirstObjectRef->connection->detachObject(mFirstObjectRef); + + if(mDirtyMaskBits) + { + if(mPrevDirtyList) + mPrevDirtyList->mNextDirtyList = mNextDirtyList; + else + mDirtyList = mNextDirtyList; + if(mNextDirtyList) + mNextDirtyList->mPrevDirtyList = mPrevDirtyList; + } +} + +NetObject *NetObject::mDirtyList = NULL; + +void NetObject::setMaskBits(U32 orMask) +{ + TNLAssert(orMask != 0, "Invalid net mask bits set."); + TNLAssert(mDirtyMaskBits == 0 || (mPrevDirtyList != NULL || mNextDirtyList != NULL || mDirtyList == this), "Invalid dirty list state."); + if(!mDirtyMaskBits) + { + TNLAssert(mNextDirtyList == NULL && mPrevDirtyList == NULL, "Object with zero mask already in list."); + if(mDirtyList) + { + mNextDirtyList = mDirtyList; + mDirtyList->mPrevDirtyList = this; + } + mDirtyList = this; + } + mDirtyMaskBits |= orMask; + TNLAssert(mDirtyMaskBits == 0 || (mPrevDirtyList != NULL || mNextDirtyList != NULL || mDirtyList == this), "Invalid dirty list state."); +} + +void NetObject::clearMaskBits(U32 orMask) +{ + if(mDirtyMaskBits) + { + mDirtyMaskBits &= ~orMask; + if(!mDirtyMaskBits) + { + if(mPrevDirtyList) + mPrevDirtyList->mNextDirtyList = mNextDirtyList; + else + mDirtyList = mNextDirtyList; + if(mNextDirtyList) + mNextDirtyList->mPrevDirtyList = mPrevDirtyList; + mNextDirtyList = mPrevDirtyList = NULL; + } + } + + for(GhostInfo *walk = mFirstObjectRef; walk; walk = walk->nextObjectRef) + { + if(walk->updateMask && walk->updateMask == orMask) + { + walk->updateMask = 0; + walk->connection->ghostPushToZero(walk); + } + else + walk->updateMask &= ~orMask; + } +} + +void NetObject::collapseDirtyList() +{ + Vector tempV; + for(NetObject *t = mDirtyList; t; t = t->mNextDirtyList) + tempV.push_back(t); + + for(NetObject *obj = mDirtyList; obj; ) + { + NetObject *next = obj->mNextDirtyList; + U32 orMask = obj->mDirtyMaskBits; + + obj->mNextDirtyList = NULL; + obj->mPrevDirtyList = NULL; + obj->mDirtyMaskBits = 0; + + if(orMask) + { + for(GhostInfo *walk = obj->mFirstObjectRef; walk; walk = walk->nextObjectRef) + { + if(!walk->updateMask) + { + walk->updateMask = orMask; + walk->connection->ghostPushNonZero(walk); + } + else + walk->updateMask |= orMask; + } + } + obj = next; + } + mDirtyList = NULL; + for(S32 i = 0; i < tempV.size(); i++) + { + TNLAssert(tempV[i]->mNextDirtyList == NULL && tempV[i]->mPrevDirtyList == NULL && tempV[i]->mDirtyMaskBits == 0, "Error in collapse"); + } +} + +bool NetObject::onGhostAdd(GhostConnection *theConnection) +{ + return true; +} + + +void NetObject::onGhostRemove() +{ +} + +void NetObject::onGhostAvailable(GhostConnection *) +{ +} + +//----------------------------------------------------------------------------- + +F32 NetObject::getUpdatePriority(NetObject*, U32, S32 updateSkips) +{ + return F32(updateSkips) * 0.1f; + + //return 0; +} + +U32 NetObject::packUpdate(GhostConnection*, U32, BitStream*) +{ + return 0; +} + +void NetObject::unpackUpdate(GhostConnection*, BitStream*) +{ +} + +void NetObject::performScopeQuery(GhostConnection *connection) +{ + // default behavior - since we have no idea here about + // the contents of the world, or why they matter, just scope + // the scope object. + connection->objectInScope(this); +} + +void NetObject::postRPCEvent(NetObjectRPCEvent *theEvent) +{ + RefPtr event = theEvent; + + TNLAssert((!isGhost() && theEvent->mRPCDirection == RPCToGhost) || + (isGhost() && theEvent->mRPCDirection == RPCToGhostParent), + "Invalid RPC call - going in the wrong direction!"); + + // ok, see what kind of an object this is: + if(isGhost()) + mOwningConnection->postNetEvent(theEvent); + else if(NetObject::getRPCDestConnection()) + { + NetObject::getRPCDestConnection()->postNetEvent(theEvent); + } + else + { + for(GhostInfo *walk = mFirstObjectRef; walk; walk = walk->nextObjectRef) + { + if(!(walk->flags & GhostInfo::NotAvailable)) + walk->connection->postNetEvent(theEvent); + } + } +} + +void NetObjectRPCEvent::pack(EventConnection *ps, BitStream *bstream) +{ + GhostConnection *gc = static_cast(ps); + S32 ghostIndex = -1; + if(!mDestObject.isNull()) + ghostIndex = gc->getGhostIndex(mDestObject); + + if(bstream->writeFlag(ghostIndex != -1)) + { + bstream->writeInt(ghostIndex, GhostConnection::GhostIdBitSize); + RPCEvent::pack(ps, bstream); + } +} + +void NetObjectRPCEvent::unpack(EventConnection *ps, BitStream *bstream) +{ + // make sure this is a valid place for this event to be... + GhostConnection *gc = static_cast(ps); + + if( (gc->doesGhostTo() && mRPCDirection == RPCToGhost) || + (gc->doesGhostFrom() && mRPCDirection == RPCToGhostParent) ) + { + if(bstream->readFlag()) + { + S32 ghostIndex = bstream->readInt(GhostConnection::GhostIdBitSize); + RPCEvent::unpack(ps, bstream); + + if(mRPCDirection == RPCToGhost) + mDestObject = gc->resolveGhost(ghostIndex); + else + mDestObject = gc->resolveGhostParent(ghostIndex); + } + } + else + gc->setLastError("Invalid Packet."); +} + +void NetObjectRPCEvent::process(EventConnection *ps) +{ + if(mDestObject.isNull()) + return; + + if(!checkClassType(mDestObject)) + return; + + void *thisPointer = (void *) mDestObject.getPointer(); + + NetObject::mRPCSourceConnection = (GhostConnection *) ps; + mFunctor->dispatch(thisPointer); + + NetObject::mRPCSourceConnection = NULL; +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/netStringTable.cpp b/tnl-1.5.0/tnl/tnl/netStringTable.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cd59ccb6819b2c5c08fceed27dc2c79caa734f78 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/netStringTable.cpp @@ -0,0 +1,441 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlNetBase.h" +#include "tnlNetConnection.h" +#include "tnlNetStringTable.h" +#include "tnlDataChunker.h" +#include "tnlNetInterface.h" + +namespace TNL { + +namespace StringTable +{ + +/// @name Implementation details +/// @{ + +/// This is internal to the _StringTable class. +struct Node +{ + StringTableEntryId masterIndex; ///< index of the Node pointer in the master list + StringTableEntryId nextIndex; ///< next string in this hash bucket. + U32 hash; ///< stored hash value of this string. + U16 stringLen; ///< length of string in this node. + U16 refCount; ///< number of StringTableEntry's that reference this node + char stringData[1]; ///< String data, with space for the NULL token. Node structure is allocated as strlen + sizeof(Node); +}; + +enum { + InitialHashTableSize = 1237, ///< Initial size of string hash table + InitialNodeListSize = 2048, ///< Initial size of node id remap table + CompactThreshold = 32768, ///< Number of string bytes freed before compaction occurs. +}; + +Node **mNodeList = NULL; ///< Master list of string table entry nodes +StringTableEntryId *mBuckets = NULL; ///< Hash table buckets, organized by string index + +U32 mNumBuckets = 0; ///< number of hash buckets in the table +U32 mNodeListSize = 0; ///< number of elements in the node list +StringTableEntryId mNodeListFreeEntry = 0; ///< index of first free entry in the node list + +U32 mItemCount = 0; ///< number of strings in the table + +DataChunker *mMemPool = NULL; ///< memory pool from which string table data is allocated +U32 mFreeStringDataSize = 0; ///< number of bytes freed by deallocated strings. When this number exceeds CompactThreshold, the table is compacted. + +// a little note about the free list... +// the free list is essentially an index linked list encoded in the node +// list. The first entry in the list is mNodeListFreeEntry. +// When the string table is compacted, we need to know which elements +// in the node list actually point to nodes, and which ones are members +// of the free list... so, what we do is, free list entries are +// actually coded with the next index shifted left 1 and or'd with a 1 +// so we have the lowest bit set. We know that pointers allocated by the +// data chunker are on at least 4-byte boundaries, so any pointer with +// the low bit set is assumed to be a free list entry. + + +/// Resize the StringTable to be able to hold newSize items. This +/// is called automatically by the StringTable when the table is +/// full past a certain threshhold. +/// +/// @param newSize Number of new items to allocate space for. +void resizeHashTable(const U32 newSize); + +/// compacts the string data associated with the string table. +void compact(); + +//--------------------------------------------------------------- +// +// StringTable functions +// +//--------------------------------------------------------------- + +namespace { +bool sgToLowerTableInit = true; +U8 sgToLowerTable[256]; + +void initToLowerTable() +{ + for (U32 i = 0; i < 256; i++) { + U8 c = dTolower(i); + sgToLowerTable[i] = c * c; + } + + sgToLowerTableInit = false; +} + +} // namespace {} + +U32 hashString(const char* str) +{ + if (sgToLowerTableInit) + initToLowerTable(); + + U32 ret = 0; + char c; + while((c = *str++) != 0) { + ret <<= 1; + ret ^= sgToLowerTable[c]; + } + return ret; +} + +U32 hashStringn(const char* str, S32 len) +{ + if (sgToLowerTableInit) + initToLowerTable(); + + U32 ret = 0; + char c; + while((c = *str++) != 0 && len--) { + ret <<= 1; + ret ^= sgToLowerTable[c]; + } + return ret; +} + +//-------------------------------------- +void init() +{ + mMemPool = new DataChunker; + mBuckets = (StringTableEntryId *) malloc(InitialHashTableSize * sizeof(StringTableEntryId)); + for(U32 i = 0; i < InitialHashTableSize; i++) + mBuckets[i] = 0; + + mNumBuckets = InitialHashTableSize; + mItemCount = 1; + + mNodeList = (Node **) malloc(InitialNodeListSize * sizeof(Node *)); + for(U32 i = 1; i < InitialNodeListSize; i++) + mNodeList[i] = (Node *) (( (i + 1) << 1) | 1); // see the doco in stringTable.h for how free list entries are coded + + mNodeList[InitialNodeListSize - 1] = NULL; + mNodeList[0] = (Node *) mMemPool->alloc(sizeof(Node)); + mNodeList[0]->stringData[0] = 0; + mNodeList[0]->stringLen = 0; + mNodeList[0]->refCount = 1; + mNodeList[0]->masterIndex = mNodeList[0]->nextIndex = 0; + mNodeListSize = InitialNodeListSize; + + mNodeListFreeEntry = (1 << 1) | 1; + mFreeStringDataSize = 0; +} + +void destroy() +{ + free(mBuckets); + mBuckets = NULL; + free(mNodeList); + mNodeList = NULL; + delete mMemPool; +} + +//-------------------------------------- + +//-------------------------------------- +StringTableEntryId insert(const char* val, const bool caseSens) +{ + if(!val) + return 0; + return insertn(val, strlen(val), caseSens); +} + +//-------------------------------------- +void validate() +{ + // count all the nodes in the node list: + U32 nodeCount = 0; + for(U32 i = 0; i < mNodeListSize; i++) + { + if(mNodeList[i] && !(U32(mNodeList[i]) & 1)) + nodeCount++; + } + TNLAssert(nodeCount == mItemCount, "Error!!!"); + U32 freeListCount = 0; + StringTableEntryId walk = mNodeListFreeEntry; + while(walk) + { + walk = StringTableEntryId(mNodeList[walk >> 1]); + if(!((walk >> 1) < mNodeListSize)) + TNLAssert((walk >> 1) < mNodeListSize, "Out of range node index!!!"); + freeListCount++; + } + TNLAssert(freeListCount + nodeCount == mNodeListSize, "Error!!!!"); + // walk through all the bucket chains... + // and make sure there are no free entries... + + for(U32 i = 0; i < mNumBuckets; i++) + { + StringTableEntryId walk = mBuckets[i]; + while(walk) + { + TNLAssert(walk < mNodeListSize, "Out of range node index!!!"); + Node *node = mNodeList[walk]; + TNLAssert((U32(node) & 1) == 0, "Free list entry in node chain!!!"); + TNLAssert(walk == node->masterIndex, "Master/node index mismatch."); + walk = node->nextIndex; + } + } +} + +StringTableEntryId insertn(const char* val, S32 len, const bool caseSens) +{ + if(!val || !*val || len == 0) + return 0; + if(!mBuckets) + init(); + StringTableEntryId *walk; + Node *stringNode; + U32 key = hashStringn(val, len); + walk = &mBuckets[key % mNumBuckets]; // find the bucket that the string would belong in + + // walk all the nodes in the bucket to see if the string is already in the table + while(*walk) + { + stringNode = mNodeList[*walk]; + if((caseSens && !strncmp(stringNode->stringData, val, len) && stringNode->stringData[len] == 0) || + (!caseSens && !strnicmp(stringNode->stringData, val, len) && stringNode->stringData[len] == 0) ) + { + // the string was found, so bump the reference count and return the node id + stringNode->refCount++; + return *walk; + } + // step to the next node in the hash bucket. + walk = &(stringNode->nextIndex); + } + + // the string was not found in the table. So allocate a new node for the string + + // first, make sure there is a free node pointer: + if(!mNodeListFreeEntry) + { + U32 oldNodeListSize = mNodeListSize; + mNodeListSize += InitialNodeListSize; + mNodeList = (Node **) realloc(mNodeList, mNodeListSize * sizeof(Node *)); + for(U32 i = oldNodeListSize; i < mNodeListSize; i++) + mNodeList[i] = (Node *) (((i + 1) << 1) | 1); + mNodeList[mNodeListSize - 1] = 0; + mNodeListFreeEntry = (oldNodeListSize << 1) | 1; + } + // now allocate a new string node, and fill it in. + stringNode = (Node *) mMemPool->alloc(sizeof(Node) + len); + stringNode->stringLen = len; + stringNode->refCount = 1; + stringNode->masterIndex = mNodeListFreeEntry >> 1; // shift off the low bit flag for the free list + stringNode->nextIndex = 0; + stringNode->hash = key; + *walk = stringNode->masterIndex; + + // dequeue the next free entry in the node list + mNodeListFreeEntry = (StringTableEntryId) mNodeList[mNodeListFreeEntry >> 1]; + TNLAssert(!mNodeListFreeEntry || (mNodeListFreeEntry & 1), "Error in freeList!!"); + mNodeList[stringNode->masterIndex] = stringNode; + + strncpy(stringNode->stringData, val, len); + stringNode->stringData[len] = 0; + mItemCount++; + + // check for hash table resize + if(mItemCount > 2 * mNumBuckets) { + resizeHashTable(4 * mNumBuckets - 1); + } + return stringNode->masterIndex; +} + +//-------------------------------------- +StringTableEntryId lookup(const char* val, const bool caseSens) +{ + StringTableEntryId *walk; + Node *stringNode; + U32 key = hashString(val); + walk = &mBuckets[key % mNumBuckets]; + while(*walk) + { + stringNode = mNodeList[*walk]; + if((caseSens && !strcmp(stringNode->stringData, val)) || + (!caseSens && !stricmp(stringNode->stringData, val)) ) + return *walk; + walk = &(stringNode->nextIndex); + } + return 0; +} + +//-------------------------------------- +StringTableEntryId lookupn(const char* val, S32 len, const bool caseSens) +{ + StringTableEntryId *walk; + Node *stringNode; + U32 key = hashStringn(val, len); + walk = &mBuckets[key % mNumBuckets]; + while(*walk) + { + stringNode = mNodeList[*walk]; + if((caseSens && !strncmp(stringNode->stringData, val, len) && stringNode->stringData[len] == 0) || + (!caseSens && !strnicmp(stringNode->stringData, val, len) && stringNode->stringData[len] == 0) ) + return *walk; + walk = &(stringNode->nextIndex); + } + return 0; +} + +//-------------------------------------- +void resizeHashTable(const U32 newSize) +{ + StringTableEntryId walk; + StringTableEntryId head = 0; + StringTableEntryId temp; + + U32 i; + // reverse individual bucket lists + // we do this because new strings are added at the end of bucket + // lists so that case sens strings are always after their + // corresponding case insens strings + + for(i = 0; i < mNumBuckets; i++) { + walk = mBuckets[i]; + while(walk) + { + temp = mNodeList[walk]->nextIndex; + mNodeList[walk]->nextIndex = head; + head = walk; + walk = temp; + } + } + mBuckets = (StringTableEntryId *) realloc(mBuckets, newSize * sizeof(StringTableEntryId)); + for(i = 0; i < newSize; i++) { + mBuckets[i] = 0; + } + mNumBuckets = newSize; + walk = head; + while(walk) + { + U32 key; + Node *temp = mNodeList[walk]; + + walk = temp->nextIndex; + key = temp->hash; + temp->nextIndex = mBuckets[key % newSize]; + mBuckets[key % newSize] = temp->masterIndex; + } +} + +void compact() +{ + DataChunker *newData = new DataChunker; + for(U32 i = 1; i < mNodeListSize; i++) + { + Node *theNode, *newNode; + theNode = mNodeList[i]; + + // if the low bit is set, it's an entry in the free list. + // if it is NULL it is the last entry (see the constructor) + // this *may* not be the best fix, but it was a crash -pw + if(((StringTableEntryId) theNode) & 1 || theNode == NULL) + continue; + newNode = (Node *) newData->alloc(sizeof(Node) + theNode->stringLen); + newNode->stringLen = theNode->stringLen; + newNode->refCount = theNode->refCount; + newNode->masterIndex = theNode->masterIndex; + newNode->nextIndex = theNode->nextIndex; + newNode->hash = theNode->hash; + strcpy(newNode->stringData, theNode->stringData); + mNodeList[i] = newNode; + } + delete mMemPool; + mMemPool = newData; + mFreeStringDataSize = 0; +} + +void incRef(StringTableEntryId index) +{ + mNodeList[index]->refCount++; +} + +void decRef(StringTableEntryId index) +{ + Node *theNode = mNodeList[index]; + if(--theNode->refCount) + return; + + // remove from the hash table first: + StringTableEntryId *walk = &mBuckets[theNode->hash % mNumBuckets]; + Node *stringNode; + while(*walk) + { + stringNode = mNodeList[*walk]; + if(stringNode == theNode) + { + *walk = theNode->nextIndex; + break; + } + walk = &(stringNode->nextIndex); + } + + mFreeStringDataSize += mNodeList[index]->stringLen + sizeof(Node); + mNodeList[index] = (Node *) mNodeListFreeEntry; + mNodeListFreeEntry = (index << 1) | 1; + + if(mFreeStringDataSize > CompactThreshold) + compact(); + mItemCount--; + if(!mItemCount) + destroy(); +} + +const char *getString(StringTableEntryId index) +{ + if(!index) + return ""; + return mNodeList[index]->stringData; +} + + +}; + +}; diff --git a/tnl-1.5.0/tnl/tnl/platform.cpp b/tnl-1.5.0/tnl/tnl/platform.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a8d92b942571d5707aab6ef3c908a578f68e8705 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/platform.cpp @@ -0,0 +1,488 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlTypes.h" +#include "tnl.h" +#include "tnlJournal.h" + +#include +#if defined (TNL_OS_XBOX) +#include + +#elif defined (TNL_OS_WIN32) +#include + +#include + +#else + +#include +#include +#include + +#endif + +#include +#include +#include +#include +#include "tnlRandom.h" +#include "tnlLog.h" + +namespace TNL { + +#if defined (TNL_OS_XBOX) + +void Platform::outputDebugString(const char *string) +{ + OutputDebugString(string); +} + +void Platform::debugBreak() +{ + DebugBreak(); +} + +void Platform::forceQuit() +{ + logprintf("-Force Quit-"); + // Reboot! + LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; + XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); +} + +U32 Platform::getRealMilliseconds() +{ + U32 tickCount; + TNL_JOURNAL_READ_BLOCK ( getRealMilliseconds, + TNL_JOURNAL_READ( (&tickCount) ); + return tickCount; + ) + + tickCount = GetTickCount(); + + TNL_JOURNAL_WRITE_BLOCK ( getRealMilliseconds, + TNL_JOURNAL_WRITE( (tickCount) ); + ) + return tickCount; +} + + +//-------------------------------------- +void Platform::AlertOK(const char *windowTitle, const char *message) +{ +// ShowCursor(true); +// MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OK); + TNLLogMessageV(LogPlatform, ("AlertOK: %s - %s", message, windowTitle)); + return; +} + +//-------------------------------------- +bool Platform::AlertOKCancel(const char *windowTitle, const char *message) +{ +// ShowCursor(true); +// return MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OKCANCEL) == IDOK; + TNLLogMessageV(LogPlatform, ("AlertOKCancel: %s - %s", message, windowTitle)); + return false; +} + +//-------------------------------------- +bool Platform::AlertRetry(const char *windowTitle, const char *message) +{ +// ShowCursor(true); +// return (MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_RETRYCANCEL) == IDRETRY); + TNLLogMessageV(LogPlatform, ("AlertRetry: %s - %s", message, windowTitle)); + return false; +} + + +class WinTimer +{ + private: + F64 mPeriod; + bool mUsingPerfCounter; + public: + WinTimer() + { + S64 frequency; + mUsingPerfCounter = QueryPerformanceFrequency((LARGE_INTEGER *) &frequency); + mPeriod = 1000.0f / F64(frequency); + } + S64 getCurrentTime() + { + if(mUsingPerfCounter) + { + S64 value; + QueryPerformanceCounter( (LARGE_INTEGER *) &value); + return value; + } + else + { + return GetTickCount(); + } + } + F64 convertToMS(S64 delta) + { + if(mUsingPerfCounter) + return mPeriod * F64(delta); + else + return F64(delta); + } +}; + +static WinTimer gTimer; + +S64 Platform::getHighPrecisionTimerValue() +{ + return gTimer.getCurrentTime(); +} + +F64 Platform::getHighPrecisionMilliseconds(S64 timerDelta) +{ + return gTimer.convertToMS(timerDelta); +} + +void Platform::sleep(U32 msCount) +{ + // no need to sleep on the xbox... +} + +#elif defined (TNL_OS_WIN32) + +bool Platform::checkHeap() +{ +#ifdef TNL_COMPILER_VISUALC + return _heapchk() == _HEAPOK; +#else + return true; +#endif +} + +void Platform::outputDebugString(const char *string) +{ + OutputDebugString(string); +} + +void Platform::debugBreak() +{ + DebugBreak(); +} + +void Platform::forceQuit() +{ + ExitProcess(1); +} + +U32 Platform::getRealMilliseconds() +{ + U32 tickCount; + TNL_JOURNAL_READ_BLOCK ( getRealMilliseconds, + TNL_JOURNAL_READ( (&tickCount) ); + return tickCount; + ) + + tickCount = GetTickCount(); + + TNL_JOURNAL_WRITE_BLOCK ( getRealMilliseconds, + TNL_JOURNAL_WRITE( (tickCount) ); + ) + return tickCount; +} + +class WinTimer +{ + private: + F64 mPeriod; + bool mUsingPerfCounter; + public: + WinTimer() + { + S64 frequency; + mUsingPerfCounter = QueryPerformanceFrequency((LARGE_INTEGER *) &frequency); + mPeriod = 1000.0f / F64(frequency); + } + S64 getCurrentTime() + { + if(mUsingPerfCounter) + { + S64 value; + QueryPerformanceCounter( (LARGE_INTEGER *) &value); + return value; + } + else + { + return GetTickCount(); + } + } + F64 convertToMS(S64 delta) + { + if(mUsingPerfCounter) + return mPeriod * F64(delta); + else + return F64(delta); + } +}; + +static WinTimer gTimer; + +S64 Platform::getHighPrecisionTimerValue() +{ + S64 currentTime; + TNL_JOURNAL_READ_BLOCK ( getHighPrecisionTimerValue, + TNL_JOURNAL_READ( (¤tTime) ); + return currentTime; + ) + + currentTime = gTimer.getCurrentTime(); + + TNL_JOURNAL_WRITE_BLOCK ( getHighPrecisionTimerValue, + TNL_JOURNAL_WRITE( (currentTime) ); + ) + + return currentTime; +} + +F64 Platform::getHighPrecisionMilliseconds(S64 timerDelta) +{ + F64 timerValue; + TNL_JOURNAL_READ_BLOCK ( getHighPrecisionMilliseconds, + TNL_JOURNAL_READ( (&timerValue) ); + return timerValue; + ) + + timerValue = gTimer.convertToMS(timerDelta); + + TNL_JOURNAL_WRITE_BLOCK ( getHighPrecisionMilliseconds, + TNL_JOURNAL_WRITE( (timerValue) ); + ) + + return timerValue; +} + +void Platform::sleep(U32 msCount) +{ + Sleep(msCount); +} + +//-------------------------------------- +void Platform::AlertOK(const char *windowTitle, const char *message) +{ + ShowCursor(true); + MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OK); +} + +//-------------------------------------- +bool Platform::AlertOKCancel(const char *windowTitle, const char *message) +{ + ShowCursor(true); + return MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OKCANCEL) == IDOK; +} + +//-------------------------------------- +bool Platform::AlertRetry(const char *windowTitle, const char *message) +{ + ShowCursor(true); + return (MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_RETRYCANCEL) == IDRETRY); +} + +#else // osx and linux + +void Platform::debugBreak() +{ + kill(getpid(), SIGTRAP); +} + +void Platform::outputDebugString(const char *string) +{ + //printf("%s", string); +} + +void Platform::forceQuit() +{ + debugBreak(); + exit(1); +} + + +U32 x86UNIXGetTickCount(); +//-------------------------------------- + +U32 Platform::getRealMilliseconds() +{ + return x86UNIXGetTickCount(); +} + +static bool sg_initialized = false; +static U32 sg_secsOffset = 0; + +U32 x86UNIXGetTickCount() +{ + // TODO: What happens when crossing a day boundary? + // + timeval t; + + if (sg_initialized == false) { + sg_initialized = true; + + ::gettimeofday(&t, NULL); + sg_secsOffset = t.tv_sec; + } + + ::gettimeofday(&t, NULL); + + U32 secs = t.tv_sec - sg_secsOffset; + U32 uSecs = t.tv_usec; + + // Make granularity 1 ms + return (secs * 1000) + (uSecs / 1000); +} + +class UnixTimer +{ + public: + UnixTimer() + { + } + S64 getCurrentTime() + { + return x86UNIXGetTickCount(); + } + F64 convertToMS(S64 delta) + { + return F64(delta); + } +}; + +static UnixTimer gTimer; + +S64 Platform::getHighPrecisionTimerValue() +{ + return gTimer.getCurrentTime(); +} + +F64 Platform::getHighPrecisionMilliseconds(S64 timerDelta) +{ + return gTimer.convertToMS(timerDelta); +} + +void Platform::sleep(U32 msCount) +{ + usleep(msCount * 1000); +} + +//-------------------------------------- +void Platform::AlertOK(const char *windowTitle, const char *message) +{ +// ShowCursor(true); +// MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OK); + TNLLogMessageV(LogPlatform, ("AlertOK: %s - %s", message, windowTitle)); + return; +} + +//-------------------------------------- +bool Platform::AlertOKCancel(const char *windowTitle, const char *message) +{ +// ShowCursor(true); +// return MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OKCANCEL) == IDOK; + TNLLogMessageV(LogPlatform, ("AlertOKCancel: %s - %s", message, windowTitle)); + return false; +} + +//-------------------------------------- +bool Platform::AlertRetry(const char *windowTitle, const char *message) +{ +// ShowCursor(true); +// return (MessageBox(NULL, message, windowTitle, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_RETRYCANCEL) == IDRETRY); + TNLLogMessageV(LogPlatform, ("AlertRetry: %s - %s", message, windowTitle)); + return false; +} + +#endif + +/* +char *strdup(const char *src) +{ + char *buffer = (char *) malloc(strlen(src) + 1); + strcpy(buffer, src); + return buffer; +}*/ +bool atob(const char *str) +{ + return !stricmp(str, "true") || atof(str); +} + +S32 dSprintf(char *buffer, U32 bufferSize, const char *format, ...) +{ + va_list args; + va_start(args, format); +#ifdef TNL_COMPILER_VISUALC + S32 len = _vsnprintf(buffer, bufferSize, format, args); +#else + S32 len = vsnprintf(buffer, bufferSize, format, args); +#endif + return (len); +} + + +S32 dVsprintf(char *buffer, U32 bufferSize, const char *format, void *arglist) +{ +#ifdef TNL_COMPILER_VISUALC + S32 len = _vsnprintf(buffer, bufferSize, format, (va_list) arglist); +#else + S32 len = vsnprintf(buffer, bufferSize, format, (char *) arglist); +#endif + return len; +} + +}; + + +#if defined (__GNUC__) + +int stricmp(const char *str1, const char *str2) +{ + while(toupper(*str1) == toupper(*str2) && *str1) + { + str1++; + str2++; + } + return (toupper(*str1) > toupper(*str2)) ? 1 : ((toupper(*str1) < toupper(*str2)) ? -1 : 0); +} + +int strnicmp(const char *str1, const char *str2, unsigned int len) +{ + for(unsigned int i = 0; i < len; i++) + { + if(toupper(str1[i]) == toupper(str2[i])) + continue; + return (toupper(str1[i]) > toupper(str2[i])) ? 1 : ((toupper(str1[i]) < toupper(str2[i])) ? -1 : 0); + } + return 0; +} + +#endif + + diff --git a/tnl-1.5.0/tnl/tnl/random.cpp b/tnl-1.5.0/tnl/tnl/random.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8f4f6f8508be649eeb54bb7d56ba90cac3253790 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/random.cpp @@ -0,0 +1,109 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + + +#include +#include "tnl.h" +#include "tnlRandom.h" +#include "tnlJournal.h" + +namespace TNL { + +namespace Random { + +static bool initialized = false; +static prng_state prng; +static U32 entropyAdded = 0; + +static void initialize() +{ + initialized = true; + yarrow_start(&prng); + yarrow_ready(&prng); +} + +void *getState() +{ + if(!initialized) + initialize(); + + return &prng; +} + +void addEntropy(const U8 *randomData, U32 dataLen) +{ + if(!initialized) + initialize(); + + yarrow_add_entropy(randomData, dataLen, &prng); + entropyAdded += dataLen; + + if(entropyAdded >= 16) + { + yarrow_ready(&prng); + entropyAdded = 0; + } +} + +void read(U8 *outBuffer, U32 randomLen) +{ + if(!initialized) + initialize(); + + yarrow_read(outBuffer, randomLen, &prng); +} + +U32 readI() +{ + U8 randomBuffer[4]; + read(randomBuffer, 4); + U32 result = (U32(randomBuffer[0]) << 24) | (U32(randomBuffer[1]) << 16) | + (U32(randomBuffer[2]) << 8 ) | U32(randomBuffer[3]); + return result; +} + +U32 readI(U32 rangeStart, U32 rangeEnd) +{ + TNLAssert(rangeStart <= rangeEnd, "Random::readI - invalid range."); + + return (readI() % (rangeEnd - rangeStart + 1)) + rangeStart; +} + +F32 readF() +{ + return F32 ( F64(readI()) / F64(U32_MAX) ); +} + +bool readB() +{ + U8 randomBuffer; + read(&randomBuffer, 1); + + return(randomBuffer & 1); +} +}; + +}; diff --git a/tnl-1.5.0/tnl/tnl/rpc.cpp b/tnl-1.5.0/tnl/tnl/rpc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f0042c70728c572f0b2e68dc6aa03bde66bdabc9 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/rpc.cpp @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlBitStream.h" +#include "tnlVector.h" +#include "tnlNetEvent.h" +#include "tnlRPC.h" +#include "tnlEventConnection.h" + +namespace TNL { + +RPCEvent::RPCEvent(RPCGuaranteeType gType, RPCDirection dir) : + NetEvent((NetEvent::GuaranteeType) gType, (NetEvent::EventDirection) dir) +{ +} + +void RPCEvent::pack(EventConnection *ps, BitStream *bstream) +{ + mFunctor->write(*bstream); +} + +void RPCEvent::unpack(EventConnection *ps, BitStream *bstream) +{ + mFunctor->read(*bstream); +} + +void RPCEvent::process(EventConnection *ps) +{ + if(checkClassType(ps)) + mFunctor->dispatch(ps); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/symmetricCipher.cpp b/tnl-1.5.0/tnl/tnl/symmetricCipher.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9938b3ca905ac256816a8505ccabcf9594de7e96 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/symmetricCipher.cpp @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlSymmetricCipher.h" +#include "tnlByteBuffer.h" +#include "mycrypt.h" + +namespace TNL { + +SymmetricCipher::SymmetricCipher(const U8 symmetricKey[SymmetricCipher::KeySize], const U8 initVector[SymmetricCipher::BlockSize]) +{ + rijndael_setup(symmetricKey, KeySize, 0, (symmetric_key *) &mSymmetricKey); + memcpy(mInitVector, initVector, BlockSize); + memcpy(mCounter, initVector, BlockSize); + rijndael_ecb_encrypt((U8 *) mCounter, mPad, (symmetric_key *) &mSymmetricKey); + mPadLen = 0; +} + +SymmetricCipher::SymmetricCipher(const ByteBuffer *theByteBuffer) +{ + if(theByteBuffer->getBufferSize() != KeySize * 2) + { + U8 buffer[KeySize]; + memset(buffer, 0, KeySize); + rijndael_setup(buffer, KeySize, 0, (symmetric_key *) &mSymmetricKey); + memcpy(mInitVector, buffer, BlockSize); + } + else + { + rijndael_setup(theByteBuffer->getBuffer(), KeySize, 0, (symmetric_key *) &mSymmetricKey); + memcpy(mInitVector, theByteBuffer->getBuffer() + KeySize, BlockSize); + } + memcpy(mCounter, mInitVector, BlockSize); + rijndael_ecb_encrypt((U8 *) mCounter, mPad, (symmetric_key *) &mSymmetricKey); + mPadLen = 0; +} + +void SymmetricCipher::setupCounter(U32 counterValue1, U32 counterValue2, U32 counterValue3, U32 counterValue4) +{ + mCounter[0] = convertHostToLEndian(convertLEndianToHost(mInitVector[0]) + counterValue1); + mCounter[1] = convertHostToLEndian(convertLEndianToHost(mInitVector[1]) + counterValue2); + mCounter[2] = convertHostToLEndian(convertLEndianToHost(mInitVector[2]) + counterValue3); + mCounter[3] = convertHostToLEndian(convertLEndianToHost(mInitVector[3]) + counterValue4); + + rijndael_ecb_encrypt((U8 *) mCounter, mPad, (symmetric_key *) &mSymmetricKey); + mPadLen = 0; +} + +void SymmetricCipher::encrypt(const U8 *plainText, U8 *cipherText, U32 len) +{ + while(len-- > 0) + { + if(mPadLen == BlockSize) + { + // we've reached the end of the pad, so compute a new pad + rijndael_ecb_encrypt(mPad, mPad, (symmetric_key *) &mSymmetricKey); + mPadLen = 0; + } + U8 encryptedChar = *plainText++ ^ mPad[mPadLen]; + mPad[mPadLen++] = *cipherText++ = encryptedChar; + } +} + +void SymmetricCipher::decrypt(const U8 *cipherText, U8 *plainText, U32 len) +{ + while(len-- > 0) + { + if(mPadLen == BlockSize) + { + rijndael_ecb_encrypt(mPad, mPad, (symmetric_key *) &mSymmetricKey); + mPadLen = 0; + } + U8 encryptedChar = *cipherText++; + *plainText++ = encryptedChar ^ mPad[mPadLen]; + mPad[mPadLen++] = encryptedChar; + } +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/thread.cpp b/tnl-1.5.0/tnl/tnl/thread.cpp new file mode 100644 index 0000000000000000000000000000000000000000..febbcdecbc19330eaa40bdf51ab77161ea4d87df --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/thread.cpp @@ -0,0 +1,300 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlThread.h" +#include "tnlLog.h" + +namespace TNL +{ + +#ifdef TNL_OS_WIN32 +Semaphore::Semaphore(U32 initialCount, U32 maximumCount) +{ + mSemaphore = CreateSemaphore(NULL, initialCount, maximumCount, NULL); +} + +Semaphore::~Semaphore() +{ + CloseHandle(mSemaphore); +} + +void Semaphore::wait() +{ + WaitForSingleObject(mSemaphore, INFINITE); +} + +void Semaphore::increment(U32 count) +{ + ReleaseSemaphore(mSemaphore, count, NULL); +} + +Mutex::Mutex() +{ + InitializeCriticalSection(&mLock); +} + +Mutex::~Mutex() +{ + DeleteCriticalSection(&mLock); +} + +void Mutex::lock() +{ + EnterCriticalSection(&mLock); +} + +void Mutex::unlock() +{ + LeaveCriticalSection(&mLock); +} + +bool Mutex::tryLock() +{ + return false;// return TryEnterCriticalSection(&mLock); +} + +ThreadStorage::ThreadStorage() +{ + mTlsIndex = TlsAlloc(); +} + +ThreadStorage::~ThreadStorage() +{ + TlsFree(mTlsIndex); +} + +void *ThreadStorage::get() +{ + return TlsGetValue(mTlsIndex); +} + +void ThreadStorage::set(void *value) +{ + TlsSetValue(mTlsIndex, value); +} + +DWORD WINAPI ThreadProc( LPVOID lpParameter ) +{ + return ((Thread *) lpParameter)->run(); +} + +U32 Thread::run() +{ + return 0; +} + +void Thread::start() +{ + mThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL); + mReturnValue = 0; +} + +Thread::Thread() +{ +} + +Thread::~Thread() +{ + CloseHandle(mThread); +} + +#else + +Semaphore::Semaphore(U32 initialCount, U32 maximumCount) +{ + sem_init(&mSemaphore, 0, initialCount); +} + +Semaphore::~Semaphore() +{ + sem_destroy(&mSemaphore); +} + +void Semaphore::wait() +{ + sem_wait(&mSemaphore); +} + +void Semaphore::increment(U32 count) +{ + for(U32 i = 0; i < count; i++) + sem_post(&mSemaphore); +} + +Mutex::Mutex() +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); +#ifdef TNL_OS_LINUX + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); +#else + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +#endif + pthread_mutex_init(&mMutex, &attr); + pthread_mutexattr_destroy(&attr); +} + +Mutex::~Mutex() +{ + pthread_mutex_destroy(&mMutex); +} + +void Mutex::lock() +{ + pthread_mutex_lock(&mMutex); +} + +void Mutex::unlock() +{ + pthread_mutex_unlock(&mMutex); +} + +bool Mutex::tryLock() +{ + return false;// return TryEnterCriticalSection(&mLock); +} + +ThreadStorage::ThreadStorage() +{ + pthread_key_create(&mThreadKey, NULL); +} + +ThreadStorage::~ThreadStorage() +{ + pthread_key_delete(mThreadKey); +} + +void *ThreadStorage::get() +{ + return pthread_getspecific(mThreadKey); +} + +void ThreadStorage::set(void *value) +{ + pthread_setspecific(mThreadKey, value); +} + +void *ThreadProc(void *lpParameter) +{ + return (void *) ((Thread *) lpParameter)->run(); +} + +Thread::Thread() +{ +} + +void Thread::start() +{ + int val = pthread_create(&mThread, NULL, ThreadProc, this); + mReturnValue = 0; +} + +Thread::~Thread() +{ +} + +#endif + +ThreadQueue::ThreadQueueThread::ThreadQueueThread(ThreadQueue *q) +{ + mThreadQueue = q; +} + +U32 ThreadQueue::ThreadQueueThread::run() +{ + mThreadQueue->threadStart(); + + mThreadQueue->lock(); + ThreadStorage &sto = mThreadQueue->getStorage(); + sto.set((void *) 0); + mThreadQueue->unlock(); + + for(;;) + mThreadQueue->dispatchNextCall(); + return 0; +} + +ThreadQueue::ThreadQueue(U32 threadCount) +{ + mStorage.set((void *) 1); + for(U32 i = 0; i < threadCount; i++) + { + Thread *theThread = new ThreadQueueThread(this); + mThreads.push_back(theThread); + theThread->start(); + } +} + +ThreadQueue::~ThreadQueue() +{ +} + +void ThreadQueue::dispatchNextCall() +{ + mSemaphore.wait(); + lock(); + if(mThreadCalls.size() == 0) + { + unlock(); + return; + } + Functor *c = mThreadCalls.first(); + mThreadCalls.pop_front(); + unlock(); + c->dispatch(this); + delete c; +} + +void ThreadQueue::postCall(Functor *theCall) +{ + lock(); + if(isMainThread()) + { + mThreadCalls.push_back(theCall); + unlock(); + mSemaphore.increment(); + } + else + { + mResponseCalls.push_back(theCall); + unlock(); + } +} + +void ThreadQueue::dispatchResponseCalls() +{ + lock(); + for(S32 i = 0; i < mResponseCalls.size(); i++) + { + Functor *c = mResponseCalls[i]; + c->dispatch(this); + delete c; + } + mResponseCalls.clear(); + unlock(); +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/tnl.changelog.txt b/tnl-1.5.0/tnl/tnl/tnl.changelog.txt new file mode 100644 index 0000000000000000000000000000000000000000..78c4ec1ca8a2095d7ed5a60932b985fa272ddf9a --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnl.changelog.txt @@ -0,0 +1,28 @@ +// Instructions for updating this file: +// - Locate the appropriate section for this version of TNL. This +// is changelog_VERSION, where VERSION is the next version of TNL. Dots +// should be replaced with _'s. +// - Add your change to the appropriate subsection. There are subsections +// for each module of the TNL. Add a subsection if necessary, the +// naming scheme is cl_VERSION_MODULE. (Modules might be: ghost, dnet, +// events, etc.) +/*! + +@page changelog Torque Network Layer Upgrade Guide + +@section changelog_intro Introduction + +TNL is a living, changing body of code. Things become superceded, outdated, deprecated. As a developer, you are probably interested in keeping up to date with the latest features in TNL - which means you have to upgrade your code to work with changes to the layer. + +With such a large project as TNL, it is difficult to make sure that you're fully up to synch with a changing target. This section of the documentation describes changes to the engine in each version, along with what you need to do to get your code up to date, so that everything works together smoothly. + + +@note For a more comprehensive and fresher list of changes, see http://www.garagegames.com/docs/tnl/changelist/. + +@section changelog_1_0 Changes in TNL HEAD + +@subsection cl_1_0_core Changes to Core... + + - Removed unused TagDictionary class (core/tagDictionary.*). + +*/ \ No newline at end of file diff --git a/tnl-1.5.0/tnl/tnl/tnl.h b/tnl-1.5.0/tnl/tnl/tnl.h new file mode 100644 index 0000000000000000000000000000000000000000..3a8c62cd30a80d25a5246082f4e1a185df826fba --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnl.h @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_H_ +#define _TNL_H_ + +/// Global namespace for all TNL classes +namespace TNL { +}; + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +#ifndef _TNL_ASSERT_H_ +#include "tnlAssert.h" +#endif + +#ifndef _TNL_ENDIAN_H_ +#include "tnlEndian.h" +#endif + +#ifndef _TNL_PLATFORM_H_ +#include "tnlPlatform.h" +#endif + +#ifndef _TNL_UDP_H_ +#include "tnlUDP.h" +#endif + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnl.overview.txt b/tnl-1.5.0/tnl/tnl/tnl.overview.txt new file mode 100644 index 0000000000000000000000000000000000000000..57104f358bec8228c276b4975a48b3c8813301bd --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnl.overview.txt @@ -0,0 +1,539 @@ +/* + Some style notes: + - subsections are named after the section they're in, with an underscore seperator; see the Intro section, which + contains Intro_TandT. This keeps the section namespace relatively clean. +*/ +namespace TNL { +/*! + +@mainpage Torque Network Library Reference + +The Torque Network Library is a networking API designed to allow developers to easily add world-class multiuser simulation capabilities to their products. The TNL has proven successful in some of the most demanding multiplayer internet games and has gone through years of steady, evolutionary improvement. + +@section scope Scope of This Documentation + +@ref gettingstarted gives new users the information they need to download TNL source files, set up projects on supported compilers, and build and run the library and example programs. + +@ref history gives a brief history of the Torque Network Library from its origins as the network technology behind Sierra/Dynamix's Starsiege: TRIBES to its current status as a standalone network programming solution. + +@ref introprogramming introduces the developer to some of the basic concepts of network programming, including fundamental limitations of data networks, standard protocols, application network topologies, security and the hurdles the TNL will help them overcome in providing a consistent simulation on an unreliable communications medium. + +@ref fundamentals describes the general strategies used in the TNL to overcome the inherent limitations of today's networks. + +@ref archoverview gives an overview of the major classes in the TNL, from the basic Socket layer to the advanced state replication facilities provided by the GhostConnection and NetObject layer. + +The TNL namespace contains all of the major classes and structures in the Torque Network Library. + +@ref simpletutorial walks the developer through the creation of a simple, networked "Hello World!" program. + +TNLTest is a more complete TNL example program, utilizing the GhostConnection's object replication facilities. + +The MasterServerInterface class describes the simple master matchmaking server that comes included with TNL, and the client connection API for communicating with it. + +Finally, the ZAP project puts it all together in a 2D overhead team-based client/server space arcade action game, featuring a LAN/internet server browser, object interpolation and extrapolation, a client-side prediction model, and a more complete demonstration of the advanced features of the Torque Network Library. + +We presume the reader is familiar with C++ programming and concepts. + +@section acknowledgements Acknowledgments +John Quigley - For his incredible patience as the Linux build master. + +Ben Garney - For his mad documentation skills and for usefully doing other projects that would have distracted Mark - and sound effects. + +Tom St. Denis - For his excellent libtomcrypt cryptographic library that is included in the TNL. + +The GLUT developers - For a cross-platform, easy-to-use OpenGL initialization, input and windowing API. + +The OpenAL team - For a good, cross-platform audio API. + +Ari Juels and John Brainard - For their work on Client Puzzles. + +Tuomas Aura, Pekka Nikander, and Jussipekka Leiwo of the Helsinki University of Technology - For their work on DoS resistant Authentication with Client Puzzles. + +*/ +/*! @page gettingstarted Getting Started + +@section downloading Downloading the Torque Network Library + +Please see the download page for information on how to get the source. + +@section building Compiling the Torque Network Library + +Once you have a copy of the source code, you may compile it by following the instructions in the Readme.html in the root of the source code. + +@section troubleshooting Troubleshooting and Questions + +For general information, please see our FAQ. + +For bugs or other issues, you can get help from our mailing list. Please check the archives first, as others may have had similar issues; if not, feel free to ask questions. + +*/ +/*! @page history History of the Torque Network Library + +Near the end of 1997, a team of developers at Dynamix were hard at work on a new, network only game that would push the requirements of internet gaming technology to a new level. Starsiege: TRIBES allowed up to 32 players to compete in seamless indoor and outdoor areas with futuristic weapons, jet packs and vehicles. + +Unlike other games at the time that were limited to tight indoor environments, the TRIBES environment posed a more difficult set of networking problems. Because of their open nature, clients in the game could often see most of the other players, along with a large number of projecticles and simulated vehicles, turrets and other objects. Also, given the state of most internet connections at the time, it was decided that TRIBES must run well even over a 28.8 kbps modem, imposing a meager 2 Kbytes per second of bandwidth limitation on each client. + +With these requirements in mind, Mark Frohnmayer, Rick Overman and Tim Gift designed a network architecture that would maximize the information value of every bit transmitted over the network, and created a new "Notify" protocol that harnessed the unreliable nature of the network transport medium to eliminate unnecessary retransmission of information. + +The Tribes Network Architecture was further refined during the development of Tribes 2 to server more players (up to 100 in a single gaming area served by a 1GHz Pentium III) and save even more packet data space, introducing the concept of a network string table and only periodic control object state updating during client-side prediction. + +When the Tribes 2 engine became GarageGames' Torque Game Engine, additional iterative improvements were made, including checksums on client state data and a new network interface class to encapsulate the connection startup and prevent connection depletion Denial-of-Service attacks. + +The final step in the history of the Torque Network Library was to refactor its constituent parts into a standalone network technology that didn't require any other components from the Torque Game Engine. As a part of this process, significant library structural improvements were made; every class and class member were documented, and strong encryption support was added. Other new features include a simple and powerful Remote Procedure Call (RPC) mechanism, client puzzles for protecting servers from server CPU depletion Denial-of-Service attacks, and 3rd-party negotiated direct connections to connect clients behind firewalls and NAT (Network Address Translation) routers, making TNL a robust, full-featured, secure networking solution for a wide variety of applications. + +*/ +/*! @page introprogramming Introduction to Network Programming Concepts + +Computer networking technology allows computers that share the network to send messages to one another. Computer networks vary greatly in complexity, from two machines connected together with a link cable, to the globe-spanning internet connecting millions of machines together over fiber-optics, satellite links, phone lines and other mediums. + +@section fundlimits Fundamental Limitations of Computer Networks + +Computer networks of any size share some common limitations to varying degrees that must be accounted for in network simulations, with the internet being the most limited in all three regards. These three fundamental problems in network simulation are: + +Limited Bandwidth - There is a limit to the rate at which hosts on the network can send data to one another. If a computer is connected to the network with a 56 kbps modem, this might be 5 Kbytes per second, while computers on a local area network might be able to communicate at 128 megabytes per second. For service providers, additional bandwidth capacity can be costly, so even if there is no physical bandwidth limitation, bandwidth conservation is important for many projects. + +Packet Loss - Computer networks are inherently unreliable. Information transmitted over a network may become corrupted in transit, or may be dropped at a router where traffic has become congested. Even when (especially when) using a guaranteed message delivery protocol such as TCP, the unreliable nature of the underlying network still must be taken into account for network applications. + +Latency - Messages sent from one host to another on the network take time to arrive at the destination. The time can be influenced by many factors, including the medium over which the messages travel, how many intermediate hosts must route the message, an the level of traffic congestion at each of those network nodes. Latency becomes particularly problematic in network simulations that attempt to present a real-time interface to the client, when the latency of the connection may be perceptible in time. + +See @ref fundamentals for information on how TNL deals with the fundamental limitations of computer networks. + +@section stdprotos Standard Network Protocols + +When computers communicate over networks, they send and receive data using specific network protocols. These protocols ensure that the computers are using the same specifications to address, forward and process data on the network. The internet, certainly the most widely used computer network today, uses a stack of three primary protocols that facilitate communication over the network. They are: + +IP - Internet Protocol: The Internet Protocol is the basic building block for internet communications. IP is a routing protocol, which means that it is used to route information packets from a source host to a destination host, specified by an IP address. IP packets are not guaranteed to arrive at the destination specified by the sender, and those packets that do arrive are not guaranteed to arrive in the order they were sent. IP packet payloads may also be corrupted when they are delivered. IP is not useful as an application protocol - it is used mainly as a foundation for the higher level TCP and UDP protocols. + +UDP - User Datagram Protocol: The User Datagram Protocol supplies a thin layer on top of IP that performs error detection and application level routing on a single host. UDP packets are addressed using both an IP address to specify the physical host, and a port number, to specify which process on the machine the packet should be delivered to. UDP packets also contain a checksum, so that corrupted packets can be discarded. UDP packets that are corrupted or dropped by an intermediate host are not retransmitted by the sender, because the sender is never notified whether a given packet was delivered or not. + +TCP/IP - Transmission Control Protocol: TCP was designed to make internet programming easier by building a reliable, connection-based protocol on top of the unreliable IP. TCP does this by sending acknowledgements when data packets arrive, and resending data that was dropped. TCP is a stream protocol, so the network connection can be treated like any other file stream in the system. TCP is not suitable for simulation data, because any dropped packets will stall the data pipeline until the dropped data can be retransmitted. + +@section prottnl Network Protocols and TNL + +Some network systems use both TCP and UDP - TCP for messages that must arrive, but are not time sensitive, and UDP for time-sensitive simulation updates. + +@ref fundamentals contains a discussion of why this is not optimal for bandwidth conservation, and an explanation of the protocol solution implemented in TNL. + +@section sockets Berkeley (BSD) Sockets - the standard network API + +The BSD Sockets API describes a set of C language interface routines for communicating using the TCP protocol suite, including IP and UDP. The sockets API allows processes to open communcation "sockets" that can then be assigned to a particular integer port number on the host. + +Sockets created to use the TCP stream protocol can either be set to "listen()" for connections from remote hosts, or can be set to "connect()" to a remote host that is currently listening for incoming connections. Once a connection is established between two stream sockets, either side can send and receive guaranteed data to the other. + +Sockets can also be created in datagram mode, in which case they will use the underlying UDP protocol for transmission of datagram packets. Since the datagram socket mode is connectionless, the destination IP address and port must be specified with each data packet sent. + +The socket API contains other utility routines for performing operations such as host name resolution and socket options configuration. The Microsoft Windows platform supplies a Windows socket API called Winsock that implements the BSD socket API. + +@see Socket, the TNL class that implements a wrapper on the BSD Sockets API. + +@section topologies Application Network Topologies + +Networked applications can be designed to communicate with each other using different topological organization strategies. Some common communcations organization paradigms are discussed below. + +Peer-to-Peer: In a peer-to-peer network application, the client processes involved in the network communicate directly with one another. Though there may be one or more hosts with authoritative control over the network of peers, peer-to-peer applications largely distribute the responsibility for the simulation or application amongst the peers. + +Client-Server: In the client-server model, one host on the network, the server, acts as a central communications hub for all the other hosts (the clients). Typically the server is authoritative, and is responsible for routing communication between the several clients. + +Client-Tiered Server Cluster: In network applications where more clients want to subscribe to a service than can be accomodated by one server, the server's role will be handled by a cluster of servers peered together. The servers in the network communicate using the peer-to-peer model, and communicate with the clients using the client-server model. The servers may also communicate with an authoritative "super-server" to handle logins or resolve conflicts. + +TNL imposes no specific network topology on applications using it. + +@section security Security and Encryption + +When a message is sent between two hosts on a network, that message may pass through any number of intermediate wires, hosts and routers or even sent wirelessly to a satellite or a WiFi base station. This opens up the potential that some third party who has access to any one of the intermediate communication forwarding points may eavesdrop on and/or change the contents of the message. Often networked applications send sensitive user data, like credit card numbers, bank account information or private correspondence. These applications rely on encryption algorithms to protect messages sent over an unsecure network. + +@subsection symmetric Symmetric Encryption + +Symmetric Encryption algorithms operate under the assumption that the two parties sending messages to each other share a common, secret key. This key is used to encode the data in such a way that only users with the secret key can decode it. In the ideal case, the ciphertext (encoded version of the message) looks like a random string of bits to any eavesdropper. + +There are many Symmetric Encryption algorithms of varying levels of security, but all of them when used alone have several drawbacks. First, both parties to the communication must have a copy of the shared secret key. If a client is attempting to communicate with a service it has never contacted before, and doesn't share a key with, it won't be able to communicate securely with it. Also, although an intermediate eavesdropper cannot read the data sent between the hosts, it can alter the messages, potentially causing one or more of the systems to fail. +@see SymmetricCipher, the TNL class that implements Symmetric Encryption. + +@subsection mesgauth Message Authentication + +In order to detect when a message has been altered by a third party, a secure messaging system will send a message authentication code (MAC) along with the data. The MAC is generated using a cryptographically secure hashing function, such as MD5 or SHA. Secure hash algorithms take an array of bytes and compute a cryptographically secure message digest of some fixed number of bytes - 16 in the case of MD5, 32 for SHA-256 and so on. + +When a message is sent using a symmetric cipher, the hash or some portion of it is encrypted and sent along as well. Any changes in the message will cause the hash algorithm to compute a different hash than that which is encrypted and included with the message, notifying the receiving party that the message has been tampered with. + +@subsection pubkey Public Key Cryptography and Key Exchange + +Public Key Cryptography algorithms were invented to solve the symmetric key distribution problem. In public key algorithms, each participant in the communication has a key pair composed of a public key and a private key. The theory of public keys suggests that a message encrypted with the public key can only be decrypted with the private key and vice-versa. + +Key exchange algorithms (Diffie-Helman, ECDH) have certain properties such that two users, A and B can share their public keys with each other in plain text, and then, using each other's public key and their own private keys they can generate the same shared secret key. Eavesdroppers can see the public keys, but, because the private keys are never transmitted, cannot know the shared secret. Because public key algorithms are computationally much more expensive than symmetric cryptography, network applications generally use public key cryptography to share a secret key that is then used as a symmetric cipher key. +@see AsymmetricKey, the TNL class that implements Asymmetric Keys and secret generation and +@see NetInterface, the TNL class that implements the secure key exchange protocol. + +@subsection digsigca Digital Signatures/Certificate Authorization + +Public key algorithms still have one vulnerability, known as the Man-in-the-Middle attack. Basically, an eavesdropper in the communication between A and B can intercept the public keys in transit and substitute its own public key, thereby establishing a secure connection with A and B - decrypting incoming data and reencrypting it with its shared key to the opposite party. + +To combat this attack, the concept of certificates was introduced. In this model, the public key of one or both of the participants in the communication is digitally signed with the private key of some known, trusted Certificate Authority (CA). Then, using the Certificate Authority's public key, the parties to the communication can validate the public key of the opposite parties. +@see Certificate, the TNL class that implements digitally signed certificates. + +@subsection sectnl Security and the TNL + +The TNL uses the publicly available libtomcrypt (http://libtomcrypt.org) as its encryption foundation. The TNL features key exchange, secret session keys, message authentication and certificate verification. + +@subsection morinfo More Information on Cryptography + +The preceding sections were only a very high level overview of some cryptographic algorithm theories. For more information, see the USENET cryptography FAQ at http://www.faqs.org/faqs/cryptography-faq/ + +@section challenges Additional Challenges Facing Network Programmers + +@subsection malicioususers Malicious Attackers and Denial of Service + +A problem facing developers of internet applications and web sites are Denial-of-Service attacks. Malicious users employing custom tools often attempt to shut down publicly available internet servers. There are a variety of well-known categories of DoS attacks. + +Traffic flooding: This attack sends a barrage of data to the public address of the server, in an attempt to overwhelm that server's connection to the internet. This attack often employs many machines, hijacked by the attacker and acting in concert. These attacks are often the most difficult to mount since they require a large number of available machines with high-speed internet access in order to attack a remote host effectively. + +Connection depletion: The connection depletion attack works by exploting a weakness of some connection based communications protocols. Connection depletion attacks work by initiating a constant flow of spurious connection attempts. When a legitimate user attempts to connect to the server, all available pending connection slots are already taken up by the spoofed connection attempts, thereby denying service to valid clients. +@see NetInterface for a description of the connection handshaking protocol. + +Server CPU depletion: If the server performs public key cryptography as part of the connection sequence, a malicious client could be constructed to initiate bogus connection attempts in an effort to initiate many CPU intesive cryptographic operations on the server. + +The TNL uses a two-phase connection protocol to protect against connection depletion attacks, and implements a client-puzzle algorithm to prevent CPU depletion attacks. Also, TNL is built so that bogus packets are discarded as quickly as possible, preventing flooding attacks from impacting the server CPU. +@see ClientPuzzleManager, the class that implements cryptographically strong client puzzles for the NetInterface class. + +@subsection firewall Firewalls and Network Address Translation (NAT) routers + +Firewalls are software or hardware devices designed to protect local networks from malicious external attackers. Most firewalls filter all incoming, unsolicited network traffic. NAT routers exist to allow potentially many machines to share a single IP address, but for practical purposes they share similar characteristics with firewalls, by often filtering out unsolicited network traffic. + +In client/server applications, firewalls and NATs aren't generally a problem. When a client behind a firewall or NAT makes a request to the server, the response is allowed to pass through the firewall or NAT because the network traffic was solicited first by the client. + +In peer-to-peer applications, NATs and firewalls pose a greater challenge. if both peers are behind different firewalls, then getting them to communicate to each other requires that they both initiate the connection in order for the other's data to be able to flow through the firewall or NAT. This can be facilitated by a third party server or client that both are able to communicate with directly. + +The TNL provides functionality for arranging a direct connection between two firewalled hosts via a third party master server. +@see MasterServerInterface for a description of the TNL Master Server and the connection RPC interface. +*/ + +/*! @page fundamentals Torque Network Library Design Fundamentals + +The Torque Network Library was designed to overcome, as much as possible, the three fundamental limitations of network programming - high packet latency, limited bandwidth and packet loss. The following strategies were identified for each of the limitations: + +@section bandwidthcons Bandwidth conservation + +Bandwidth conservation in multiuser simulations is of premium importance, not only for clients that may be connected over very low bandwidth transports, but also for servers whose operators have to pay for bandwidth usage. Realizing this, the following techniques are used to conserve bandwidth as much as possible: + +Send static data once, or not at all: Often in a networked application, a server will transmit some amount of static data to a client. This data may be initialization parameters for a 3D world, a client's name, or some object state that is immutable for objects of a given type. TNL provides direct facilities for caching string data (client names, mission descriptions, etc), sending a given string only once and an integer representation thereafter. The Torque Game Engine also shows how simulations can cache common object instance data in DataBlock objects, which are transmitted only when a client connects. + +Compress data to the minimum space necessary: When conserving bandwidth, every bit counts. TNL uses a utility class call BitStream to write standard data types into a packet compressed to the minimum number of bits necessary for that data. Boolean values are written as a single bit, integer writes can specify the bit field width, and floating point values can be specified as 0 to 1 compressed to a specified bit count. The BitStream also implements Huffman compression of string data and compression of 3D positions and surface normals. + +Only send information that is relevant to the client: In a client/server simulation, the server often has information that is not relevant at all to some or all of the clients. For example, in a 3D world, if an object is outside the visible distance of a given client, there is no reason to consume valuable packet space describing that object to the client. The TNL allows the application level code to easily specify which objects are relevant, or "in scope" for each client. +@see NetObject + +Prioritize object updates: Because bandwidth is limited and there is generally a much greater amount of data a server could send to a given client than it has capacity for, the TNL implements a very fine-grained prioritization scheme for updating objects. User code can determine the policy by which objects are judged to be more or less "important" to each client in the simulation, and objects with more importance are updated with a greater frequency. +@see NetObject, @see GhostConnection + +Only update the parts of an object that have changed: Often in a networked simulation, not all object state is updated at the same time - for exampe, a player in a 3D action game may have state that includes the player's current position, velocity, health and ammunition. If the player moves, only the position and velocity states will change, so sending the full state, including the health and ammunition values would waste space unnecessarily. The TNL allows objects individual objects to have state that are updated independently of one another. +@see NetObject + +@section packetloss Coping with Packet Loss + +In any networked simulation, packet loss will be a consideration - whether because of network congestion, hardware failure or software defects, some packets will inevitably be lost. One solution to the packet loss problem is to use a guaranteed messaging protocol like TCP/IP. Unfortunately, TCP has some behavioral characteristics that make it a poor choice for real-time networked simulations. + +TCP guarantees that all data sent over the network will arrive, and will arrive in order. This means that if a data packet sent using TCP is dropped in transit, the sending host must retransmit that data before any additional data, that may have already arrived at the remote host, can be processed. In practice this can mean a complete stall of ANY communications for several seconds. Also, TCP may be retransmitting data that is not important from the point of view of the simulation - holding up data that is. + +The other possible protocol choice would be to use UDP for time critical, but unguaranteed data, and use TCP only for data that will not hold up the real-time aspects of the simulation. This solution ends up being non-optimal for several reasons. First, maintaining two communications channels increases the complexity of the networking component. If an object is sent to a client using the guaranteed channel, unguaranteed messages sent to that object at a later time may arrive for processing before the original guaranteed send. Also, because the unguaranteed channel may lose information, the server will have to send more redundant data, with greater frequency. + +To solve these problems, TNL implements a new network protocol that fits somewhere between UDP and TCP in its feature set. This protocol, dubbed the "Notify" protocol, does not attempt to hide the underlying unreliability of the network as TCP does, but at the same time it provides more information to the application than straight UDP. The notify protocol is a connection-oriented unreliable communication protocol with packet delivery notification. When a datagram packet is sent from one process, that process will eventually be notified as to whether that datagram was received or not. Each data packet is sent with a packet header that includes acknowledgement information about packets the sending process has received from the remote process. This negates the need for seperate acknowledgement packets, thereby conserving additional bandwidth. +@see NetConnection + +The notify protocol foundation allows the TNL to provide a rich set of data transmission policies. Rather than simply grouping data as either guaranteed or unguaranteed, the TNL allows at least five different categorizations of data: + +Guaranteed Ordered data: Guaranteed Ordered data are data that would be sent using a guaranteed delivery protocol like TCP. Messages indicating clients joining a simulation, text messages between clients, and many other types of information would fall into this category. In TNL, Guaranteed Ordered data are sent using Event objects and RPC method calls. When the notify protocol determines that a packet containing guaranteed ordered data was lost, it requeues the data to be sent in a future packet. +@see NetEvent + +Guaranteed data: TNL processes Guaranteed data is in a way similar to Guaranteed Ordered data, with the only difference being that a client can process Guaranteed data as soon as it arrives, rather than waiting for any ordered data to arrive that was dropped. +@see NetEvent + +Unguaranteed data: Unguaranteed data is sent, and if the packet it is sent in arrives, is processed. If a packet containing unguaranteed data events is dropped, that data is not resent. The unguaranteed data sending policy could be used for information like real-time voice communication, where a retransmitted voice fragment would be useless. +@see NetEvent + +Current State data: For many objects in a simulation, the client isn't concerned with "intervening" states of an object on the server, but only its current state. For example, in a 3D action game, if an enemy player moves from point A to B to C, another client in the simulation is only interested in the final position, C of the object. With the notify protocol, TNL is able to resend object state from a dropped packet only if that state was not updated in a subsequent packet. +@see NetObject + +Quickest Delivery data: Some information sent in a simulation is of such importance that it must be delivered as quickly as possible. In this situation, data can be sent with every packet until the remote host acknowledges any of the packets known to contain the data. Client movement information is an example of data that might be transmitted using this policy. + +By implementing various data delivery policies, the TNL is able to optimize packet space utilization in high packet loss environments. + +@section latency Strategies for Dealing With Latency + +Latency is a function of the time-based limitations of physical data networks. The time it takes information to travel from one host to another is dependent on many factors, and can definitely affect the user's perceptions of what is happening in the simulation. + +For example, in a client-server 3D simulation, suppose the round-trip time between one client and server is 250 milliseconds. If the client is observing an object that is moving. If the server is sending position updates of the object to the client, those positions will be "out of date" by 125 milliseconds by the time they arrive on the client. Also, suppose that the server is sending packets to the client at a rate of 10 packets per second. When the next update for the object arrives at the client, it may have moved a large distance relative to the perceptions of the client. + +Also, if the server is considered to be authoritative over the client's own position in the world, the client would have to wait at least a quarter of a second before its inputs were validated and reflected in its view of the world. This gives the appearance of very perceptible input "lag" on the client. + +In the worst case, the client would always see an out of date version of the server's world, as objects moved they would "pop" from one position to another, and each keypress wouldn't be reflected until a quarter of a second later. For most real-time simulations, this behavior is not optimal. + +Because TNL is predominantly a data transport and connection management API, it doesn't provide facilities for solving these problems directly. TNL provides a simple mechanism for computing the average round-trip time of a connection from which the following solutions to connection latency issues can be implemented: + +Interpolation: Interpolation is used to smoothly move an object from where the client thinks it is to where the server declares it to be over some short period of time. Parameters like position and rotation can be interpolated using linear or cubic interpolation to present a consistent, no "pop" view of the world to the client. The downside of interpolation when used alone is that it actually exacerbates the time difference between the client and the server, because the client is spending even more time than the one-way message time to move the object from its current position to the known server position. + +Extrapolation: To solve the problem of out-of-date state information, extrapolation can be employed. Extrapolation is a best guess of the current state of an object, given a known past state. For example, suppose a player object has a last known position and velocity. Rather than placing the player at the server's stated position, the player object can be placed at the position extrapolated forward by velocity times the time difference. + +In the Torque Game Engine, player objects controlled by other clients are simulated using both interpolation and extrapolation. When a player update is received from the server, the client extrapolates that position forward using the player's velocity and the sum of the time it will use to interpolate and the one-way message time from the server - essentially, the player interpolates to an extrapolated position. Once it has reached the extrapolated end point, the player will continue to extrapolate new positions until another update of the obect is received from the server. + +By using interpolation and extrapolation, the client view can be made to reasonably, smoothly approximate the world of the server, but neither approach is sufficient for real-time objects that are directly controlled by player input. To solve this third, more difficult problem, client-side prediction is employed. + +Client-side prediction is similar to extrapolation, in that the client is attempting to guess the server state of an object the server has authority over. In the case of simple extrapolation, however, the client doesn't have the benefit of the actual input data. Client-side prediction uses the inputs of the user to make a better guess about where the client-controlled object will be. Basically, the client performs the exact same object simulation as the server will eventually perform on that client's input data. As long as the client-controlled object is not acted upon by forces on the server that don't exist on the client or vice versa, the client and server state information for the object should perfectly agree. When they don't agree, interpolation can be employed to smoothly move the client object to the known server position and client-side prediction can be continued. + +*/ + +/*! @page archoverview Torque Network Library Architectural Overview + +The Torque Network Library is built in layers, each adding more functionality to the layer below it. + +@section platf The Platform Layer + +At the lowest level, TNL provides a platform independent interface to operating system functions. The platform layer includes functions for querying system time, sleeping the current process and displaying alerts. The platform layer includes wrappers for all of the C standard library functions used in the TNL. + +The platform layer also contains the Socket and Address classes, which provide a cross-platform, simplified interface to datagram sockets and network addresses. + +@section netb The NetBase Layer + +The NetBase layer is the foundation upon which most of the classes in TNL are based. At the root of the class hierarchy is the Object base class. Every subclass of Object is associated with an instance of NetClassRep through a set of macros, allowing for instances of that class to be constructed by a class name string or by an automatically assigned class id. + +This id-based instantiation allows objects subclassed from NetEvent and NetObject to be serialized into data packets, transmitted, constructed on a remote host and deserialized. + +Object also has two helper template classes, SafePtr, which provides safe object pointers that become NULL when the referenced object is deleted, and a reference pointer class, RefPtr, that automatically deletes a referenced object when all the references to it are destructed. + +@section bitstr The BitStream and PacketStream classes + +The BitStream class presents a stream interface on top of a buffer of bytes. BitStream provides standard read and write functions for the various TNL basic data types, including integers, characters and floating point values. BitStream also allows fields to be written as bit-fields of specific size. An integer that is always between 3 and 9 inclusive can be written using only 3 bits using the writeRangedU32 method, for example. + +BitStream huffman encodes string data for additional space savings, and provides methods for compressing 3D points and normals, as routines for writing arbitrary buffers of bits. + +The PacketStream subclass of BitStream is simply a thin interface that statically allocates space up to the maximum size of a UDP packet. A routine can declare a stack allocated PacketStream instance, write data into it and send it to a remote address with just a few lines of code. + +@section netconint The NetInterface and NetConnection Layer + +The NetInterface class wraps a platform Socket instance and manages the set of NetConnection instances that are communicating through that socket. NetInterface is manages the two-phase connection initiation process, dispatch of protocol packets to NetConnection objects, and provides a generic interface for subclasses to define and process their own unconnected datagram packets. + +The NetConnection class implements the connected Notify Protocol layered on UDP. NetConnection manages packet send rates, writes and decodes packet headers, and notifies subclasses when previously sent packets are known to be either received or dropped. + +NetInterface instances can be set to use a public/private key pair for creating secure connections. In order to prevent attackers from depleting server CPU resources, the NetItnerface issues a cryptographically difficult "client puzzle" to each host attempting to connect to the server. Client puzzles have the property that they can be made arbitrarily difficult for the client to solve, but whose solutions can be checked by the server in a trivial amount of time. This way, when a server is under attack from many connection attempts, it can increase the difficulty of the puzzle it issues to connecting clients. + +@section neteventconn The Event Layer - EventConnection, NetEvent and Remote Procedure Calls + +The EventConnection class subclasses NetConnection to provide several different types of data transmission policies. EventConnection uses the NetEvent class to encapsulate event data to be sent to remote hosts. Subclasses of NetEvent are responsible for serializing and deserializing themselves into BitStreams, as well as processing event data in the proper sequence. + +NetEvent subclasses can use one of three data guarantee policies. They can be declared as GuaranteedOrdered, for ordered, reliable message delivery; Guaranteed, for reliable but possibly out of order delivery, or Unguaranteed, for ordered but not guaranteed messaging. The EventConnection class uses the notify protocol to requeue dropped events for retransmission, and orders the invocations of the events' process methods if ordered processing is requested. + +Because declaring an individual NetEvent subclass for each type of message and payload to be sent over the network, with its corresponding pack, unpack and process routines, can be somewhat tedious, TNL provides a Remote Procedure Call (RPC) framework. Using some macro magic, argument list parsing and a little assembly language, methods in EventConnection subclasses can be declared as RPC methods. When called from C++, the methods construct an event containing the argument data passed to the function and send it to the remote host. When the event is unpacked and processed, the body of the RPC method implementation is executed. + +See Also @ref rpcdesc for a more complete description of RPC in the Torque Network Library. + +@section ghostingconn Ghosting - GhostConnection and NetObject + +The GhostConnection class subclasses EventConnection in order to provide the most-recent and partial object state data update policies. Instances of the NetObject class and its subclasses can be replicated over a connection from one host to another. The GhostConnection class manages the relationship between the original object, and its "ghost" on the client side of the connection. + +In order to best utilize the available bandwidth, the GhostConnection attempts to determine which objects are "interesting" to each client - and among those objects, which ones are most important. If an object is interesting to a client it is said to be "in scope" - for example, a visible enemy to a player in a first person shooter would be in scope. + +Each GhostConnection object maintains a NetObject instance called the scope object - responsible for determining which objects are in scope for that client. Before the GhostConnection writes ghost update information into each packet, it calls the scope object's performScopeQuery method which must determine which objects are "in scope" for that client. + +Each scoped object that needs to be updated is then prioritized based on the return value from the NetObject::getUpdatePriority() function, which by default returns a constant value. This function can be overridden by NetObject subclasses to take into account such factors as the object's distance from the camera, its velocity perpendicular to the view vector, its orientation relative to the view direction and more. + +Rather than always sending the full state of the object each time it is updated across the network, the TNL supports only sending portions of the object's state that have changed. To facilitate this, each NetObject can specify up to 32 independent states that can be modified individually. For example, a player object might have a movement state, detailing its position and velocity, a damage state, detailing its damage level and hit locations, and an animation state, signifying what animation, if any, the player is performing. + +A NetObject can notify the network system when one of its states has changed, allowing the GhostConnections that are ghosting that object to replicate the changed state to the clients for which that object is in scope. + +@section encrypttnl Encryption and TNL + +The TNL has hooks in various places to use encryption when requested. To enable encrypted connections, the NetInterface must be assigned an instance of AsymmetricKey as a public/private key pair using NetInterface::setPrivateKey. The NetInterface::setRequiresKeyExchange method may then be called to instruct the NetInterface that all incoming connection requests must include a key exchange. + +Asymmetric keys can be constructed with varying levels of security. The TNL uses Elliptic Curve public key crytpography, with key sizes ranging from 20 to 32 bytes. AsymmetricKey instances can be constructed either with a new, random key of a specified size, or can be created from an existing ByteBuffer. + +Once a secure connection handshake is completed, TNL uses the AES symmetric cipher to encode connected packets. The BitStream::hashAndEncrypt and BitStream::decryptAndCheckHash methods use an instance of SymmetricCipher to encrypt and decrypt packets using a shared session key. + +In order to have properly secure communications, the cryptographically strong pseudo-random number generator (PRNG) in TNL must be initialized with good (high entropy) random data. + +@section usefulclasses Useful Classes + +TNL uses a number of utility classes throughout. Some of these include: + +Vector - The Vector template class is a lightweight version of the STL Vector container. + +DataChunker - The DataChunker class performs small, very low overhead memory allocation out of a pool. Individual allocations cannot be freed, however the entire pool can be freed at once. + +ClassChunker - The ClassChunker template class uses the DataChunker to manage allocation and deallocation of instances of the specific class. ClassChunker maintains a free list for quick allocation and deallocation. + +StringTableEntry - StringTableEntry wraps a ref-counted element in the StringTable, with simple conversion operations to C strings. StringTableEntry instances can be sent in the parameter lists of RPC methods or using the EventConnection::packStringTableEntry method. + +ByteBuffer - The ByteBuffer class wraps a buffer of arbitray binary data. ByteBuffer serves as a base class for BitStream, as well as the cryptographic primitives. + +@section debugerror Debugging and Error Handling + +Correcting bugs in a networked simulation can sometimes be an incredibly difficult task. TNL provides some handy features to make debugging somewhat less challenging: + +Asserts - The TNLAssert and TNLAssertV macros specify a condition that, if false, will cause the application to display an error dialog and halt in the debugger where the assert was hit. Asserts are very useful for sanity-checking arguments to functions, and making sure network data is being properly read from and written to packets. + +Logging - TNL has a set of simple but effective facilities for logging status information. The TNLLogMessage and TNLLogMessageV macros allow the user to specify logging tokens with particular log messages. Logging of messages associated with a given token can be enabled or disabled using the TNLLogEnable macro. Also, the TNLLogBlock macro can be used to log multiple logprintf statements in a single test. Rather than log to a file or other destination, TNL applications must declare at least one instance of a sublclass of TNLLogConsumer. Every TNLLogConsumer instance receives all the logging messages that are currently enabled. + +Debugging object writes into packets - One of the most common errors programmers experience when using TNL is failing to properly match the NetEvent::pack and NetEvent::unpack or NetObject::packUpdate and NetObject::unpackUpdate routines. By default, if TNL_DEBUG is defined, the EventConnection and GhostConnection classes will write extra size information into the packet before each object's data are written. The ConnectionParameters::mDebugObjectSizes flag can be modified directly to further control this behavior. +*/ + +/*! @page simpletutorial Simple Torque Network Library Tutorial: Hello World + +This simple tutorial walks the user through the creation of a very simple networked example program using the RPC functionality of the EventConnection class. This command-line program can be run in either client or server modes. As a client it will attempt to connect to a server at the specified address and send it a message every second. When the server receives a message from a client, it will respond back with a "Hello, World!" message. + +See Also @ref rpcdesc for a more complete description of RPC in the Torque Network Library. + +First, create a new source file, "simpleNet.cpp", containing the following lines to start: + +@code +#include "tnl.h" +#include "tnlEventConnection.h" +#include "tnlNetInterface.h" +#include "tnlRPC.h" +#include + +bool gQuit = false; // a flag used when the client wants to quit. + +using namespace TNL; // make sure we can simply use the TNL classes. +@endcode + +If the compiler complains of missing include files, be sure the "tnl" directory is in the include path. + +Next, create a custom subclass of EventConnection for the example program to communicate across, and declare the client-to-server and server-to-client RPC methods: + +@code +class SimpleEventConnection : public EventConnection +{ + typedef EventConnection Parent; + +public: + // Let the network system know this is a valid network connection. + TNL_DECLARE_NETCONNECTION(SimpleEventConnection); + + // declare the client to server message + TNL_DECLARE_RPC(rpcMessageClientToServer, (const char *theMessageString)); + + // declare the server to client message + TNL_DECLARE_RPC(rpcMessageServerToClient, (const char *theMessageString)); +}; +@endcode + +The first macro invoked, TNL_DECLARE_NETCONNECTION declares members necessary to make this class work as a connection in TNL. The RPC methods are then declared using the TNL_DECLARE_RPC macro. The first parameter to the macro is the name of the RPC method, which can be invoked like any other member function on the object. The second argument is a parenthesized argument list to the RPC. Although these functions are both declared to take only a single string, RPC method parameter lists can contain all the basic TNL types, as well as StringTableEntry, ByteBuffer and Vector objects. + +Next, define the implementation of the SimpleEventConnection class: + +@code +TNL_IMPLEMENT_NETCONNECTION(SimpleEventConnection, NetClassGroupGame, true); + +TNL_IMPLEMENT_RPC(SimpleEventConnection, rpcMessageClientToServer, (const char *messageString), +NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 0) +{ + // display the message the client sent + printf("Got message from client: %s\n", messageString); + // send a hello world back to the client. + rpcMessageServerToClient("Hello, World!"); +} + +TNL_IMPLEMENT_RPC(SimpleEventConnection, rpcMessageServerToClient, (const char *messageString), +NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 0) +{ + // display the message the server sent + printf("Got a message from server: %s\n", messageString); + + // once the client has heard back from the server, it should quit. + gQuit = true; +} +@endcode + +The TNL_IMPLEMENT_NETCONNECTION macro specifies two properties. The first, NetClassGroupGame declares that this connection traffics only in NetEvent, NetObject and RPC instances that have the NetClassGroupGame mask bit set in their implementations. The second property, as declared by the boolean true specifies that remote hosts can request a connection of type SimpleEventConnection from this process. + +The TNL_IMPLEMENT_RPC macro behaves like a standard function signature declaration, but with some important additions. The first three arguments, class name, method name and arguments are fairly self-explanatory. The fourth argument is the connection type mask, which specifies which types of connections the specified RPC can travel over. Since RPC's (unlike NetEvent and NetObject subclasses) are declared for only a single connection class, this mask should always be the mask associated with the connection type declared in TNL_IMPLEMENT_NETCONNECTION. + +The fifth argument to the macro specifies the guarantee type of the RPC, which can be one of RPCGuaranteedOrdered, RPCGuaranteed or RPCUnguaranteed. The sixth parameter is the direction the RPC is allowed to travel, which when specified can make an application more secure from attacks that modify packets in transit. The last argument is a version number, which can be specified so that older clients can still connect to servers offering newer RPCs. + +The function body of the RPC similar to any other function body with one important difference. When an RPC method is invoked, the function body code is executed on the remote side of the connection. So if the client calls the method rpcMessageClientToServer("Hello?"), the code for the body will execute on the server. + +Now that the connection class is defined, all that is left to do is create the main() function that will start up the instance as either a client or a server. + +@code +int main(int argc, const char **argv) +{ + if(argc != 3) + { + printf("usage: simpletnltest <-server|-client> "); + return 1; + } + bool isClient = !strcmp(argv[1], "-client"); + + // convert the command-line address into TNL address form + Address cmdAddress(argv[2]); + + RefPtr theNetInterface; + if(isClient) + { + Address bindAddress(IPProtocol, Address::Any, 0); + + // create a new NetInterface bound to any interface, any port (0) + theNetInterface = new NetInterface(bindAddress); + + // create a new SimpleEventConnection and tell it to connect to the + // server at cmdAddress. + SimpleEventConnection *newConnection = new SimpleEventConnection; + newConnection->connect(theNetInterface, cmdAddress); + + // post an RPC, to be executed when the connection is established + newConnection->rpcMessageClientToServer("Hello??"); + } + else + { + // create a server net interface, bound to the cmdAddress + theNetInterface = new NetInterface(cmdAddress); + + // notify the NetInterface that it can allow connections + theNetInterface->setAllowsConnections(true); + } + + // now just loop, processing incoming packets and sending outgoing packets + // until the global quit flag is set. + while(!gQuit) + { + theNetInterface->checkIncomingPackets(); + theNetInterface->processConnections(); + Platform::sleep(1); + } + return 0; +} +@endcode + +Once the code is written, use your compiler to build simpletnltest, making sure to link in the tnl library, along with whatever network libraries your platform requires (wsock32.lib on Windows, for example). + +Also, make sure Run-Time Type Checking is turned ON for your compiler or the program will not function correctly (option /GR in MSVC, for example). + +To test the program, open up two console shells, and in the first, type: + +@code +simpletnltest -server 127.0.0.1:28000 +@endcode + +This will create an instance of simpletnltest running as a server and bound to port 28000 on the local host machine. In the second window, run another instance as a client, set to connect to the server like this: + +@code +simpletnltest -client 127.0.0.1:28000 +@endcode + +Once the client runs, the server display should read: + +@code +Got a message from client: Hello? +@endcode + +and the client window should read: + +@code +Got a message from server: Hello, World! +@endcode + +The server will continue to accept new connections from clients until it is terminated manually. + +For an example program that uses more of TNL's advanced features, including RPCs with bit compressed arguments, a custom NetInterface subclass, and the NetObject replication system, look at the TNLTest project and documentation. + + +*/ + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/tnl/tnl.suo b/tnl-1.5.0/tnl/tnl/tnl.suo new file mode 100644 index 0000000000000000000000000000000000000000..2122d8cdb0a1f97ae9aecb2e51c3e4051256c915 Binary files /dev/null and b/tnl-1.5.0/tnl/tnl/tnl.suo differ diff --git a/tnl-1.5.0/tnl/tnl/tnl.vcproj b/tnl-1.5.0/tnl/tnl/tnl.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..5c291ca23b37c2cff3c4a9c9a3658f1b80aff101 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnl.vcproj @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/tnl/tnlAssert.h b/tnl-1.5.0/tnl/tnl/tnlAssert.h new file mode 100644 index 0000000000000000000000000000000000000000..46d355dea4c9347bc7906c73ca163c3e87269663 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlAssert.h @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_ASSERT_H_ +#define _TNL_ASSERT_H_ + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +namespace TNL +{ + +/** + sprintf style string formating into a fixed temporary buffer. + @param in_msg sprintf style format string + @returns pointer to fixed buffer containing formatted string + + Example: + @code + U8 a = 5; + S16 b = -10; + char *output = avar("hello %s! a=%u, b=%d", "world"); + ouput = "hello world! a=5, b=-10" + @endcode + @warning avar uses a static fixed buffer. Treat the buffer as volatile data + and use it immediately. Other functions my use avar too and clobber the buffer. + */ +const char* avar(const char *in_msg, ...); + +#ifdef TNL_ENABLE_ASSERTS + +/// Assert functions for validating proper program state. +class Assert +{ +public: + static void processAssert(const char* filename, U32 lineNumber, const char* message); + static bool processingAssert(); +}; + + + /** + Assert that the statement x is true, otherwise halt. + If the statement x is true, continue processing. + If the statement x is false, log the file and line where the assert occured, + the message y and displaying a dialog containing the message y. The user then + has the option to halt or continue causing the debugger to break. + These asserts are only present when TNL_ENABLE_ASSERTS is defined. + This assert is very useful for verifying data as well as function entry and + exit conditions. + */ + #define TNLAssert(x, y) { if (!bool(x)) { TNL::Assert::processAssert( __FILE__, __LINE__, y); TNL_DEBUGBREAK(); } } + + /** + TNLAssertV - same as TNLAssert, except that the message y must be a + parenthesized printf-style variable argument list. + These asserts are only present in DEBUG builds. + */ + #define TNLAssertV(x, y) { if (!bool(x)) { TNL::Assert::processAssert(__FILE__, __LINE__, avar y); TNL_DEBUGBREAK(); } } + +#else + #define TNLAssert(x, y) { } + #define TNLAssertV(x, y) { } +#endif + +}; + +#endif // _TNL_ASSERT_H_ + diff --git a/tnl-1.5.0/tnl/tnl/tnlAsymmetricKey.h b/tnl-1.5.0/tnl/tnl/tnlAsymmetricKey.h new file mode 100644 index 0000000000000000000000000000000000000000..8f581cf5d8f439b1237b0ac35ec15b91c1abf818 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlAsymmetricKey.h @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_ASYMMETRICKEY_H_ +#define _TNL_ASYMMETRICKEY_H_ + +#ifndef _TNL_BITSTREAM_H_ +#include "tnlBitStream.h" +#endif + + +namespace TNL { + +class AsymmetricKey : public Object +{ + /// Raw key data. + /// + /// The specific format of this buffer varies by cryptosystem, so look + /// at the subclass to see how it's laid out. In general this is an + /// opaque buffer. + void *mKeyData; + + /// Size of the key at construct time. + U32 mKeySize; + + /// Do we have the private key for this? + /// + /// We may only have access to the public key (for instance, when validating + /// a message signed by someone else). + bool mHasPrivateKey; + + /// Buffer containing the public half of this keypair. + ByteBufferPtr mPublicKey; + + /// Buffer containing the private half of this keypair. + ByteBufferPtr mPrivateKey; + bool mIsValid; + + /// Load keypair from a buffer. + void load(const ByteBuffer &theBuffer); + + /// Enum used to indicate the portion of the key we are working with. + enum KeyType { + KeyTypePrivate, + KeyTypePublic, + }; +public: + + /// Constructs an AsymmetricKey from the specified data pointer. + AsymmetricKey(U8 *dataPtr, U32 bufferSize) : mKeyData(NULL) + { + load(ByteBuffer(dataPtr, bufferSize)); + } + + /// Constructs an AsymmetricKey from a ByteBuffer. + AsymmetricKey(const ByteBuffer &theBuffer) : mKeyData(NULL) + { + load(theBuffer); + } + + /// Constructs an AsymmetricKey by reading it from a BitStream. + AsymmetricKey(BitStream *theStream) + { + ByteBuffer theBuffer; + theStream->read(&theBuffer); + load(theBuffer); + } + + /// Generates a new asymmetric key of keySize bytes + AsymmetricKey(U32 keySize); + + /// Destructor for the AsymmetricKey. + ~AsymmetricKey(); + + /// Returns a ByteBuffer containing an encoding of the public key. + ByteBufferPtr getPublicKey() { return mPublicKey; } + + /// Returns a ByteBuffer containing an encoding of the private key. + ByteBufferPtr getPrivateKey() { return mPrivateKey; } + + /// Returns true if this AsymmetricKey is a key pair. + bool hasPrivateKey() { return mHasPrivateKey; } + + /// Returns true if this is a valid key. + bool isValid() { return mIsValid; } + /// Compute a key we can share with the specified AsymmetricKey + /// for a symmetric crypto. + ByteBufferPtr computeSharedSecretKey(AsymmetricKey *publicKey); + + /// Returns the strength of the AsymmetricKey in byte size. + U32 getKeySize() { return mKeySize; } + + /// Constructs a digital signature for the specified buffer of bits. This + /// method only works for private keys. A public key only Asymmetric key + /// will generate a signature of 0 bytes in length. + ByteBufferPtr hashAndSign(const ByteBuffer &theByteBuffer); + + /// Returns true if the private key associated with this AsymmetricKey + /// signed theByteBuffer with theSignature. + bool verifySignature(const ByteBuffer &theByteBuffer, const ByteBuffer &theSignature); +}; + +typedef RefPtr AsymmetricKeyPtr; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlBitSet.h b/tnl-1.5.0/tnl/tnl/tnlBitSet.h new file mode 100644 index 0000000000000000000000000000000000000000..ffd29f6f9503ef58044c68c5f0d1f7864fa8e7af --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlBitSet.h @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_BITSET_H_ +#define _TNL_BITSET_H_ + +//Includes +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +namespace TNL { + +/// Represents a word of bits. +/// +/// A helper class to perform operations on a set of 32 bits. +class BitSet32 +{ +private: + U32 mBits; + +public: + /// Default constructor initializes this bit set to all zeros. + BitSet32() { mBits = 0; } + + /// Copy constructor. + BitSet32(const BitSet32& in_rCopy) { mBits = in_rCopy.mBits; } + + /// Construct from an input U32. + BitSet32(const U32 in_mask) { mBits = in_mask; } + + /// @name Accessors + /// @{ + + /// Returns the U32 representation of the bit set. + operator U32() const { return mBits; } + + /// Returns the U32 representation of the bit set. + U32 getMask() const { return mBits; } + + /// @} + + /// @name Mutators + /// + /// Most of these methods take a word (ie, a BitSet32) of bits + /// to operate with. + /// @{ + + /// Sets all the bits in the bit set to 1 + void set() { mBits = 0xFFFFFFFFUL; } + + /// Sets all the bits in the bit set that are set in m. + void set(const U32 m) { mBits |= m; } + + /// For each bit set in s, sets or clears that bit in this, depending on whether b is true or false. + void set(BitSet32 s, bool b) { mBits = (mBits&~(s.mBits))|(b?s.mBits:0); } + + /// Clears all the bits in the bit set to 0. + void clear() { mBits = 0; } + + /// Clears all the bits in the bit set that are set in m. + void clear(const U32 m) { mBits &= ~m; } + + /// Flips all the bits in the bit set that are set in m. + void toggle(const U32 m) { mBits ^= m; } + + /// Test if the passed bits are set. + bool test(const U32 m) const { return (mBits & m) != 0; } + + /// Test if the passed bits and only the passed bits are set. + bool testStrict(const U32 m) const { return (mBits & m) == m; } + + BitSet32& operator =(const U32 m) { mBits = m; return *this; } + BitSet32& operator|=(const U32 m) { mBits |= m; return *this; } + BitSet32& operator&=(const U32 m) { mBits &= m; return *this; } + BitSet32& operator^=(const U32 m) { mBits ^= m; return *this; } + + BitSet32 operator|(const U32 m) const { return BitSet32(mBits | m); } + BitSet32 operator&(const U32 m) const { return BitSet32(mBits & m); } + BitSet32 operator^(const U32 m) const { return BitSet32(mBits ^ m); } + + /// @} +}; + +}; + +#endif //_TNL_BITSET_H_ diff --git a/tnl-1.5.0/tnl/tnl/tnlBitStream.h b/tnl-1.5.0/tnl/tnl/tnlBitStream.h new file mode 100644 index 0000000000000000000000000000000000000000..00ee140b22e82264f57a82be4b354d1390b792c2 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlBitStream.h @@ -0,0 +1,405 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_BITSTREAM_H_ +#define _TNL_BITSTREAM_H_ + +#ifndef _TNL_BYTEBUFFER_H_ +#include "tnlByteBuffer.h" +#endif + +#ifndef _TNL_CONNECTIONSTRINGTABLE_H_ +#include "tnlConnectionStringTable.h" +#endif + +namespace TNL { + +class SymmetricCipher; + +/// Point3F is used by BitStream for transmitting 3D points and vectors. +/// +/// Users of the TNL should provide conversion operators to and from +/// this TNL-native type. +struct Point3F +{ + F32 x; ///< the X coordinate + F32 y; ///< the Y coordinate + F32 z; ///< the Z coordinate +}; + +/// Helper macro used in BitStream declaration. +/// +/// @note DeclareTemplatizedReadWrite macro declares a read and write function +/// for the specified type. This is a macro because MSVC6 has seriously +/// broken template functionality. Thanks MS! +#define DeclareTemplatizedReadWrite(T) \ +inline bool write(T value) { T temp = convertHostToLEndian(value); return write(sizeof(T), &temp); } \ +inline bool read(T *value) { T temp; bool success = read(sizeof(T), &temp); *value = convertLEndianToHost(temp); return success;} + +/// BitStream provides a bit-level stream interface to a data buffer. +class BitStream : public ByteBuffer +{ +protected: + enum { + ResizePad = 1500, + }; + U32 bitNum; ///< The current bit position for reading/writing in the bit stream. + bool error; ///< Flag set if a user operation attempts to read or write past the max read/write sizes. + bool mCompressRelative; ///< Flag set if the bit stream should compress points relative to a compression point. + Point3F mCompressPoint; ///< Reference point for relative point compression. + U32 maxReadBitNum; ///< Last valid read bit position. + U32 maxWriteBitNum; ///< Last valid write bit position. + ConnectionStringTable *mStringTable; ///< String table used to compress StringTableEntries over the network. + /// String buffer holds the last string written into the stream for substring compression. + char mStringBuffer[256]; + + bool resizeBits(U32 numBitsNeeded); +public: + + /// @name Constructors + /// + /// Note that the BitStream essentially wraps an existing buffer, so to use a bitstream you must + /// have an existing buffer for it to work with! + /// + /// @{ + + /// Default to maximum write size being the size of the buffer. + BitStream(U8 *bufPtr, U32 bufSize) : ByteBuffer(bufPtr, bufSize) { setMaxSizes(bufSize, bufSize); reset(); } + + /// Optionally, specify a maximum write size. + BitStream(U8 *bufPtr, U32 bufSize, U32 maxWriteSize) + : ByteBuffer(bufPtr, bufSize) { setMaxSizes(bufSize, maxWriteSize); reset(); } + + /// Creates a resizable BitStream + BitStream() : ByteBuffer() { setMaxSizes( getBufferSize(), getBufferSize() ); reset(); } + /// @} + + /// Sets the maximum read and write sizes for the BitStream. + void setMaxSizes(U32 maxReadSize, U32 maxWriteSize = 0); + + /// Sets the maximum read and write bit sizes for the BitStream. + void setMaxBitSizes(U32 maxReadBitSize, U32 maxWriteBitSize = 0); + + /// resets the read/write position to 0 and clears any error state. + void reset(); + + /// clears the string compression buffer. + void clearStringBuffer() { mStringBuffer[0] = 0; } + + /// sets the ConnectionStringTable for compressing string table entries across the network + void setStringTable(ConnectionStringTable *table) { mStringTable = table; } + + /// clears the error state from an attempted read or write overrun + void clearError() { error = false; } + + /// Returns a pointer to the next byte in the BitStream from the current bit position + U8* getBytePtr(); + + /// Returns the current position in the stream rounded up to the next byte. + U32 getBytePosition() const; + /// Returns the current bit position in the stream + U32 getBitPosition() const; + /// Sets the position in the stream to the first bit of byte newPosition. + void setBytePosition(const U32 newPosition); + /// Sets the position in the stream to newBitPosition. + void setBitPosition(const U32 newBitPosition); + /// Advances the position in the stream by numBits. + void advanceBitPosition(const S32 numBits); + + /// Returns the maximum readable bit position + U32 getMaxReadBitPosition() const { return maxReadBitNum; } + + /// Returns the number of bits that can be written into the BitStream without resizing + U32 getBitSpaceAvailable() const { return maxWriteBitNum - bitNum; } + + /// Pads the bits up to the next byte boundary with 0's. + void zeroToByteBoundary(); + + /// Writes an unsigned integer value between 0 and 2^(bitCount - 1) into the stream. + void writeInt(U32 value, U8 bitCount); + /// Reads an unsigned integer value between 0 and 2^(bitCount - 1) from the stream. + U32 readInt(U8 bitCount); + + /// Writes an unsigned integer value between 0 and 2^(bitCount -1) into the stream at the specified position, without changing the current write position. + void writeIntAt(U32 value, U8 bitCount, U32 bitPosition); + + /// Writes a signed integer value between -2^(bitCount-1) and 2^(bitCount-1) - 1. + void writeSignedInt(S32 value, U8 bitCount); + /// Reads a signed integer value between -2^(bitCount-1) and 2^(bitCount-1) - 1. + S32 readSignedInt(U8 bitCount); + + /// Writes an unsigned integer value in the range rangeStart to rangeEnd inclusive. + void writeRangedU32(U32 value, U32 rangeStart, U32 rangeEnd); + /// Reads an unsigned integer value in the range rangeStart to rangeEnd inclusive. + U32 readRangedU32(U32 rangeStart, U32 rangeEnd); + + /// Writes an enumeration value in the range of 0 ... enumRange - 1. + void writeEnum(U32 enumValue, U32 enumRange); + /// Reads an enumeration value in the range 0 ... enumRange - 1. + U32 readEnum(U32 enumRange); + + /// Writes a float from 0 to 1 inclusive, using bitCount bits of precision. + void writeFloat(F32 f, U8 bitCount); + /// Reads a float from 0 to 1 inclusive, using bitCount bits of precision. + F32 readFloat(U8 bitCount); + + /// Writes a signed float from -1 to 1 inclusive, using bitCount bits of precision. + void writeSignedFloat(F32 f, U8 bitCount); + /// Reads a signed float from -1 to 1 inclusive, using bitCount bits of precision. + F32 readSignedFloat(U8 bitCount); + + /// Writes an object's class ID, given its class type and class group. + void writeClassId(U32 classId, U32 classType, U32 classGroup); + /// Reads a class ID for an object, given a class type and class group. Returns -1 if the class type is out of range + U32 readClassId(U32 classType, U32 classGroup); + + /// Writes a normalized vector into the stream, using bitCount bits for the precision of angles phi and theta. + void writeNormalVector(const Point3F &vec, U8 bitCount); + /// Reads a normalized vector from the stream, using bitCount bits for the precision of angles phi and theta. + void readNormalVector(Point3F *vec, U8 bitCount); + + /// Uses the same method as in writeNormalVector to reduce the precision of a normal vector + /// to determine what will be read from the stream. + static Point3F dumbDownNormal(const Point3F& vec, U8 bitCount); + + /// Writes a normalized vector by writing a z value and theta angle. + void writeNormalVector(const Point3F& vec, U8 angleBitCount, U8 zBitCount); + /// Reads a normalized vector by reading a z value and theta angle. + void readNormalVector(Point3F *vec, U8 angleBitCount, U8 zBitCount); + + /// Sets a reference point for subsequent compressed point writing. + void setPointCompression(const Point3F &p); + /// Disables compression of point. + void clearPointCompression(); + /// Writes a point into the stream, to a precision denoted by scale. + void writePointCompressed(const Point3F &p, F32 scale); + /// Reads a compressed point from the stream, to a precision denoted by scale. + void readPointCompressed(Point3F *p, F32 scale); + + /// Writes bitCount bits into the stream from bitPtr. + bool writeBits(U32 bitCount, const void *bitPtr); + /// Reads bitCount bits from the stream into bitPtr. + bool readBits(U32 bitCount, void *bitPtr); + + /// Writes a ByteBuffer into the stream. The ByteBuffer can be no larger than 1024 bytes in size. + bool write(const ByteBuffer *theBuffer); + + /// Reads a ByteBuffer in from the stream. + bool read(ByteBuffer *theBuffer); + + /// Writes a single boolean flag (bit) into the stream, and returns the boolean that was written. + /// + /// This is set up so you can do... + /// + /// @code + /// if(stream->writeFlag(foo == bar)) + /// { + /// ... write other stuff ... + /// } + /// @endcode + bool writeFlag(bool val); + + /// Reads a single bit from the stream. + /// + /// This is set up so you can do... + /// + /// @code + /// if(stream->readFlag()) + /// { + /// ... read other stuff ... + /// } + /// @endcode + bool readFlag(); + + bool write(bool value) { writeFlag(value); return !error; } + bool read(bool *value) { *value = readFlag(); return !error; } + + /// Writes a huffman compressed string into the stream. + void writeString(const char *stringBuf, U8 maxLen=255); + /// Reads a huffman compressed string from the stream. + void readString(char stringBuf[256]); + + /// Writes a string table entry into the stream + void writeStringTableEntry(const StringTableEntry &ste); + + /// Reads a string table entry from the stream + void readStringTableEntry(StringTableEntry *ste); + + /// Writes byte data into the stream. + bool write(const U32 in_numBytes, const void* in_pBuffer); + /// Reads byte data from the stream. + bool read(const U32 in_numBytes, void* out_pBuffer); + + /// @name Various types that the BitStream can read and write... + /// @{ + + /// + DeclareTemplatizedReadWrite(U8); + DeclareTemplatizedReadWrite(S8); + DeclareTemplatizedReadWrite(U16); + DeclareTemplatizedReadWrite(S16); + DeclareTemplatizedReadWrite(U32); + DeclareTemplatizedReadWrite(S32); + DeclareTemplatizedReadWrite(S64); + DeclareTemplatizedReadWrite(U64); + DeclareTemplatizedReadWrite(F32); + DeclareTemplatizedReadWrite(F64); + + /// @} + + /// Sets the bit at position bitCount to the value of set + bool setBit(U32 bitCount, bool set); + /// Tests the value of the bit at position bitCount. + bool testBit(U32 bitCount); + + /// Returns whether the BitStream writing has exceeded the write target size. + bool isFull() { return bitNum > (getBufferSize() << 3); } + /// Returns whether the stream has generated an error condition due to reading or writing past the end of the buffer. + bool isValid() { return !error; } + + /// Hashes the BitStream, writing the hash digest into the end of the buffer, and then encrypts with the given cipher + void hashAndEncrypt(U32 hashDigestSize, U32 encryptStartOffset, SymmetricCipher *theCipher); + + /// Decrypts the BitStream, then checks the hash digest at the end of the buffer to validate the contents + bool decryptAndCheckHash(U32 hashDigestSize, U32 decryptStartOffset, SymmetricCipher *theCipher); +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + + +inline U32 BitStream::getBytePosition() const +{ + return (bitNum + 7) >> 3; +} + +inline U32 BitStream::getBitPosition() const +{ + return bitNum; +} + +inline void BitStream::setBytePosition(const U32 newPosition) +{ + bitNum = newPosition << 3; +} + +inline void BitStream::setBitPosition(const U32 newBitPosition) +{ + bitNum = newBitPosition; +} + +inline void BitStream::advanceBitPosition(const S32 numBits) +{ + setBitPosition(getBitPosition() + numBits); +} + +inline void BitStream::zeroToByteBoundary() +{ + if(bitNum & 0x7) + writeInt(0, 8 - (bitNum & 0x7)); +} + +inline bool BitStream::write(const U32 in_numBytes, const void* in_pBuffer) +{ + return writeBits(in_numBytes << 3, in_pBuffer); +} + +inline bool BitStream::read(const U32 in_numBytes, void* out_pBuffer) +{ + return readBits(in_numBytes << 3, out_pBuffer); +} + +inline bool BitStream::readFlag() +{ + if(bitNum > maxReadBitNum) + { + error = true; + TNLAssert(false, "Out of range read"); + return false; + } + S32 mask = 1 << (bitNum & 0x7); + bool ret = (*(getBuffer() + (bitNum >> 3)) & mask) != 0; + bitNum++; + return ret; +} + +inline void BitStream::writeIntAt(U32 value, U8 bitCount, U32 bitPosition) +{ + U32 curPos = getBitPosition(); + setBitPosition(bitPosition); + writeInt(value, bitCount); + setBitPosition(curPos); +} + +inline void BitStream::writeRangedU32(U32 value, U32 rangeStart, U32 rangeEnd) +{ + TNLAssert(value >= rangeStart && value <= rangeEnd, "Out of bounds value!"); + TNLAssert(rangeEnd >= rangeStart, "error, end of range less than start"); + + U32 rangeSize = rangeEnd - rangeStart + 1; + U32 rangeBits = getNextBinLog2(rangeSize); + + writeInt(S32(value - rangeStart), S32(rangeBits)); +} + +inline U32 BitStream::readRangedU32(U32 rangeStart, U32 rangeEnd) +{ + TNLAssert(rangeEnd >= rangeStart, "error, end of range less than start"); + + U32 rangeSize = rangeEnd - rangeStart + 1; + U32 rangeBits = getNextBinLog2(rangeSize); + + U32 val = U32(readInt(S32(rangeBits))); + return val + rangeStart; +} + +inline void BitStream::writeEnum(U32 enumValue, U32 enumRange) +{ + writeInt(enumValue, getNextBinLog2(enumRange)); +} + +inline U32 BitStream::readEnum(U32 enumRange) +{ + return U32(readInt(getNextBinLog2(enumRange))); +} + +/// PacketStream provides a network interface to the BitStream for easy construction of data packets. +class PacketStream : public BitStream +{ + typedef BitStream Parent; + U8 buffer[MaxPacketDataSize]; ///< internal buffer for packet data, sized to the maximum UDP packet size. +public: + /// Constructor assigns the internal buffer to the BitStream. + PacketStream(U32 targetPacketSize = MaxPacketDataSize) : BitStream(buffer, targetPacketSize, MaxPacketDataSize) {} + /// Sends this packet to the specified address through the specified socket. + NetError sendto(Socket &outgoingSocket, const Address &theAddress); + /// Reads a packet into the stream from the specified socket. + NetError recvfrom(Socket &incomingSocket, Address *recvAddress); +}; + + +}; +#endif //_TNL_BITSTREAM_H_ diff --git a/tnl-1.5.0/tnl/tnl/tnlByteBuffer.h b/tnl-1.5.0/tnl/tnl/tnlByteBuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..8297e18eff9db486130784b9d141e8a3bd01210e --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlByteBuffer.h @@ -0,0 +1,208 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_BYTEBUFFER_H_ +#define _TNL_BYTEBUFFER_H_ + +#ifndef _TNL_H_ +#include "tnl.h" +#endif + +#ifndef _TNL_NETBASE_H_ +#include "tnlNetBase.h" +#endif + +namespace TNL { + +class ByteBuffer : public Object +{ + friend struct MethodArgList; +protected: + /// Pointer to our data buffer. + U8 *mDataPtr; + + /// Length of buffer. + U32 mBufSize; + + /// Do we own the memory we are using? (If so, we should free it.) + bool mOwnsMemory; +public: + // Act 1, Scene 1 + // Enter: enums, constructors, with divers alarums + + // Prologue: + enum { + DefaultBufferSize = 1500, ///< Starting size of the buffer, varlot. + }; + + // Chorus: + + /// Create a ByteBuffer from a chunk of memory. + ByteBuffer(U8 *dataPtr, U32 bufferSize) + { + mBufSize = bufferSize; + mDataPtr = dataPtr; + mOwnsMemory = false; + } + + /// Create a ByteBuffer of the specified size. + ByteBuffer(U32 bufferSize = DefaultBufferSize) + { + mBufSize = bufferSize; + mDataPtr = (U8 *) malloc(bufferSize); + mOwnsMemory = true; + } + + /// Copy constructor! + ByteBuffer(const ByteBuffer &theBuffer) + { + mBufSize = theBuffer.mBufSize; + mDataPtr = theBuffer.mDataPtr; + mOwnsMemory = false; + } + + ~ByteBuffer() + { + if(mOwnsMemory) + free(mDataPtr); + } + + /// Set the ByteBuffer to point to a new chunk of memory. + void setBuffer(U8 *dataPtr, U32 bufferSize) + { + if(mOwnsMemory) + { + mOwnsMemory = false; + free(mDataPtr); + } + mDataPtr = dataPtr; + mBufSize = bufferSize; + } + + /// Set the ByteBuffer to point to a new chunk of memory, indicating whether + /// it should own the chunk or not. + void setBuffer(U8 *dataPtr, U32 bufferSize, bool newOwnsMemory) + { + setBuffer(dataPtr, bufferSize); + mOwnsMemory = newOwnsMemory; + } + + /// Attempts to resize the buffer. + /// + /// @returns True if it owns its own memory, false otherwise. + bool resize(U32 newBufferSize) + { + if(mBufSize >= newBufferSize) + mBufSize = newBufferSize; + else if(mOwnsMemory) + { + mBufSize = newBufferSize; + mDataPtr = (U8 *) realloc(mDataPtr, newBufferSize); + return true; + } + return false; + } + + /// Appends the specified buffer to the end of the byte buffer. + /// returns false if it does not own its own memory. + bool appendBuffer(const U8 *dataBuffer, U32 bufferSize) + { + U32 start = mBufSize; + if(!resize(mBufSize + bufferSize)) + return false; + memcpy(mDataPtr + start, dataBuffer, bufferSize); + return true; + } + + /// Appends the specified ByteBuffer to the end of this byte buffer. + /// returns fals if it does not own its own memory. + bool appendBuffer(const ByteBuffer &theBuffer) + { + return appendBuffer(theBuffer.getBuffer(), theBuffer.getBufferSize()); + } + + /// Copies the current buffer into a newly allocated buffer that the ByteBuffer owns. + void takeOwnership() + { + if(!mOwnsMemory) + { + U8 *memPtr = (U8 *) malloc(mBufSize); + memcpy(memPtr, mDataPtr, mBufSize); + mDataPtr = memPtr; + mOwnsMemory = true; + } + } + + /// Does this ByteBuffer own its own memory? + bool ownsMemory() + { + return mOwnsMemory; + } + + U32 getBufferSize() const + { + return mBufSize; + } + + U8 *getBuffer() + { + return mDataPtr; + } + + const U8 *getBuffer() const + { + return mDataPtr; + } + + /// Clear the buffer. + void clear() + { + memset(mDataPtr, 0, mBufSize); + } + + /// Encode the buffer to base 64, returning the encoded buffer. + RefPtr encodeBase64() const; + /// Decode the buffer from base 64, returning the decoded buffer. + RefPtr decodeBase64() const; + + /// Computes an MD5 hash and returns it in a ByteBuffer + RefPtr computeMD5Hash(U32 len = 0) const; + + /// Converts to ascii-hex, returning the encoded buffer. + RefPtr encodeBase16() const; + /// Decodes the buffer from base 16, returning the decoded buffer. + RefPtr decodeBase16() const; + + /// Returns a 32 bit CRC for the buffer. + U32 calculateCRC(U32 start = 0, U32 end = 0xFFFFFFFF, U32 crcVal = 0xFFFFFFFF) const; +}; + +typedef RefPtr ByteBufferPtr; +typedef const ByteBuffer &ByteBufferRef; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlCertificate.h b/tnl-1.5.0/tnl/tnl/tnlCertificate.h new file mode 100644 index 0000000000000000000000000000000000000000..da8eed07de19428b802c52a69781699d71dc43cb --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlCertificate.h @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_CERTIFICATE_H_ +#define _TNL_CERTIFICATE_H_ + +#ifndef _TNL_BYTEBUFFER_H_ +#include "tnlByteBuffer.h" +#endif + +#ifndef _TNL_ASYMMETRICKEY_H_ +#include "tnlAsymmetricKey.h" +#endif + +namespace TNL +{ + +/// The Certificate class manages a digitally signed certificate. +/// Certificates consist of an application-defined payload, a public +/// key, and a signature. It is up to the application to determine +/// from the payload what, if any, certificate authority (CA) signed +/// the certificate. The validate() method can be used to check the +/// certificate's authenticity against the known public key of the +/// signing Certificate Authority. +/// +/// The payload could include such items as: +/// - The valid date range for the certificate +/// - The domain of the certificate holder +/// - The identifying name of the Certificate Authority +/// - A player's name and user id for a multiplayer game +/// +/// +class Certificate : public ByteBuffer +{ +protected: + RefPtr mPublicKey; ///< The public key for the holder of this certificate + ByteBufferPtr mPayload; ///< The certificate payload, including the identity of the holder and the Certificate Authority + ByteBufferPtr mSignature; ///< The digital signature of this certificate by the signatory + bool mIsValid; ///< flag to signify whether this certificate has a valid form + U32 mSignatureByteSize; ///< Number of bytes of the ByteBuffer signed by the CA +public: + enum { + MaxPayloadSize = 512, + }; + /// Certificate constructor + Certificate(U8 *dataPtr, U32 dataSize) : ByteBuffer(dataPtr, dataSize) + { + mSignatureByteSize = 0; + mIsValid = false; + takeOwnership(); + parse(); + } + + Certificate(const ByteBuffer &buffer) : ByteBuffer(buffer) + { + mSignatureByteSize = 0; + mIsValid = false; + takeOwnership(); + parse(); + } + Certificate(BitStream *stream) + { + mSignatureByteSize = 0; + mIsValid = false; + stream->read(this); + parse(); + } + Certificate(const ByteBuffer &payload, RefPtr publicKey, RefPtr theCAPrivateKey); + + void parse(); ///< Parses this certificate into the payload, public key, identiy, certificate authority and signature + + /// returns the validity of the certificate's formation + bool isValid() + { + return mIsValid; + } + /// returns true if this certificate was signed by the private key corresponding to the passed public key. + bool validate(RefPtr signatoryPublicKey); + + /// Returns the public key from the certificate + RefPtr getPublicKey() { return mPublicKey; } + + /// Returns the certificate payload + ByteBufferPtr getPayload() { return mPayload; } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlClientPuzzle.h b/tnl-1.5.0/tnl/tnl/tnlClientPuzzle.h new file mode 100644 index 0000000000000000000000000000000000000000..45e2fc747abf5bc8a93fe0a9d6cd8e94eca68744 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlClientPuzzle.h @@ -0,0 +1,144 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_CLIENTPUZZLE_H_ +#define _TNL_CLIENTPUZZLE_H_ + +#include "tnlDataChunker.h" +#include "tnlNonce.h" + +// JMQ: work around X.h header file +#if defined(TNL_OS_LINUX) && defined(Success) +#undef Success +#endif + +namespace TNL { + +/// The ClientPuzzleManager class issues, solves and validates client +/// puzzles for connection authentication. +class ClientPuzzleManager +{ +public: +private: + /// NonceTable manages the list of client nonces for which clients + /// have constructed valid puzzle solutions for the current server + /// nonce. There are 2 nonce tables in the ClientPuzzleManager - + /// one for the current nonce and one for the previous nonce. + + class NonceTable { + private: + struct Entry { + Nonce mNonce; + Entry *mHashNext; + }; + enum { + MinHashTableSize = 127, + MaxHashTableSize = 387, + }; + + Entry **mHashTable; + U32 mHashTableSize; + DataChunker mChunker; + + public: + /// NonceTable constructor + NonceTable() { reset(); } + + /// Resets and clears the nonce table + void reset(); + + /// checks if the given nonce is already in the table and adds it + /// if it is not. Returns true if the nonce was not in the table + /// when the function was called. + bool checkAdd(Nonce &theNonce); + }; + + U32 mCurrentDifficulty; + U32 mLastUpdateTime; + U32 mLastTickTime; + + Nonce mCurrentNonce; + Nonce mLastNonce; + + NonceTable *mCurrentNonceTable; + NonceTable *mLastNonceTable; + static bool checkOneSolution(U32 solution, Nonce &clientNonce, Nonce &serverNonce, U32 puzzleDifficulty, U32 clientIdentity); +public: + ClientPuzzleManager(); + ~ClientPuzzleManager(); + + /// Checks to see if a new nonce needs to be created, and if so + /// generates one and tosses out the current list of accepted nonces + void tick(U32 currentTime); + + /// Error codes that can be returned by checkSolution + enum ErrorCode { + Success, + InvalidSolution, + InvalidServerNonce, + InvalidClientNonce, + InvalidPuzzleDifficulty, + ErrorCodeCount, + }; + + /// Difficulty levels of puzzles + enum { + PuzzleRefreshTime = 30000, ///< Refresh the server puzzle every 30 seconds + InitialPuzzleDifficulty = 17, ///< Initial puzzle difficulty is set so clients do approx 2-3x the shared secret + /// generation of the server + MaxPuzzleDifficulty = 26, ///< Maximum puzzle difficulty is approx 1 minute to solve on ~2004 hardware. + MaxSolutionComputeFragment = 30, ///< Number of milliseconds spent computing solution per call to solvePuzzle. + SolutionFragmentIterations = 50000, ///< Number of attempts to spend on the client puzzle per call to solvePuzzle. + }; + + /// Checks a puzzle solution submitted by a client to see if it is a valid solution for the current or previous puzzle nonces + ErrorCode checkSolution(U32 solution, Nonce &clientNonce, Nonce &serverNonce, U32 puzzleDifficulty, U32 clientIdentity); + + /// Computes a puzzle solution value for the given puzzle difficulty and server nonce. If the execution time of this function + /// exceeds MaxSolutionComputeFragment milliseconds, it will return the current trail solution in the solution variable and a + /// return value of false. + /// + /// @note Although the behavior of this function can be tweaked using MaxSolutionComputeFragment and + /// SolutionFragmentIterations, it's important to bias these settings in favor of rapid puzzle + /// completion. A client puzzle is only valid for two times PuzzleRefreshTime, so for about a + /// minute, maximum. Most of the time the puzzle can be solved in only a few hundred + /// milliseconds. It's better to solve the puzzle fast than to let it drag out, (ie, it's better to + /// let your application hitch for a moment whilst calculating than to make the user endure many + /// seconds of lag) so reducing the timeout or iterations should be done only if you know what + /// you're doing. + /// + static bool solvePuzzle(U32 *solution, Nonce &clientNonce, Nonce &serverNonce, U32 puzzleDifficulty, U32 clientIdentity); + + /// Returns the current server nonce + Nonce getCurrentNonce() { return mCurrentNonce; } + + /// Returns the current client puzzle difficulty + U32 getCurrentDifficulty() { return mCurrentDifficulty; } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlConnectionStringTable.h b/tnl-1.5.0/tnl/tnl/tnlConnectionStringTable.h new file mode 100644 index 0000000000000000000000000000000000000000..e47a5be8c2ddaa8e920d2669b013102c27747adb --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlConnectionStringTable.h @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_CONNECTIONSTRINGTABLE_H_ +#define _TNL_CONNECTIONSTRINGTABLE_H_ + +#ifndef _TNL_NETSTRINGTABLE_H_ +#include "tnlNetStringTable.h" +#endif + +namespace TNL { + +class NetConnection; +class BitStream; + +/// ConnectionStringTable is a helper class to EventConnection for reducing duplicated string data sends +class ConnectionStringTable +{ +public: + enum StringTableConstants{ + EntryCount = 1024, + EntryBitSize = 10, + }; + + struct Entry; + + struct PacketEntry { + PacketEntry *nextInPacket; ///< The next string table entry updated in the packet this is linked in. + Entry *stringTableEntry; ///< The ConnectionStringTable::Entry this refers to + StringTableEntry string; ///< The StringTableEntry that was set in that string + }; + +public: + struct PacketList { + PacketEntry *stringHead; ///< The head of the linked list of strings sent in this packet. + PacketEntry *stringTail; ///< The tail of the linked list of strings sent in this packet. + + PacketList() { stringHead = stringTail = NULL; } + }; + + /// An entry in the EventConnection's string table + struct Entry { + StringTableEntry string; ///< Global string table entry of this string + ///< will be 0 if this string is unused. + U32 index; ///< Index of this entry. + Entry *nextHash; ///< The next hash entry for this id. + Entry *nextLink; ///< The next entry in the LRU list. + Entry *prevLink; ///< The prev entry in the LRU list. + + /// Does the other side now have this string? + bool receiveConfirmed; + }; + +private: + Entry mEntryTable[EntryCount]; + Entry *mHashTable[EntryCount]; + StringTableEntry mRemoteStringTable[EntryCount]; + Entry mLRUHead, mLRUTail; + + NetConnection *mParent; + + /// Pushes an entry to the back of the LRU list. + inline void pushBack(Entry *entry) + { + entry->prevLink->nextLink = entry->nextLink; + entry->nextLink->prevLink = entry->prevLink; + entry->nextLink = &mLRUTail; + entry->prevLink = mLRUTail.prevLink; + entry->nextLink->prevLink = entry; + entry->prevLink->nextLink = entry; + } +public: + ConnectionStringTable(NetConnection *parent); + + void writeStringTableEntry(BitStream *stream, StringTableEntryRef string); + StringTableEntry readStringTableEntry(BitStream *stream); + + void packetReceived(PacketList *note); + void packetDropped(PacketList *note); +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/tnl/tnlDataChunker.h b/tnl-1.5.0/tnl/tnl/tnlDataChunker.h new file mode 100644 index 0000000000000000000000000000000000000000..95f2b4788f71b48666c151db24448f56ad936d02 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlDataChunker.h @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_DATACHUNKER_H_ +#define _TNL_DATACHUNKER_H_ + + +//---------------------------------------------------------------------------- + +namespace TNL { + +//---------------------------------------------------------------------------- +/// Implements a chunked data allocater. +/// +/// Calling new/malloc all the time is a time consuming operation. Therefore, +/// we provide the DataChunker, which allocates memory in blocks of +/// chunkSize (by default 16k, see ChunkSize, though it can be set in +/// the constructor), then doles it out as requested, in chunks of up to +/// chunkSize in size. +/// +/// It will assert if you try to get more than ChunkSize bytes at a time, +/// and it deals with the logic of allocating new blocks and giving out +/// word-aligned chunks. +/// +/// Note that new/free/realloc WILL NOT WORK on memory gotten from the +/// DataChunker. This also only grows (you can call freeBlocks to deallocate +/// and reset things). +class DataChunker +{ + public: + enum { + ChunkSize = 16376 ///< Default size of each DataBlock page in the DataChunker + }; + + private: + /// DataBlock representation for each page of the DataChunker + struct DataBlock + { + DataBlock *next; ///< linked list pointer to the next DataBlock for this chunker + U8 *data; ///< allocated pointer for the base of this page + S32 curIndex; ///< current allocation point within this DataBlock + DataBlock(S32 size); + ~DataBlock(); + }; + DataBlock *curBlock; ///< current page we're allocating data from. If the + ///< data size request is greater than the memory space currently + ///< available in the current page, a new page will be allocated. + S32 chunkSize; ///< The size allocated for each page in the DataChunker + public: + void *alloc(S32 size); ///< allocate a pointer to memory of size bytes from the DataChunker + void freeBlocks(); ///< free all pages currently allocated in the DataChunker + + DataChunker(S32 size=ChunkSize); ///< Construct a DataChunker with a page size of size bytes. + ~DataChunker(); + + /// Swaps the memory allocated in one data chunker for another. This can be used to implement + /// packing of memory stored in a DataChunker. + void swap(DataChunker &d) + { + DataBlock *temp = d.curBlock; + d.curBlock = curBlock; + curBlock = temp; + } +}; + +//---------------------------------------------------------------------------- + +/// Templatized data chunker class with proper construction and destruction of its elements. +/// +/// DataChunker just allocates space. This subclass actually constructs/destructs the +/// elements. This class is appropriate for more complex classes. +template +class ClassChunker: private DataChunker +{ + S32 numAllocated; ///< number of elements currently allocated through this ClassChunker + S32 elementSize; ///< the size of each element, or the size of a pointer, whichever is greater + T *freeListHead; ///< a pointer to a linked list of freed elements for reuse +public: + ClassChunker(S32 size = DataChunker::ChunkSize) : DataChunker(size) + { + numAllocated = 0; + elementSize = getMax(U32(sizeof(T)), U32(sizeof(T *))); + freeListHead = NULL; + } + /// Allocates and properly constructs in place a new element. + T *alloc() + { + numAllocated++; + if(freeListHead == NULL) + return constructInPlace(reinterpret_cast(DataChunker::alloc(elementSize))); + T* ret = freeListHead; + freeListHead = *(reinterpret_cast(freeListHead)); + return constructInPlace(ret); + } + + /// Properly destructs and frees an element allocated with the alloc method. + void free(T* elem) + { + destructInPlace(elem); + numAllocated--; + *(reinterpret_cast(elem)) = freeListHead; + freeListHead = elem; + } + + void freeBlocks() + { + DataChunker::freeBlocks(); + } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlEndian.h b/tnl-1.5.0/tnl/tnl/tnlEndian.h new file mode 100644 index 0000000000000000000000000000000000000000..9b9e77609ce44d917841f82148893674363f4c39 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlEndian.h @@ -0,0 +1,140 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_ENDIAN_H_ +#define _TNL_ENDIAN_H_ + +namespace TNL { + +inline U8 endianSwap(const U8 in_swap) +{ + return in_swap; +} + +inline S8 endianSwap(const S8 in_swap) +{ + return in_swap; +} + +/** + Convert the byte ordering on the U16 to and from big/little endian format. + @param in_swap Any U16 + @returns swapped U16. + */ + +inline U16 endianSwap(const U16 in_swap) +{ + return U16(((in_swap >> 8) & 0x00ff) | + ((in_swap << 8) & 0xff00)); +} + +inline S16 endianSwap(const S16 in_swap) +{ + return S16(endianSwap(U16(in_swap))); +} + +/** + Convert the byte ordering on the U32 to and from big/little endian format. + @param in_swap Any U32 + @returns swapped U32. + */ +inline U32 endianSwap(const U32 in_swap) +{ + return U32(((in_swap >> 24) & 0x000000ff) | + ((in_swap >> 8) & 0x0000ff00) | + ((in_swap << 8) & 0x00ff0000) | + ((in_swap << 24) & 0xff000000)); +} + +inline S32 endianSwap(const S32 in_swap) +{ + return S32(endianSwap(U32(in_swap))); +} + +inline U64 endianSwap(const U64 in_swap) +{ + U32 *inp = (U32 *) &in_swap; + U64 ret; + U32 *outp = (U32 *) &ret; + outp[0] = endianSwap(inp[1]); + outp[1] = endianSwap(inp[0]); + return ret; +} + +inline S64 endianSwap(const S64 in_swap) +{ + return S64(endianSwap(U64(in_swap))); +} + +inline F32 endianSwap(const F32 in_swap) +{ + U32 result = endianSwap(* ((U32 *) &in_swap) ); + return * ((F32 *) &result); +} + +inline F64 endianSwap(const F64 in_swap) +{ + U64 result = endianSwap(* ((U64 *) &in_swap) ); + return * ((F64 *) &result); +} + +//------------------------------------------------------------------------------ +// Endian conversions +#ifdef TNL_LITTLE_ENDIAN + +#define TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(type) \ + inline type convertHostToLEndian(type i) { return i; } \ + inline type convertLEndianToHost(type i) { return i; } \ + inline type convertHostToBEndian(type i) { return endianSwap(i); } \ + inline type convertBEndianToHost(type i) { return endianSwap(i); } + +#elif defined(TNL_BIG_ENDIAN) + +#define TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(type) \ + inline type convertHostToLEndian(type i) { return endianSwap(i); } \ + inline type convertLEndianToHost(type i) { return endianSwap(i); } \ + inline type convertHostToBEndian(type i) { return i; } \ + inline type convertBEndianToHost(type i) { return i; } + +#else +#error "Endian define not set!" +#endif + + +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(U8) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(S8) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(U16) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(S16) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(U32) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(S32) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(U64) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(S64) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(F32) +TNL_DECLARE_TEMPLATIZED_ENDIAN_CONV(F64) + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlEventConnection.h b/tnl-1.5.0/tnl/tnl/tnlEventConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..7442ec21f106d365e4f13b31c2df1f4f68b66923 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlEventConnection.h @@ -0,0 +1,158 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_EVENTCONNECTION_H_ +#define _TNL_EVENTCONNECTION_H_ + +#ifndef _TNL_NETCONNECTION_H_ +#include "tnlNetConnection.h" +#endif + +#ifndef _TNL_NETEVENT_H_ +#include "tnlNetEvent.h" +#endif + +#ifndef _TNL_DATACHUNKER_H_ +#include "tnlDataChunker.h" +#endif + +namespace TNL { + +/// EventConnection is a NetConnection subclass used for sending guaranteed and unguaranteed +/// event packages across a connection. +/// +/// The EventConnection is responsible for transmitting NetEvents over the wire. +/// It deals with ensuring that the various types of NetEvents are delivered appropriately, +/// and with notifying the event of its delivery status. +/// +/// The EventConnection is mainly accessed via postNetEvent(), which accepts NetEvents. +/// +/// @see NetEvent for a more thorough explanation of how to use events. + +class EventConnection : public NetConnection +{ + typedef NetConnection Parent; + + /// EventNote associates a single event posted to a connection with a sequence number for ordered processing + struct EventNote + { + RefPtr mEvent; ///< A safe reference to the event + S32 mSeqCount; ///< the sequence number of this event for ordering + EventNote *mNextEvent; ///< The next event either on the connection or on the PacketNotify + }; +public: + /// EventPacketNotify tracks all the events sent with a single packet + struct EventPacketNotify : public NetConnection::PacketNotify + { + EventNote *eventList; ///< linked list of events sent with this packet + EventPacketNotify() { eventList = NULL; } + }; + + EventConnection(); + ~EventConnection(); +protected: + enum DebugConstants + { + DebugChecksum = 0xF00DBAAD, + BitStreamPosBitSize = 16, + }; + + /// Allocates a PacketNotify for this connection + PacketNotify *allocNotify() { return new EventPacketNotify; } + + /// Override processing to requeue any guaranteed events in the packet that was dropped + void packetDropped(PacketNotify *notify); + + /// Override processing to notify for delivery and dereference any events sent in the packet + void packetReceived(PacketNotify *notify); + + /// Writes pending events into the packet, and attaches them to the PacketNotify + void writePacket(BitStream *bstream, PacketNotify *notify); + + /// Reads events from the stream, and queues them for processing + void readPacket(BitStream *bstream); + + /// Returns true if there are events pending that should be sent across the wire + virtual bool isDataToTransmit(); + + /// Dispatches an event + void processEvent(NetEvent *theEvent); + + +//---------------------------------------------------------------- +// event manager functions/code: +//---------------------------------------------------------------- + +private: + static ClassChunker mEventNoteChunker; ///< Quick memory allocator for net event notes + + EventNote *mSendEventQueueHead; ///< Head of the list of events to be sent to the remote host + EventNote *mSendEventQueueTail; ///< Tail of the list of events to be sent to the remote host. New events are tagged on to the end of this list + EventNote *mUnorderedSendEventQueueHead; ///< Head of the list of events sent without ordering information + EventNote *mUnorderedSendEventQueueTail; ///< Tail of the list of events sent without ordering information + EventNote *mWaitSeqEvents; ///< List of ordered events on the receiving host that are waiting on previous sequenced events to arrive. + EventNote *mNotifyEventList; ///< Ordered list of events on the sending host that are waiting for receipt of processing on the client. + + S32 mNextSendEventSeq; ///< The next sequence number for an ordered event sent through this connection + S32 mNextRecvEventSeq; ///< The next receive event sequence to process + S32 mLastAckedEventSeq; ///< The last event the remote host is known to have processed + + enum { + InvalidSendEventSeq = -1, + FirstValidSendEventSeq = 0 + }; + +protected: + U32 mEventClassCount; ///< Number of NetEvent classes supported by this connection + U32 mEventClassBitSize; ///< Bit field width of NetEvent class count. + U32 mEventClassVersion; ///< The highest version number of events on this connection. + + /// Writes the NetEvent class count into the stream, so that the remote + /// host can negotiate a class count for the connection + void writeConnectRequest(BitStream *stream); + + /// Reads the NetEvent class count max that the remote host is requesting. + /// If this host has MORE NetEvent classes declared, the mEventClassCount + /// is set to the requested count, and is verified to lie on a boundary between versions. + bool readConnectRequest(BitStream *stream, const char **errorString); + + /// Writes the negotiated NetEvent class count into the stream. + void writeConnectAccept(BitStream *stream); + + /// Reads the negotiated NetEvent class count from the stream and validates that it is on + /// a boundary between versions. + bool readConnectAccept(BitStream *stream, const char **errorString); +public: + /// returns the highest event version number supported on this connection. + U32 getEventClassVersion() { return mEventClassVersion; } + + /// Posts a NetEvent for processing on the remote host + bool postNetEvent(NetEvent *event); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlGhostConnection.h b/tnl-1.5.0/tnl/tnl/tnlGhostConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..41318a222a22054b3d2aad8504c22a15e0ef16a9 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlGhostConnection.h @@ -0,0 +1,331 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_GHOSTCONNECTION_H_ +#define _TNL_GHOSTCONNECTION_H_ + +#ifndef _TNL_EVENTCONNECTION_H_ +#include "tnlEventConnection.h" +#endif + +#ifndef _TNL_RPC_H_ +#include "tnlRPC.h" +#endif + +namespace TNL { + +struct GhostInfo; + +/// GhostConnection is a subclass of EventConnection that manages the transmission +/// (ghosting) and updating of NetObjects over a connection. +/// +/// The GhostConnection is responsible for doing scoping calculations (on the server side) +/// and transmitting most-recent ghost information to the client. +/// +/// Ghosting is the most complex, and most powerful, part of TNL's capabilities. It +/// allows the information sent to clients to be very precisely matched to what they need, so that +/// no excess bandwidth is wasted. Each GhostConnection has a scope object that is responsible +/// for determining what other NetObject instances are relevant to that connection's client. Each time +/// GhostConnection sends a packet, NetObject::performScopeQuery() is called on the scope object, which +/// calls GhostConnection::objectInScope() for each relevant object. +/// +/// Each object that is in scope, and in need of update (based on its maskbits) is given a priority +/// ranking by calling that object's getUpdatePriority() method. The packet is then filled with +/// updates, ordered by priority. This way the most important updates get through first, with less +/// important updates being sent as space is available. +/// +/// There is a cap on the maximum number of ghosts that can be active through a GhostConnection at once. +/// The enum GhostIdBitSize (defaults to 10) determines how many bits will be used to transmit the ID for +/// each ghost, so the maximum number is 2^GhostIdBitSize or 1024. This can be easily raised; see the +/// GhostConstants enum. +/// +/// Each object ghosted is assigned a ghost ID; the client is only aware of the ghost ID. This acts +/// to enhance simulation security, as it becomes difficult to map objects from one connection to another, +/// or to reliably identify objects from ID alone. IDs are also reassigned based on need, making it hard +/// to track objects that have fallen out of scope (as any object which the player shouldn't see would). +/// +/// resolveGhost() is used on the client side, and resolveObjectFromGhostIndex() on the server side, to +/// convert ghost IDs to object references. +/// +/// @see NetObject for more information on network object functionality. +class GhostConnection : public EventConnection +{ + typedef EventConnection Parent; + friend class ConnectionMessageEvent; +public: + /// GhostRef tracks an update sent in one packet for the ghost of one NetObject. + /// + /// When we are notified that a pack is sent/lost, this is used to determine what + /// updates need to be resent and so forth. + struct GhostRef + { + U32 mask; ///< The mask of bits that were updated in this packet + U32 ghostInfoFlags; ///< GhostInfo::Flags bitset, determes if the ghost is in a + /// special processing mode (created/deleted) + GhostInfo *ghost; ///< The ghost information for the object on the connection that sent + /// the packet this GhostRef is attached to + GhostRef *nextRef; ///< The next ghost updated in this packet + GhostRef *updateChain; ///< A pointer to the GhostRef on the least previous packet that + /// updated this ghost, or NULL, if no prior packet updated this ghost + }; + + /// Notify structure attached to each packet with information about the ghost updates in the packet + struct GhostPacketNotify : public EventConnection::EventPacketNotify + { + GhostRef *ghostList; ///< list of ghosts updated in this packet + GhostPacketNotify() { ghostList = NULL; } + }; + +protected: + + /// Override of EventConnection's allocNotify, to use the GhostPacketNotify structure. + PacketNotify *allocNotify() { return new GhostPacketNotify; } + + /// Override to properly update the GhostInfo's for all ghosts that had upates in the dropped packet. + void packetDropped(PacketNotify *notify); + + /// Override to update flags associated with the ghosts updated in this packet. + void packetReceived(PacketNotify *notify); + + /// Performs the scoping query in order to determine if there is data to send from this GhostConnection. + void prepareWritePacket(); + + /// Override to write ghost updates into each packet. + void writePacket(BitStream *bstream, PacketNotify *notify); + + /// Override to read updated ghost information from the packet stream. + void readPacket(BitStream *bstream); + + /// Override to check if there is data pending on this GhostConnection. + bool isDataToTransmit(); + +//---------------------------------------------------------------- +// ghost manager functions/code: +//---------------------------------------------------------------- + +protected: + GhostInfo **mGhostArray; ///< Array of GhostInfo structures used to track all the objects ghosted by this side of the connection. + /// + /// For efficiency, ghosts are stored in three segments - the first segment contains GhostInfos + /// that have pending updates, the second ghostrefs that need no updating, and last, free + /// GhostInfos that may be reused. + + S32 mGhostZeroUpdateIndex; ///< Index in mGhostArray of first ghost with 0 update mask (ie, with no updates). + S32 mGhostFreeIndex; ///< index in mGhostArray of first free ghost. + + bool mGhosting; ///< Am I currently ghosting objects over? + bool mScoping; ///< Am I currently allowing objects to be scoped? + U32 mGhostingSequence; ///< Sequence number describing this ghosting session. + + NetObject **mLocalGhosts; ///< Local ghost array for remote objects, or NULL if mGhostTo is false. + + GhostInfo *mGhostRefs; ///< Allocated array of ghostInfos, or NULL if mGhostFrom is false. + GhostInfo **mGhostLookupTable; ///< Table indexed by object id->GhostInfo, or NULL if mGhostFrom is false. + + SafePtr mScopeObject; ///< The local NetObject that performs scoping queries to determine what + /// objects to ghost to the client. + + void clearGhostInfo(); + void deleteLocalGhosts(); + bool validateGhostArray(); + + void freeGhostInfo(GhostInfo *); + + /// Notifies subclasses that the remote host is about to start ghosting objects. + virtual void onStartGhosting(); + + /// Notifies subclasses that the server has stopped ghosting objects on this connection. + virtual void onEndGhosting(); + +public: + GhostConnection(); + ~GhostConnection(); + + void setGhostFrom(bool ghostFrom); ///< Sets whether ghosts transmit from this side of the connection. + void setGhostTo(bool ghostTo); ///< Sets whether ghosts are allowed from the other side of the connection. + + bool doesGhostFrom() { return mGhostArray != NULL; } ///< Does this GhostConnection ghost NetObjects to the remote host? + bool doesGhostTo() { return mLocalGhosts != NULL; } ///< Does this GhostConnection receive ghosts from the remote host? + + /// Returns the sequence number of this ghosting session. + U32 getGhostingSequence() { return mGhostingSequence; } + + enum GhostConstants { + GhostIdBitSize = 10, ///< Size, in bits, of the integer used to transmit ghost IDs + GhostLookupTableSizeShift = 10, ///< The size of the hash table used to lookup source NetObjects by remote ghost ID is 1 << GhostLookupTableSizeShift. + + MaxGhostCount = (1 << GhostIdBitSize), ///< Maximum number of ghosts that can be active at any one time. + GhostCountBitSize = GhostIdBitSize + 1, ///< Size of the field needed to transmit the total number of ghosts. + + GhostLookupTableSize = (1 << GhostLookupTableSizeShift), ///< Size of the hash table used to lookup source NetObjects by remote ghost ID. + GhostLookupTableMask = (GhostLookupTableSize - 1), ///< Hashing mask for table lookups. + + }; + + void setScopeObject(NetObject *object); ///< Sets the object that is queried at each packet to determine + /// what NetObjects should be ghosted on this connection. + NetObject *getScopeObject() { return (NetObject*)mScopeObject; }; ///< Returns the current scope object. + + void objectInScope(NetObject *object); ///< Indicate that the specified object is currently in scope. + /// + /// Method called by the scope object to indicate that the specified object is in scope. + void objectLocalScopeAlways(NetObject *object); ///< The specified object should be always in scope for this connection. + void objectLocalClearAlways(NetObject *object); ///< The specified object should not be always in scope for this connection. + + NetObject *resolveGhost(S32 id); ///< Given an object's ghost id, returns the ghost of the object (on the client side). + NetObject *resolveGhostParent(S32 id); ///< Given an object's ghost id, returns the source object (on the server side). + void ghostPushNonZero(GhostInfo *gi); ///< Moves the specified GhostInfo into the range of the ghost array for non-zero updateMasks. + void ghostPushToZero(GhostInfo *gi); ///< Moves the specified GhostInfo into the range of the ghost array for zero updateMasks. + void ghostPushZeroToFree(GhostInfo *gi); ///< Moves the specified GhostInfo into the range of the ghost array for free (unused) GhostInfos. + inline void ghostPushFreeToZero(GhostInfo *info); ///< Moves the specified GhostInfo from the free area into the range of the ghost array for zero updateMasks. + + S32 getGhostIndex(NetObject *object); ///< Returns the client-side ghostIndex of the specified server object, or -1 if the object is not available on the client. + + /// Returns true if the object is available on the client. + bool isGhostAvailable(NetObject *object) { return getGhostIndex(object) != -1; } + + void resetGhosting(); ///< Stops ghosting objects from this GhostConnection to the remote host, which causes all ghosts to be destroyed on the client. + void activateGhosting(); ///< Begins ghosting objects from this GhostConnection to the remote host, starting with the GhostAlways objects. + bool isGhosting() { return mGhosting; } ///< Returns true if this connection is currently ghosting objects to the remote host. + + void detachObject(GhostInfo *info); ///< Notifies the GhostConnection that the specified GhostInfo should no longer be scoped to the client. + + /// RPC from server to client before the GhostAlwaysObjects are transmitted + TNL_DECLARE_RPC(rpcStartGhosting, (U32 sequence)); + + /// RPC from client to server sent when the client receives the rpcGhostAlwaysActivated + TNL_DECLARE_RPC(rpcReadyForNormalGhosts, (U32 sequence)); + + /// RPC from server to client sent to notify that ghosting should stop + TNL_DECLARE_RPC(rpcEndGhosting, ()); +}; + +//---------------------------------------------------------------------------- + +/// Each GhostInfo structure tracks the state of a single NetObject's ghost for a single GhostConnection. +struct GhostInfo +{ + // NOTE: + // if the size of this structure changes, the + // NetConnection::getGhostIndex function MUST be changed + // to reflect. + + NetObject *obj; ///< The real object on the server. + U32 updateMask; ///< The current out-of-date state mask for the object for this connection. + GhostConnection::GhostRef *lastUpdateChain; ///< The GhostRef for this object in the last packet it was updated in, + /// or NULL if that last packet has been notified yet. + GhostInfo *nextObjectRef; ///< Next GhostInfo for this object in the doubly linked list of GhostInfos across + /// all connections that scope this object + GhostInfo *prevObjectRef; ///< Previous GhostInfo for this object in the doubly linked list of GhostInfos across + /// all connections that scope this object + + GhostConnection *connection; ///< The connection that owns this GhostInfo + GhostInfo *nextLookupInfo; ///< Next GhostInfo in the hash table for NetObject*->GhostInfo* + U32 updateSkipCount; ///< How many times this object has NOT been updated in writePacket + + U32 flags; ///< Current flag status of this object for this connection. + F32 priority; ///< Priority for the update of this object, computed after the scoping process has run. + U32 index; ///< Fixed index of the object in the mGhostRefs array for the connection, and the ghostId of the object on the client. + S32 arrayIndex; ///< Position of the object in the mGhostArray for the connection, which changes as the object is pushed to zero, non-zero and free. + + enum Flags + { + InScope = BIT(0), ///< This GhostInfo's NetObject is currently in scope for this connection. + ScopeLocalAlways = BIT(1), ///< This GhostInfo's NetObject is always in scope for this connection. + NotYetGhosted = BIT(2), ///< This GhostInfo's NetObject has not been sent to or constructed on the remote host. + Ghosting = BIT(3), ///< This GhostInfo's NetObject has been sent to the client, but the packet it was sent in hasn't been acked yet. + KillGhost = BIT(4), ///< The ghost of this GhostInfo's NetObject should be destroyed ASAP. + KillingGhost = BIT(5), ///< The ghost of this GhostInfo's NetObject is in the process of being destroyed. + + /// Flag mask - if any of these are set, the object is not yet available for ghost ID lookup. + NotAvailable = (NotYetGhosted | Ghosting | KillGhost | KillingGhost), + }; +}; + + +inline void GhostConnection::ghostPushNonZero(GhostInfo *info) +{ + TNLAssert(info->arrayIndex >= mGhostZeroUpdateIndex && info->arrayIndex < mGhostFreeIndex, "Out of range arrayIndex."); + TNLAssert(mGhostArray[info->arrayIndex] == info, "Invalid array object."); + if(info->arrayIndex != mGhostZeroUpdateIndex) + { + mGhostArray[mGhostZeroUpdateIndex]->arrayIndex = info->arrayIndex; + mGhostArray[info->arrayIndex] = mGhostArray[mGhostZeroUpdateIndex]; + mGhostArray[mGhostZeroUpdateIndex] = info; + info->arrayIndex = mGhostZeroUpdateIndex; + } + mGhostZeroUpdateIndex++; + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +inline void GhostConnection::ghostPushToZero(GhostInfo *info) +{ + TNLAssert(info->arrayIndex < mGhostZeroUpdateIndex, "Out of range arrayIndex."); + TNLAssert(mGhostArray[info->arrayIndex] == info, "Invalid array object."); + mGhostZeroUpdateIndex--; + if(info->arrayIndex != mGhostZeroUpdateIndex) + { + mGhostArray[mGhostZeroUpdateIndex]->arrayIndex = info->arrayIndex; + mGhostArray[info->arrayIndex] = mGhostArray[mGhostZeroUpdateIndex]; + mGhostArray[mGhostZeroUpdateIndex] = info; + info->arrayIndex = mGhostZeroUpdateIndex; + } + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +inline void GhostConnection::ghostPushZeroToFree(GhostInfo *info) +{ + TNLAssert(info->arrayIndex >= mGhostZeroUpdateIndex && info->arrayIndex < mGhostFreeIndex, "Out of range arrayIndex."); + TNLAssert(mGhostArray[info->arrayIndex] == info, "Invalid array object."); + mGhostFreeIndex--; + if(info->arrayIndex != mGhostFreeIndex) + { + mGhostArray[mGhostFreeIndex]->arrayIndex = info->arrayIndex; + mGhostArray[info->arrayIndex] = mGhostArray[mGhostFreeIndex]; + mGhostArray[mGhostFreeIndex] = info; + info->arrayIndex = mGhostFreeIndex; + } + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +inline void GhostConnection::ghostPushFreeToZero(GhostInfo *info) +{ + TNLAssert(info->arrayIndex >= mGhostFreeIndex, "Out of range arrayIndex."); + TNLAssert(mGhostArray[info->arrayIndex] == info, "Invalid array object."); + if(info->arrayIndex != mGhostFreeIndex) + { + mGhostArray[mGhostFreeIndex]->arrayIndex = info->arrayIndex; + mGhostArray[info->arrayIndex] = mGhostArray[mGhostFreeIndex]; + mGhostArray[mGhostFreeIndex] = info; + info->arrayIndex = mGhostFreeIndex; + } + mGhostFreeIndex++; + //TNLAssert(validateGhostArray(), "Invalid ghost array!"); +} + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlHuffmanStringProcessor.h b/tnl-1.5.0/tnl/tnl/tnlHuffmanStringProcessor.h new file mode 100644 index 0000000000000000000000000000000000000000..31fbe0566b771092ce2b185a800c3d2bd72d3a1f --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlHuffmanStringProcessor.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_HUFFMANSTRINGPROCESSOR_H_ +#define _TNL_HUFFMANSTRINGPROCESSOR_H_ + +namespace TNL { + +/// HuffmanStringProcessor does Huffman coding on strings written into +/// BitStream objects. +namespace HuffmanStringProcessor +{ + /// Reads a Huffman compressed string out of a BitStream. + bool readHuffBuffer(BitStream* pStream, char* out_pBuffer); + + /// Writes and Huffman compresses a string into a BitStream. + /// + /// @param pStream Stream to output compressed data to. + /// @param out_pBuffer String to compress. + /// @param maxLen Maximum length of the string. If string length + /// exceeds this, then the string is terminated + /// early. + /// + /// @note The Huffman encoder uses BitStream::writeString as a fallback. + /// WriteString can only write strings of up to 255 characters length. + /// Therefore, it is wise not to exceed that limit. + bool writeHuffBuffer(BitStream* pStream, const char* out_pBuffer, U32 maxLen); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlJournal.h b/tnl-1.5.0/tnl/tnl/tnlJournal.h new file mode 100644 index 0000000000000000000000000000000000000000..4e73947744c62831ea1d63889d036a5e5cb166fc --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlJournal.h @@ -0,0 +1,189 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_JOURNAL_H_ +#define _TNL_JOURNAL_H_ + +#include "tnlMethodDispatch.h" +#include + +#define TNL_ENABLE_JOURNALING +//#define TNL_ENABLE_BIG_JOURNALS +namespace TNL +{ + +/// The Journal class represents the recordable entry point(s) into program execution. +/// When journaling is enabled by the TNL_ENABLE_JOURNALING macro, any calls into specially +/// marked Journal methods will be intercepted and potentially recorded for later playback. +/// If TNL_ENABLE_JOURNALING is not defined, all of the interception code will be disabled. + +class Journal : public Object +{ + static FILE *mJournalFile; + static BitStream mReadStream; + static BitStream mWriteStream; + static Journal *mJournal; + static U32 mWritePosition; + static U32 mReadBreakBitPos; + static U32 mBreakBlockIndex; + static U32 mBlockIndex; +public: + enum Mode + { + Inactive, + Record, + Playback, + }; +protected: + static Mode mCurrentMode; + static bool mInsideEntrypoint; + static void checkReadPosition(); + static void syncWriteStream(); +public: + Journal(); + void record(const char *fileName); + void load(const char *fileName); + + void callEntry(const char *funcName, Functor *theCall); + void processNextJournalEntry(); + + static Mode getCurrentMode() { return mCurrentMode; } + static Journal *get() { return mJournal; } + static BitStream *getReadStream() { return &mReadStream; } + static BitStream *getWriteStream() { return &mWriteStream; } + static bool isInEntrypoint() { return mInsideEntrypoint; } + + static void beginBlock(U32 blockId, bool writeBlock); + static void endBlock(U32 blockId, bool writeBlock); +}; + +struct JournalEntryRecord +{ + U32 mEntryIndex; + const char *mFunctionName; + JournalEntryRecord *mNext; + Functor *mFunctor; + + static Vector *mEntryVector; + + JournalEntryRecord(const char *functionName); + virtual ~JournalEntryRecord(); +}; + +#ifdef TNL_ENABLE_JOURNALING +#define TNL_DECLARE_JOURNAL_ENTRYPOINT(func, args) \ + void func args; \ + void func##_body args + +#define TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(className, func, args, argNames) \ + struct Journal_##className##_##func##_er : public JournalEntryRecord { \ + FunctorDecl mFunctorDecl; \ + Journal_##className##_##func##_er(const char *name) : JournalEntryRecord(name), mFunctorDecl(&className::func##_body) { mFunctor = &mFunctorDecl; } \ + } gJournal_##className##_##func##_er(#func); \ + void className::func args { \ + gJournal_##className##_##func##_er.mFunctorDecl.set argNames; \ + callEntry(#func, gJournal_##className##_##func##_er.mFunctor); \ + } \ + void className::func##_body args + +class JournalToken +{ + bool mWriting; + U32 mBlockType; +public: + JournalToken(U32 blockType, bool writing) + { + mWriting = writing; + mBlockType = blockType; + TNL::Journal::beginBlock(mBlockType, mWriting); + } + + ~JournalToken() + { + TNL::Journal::endBlock(mBlockType, mWriting); + } +}; + +class JournalBlockTypeToken +{ + const char *mString; + U32 mValue; + JournalBlockTypeToken *mNext; + static bool mInitialized; + static JournalBlockTypeToken *mList; +public: + JournalBlockTypeToken(const char *typeString); + U32 getValue(); + static const char *findName(U32 value); + const char *getString() { return mString; } +}; + +#define TNL_JOURNAL_WRITE_BLOCK(blockType, x) \ +{ \ + if(TNL::Journal::getCurrentMode() == TNL::Journal::Record && TNL::Journal::isInEntrypoint()) \ + { \ + static TNL::JournalBlockTypeToken typeToken(#blockType);\ + TNL::JournalToken dummy(typeToken.getValue(), true); \ + { \ + x \ + } \ + } \ +} + +#define TNL_JOURNAL_READ_BLOCK(blockType, x) \ +{ \ + if(TNL::Journal::getCurrentMode() == TNL::Journal::Playback && TNL::Journal::isInEntrypoint()) \ + { \ + static TNL::JournalBlockTypeToken typeToken(#blockType);\ + TNL::JournalToken dummy(typeToken.getValue(), false); \ + { \ + x \ + } \ + } \ +} + +#define TNL_JOURNAL_READ(x) \ + TNL::Journal::getReadStream()->read x + +#define TNL_JOURNAL_WRITE(x) \ + TNL::Journal::getWriteStream()->write x + +#else +#define TNL_DECLARE_JOURNAL_ENTRYPOINT(func, args) \ + void func args + +#define TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(className, func, args) \ + void className::func args + +#define TNL_JOURNAL_WRITE_BLOCK(blockType, x) +#define TNL_JOURNAL_READ_BLOCK(blockType, x) + +#endif +}; + + +#endif + diff --git a/tnl-1.5.0/tnl/tnl/tnlLog.h b/tnl-1.5.0/tnl/tnl/tnlLog.h new file mode 100644 index 0000000000000000000000000000000000000000..1ec1c0a17d4a7a76bfe444581348675e553a992c --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlLog.h @@ -0,0 +1,134 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_LOG_H_ +#define _TNL_LOG_H_ + +#include "tnlBitSet.h" +#include "tnl.h" + +namespace TNL +{ + +/// Global interface to the TNL logging system. +/// +/// The TNL logging system is consumer based. This is just a +/// global stub that routes the log string to all the consumers. +/// +/// You should really be using the TNLLogMessage() and +/// TNLLogMessageV() macros instead of calling this. +/// +/// @see LogConsumer +extern void logprintf(const char *format, ...); + + +/// LogConsumer is the base class for the message logging system in TNL. +/// +/// TNL by default doesn't log messages anywhere, but users of the library +/// can instantiate subclasses that override the logString method. +/// Any instantiated subclass of LogConsumer will receive all general +/// logprintf's, as well as any TNLLogMessages that are enabled via +/// the TNLLogEnable macro. +class LogConsumer +{ + LogConsumer *mNextConsumer; ///< Next LogConsumer in the global linked list of log consumers. + LogConsumer *mPrevConsumer; ///< Previous LogConsumer in the global linked list of log consumers. + + static LogConsumer *mLinkedList; ///< Head of the global linked list of log consumers. + +public: + /// Constructor adds this LogConsumer to the global linked list. + LogConsumer(); + + /// Destructor removes this LogConsumer from the global linked list, and updates the log flags. + virtual ~LogConsumer(); + + /// Returns the head of the linked list of all log consumers. + static LogConsumer *getLinkedList() { return mLinkedList; } + + /// Returns the next LogConsumer in the linked list. + LogConsumer *getNext() { return mNextConsumer; } + + /// Writes a string to this instance of LogConsumer. + /// + /// By default the string is sent to the Platform::outputDebugString function. Subclasses + /// might log to a file, a remote service, or even a message box. + virtual void logString(const char *string); +}; + +struct LogType +{ + LogType *next; + static LogType *linkedList; + + bool isEnabled; + const char *typeName; + static LogType *current; + +#ifdef TNL_ENABLE_LOGGING + static void setCurrent(LogType *theType) { current = theType; } + static LogType *find(const char *name); +#endif +}; + +#ifdef TNL_ENABLE_LOGGING + +struct LogTypeRef +{ + LogType *theLogType; + LogTypeRef(const char *name) + { + theLogType = LogType::find(name); + } +}; + +/// LogConnectionProtocol, +/// LogNetConnection, +/// LogEventConnection, +/// LogGhostConnection, +/// LogNetInterface, +/// LogPlatform, + +/// Logs a message of the specified type to the currently active LogConsumers. +#define TNLLogMessage(logType, message) { static TNL::LogTypeRef theType(#logType); if(theType.theLogType->isEnabled) { TNL::LogType::setCurrent(theType.theLogType); logprintf("%s", message); TNL::LogType::setCurrent(NULL); } } + +/// Logs a printf-style variable argument message of the specified type to the currently active LogConsumers. +#define TNLLogMessageV(logType, message) { static TNL::LogTypeRef theType(#logType); if(theType.theLogType->isEnabled) { TNL::LogType::setCurrent(theType.theLogType); logprintf message; TNL::LogType::setCurrent(NULL); } } + +#define TNLLogEnable(logType, enabled) { static TNL::LogTypeRef theType(#logType); theType.theLogType->isEnabled = enabled; } + +#define TNLLogBlock(logType, code) { static TNL::LogTypeRef theType(#logType); if(theType.theLogType->isEnabled) { TNL::LogType::setCurrent(theType.theLogType); { code } TNL::LogType::setCurrent(NULL); } } + +#else +#define TNLLogMessage(logType, message) { } +#define TNLLogMessageV(logType, message) { } +#define TNLLogEnable(logType, enabled) { } +#define TNLLogBlock(logType, code) { } +#endif + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.cpp b/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c2223b828c1fc5c2607af275161eb16b3c1ac8a5 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.cpp @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlMethodDispatch.h" +#include "tnlNetStringTable.h" +#include "tnlThread.h" + +namespace Types +{ +void read(TNL::BitStream &s, TNL::StringPtr *val) +{ + char buffer[256]; + s.readString(buffer); + *val = buffer; +} + +void write(TNL::BitStream &s, TNL::StringPtr &val) +{ + s.writeString(val.getString()); +} + +void read(TNL::BitStream &s, TNL::ByteBufferPtr *val) +{ + TNL::U32 size = s.readInt(ByteBufferSizeBitSize); + *val = new TNL::ByteBuffer(size); + s.read(size, (*val)->getBuffer()); +} +void write(TNL::BitStream &s, TNL::ByteBufferPtr &val) +{ + s.writeInt(val->getBufferSize(), ByteBufferSizeBitSize); + s.write(val->getBufferSize(), val->getBuffer()); +} +void read(TNL::BitStream &s, TNL::IPAddress *val) +{ + s.read(&val->netNum); + s.read(&val->port); +} + +void write(TNL::BitStream &s, TNL::IPAddress &val) +{ + s.write(val.netNum); + s.write(val.port); +} + + +}; + +namespace TNL +{ + + +}; diff --git a/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.h b/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.h new file mode 100644 index 0000000000000000000000000000000000000000..68053d8e816563146905d1c8688d36ec33159b0b --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.h @@ -0,0 +1,319 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_METHODDISPATCH_H_ +#define _TNL_METHODDISPATCH_H_ + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +#ifndef _TNL_VECTOR_H_ +#include "tnlVector.h" +#endif + +#ifndef _TNL_BITSTREAM_H_ +#include "tnlBitStream.h" +#endif + +#ifndef _TNL_NETSTRINGTABLE_H_ +#include "tnlNetStringTable.h" +#endif + +#ifndef _TNL_STRING_H_ +#include "tnlString.h" +#endif + +namespace Types +{ + enum { + VectorSizeBitSize = 8, + ByteBufferSizeBitSize = 10, + }; + + /// Reads a string from a BitStream. + extern void read(TNL::BitStream &s, TNL::StringPtr *val); + /// Rrites a string into a BitStream. + extern void write(TNL::BitStream &s, TNL::StringPtr &val); + /// Reads a ByteBuffer from a BitStream. + extern void read(TNL::BitStream &s, TNL::ByteBufferPtr *val); + /// Writes a ByteBuffer into a BitStream. + extern void write(TNL::BitStream &s, TNL::ByteBufferPtr &val); + /// Reads an IP address from a BitStream. + extern void read(TNL::BitStream &s, TNL::IPAddress *val); + /// Writes an IP address into a BitStream. + extern void write(TNL::BitStream &s, TNL::IPAddress &val); + + /// Reads a StringTableEntry from a BitStream. + inline void read(TNL::BitStream &s, TNL::StringTableEntry *val) + { + s.readStringTableEntry(val); + } + /// Writes a StringTableEntry into a BitStream. + inline void write(TNL::BitStream &s, TNL::StringTableEntry &val) + { + s.writeStringTableEntry(val); + } + + /// Reads a generic object from a BitStream. This can be used for any + /// type supported by BitStream::read. + template inline void read(TNL::BitStream &s, T *val) + { + s.read(val); + } + /// Writes a generic object into a BitStream. This can be used for any + /// type supported by BitStream::write. + template inline void write(TNL::BitStream &s, T &val) + { + s.write(val); + } + /// Reads a Vector of objects from a BitStream. + template inline void read(TNL::BitStream &s, TNL::Vector *val) + { + TNL::U32 size = s.readInt(VectorSizeBitSize); + val->setSize(size); + for(TNL::S32 i = 0; i < val->size(); i++) + read(s, &((*val)[i])); + } + /// Writes a Vector of objects into a BitStream. + template void write(TNL::BitStream &s, TNL::Vector &val) + { + s.writeInt(val.size(), VectorSizeBitSize); + for(TNL::S32 i = 0; i < val.size(); i++) + write(s, val[i]); + } + /// Reads a bit-compressed integer from a BitStream. + template inline void read(TNL::BitStream &s, TNL::Int *val) + { + val->value = s.readInt(BitCount); + } + /// Writes a bit-compressed integer into a BitStream. + template inline void write(TNL::BitStream &s,TNL::Int &val) + { + s.writeInt(val.value, BitCount); + } + + /// Reads a bit-compressed signed integer from a BitStream. + template inline void read(TNL::BitStream &s, TNL::SignedInt *val) + { + val->value = s.readSignedInt(BitCount); + } + /// Writes a bit-compressed signed integer into a BitStream. + template inline void write(TNL::BitStream &s,TNL::SignedInt &val) + { + s.writeSignedInt(val.value, BitCount); + } + + /// Reads a bit-compressed RangedU32 from a BitStream. + template inline void read(TNL::BitStream &s, TNL::RangedU32 *val) + { + val->value = s.readRangedU32(MinValue, MaxValue); + } + + /// Writes a bit-compressed RangedU32 into a BitStream. + template inline void write(TNL::BitStream &s,TNL::RangedU32 &val) + { + s.writeRangedU32(val.value, MinValue, MaxValue); + } + + /// Reads a bit-compressed SignedFloat (-1 to 1) from a BitStream. + template inline void read(TNL::BitStream &s, TNL::Float *val) + { + val->value = s.readFloat(BitCount); + } + /// Writes a bit-compressed SignedFloat (-1 to 1) into a BitStream. + template inline void write(TNL::BitStream &s,TNL::Float &val) + { + s.writeFloat(val.value, BitCount); + } + /// Reads a bit-compressed Float (0 to 1) from a BitStream. + template inline void read(TNL::BitStream &s, TNL::SignedFloat *val) + { + val->value = s.readSignedFloat(BitCount); + } + /// Writes a bit-compressed Float (0 to 1) into a BitStream. + template inline void write(TNL::BitStream &s,TNL::SignedFloat &val) + { + s.writeSignedFloat(val.value, BitCount); + } +}; + +namespace TNL { + +/// Base class for FunctorDecl template classes. The Functor objects +/// store the parameters and member function pointer for the invocation +/// of some class member function. Functor is used in TNL by the +/// RPC mechanism, the journaling system and the ThreadQueue to store +/// a function for later transmission and dispatch, either to a remote +/// host, a journal file, or another thread in the process. +struct Functor { + /// Construct the Functor. + Functor() {} + /// Destruct the Functor. + virtual ~Functor() {} + /// Reads this Functor from a BitStream. + virtual void read(BitStream &stream) = 0; + /// Writes this Functor to a BitStream. + virtual void write(BitStream &stream) = 0; + /// Dispatch the function represented by the Functor. + virtual void dispatch(void *t) = 0; +}; + +/// FunctorDecl template class. This class is specialized based on the +/// member function call signature of the method it represents. Other +/// specializations hold specific member function pointers and slots +/// for each of the function arguments. +template +struct FunctorDecl : public Functor { + FunctorDecl() {} + void set() {} + void read(BitStream &stream) {} + void write(BitStream &stream) {} + void dispatch(void *t) { } +}; +template +struct FunctorDecl : public Functor { + typedef void (T::*FuncPtr)(); + FuncPtr ptr; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set() {} + void read(BitStream &stream) {} + void write(BitStream &stream) {} + void dispatch(void *t) { ((T *)t->*ptr)(); } +}; +template +struct FunctorDecl : public Functor { + typedef void (T::*FuncPtr)(A); + FuncPtr ptr; A a; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a) { a = _a; } + void read(BitStream &stream) { Types::read(stream, &a); } + void write(BitStream &stream) { Types::write(stream, a); } + void dispatch(void *t) { (((T *)t)->*ptr)(a); } +}; +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B); + FuncPtr ptr; A a; B b; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b) { a = _a; b = _b;} + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C); + FuncPtr ptr; A a; B b; C c; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c) { a = _a; b = _b; c = _c;} + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D); + FuncPtr ptr; A a; B b; C c; D d; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d) { a = _a; b = _b; c = _c; d = _d; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D,E); + FuncPtr ptr; A a; B b; C c; D d; E e; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d, E &_e) { a = _a; b = _b; c = _c; d = _d; e = _e; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); Types::read(stream, &e); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); Types::write(stream, e); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d, e); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D,E,F); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d, E &_e, F &_f) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); Types::read(stream, &e); Types::read(stream, &f); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); Types::write(stream, e); Types::write(stream, f); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d, e, f); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D,E,F,G); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d, E &_e, F &_f, G &_g) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; g = _g; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); Types::read(stream, &e); Types::read(stream, &f); Types::read(stream, &g); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); Types::write(stream, e); Types::write(stream, f); Types::write(stream, g); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d, e, f, g); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D,E,F,G,H); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d, E &_e, F &_f, G &_g, H &_h) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; g = _g; h = _h; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); Types::read(stream, &e); Types::read(stream, &f); Types::read(stream, &g); Types::read(stream, &h); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); Types::write(stream, e); Types::write(stream, f); Types::write(stream, g); Types::write(stream, h); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d, e, f, g, h); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D,E,F,G,H,I); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d, E &_e, F &_f, G &_g, H &_h, I &_i) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; g = _g; h = _h; i = _i; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); Types::read(stream, &e); Types::read(stream, &f); Types::read(stream, &g); Types::read(stream, &h); Types::read(stream, &i); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); Types::write(stream, e); Types::write(stream, f); Types::write(stream, g); Types::write(stream, h); Types::write(stream, i); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d, e, f, g, h, i); } +}; + +template +struct FunctorDecl: public Functor { + typedef void (T::*FuncPtr)(A,B,C,D,E,F,G,H,I,J); + FuncPtr ptr; A a; B b; C c; D d; E e; F f; G g; H h; I i; J j; + FunctorDecl(FuncPtr p) : ptr(p) {} + void set(A &_a, B &_b, C &_c, D &_d, E &_e, F &_f, G &_g, H &_h, I &_i, J &_j) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; g = _g; h = _h; i = _i; j = _j; } + void read(BitStream &stream) { Types::read(stream, &a); Types::read(stream, &b); Types::read(stream, &c); Types::read(stream, &d); Types::read(stream, &e); Types::read(stream, &f); Types::read(stream, &g); Types::read(stream, &h); Types::read(stream, &i); Types::read(stream, &j); } + void write(BitStream &stream) { Types::write(stream, a); Types::write(stream, b); Types::write(stream, c); Types::write(stream, d); Types::write(stream, e); Types::write(stream, f); Types::write(stream, g); Types::write(stream, h); Types::write(stream, i); Types::write(stream, j); } + void dispatch(void *t) { (((T *)t)->*ptr)(a, b, c, d, e, f, g, h, i, j); } +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/tnl/tnlNetBase.h b/tnl-1.5.0/tnl/tnl/tnlNetBase.h new file mode 100644 index 0000000000000000000000000000000000000000..0dd42f9653e844858688415979052046b2832bb0 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNetBase.h @@ -0,0 +1,657 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NETBASE_H_ +#define _TNL_NETBASE_H_ + +//------------------------------------------------------------------------------ + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +#ifndef _TNL_PLATFORM_H_ +#include "tnlPlatform.h" +#endif + +#ifndef _TNL_ASSERT_H_ +#include "tnlAssert.h" +#endif + +#ifndef _TNL_BITSET_H_ +#include "tnlBitSet.h" +#endif + +#ifndef _TNL_VECTOR_H_ +#include "tnlVector.h" +#endif + +namespace TNL +{ + +/// NetClassTypes are used to define the ranges of individual +/// class identifiers, in order to reduce the number of bits +/// necessary to identify the class of an object across the +/// network. +/// +/// For example, if there are only 21 classes declared +/// of NetClassTypeObject, the class identifier only needs to +/// be sent using 5 bits. +enum NetClassType { + NetClassTypeNone = -1, ///< Not an id'able network class + NetClassTypeObject = 0, ///< Game object classes + NetClassTypeDataBlock, ///< Data block classes + NetClassTypeEvent, ///< Event classes + NetClassTypeCount, +}; + +/// NetClassGroups are used to define different service types +/// for an application. +/// +/// Each network-related class can be marked as valid across one or +/// more NetClassGroups. Each network connection belongs to a +/// particular group, and can only transmit objects that are valid +/// in that group. +enum NetClassGroup { + NetClassGroupGame, ///< Group for game related network classes + NetClassGroupCommunity, ///< Group for community server/authentication classes + NetClassGroupMaster, ///< Group for simple master server. + NetClassGroupUnused2, ///< Reserved group. + NetClassGroupCount, + NetClassGroupInvalid = NetClassGroupCount, +}; + +/// Mask values used to indicate which NetClassGroup(s) a NetObject or NetEvent +/// can be transmitted through. +enum NetClassMask { + NetClassGroupGameMask = 1 << NetClassGroupGame, + NetClassGroupCommunityMask = 1 << NetClassGroupCommunity, + NetClassGroupMasterMask = 1 << NetClassGroupMaster, + + NetClassGroupAllMask = (1 << NetClassGroupCount) - 1, +}; + +class Object; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +/// NetClassRep class instances represent each declared NetClass +/// and are used to construct object instances. +/// +/// Core functionality for TNL-registered class manipulation. +/// +/// @section NetClassRep_intro Introduction (or, Why AbstractClassRep?) +/// +/// TNL requires the ability to programatically instantiate classes, by name or by +/// ID numbers. This is used for handling connections, ghosting, working with +/// events, and in many other areas. Torque uses this functionality for its scripting +/// language, too. +/// +/// Since standard C++ doesn't provide a function to create a new instance of +/// an arbitrary class at runtime, one must be created. This is what +/// NetClassRep and NetClassRepInstance are all about. They allow the registration +/// and instantiation of arbitrary classes at runtime. +/// +/// @see TNL::Object +/// +/// @note In general, you will only access the functionality implemented in this class via +/// TNL::Object::create(). Most of the time, you will only ever need to use this part +/// part of the engine indirectly - ie, you will use the networking system. +/// The following discussion is really only relevant for advanced TNL users. +/// +/// @section NetClassRep_netstuff NetClasses and Class IDs +/// +/// TNL supports a notion of group, type, and direction for objects passed over +/// the network. Class IDs are assigned sequentially per-group, per-type, so that, for instance, +/// the IDs assigned to TNL::NetObjects are seperate from the IDs assigned to NetEvents. +/// This can translate into significant bandwidth savings (especially since the size of the fields +/// for transmitting these bits are determined at run-time based on the number of IDs given out. +/// +/// @section NetClassRep_details NetClassRep Internals +/// +/// NCR does some preparatory work at runtime before execution is passed to main(), through static +/// initialization. In actual fact, this preparatory work is done by the NetClassRepInstasnce +/// template. Let's examine this more closely. +/// +/// If we examine TNL::Object, we see that two macros must be used in the definition of a +/// properly integrated objects. Let's look at an example: +/// +/// @code +/// // This is from inside the class definition... +/// DECLARE_CONOBJECT(TestObject); +/// +/// // And this is from outside the class definition... +/// IMPLEMENT_CONOBJECT(TestObject); +/// @endcode +/// +/// What do these things actually do? +/// +/// Not all that much, in fact. They expand to code something like this: +/// +/// @code +/// // This is from inside the class definition... +/// static NetClassRepInstance dynClassRep; +/// static NetClassRep* getParentStaticClassRep(); +/// static NetClassRep* getStaticClassRep(); +/// virtual NetClassRep* getClassRep() const; +/// @endcode +/// +/// @code +/// // And this is from outside the class definition... +/// NetClassRep* TestObject::getClassRep() const { return &TestObject::dynClassRep; } +/// NetClassRep* TestObject::getStaticClassRep() { return &dynClassRep; } +/// NetClassRep* TestObject::getParentStaticClassRep() { return Parent::getStaticClassRep(); } +/// NetClassRepInstance TestObject::dynClassRep("TestObject", 0, -1, 0); +/// @endcode +/// +/// As you can see, getClassRep(), getStaticClassRep(), and getParentStaticClassRep() are just +/// accessors to allow access to various NetClassRepInstance instances. This is where the Parent +/// typedef comes into play as well - it lets getParentStaticClassRep() get the right +/// class rep. +/// +/// In addition, dynClassRep is declared as a member of TestObject, and defined later +/// on. Much like Torque's ConsoleConstructor, NetClassRepInstances add themselves to a global linked +/// list in their constructor. +/// +/// Then, when NetClassRep::initialize() is called, we iterate through +/// the list and perform the following tasks: +/// - Assigns network IDs for classes based on their NetGroup membership. Determines +/// bit allocations for network ID fields. +/// +/// @nosubgrouping +class NetClassRep +{ + friend class Object; + +protected: + NetClassRep(); + virtual ~NetClassRep() {} + U32 mClassGroupMask; ///< Mask for which class groups this class belongs to. + S32 mClassVersion; ///< The version number for this class. + NetClassType mClassType; ///< Which class type is this? + U32 mClassId[NetClassGroupCount]; ///< The id for this class in each class group. + char *mClassName; ///< The unmangled name of the class. + + U32 mInitialUpdateBitsUsed; ///< Number of bits used on initial updates of objects of this class. + U32 mPartialUpdateBitsUsed; ///< Number of bits used on partial updates of objects of this class. + U32 mInitialUpdateCount; ///< Number of objects of this class constructed over a connection. + U32 mPartialUpdateCount; ///< Number of objects of this class updated over a connection. + + /// Next declared NetClassRep. + /// + /// These are stored in a linked list built by the macro constructs. + NetClassRep *mNextClass; + + static NetClassRep *mClassLinkList; ///< Head of the linked class list. + static Vector mClassTable[NetClassGroupCount][NetClassTypeCount]; ///< Table of NetClassReps for construction by class ID. + static U32 mClassCRC[NetClassGroupCount]; ///< Internally computed class group CRC. + static bool mInitialized; ///< Set once the class tables are built, from initialize. + + /// mNetClassBitSize is the number of bits needed to transmit the class ID for a group and type. + static U32 mNetClassBitSize[NetClassGroupCount][NetClassTypeCount]; + + /// @name Object Creation + /// + /// These helper functions let you create an instance of a class by name or ID. + /// + /// @note Call Object::create() instead of these. + /// @{ + + static Object *create(const char *className); + static Object *create(const U32 groupId, const U32 typeId, const U32 classId); + + /// @} + +public: + U32 getClassId(NetClassGroup classGroup) const; ///< Returns the class ID, within its type, for the particular group. + NetClassType getClassType() const; ///< Returns the NetClassType of this class. + S32 getClassVersion() const; ///< Returns the version of this class. + const char *getClassName() const; ///< Returns the string class name. + + /// Records bits used in the initial update of objects of this class. + void addInitialUpdate(U32 bitCount) + { + mInitialUpdateCount++; + mInitialUpdateBitsUsed += bitCount; + } + + /// Records bits used in a partial update of an object of this class. + void addPartialUpdate(U32 bitCount) + { + mPartialUpdateCount++; + mPartialUpdateBitsUsed += bitCount; + } + + virtual Object *create() const = 0; ///< Creates an instance of the class this represents. + + /// Returns the number of classes registered under classGroup and classType. + static U32 getNetClassCount(U32 classGroup, U32 classType) + { return mClassTable[classGroup][classType].size(); } + + /// Returns the number of bits necessary to transmit class ids of the specified classGroup and classType. + static U32 getNetClassBitSize(U32 classGroup, U32 classType) + { return mNetClassBitSize[classGroup][classType]; } + + /// Returns true if the given class count is on a version boundary + static bool isVersionBorderCount(U32 classGroup, U32 classType, U32 count) + { return count == U32(mClassTable[classGroup][classType].size()) || + (count > 0 && mClassTable[classGroup][classType][count]->getClassVersion() != + mClassTable[classGroup][classType][count - 1]->getClassVersion()); } + + static NetClassRep *getClass(U32 classGroup, U32 classType, U32 index) + { return mClassTable[classGroup][classType][index]; } + + /// Returns a CRC of class data, for checking on connection. + static U32 getClassGroupCRC(NetClassGroup classGroup); + + /// Initializes the class table and associated data - called from TNL::init(). + static void initialize(); + + /// Logs the bit usage information of all the NetClassReps + static void logBitUsage(); +}; + +inline U32 NetClassRep::getClassId(NetClassGroup classGroup) const +{ + return mClassId[classGroup]; +} + +inline NetClassType NetClassRep::getClassType() const +{ + return mClassType; +} + +inline S32 NetClassRep::getClassVersion() const +{ + return mClassVersion; +} + +inline const char * NetClassRep::getClassName() const +{ + return mClassName; +} + +inline U32 NetClassRep::getClassGroupCRC(NetClassGroup classGroup) +{ + return mClassCRC[classGroup]; +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +/// NetClassRepInstance - one of these templates is instantiated for each +/// class that is declared via the IMPLEMENT_* macros below. +/// +/// There will be an instance for each networkable class. +template +class NetClassRepInstance : public NetClassRep +{ +public: + /// Each class registers itself through the constructor of its NetClassInstance + NetClassRepInstance(const char *className, U32 groupMask, NetClassType classType, S32 classVersion) + { + // Store data about ourselves + mClassName = strdup(className); + mClassType = classType; + mClassGroupMask = groupMask; + mClassVersion = classVersion; + for(U32 i = 0; i < NetClassGroupCount; i++) + mClassId[i] = 0; + + // link the class into our global list + mNextClass = mClassLinkList; + mClassLinkList = this; + } + ~NetClassRepInstance() + { + free(mClassName); + } + + /// Each NetClassRepInstance overrides the virtual create() function to construct its object instances. + Object *create() const + { + return new T; + } +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +class SafeObjectRef; + +/// Base class for all NetObject, NetEvent, NetConnection and NetInterface instances. +/// +/// @section TNLObject_references Ways of Referencing Object +/// +/// Object supports both reference counting and safe pointers. Ref counted objects +/// are accessed via the RefPtr template class. Once an object has been assigned using +/// a RefPtr, it will be deleted when all the reference pointers to it are destructed. +/// Object instances can also be safely referenced with the SafePtr template. The +/// SafePtr template instances are automatically set NULL when the object they point +/// to is deleted. +/// +/// @section TNLObject_basics The Basics +/// +/// Any object which you want to work with the networking system should derive from this, +/// and access functionality through the static interface. +/// +/// This class is always used with the TNL_DECLARE_CLASS and TNL_IMPLEMENT_CLASS macros. +/// +/// @code +/// // A very basic example object. It will do nothing! +/// class TestObject : public NetObject { +/// // Must provide a Parent typedef so the console system knows what we inherit from. +/// typedef NetObject Parent; +/// +/// // This does a lot of menial declaration for you. +/// TNL_DECLARE_CLASS(TestObject); +/// } +/// @endcode +/// +/// @code +/// // And the accordant implementation... +/// TNL_IMPLEMENT_CLASS(TestObject); +/// +/// @endcode +/// +/// That's all you need to do to get a class registered with the TNL object system. At this point, +/// you can instantiate it via TNL::Object::create, ghost it, and so forth. +/// +/// @see NetClassRepInstance for gory implementation details. +/// @nosubgrouping + +class Object +{ + SafeObjectRef *mFirstObjectRef; ///< The head of the linked list of safe object references. + U32 mRefCount; ///< Reference counter for RefPtr objects. + + friend class SafeObjectRef; + friend class RefObjectRef; +public: + /// Returns the NetClassRep associated with this object. + virtual NetClassRep* getClassRep() const; + + Object(); + virtual ~Object(); + + /// Object destroy self call (from RefPtr). + /// + /// @note Override if this class has specially allocated memory. + virtual void destroySelf() { delete this; } + + /// Get our class ID within the specified NetClassGroup. + U32 getClassId(NetClassGroup classGroup) const; + + /// Get our unmangled class name. + const char *getClassName() const; + + /// @name Object Creation + /// + /// These helper functions let you create an instance of a class by name or ID. + /// + /// @note Call these instead of NetClassRep::create + /// @{ + + /// static function to create an instance of a named class + static Object* create(const char* className) { return NetClassRep::create(className); } + + /// static function to create an instance of a class identified by a class group, class type and class id + static Object* create( const NetClassGroup groupId, + const NetClassType typeId, + const U32 classId) + { + return NetClassRep::create(groupId, typeId, classId); + } + + void incRef() + { + mRefCount++; + } + + void decRef() + { + mRefCount--; + if(!mRefCount) + destroySelf(); + } + /// @} +}; + +inline U32 Object::getClassId(NetClassGroup classGroup) const +{ + TNLAssert(getClassRep() != NULL, + "Cannot get class id from non-declared dynamic class"); + return getClassRep()->getClassId(classGroup); +} + +inline const char * Object::getClassName() const +{ + TNLAssert(getClassRep() != NULL, + "Cannot get class name from non-declared dynamic class"); + return getClassRep()->getClassName(); +} + +/// Base class for Object reference counting. +class RefObjectRef +{ +protected: + Object *mObject; ///< The object this RefObjectRef references. + + /// Increments the reference count on the referenced object. + void incRef() + { + if(mObject) + mObject->incRef(); + } + + /// Decrements the reference count on the referenced object. + void decRef() + { + if(mObject) + { + mObject->decRef(); + } + } +public: + + /// Constructor, assigns from the object and increments its reference count if it's not NULL. + RefObjectRef(Object *object = NULL) + { + mObject = object; + incRef(); + } + + /// Destructor, dereferences the object, if there is one. + ~RefObjectRef() + { + decRef(); + } + + /// Assigns this reference object from an existing Object instance. + void set(Object *object) + { + decRef(); + mObject = object; + incRef(); + } +}; + +/// Reference counted object template pointer class. +/// +/// Instances of this template class can be used as pointers to +/// instances of Object and its subclasses. The object will not +/// be deleted until all of the RefPtr instances pointing to it +/// have been destructed. +template class RefPtr : public RefObjectRef +{ +public: + RefPtr() : RefObjectRef() {} + RefPtr(T *ptr) : RefObjectRef(ptr) {} + RefPtr(const RefPtr& ref) : RefObjectRef((T *) ref.mObject) {} + + RefPtr& operator=(const RefPtr& ref) + { + set((T *) ref.mObject); + return *this; + } + RefPtr& operator=(T *ptr) + { + set(ptr); + return *this; + } + bool isNull() const { return mObject == 0; } + bool isValid() const { return mObject != 0; } + T* operator->() const { return static_cast(mObject); } + T& operator*() const { return *static_cast(mObject); } + operator T*() const { return static_cast(mObject); } + operator T*() { return static_cast(mObject); } + T* getPointer() { return static_cast(mObject); } +}; + +/// Base class for Object safe pointers. +class SafeObjectRef +{ + friend class Object; +protected: + Object *mObject; ///< The object this is a safe pointer to, or NULL if the object has been deleted. + SafeObjectRef *mPrevObjectRef; ///< The previous SafeObjectRef for mObject. + SafeObjectRef *mNextObjectRef; ///< The next SafeObjectRef for mObject. +public: + SafeObjectRef(Object *object); + SafeObjectRef(); + void set(Object *object); + ~SafeObjectRef(); + + void registerReference(); ///< Links this SafeObjectRef into the doubly linked list of SafeObjectRef instances for mObject. + void unregisterReference(); ///< Unlinks this SafeObjectRef from the doubly linked list of SafeObjectRef instance for mObject. +}; + +inline void SafeObjectRef::unregisterReference() +{ + if(mObject) + { + if(mPrevObjectRef) + mPrevObjectRef->mNextObjectRef = mNextObjectRef; + else + mObject->mFirstObjectRef = mNextObjectRef; + if(mNextObjectRef) + mNextObjectRef->mPrevObjectRef = mPrevObjectRef; + } +} + +inline void SafeObjectRef::registerReference() +{ + if(mObject) + { + mNextObjectRef = mObject->mFirstObjectRef; + if(mNextObjectRef) + mNextObjectRef->mPrevObjectRef = this; + mPrevObjectRef = NULL; + mObject->mFirstObjectRef = this; + } +} + +inline void SafeObjectRef::set(Object *object) +{ + unregisterReference(); + mObject = object; + registerReference(); +} + +inline SafeObjectRef::~SafeObjectRef() +{ + unregisterReference(); +} + +inline SafeObjectRef::SafeObjectRef(Object *object) +{ + mObject = object; + registerReference(); +} + +inline SafeObjectRef::SafeObjectRef() +{ + mObject = NULL; +} + +/// Safe object template pointer class. +/// +/// Instances of this template class can be used as pointers to +/// instances of Object and its subclasses. +/// +/// When the object referenced by a SafePtr instance is deleted, +/// the pointer to the object is set to NULL in the SafePtr instance. +template class SafePtr : public SafeObjectRef +{ +public: + SafePtr() : SafeObjectRef() {} + SafePtr(T *ptr) : SafeObjectRef(ptr) {} + SafePtr(const SafePtr& ref) : SafeObjectRef((T *) ref.mObject) {} + + SafePtr& operator=(const SafePtr& ref) + { + set((T *) ref.mObject); + return *this; + } + SafePtr& operator=(T *ptr) + { + set(ptr); + return *this; + } + bool isNull() const { return mObject == 0; } + bool isValid() const { return mObject != 0; } + T* operator->() const { return static_cast(mObject); } + T& operator*() const { return *static_cast(mObject); } + operator T*() const { return static_cast(mObject); } + operator T*() { return reinterpret_cast(mObject); } + T* getPointer() { return static_cast(mObject); } +}; + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Macros for declaring and implementing Object subclasses +// the TNL_DECLARE_CLASS(className) macro needs to be placed +// in the class declaraction for each network aware class. +// +// Different TNL_IMPLEMENT_* macros can be used depending on +// which NetClassType the class belongs to. + +/// The TNL_DECLARE_CLASS macro should be called within the declaration of any network class +#define TNL_DECLARE_CLASS(className) \ + static TNL::NetClassRepInstance dynClassRep; \ + virtual TNL::NetClassRep* getClassRep() const + +/// The TNL_IMPLEMENT_CLASS macro should be used for classes that will be auto-constructed +/// by name only. +#define TNL_IMPLEMENT_CLASS(className) \ + TNL::NetClassRep* className::getClassRep() const { return &className::dynClassRep; } \ + TNL::NetClassRepInstance className::dynClassRep(#className, 0, TNL::NetClassTypeNone, 0) + + +}; +#endif + diff --git a/tnl-1.5.0/tnl/tnl/tnlNetConnection.h b/tnl-1.5.0/tnl/tnl/tnlNetConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..cd166eacc91769fcd7da0c3c61948dbc145a27b1 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNetConnection.h @@ -0,0 +1,599 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NETCONNECTION_H_ +#define _TNL_NETCONNECTION_H_ + +#ifndef _TNL_NETBASE_H_ +#include "tnlNetBase.h" +#endif + +#ifndef _TNL_LOG_H_ +#include "tnlLog.h" +#endif + +#ifndef _TNL_NONCE_H_ +#include "tnlNonce.h" +#endif + +#ifndef _TNL_SYMMETRICCIPHER_H_ +#include "tnlSymmetricCipher.h" +#endif + +#ifndef _TNL_CONNECTIONSTRINGTABLE_H_ +#include "tnlConnectionStringTable.h" +#endif + +namespace TNL { + +class NetConnection; +class NetObject; +class BitStream; +class NetInterface; +class AsymmetricKey; +class Certificate; + +/// NetConnectionRep maintians a linked list of valid connection classes. +struct NetConnectionRep +{ + static NetConnectionRep *mLinkedList; + + NetConnectionRep *mNext; + NetClassRep *mClassRep; + bool mCanRemoteCreate; + + NetConnectionRep(NetClassRep *classRep, bool canRemoteCreate) + { + mNext = mLinkedList; + mLinkedList = this; + mClassRep = classRep; + mCanRemoteCreate = canRemoteCreate; + } + static NetConnection *create(const char *name); +}; + +#define TNL_DECLARE_NETCONNECTION(className) \ + TNL_DECLARE_CLASS(className); \ + TNL::NetClassGroup getNetClassGroup() const + +#define TNL_IMPLEMENT_NETCONNECTION(className, classGroup, canRemoteCreate) \ + TNL::NetClassRep* className::getClassRep() const { return &className::dynClassRep; } \ + TNL::NetClassRepInstance className::dynClassRep(#className, 0, TNL::NetClassTypeNone, 0); \ + TNL::NetClassGroup className::getNetClassGroup() const { return classGroup; } \ + static TNL::NetConnectionRep g##className##Rep(&className::dynClassRep, canRemoteCreate) + + +/// All data associated with the negotiation of the connection +struct ConnectionParameters +{ + bool mIsArranged; ///< True if this is an arranged connection + bool mUsingCrypto; ///< Set to true if this connection is using crypto (public key and symmetric) + bool mPuzzleRetried; ///< True if a puzzle solution was already rejected by the server once. + Nonce mNonce; ///< Unique nonce generated for this connection to send to the server. + Nonce mServerNonce; ///< Unique nonce generated by the server for the connection. + U32 mPuzzleDifficulty; ///< Difficulty of the client puzzle solved by this client. + U32 mPuzzleSolution; ///< Solution to the client puzzle the server sends to the client. + U32 mClientIdentity; ///< The client identity as computed by the remote host. + RefPtr mPublicKey; ///< The public key of the remote host. + RefPtr mPrivateKey;///< The private key for this connection. May be generated on the connection attempt. + RefPtr mCertificate; ///< The certificate of the remote host. + ByteBufferPtr mSharedSecret; ///< The shared secret key + bool mRequestKeyExchange; ///< The initiator of the connection wants a secure key exchange + bool mRequestCertificate; ///< The client is requesting a certificate + U8 mSymmetricKey[SymmetricCipher::KeySize]; ///< The symmetric key for the connection, generated by the client + U8 mInitVector[SymmetricCipher::KeySize]; ///< The init vector, generated by the server + Vector
mPossibleAddresses; ///< List of possible addresses for the remote host in an arranged connection. + bool mIsInitiator; ///< True if this host initiated the arranged connection. + bool mIsLocal; ///< True if this is a connectLocal connection. + ByteBufferPtr mArrangedSecret; ///< The shared secret as arranged by the connection intermediary. + bool mDebugObjectSizes; ///< This connection's initiator requested debugging size information during packet writes. + + ConnectionParameters() + { + mIsInitiator = false; + mPuzzleRetried = false; + mUsingCrypto = false; + mIsArranged = false; +#ifdef TNL_DEBUG + mDebugObjectSizes = true; +#else + mDebugObjectSizes = false; +#endif + mIsLocal = false; + } +}; + +//---------------------------------------------------------------------------- +/// TNL network connection base class. +/// +/// NetConnection is the base class for the connection classes in TNL. It implements a +/// notification protocol on the unreliable packet transport of UDP (via the TNL::Net layer). +/// NetConnection manages the flow of packets over the network, and calls its subclasses +/// to read and write packet data, as well as handle packet delivery notification. +/// +/// Because string data can easily soak up network bandwidth, for +/// efficiency NetConnection implements an optional networked string table. +/// Users can then notify the connection of strings it references often, such as player names, +/// and transmit only a tag, instead of the whole string. +/// +class NetConnection : public Object +{ + friend class NetInterface; + friend class ConnectionStringTable; + + typedef Object Parent; + + /// Constants controlling the data representation of each packet header + enum HeaderConstants { + // NOTE - IMPORTANT! + // The first bytes of each packet are made up of: + // 1 bit - game data packet flag + // 2 bits - packet type + // SequenceNumberBitSize bits - sequence number + // AckSequenceNumberBitSize bits - high ack sequence received + // these values should be set to align to a byte boundary, otherwise + // bits will just be wasted. + + MaxPacketWindowSizeShift = 5, ///< Packet window size is 2^MaxPacketWindowSizeShift. + MaxPacketWindowSize = (1 << MaxPacketWindowSizeShift), ///< Maximum number of packets in the packet window. + PacketWindowMask = MaxPacketWindowSize - 1, ///< Mask for accessing the packet window. + MaxAckMaskSize = 1 << (MaxPacketWindowSizeShift - 5), ///< Each ack word can ack 32 packets. + MaxAckByteCount = MaxAckMaskSize << 2, ///< The maximum number of ack bytes sent in each packet. + SequenceNumberBitSize = 11, ///< Bit size of the send and sequence number. + SequenceNumberWindowSize = (1 << SequenceNumberBitSize), ///< Size of the send sequence number window. + SequenceNumberMask = -SequenceNumberWindowSize, ///< Mask used to reconstruct the full send sequence number of the packet from the partial sequence number sent. + AckSequenceNumberBitSize = 10, ///< Bit size of the ack receive sequence number. + AckSequenceNumberWindowSize = (1 << AckSequenceNumberBitSize), ///< Size of the ack receive sequence number window. + AckSequenceNumberMask = -AckSequenceNumberWindowSize, ///< Mask used to reconstruct the full ack receive sequence number of the packet from the partial sequence number sent. + + PacketHeaderBitSize = 3 + AckSequenceNumberBitSize + SequenceNumberBitSize, ///< Size, in bits, of the packet header sequence number section + PacketHeaderByteSize = (PacketHeaderBitSize + 7) >> 3, ///< Size, in bytes, of the packet header sequence number information + PacketHeaderPadBits = (PacketHeaderByteSize << 3) - PacketHeaderBitSize, ///< Padding bits to get header bytes to align on a byte boundary, for encryption purposes. + + MessageSignatureBytes = 5, ///< Special data bytes written into the end of the packet to guarantee data consistency + }; + U32 mLastPacketRecvTime; ///< Time of the receipt of the last data packet. + U32 mLastSeqRecvdAtSend[MaxPacketWindowSize]; ///< The sequence number of the last packet received from the remote host when we sent the packet with sequence X & PacketWindowMask. + U32 mLastSeqRecvd; ///< The sequence number of the most recently received packet from the remote host. + U32 mHighestAckedSeq; ///< The highest sequence number the remote side has acknowledged. + U32 mLastSendSeq; ///< The sequence number of the last packet sent. + U32 mAckMask[MaxAckMaskSize]; ///< long string of bits, each acking a packet sent by the remote host. + ///< The bit associated with mLastSeqRecvd is the low bit of the 0'th word of mAckMask. + U32 mLastRecvAckAck; ///< The highest sequence this side knows the other side has received an ACK or NACK for. + + U32 mInitialSendSeq; ///< The first mLastSendSeq for this side of the connection. + U32 mInitialRecvSeq; ///< The first mLastSeqRecvd (the first mLastSendSeq for the remote host). + U32 mHighestAckedSendTime; ///< The send time of the highest packet sequence acked by the remote host. Used in the computation of round trip time. + /// Two-bit identifier for each connected packet. + enum NetPacketType + { + DataPacket, ///< Standard data packet. Each data packet sent increments the current packet sequence number (mLastSendSeq). + PingPacket, ///< Ping packet, sent if this instance hasn't heard from the remote host for a while. Sending a + /// ping packet does not increment the packet sequence number. + AckPacket, ///< Packet sent in response to a ping packet. Sending an ack packet does not increment the sequence number. + InvalidPacketType, + }; + /// Constants controlling the behavior of pings and timeouts + enum DefaultPingConstants { + AdaptiveInitialPingTimeout = 60000, + AdaptivePingRetryCount = 4, + DefaultPingTimeout = 5000, ///< Default milliseconds to wait before sending a ping packet. + DefaultPingRetryCount = 10, ///< Default number of unacknowledged pings to send before timing out. + AdaptiveUnackedSentPingTimeout = 3000, + }; + U32 mPingTimeout; ///< Milliseconds to wait before sending a ping packet. + U32 mPingRetryCount; ///< Number of unacknowledged pings to send before timing out. + + /// Returns true if this connection has sent packets that have not yet been acked by the remote host. + bool hasUnackedSentPackets() { return mLastSendSeq != mHighestAckedSeq; } +public: + struct PacketNotify; + + NetConnection(); + ~NetConnection(); + + enum TerminationReason { + ReasonTimedOut, + ReasonFailedConnectHandshake, + ReasonRemoteHostRejectedConnection, + ReasonRemoteDisconnectPacket, + ReasonDuplicateConnectionAttempt, + ReasonSelfDisconnect, + ReasonError, + }; + +protected: + + virtual void onConnectTerminated(TerminationReason reason, const char *rejectionString); ///< Called when a pending connection is terminated + virtual void onConnectionTerminated(TerminationReason, const char *errorDisconnectString); ///< Called when this established connection is terminated for any reason + virtual void onConnectionEstablished(); ///< Called when the connection is successfully established with the remote host. + + /// validates that the given certificate is a valid certificate for this + /// connection. + virtual bool validateCertficate(Certificate *theCertificate, bool isInitiator) { return true; } + + /// Validates that the given public key is valid for this connection. If this + /// host requires a valid certificate for the communication, this function + /// should always return false. It will only be called if the remote side + /// of the connection did not provide a certificate. + virtual bool validatePublicKey(AsymmetricKey *theKey, bool isInitiator) { return true; } + + /// Fills the connect request packet with additional custom data (from a subclass). + virtual void writeConnectRequest(BitStream *stream); + + /// Called after this connection instance is created on a non-initiating host (server). + /// + /// Reads data sent by the writeConnectRequest method and returns true if the connection is accepted + /// or false if it's not. The errorString pointer should be filled if the connection is rejected. + virtual bool readConnectRequest(BitStream *stream, const char **errorString); + + /// Writes any data needed to start the connection on the accept packet. + virtual void writeConnectAccept(BitStream *stream); + + /// Reads out the extra data read by writeConnectAccept and returns true if it is processed properly. + virtual bool readConnectAccept(BitStream *stream, const char **errorString); + + virtual void readPacket(BitStream *bstream); ///< Called to read a subclass's packet data from the packet. + + virtual void prepareWritePacket(); ///< Called to prepare the connection for packet writing. + /// + /// Any setup work to determine if there isDataToTransmit() should happen in + /// this function. prepareWritePacket should _always_ call the Parent:: function. + + virtual void writePacket(BitStream *bstream, PacketNotify *note); ///< Called to write a subclass's packet data into the packet. + /// + /// Information about what the instance wrote into the packet can be attached + /// to the notify object. + + virtual void packetReceived(PacketNotify *note); ///< Called when the packet associated with the specified notify is known to have been received by the remote host. + /// + /// Packets are guaranteed to be notified in the order in which they were sent. + virtual void packetDropped(PacketNotify *note); ///< Called when the packet associated with the specified notify is known to have been not received by the remote host. + /// + /// Packets are guaranteed to be notified in the order in which they were sent. + + /// Allocates a data record to track data sent on an individual packet. + /// + /// If you need to track additional notification information, you'll have to + /// override this so you allocate a subclass of PacketNotify with extra fields. + virtual PacketNotify *allocNotify() { return new PacketNotify; } + +public: + /// Returns the next send sequence that will be sent by this side. + U32 getNextSendSequence() { return mLastSendSeq + 1; } + + /// Returns the sequence of the last packet sent by this connection, or + /// the current packet's send sequence if called from within writePacket(). + U32 getLastSendSequence() { return mLastSendSeq; } + +protected: + /// Reads a raw packet from a BitStream, as dispatched from NetInterface. + void readRawPacket(BitStream *bstream); + /// Writes a full packet of the specified type into the BitStream + void writeRawPacket(BitStream *bstream, NetPacketType packetType); + + /// Writes the notify protocol's packet header into the BitStream. + void writePacketHeader(BitStream *bstream, NetPacketType packetType); + /// Reads a notify protocol packet header from the BitStream and + /// returns true if it was a data packet that needs more processing. + bool readPacketHeader(BitStream *bstream); + + void writePacketRateInfo(BitStream *bstream, PacketNotify *note); ///< Writes any packet send rate change information into the packet. + void readPacketRateInfo(BitStream *bstream); ///< Reads any packet send rate information requests from the packet. + + void sendPingPacket(); ///< Sends a ping packet to the remote host, to determine if it is still alive and what its packet window status is. + void sendAckPacket(); ///< Sends an ack packet to the remote host, in response to receiving a ping packet. + + /// Dispatches a notify when a packet is ACK'd or NACK'd. + void handleNotify(U32 sequence, bool recvd); + + /// Called when a packet is received to stop any timeout action in progress. + void keepAlive(); + + void clearAllPacketNotifies(); ///< Clears out the pending notify list. + +public: + /// Sets the initial sequence number of packets read from the remote host. + void setInitialRecvSequence(U32 sequence); + + /// Returns the initial sequence number of packets sent from the remote host. + U32 getInitialRecvSequence() { return mInitialRecvSeq; } + + /// Returns the initial sequence number of packets sent to the remote host. + U32 getInitialSendSequence() { return mInitialSendSeq; } + + /// Connect to a server through a given network interface. + /// The connection request can require that the connection use encryption, + /// or that the remote host's certificate be validated by a known Certificate Authority + void connect(NetInterface *connectionInterface, const Address &address, bool requestKeyExchange = false, bool requestCertificate = false); + + /// Connects to a server interface within the same process. + bool connectLocal(NetInterface *connectionInterface, NetInterface *localServerInterface); + + /// Connects to a remote host that is also connecting to this connection (negotiated by a third party) + void connectArranged(NetInterface *connectionInterface, const Vector
&possibleAddresses, Nonce &myNonce, Nonce &remoteNonce, ByteBufferPtr sharedSecret, bool isInitiator, bool requestsKeyExchange = false, bool requestsCertificate = false); + + /// Sends a disconnect packet to notify the remote host that this side is terminating the connection for the specified reason. + /// This will remove the connection from its NetInterface, and may have the side + /// effect that the connection is deleted, if there are no other objects with RefPtrs + /// to the connection. + void disconnect(const char *reason); + + /// Returns true if the packet send window is full and no more data packets can be sent. + bool windowFull(); + + /// Structure used to track what was sent in an individual packet for processing + /// upon notification of delivery success or failure. + struct PacketNotify + { + // packet stream notify stuff: + bool rateChanged; ///< True if this packet requested a change of rate. + U32 sendTime; ///< Platform::getRealMilliseconds() when packet was sent. + ConnectionStringTable::PacketList stringList; ///< List of string table entries sent in this packet + + PacketNotify *nextPacket; ///< Pointer to the next packet sent on this connection + PacketNotify(); + }; + +//---------------------------------------------------------------- +// Connection functions +//---------------------------------------------------------------- + + /// Flags specifying the type of the connection instance. + enum NetConnectionTypeFlags { + ConnectionToServer = BIT(0), ///< A connection to a "server", used for directing NetEvents + ConnectionToClient = BIT(1), ///< A connection to a "client" + ConnectionAdaptive = BIT(2), ///< Indicates that this connection uses the adaptive protocol. + ConnectionRemoteAdaptive = BIT(3), ///< Indicates that the remote side of this connection requested the adaptive protocol. + }; + +private: + BitSet32 mTypeFlags; ///< Flags describing the type of connection this is, OR'd from NetConnectionTypeFlags. + U32 mLastUpdateTime; ///< The last time a packet was sent from this instance. + F32 mRoundTripTime; ///< Running average round trip time. + U32 mSendDelayCredit; ///< Metric to help compensate for irregularities on fixed rate packet sends. + + U32 mSimulatedLatency; ///< Amount of additional time this connection delays its packet sends to simulate latency in the connection + F32 mSimulatedPacketLoss; ///< Function to simulate packet loss on a network + + enum RateDefaults { + DefaultFixedBandwidth = 2500, ///< The default send/receive bandwidth - 2.5 Kb per second. + DefaultFixedSendPeriod = 96, ///< The default delay between each packet send - approx 10 packets per second. + MaxFixedBandwidth = 65535, ///< The maximum bandwidth for a connection using the fixed rate transmission method. + MaxFixedSendPeriod = 2047, ///< The maximum period between packets in the fixed rate send transmission method. + }; + + /// Rate management structure used specify the rate at which packets are sent and the maximum size of each packet. + struct NetRate + { + U32 minPacketSendPeriod; ///< Minimum millisecond delay (maximum rate) between packet sends. + U32 minPacketRecvPeriod; ///< Minimum millisecond delay the remote host should allow between sends. + U32 maxSendBandwidth; ///< Number of bytes per second we can send over the connection. + U32 maxRecvBandwidth; ///< Number of bytes per second max that the remote instance should send. + }; + void computeNegotiatedRate(); ///< Called internally when the local or remote rate changes. + NetRate mLocalRate; ///< Current communications rate negotiated for this connection. + NetRate mRemoteRate; ///< Maximum allowable communications rate for this connection. + + bool mLocalRateChanged; ///< Set to true when the local connection's rate has changed. + U32 mCurrentPacketSendSize; ///< Current size of each packet sent to the remote host. + U32 mCurrentPacketSendPeriod; ///< Millisecond delay between sent packets. + + Address mNetAddress; ///< The network address of the host this instance is connected to. + + // timeout management stuff: + U32 mPingSendCount; ///< Number of unacknowledged ping packets sent to the remote host + U32 mLastPingSendTime; ///< Last time a ping packet was sent from this connection + +protected: + PacketNotify *mNotifyQueueHead; ///< Linked list of structures representing the data in sent packets + PacketNotify *mNotifyQueueTail; ///< Tail of the notify queue linked list. New packets are added to the end of the tail. + + /// Returns the notify structure for the current packet write, or last written packet. + PacketNotify *getCurrentWritePacketNotify() { return mNotifyQueueTail; } + + + SafePtr mRemoteConnection; ///< Safe pointer to a short-circuit remote connection on the same host. + /// + /// This currently isn't enabled - see the end of netConnection.cpp for an example + /// of how to use this. If it's set, the code will use short circuited networking. + ConnectionParameters mConnectionParameters; +public: + ConnectionParameters &getConnectionParameters() { return mConnectionParameters; } + + /// returns true if this object initiated the connection with the remote host + bool isInitiator() { return mConnectionParameters.mIsInitiator; } + void setRemoteConnectionObject(NetConnection *connection) { mRemoteConnection = connection; }; + NetConnection *getRemoteConnectionObject() { return mRemoteConnection; } + + U32 mConnectSendCount; ///< Number of challenge or connect requests sent to the remote host. + U32 mConnectLastSendTime; ///< The send time of the last challenge or connect request. + +protected: + static char mErrorBuffer[256]; ///< String buffer that errors are written into +public: + static char *getErrorBuffer() { return mErrorBuffer; } ///< returns the current error buffer + static void setLastError(const char *fmt,...); ///< Sets an error string and notifies the currently processing connection that it should terminate. + +protected: + SafePtr mInterface; ///< The NetInterface of which this NetConnection is a member. +public: + void setInterface(NetInterface *myInterface); ///< Sets the NetInterface this NetConnection will communicate through. + NetInterface *getInterface(); ///< Returns the NetInterface this connection communicates through. + +protected: + RefPtr mSymmetricCipher; ///< The helper object that performs symmetric encryption on packets +public: + void setSymmetricCipher(SymmetricCipher *theCipher); ///< Sets the SymmetricCipher this NetConnection will use for encryption + +public: + /// Returns the class group of objects that can be transmitted over this NetConnection. + virtual NetClassGroup getNetClassGroup() const { return NetClassGroupInvalid; } + + /// Sets the ping/timeout characteristics for a fixed-rate connection. Total timeout is msPerPing * pingRetryCount. + void setPingTimeouts(U32 msPerPing, U32 pingRetryCount) + { mPingRetryCount = pingRetryCount; mPingTimeout = msPerPing; } + + /// Simulates a network situation with a percentage random packet loss and a connection one way latency as specified. + void setSimulatedNetParams(F32 packetLoss, U32 latency) + { mSimulatedPacketLoss = packetLoss; mSimulatedLatency = latency; } + + /// Specifies that this NetConnection instance is a connection to a "server." + void setIsConnectionToServer() { mTypeFlags.set(ConnectionToServer); } + + /// Returns true if this is a connection to a "server." + bool isConnectionToServer() { return mTypeFlags.test(ConnectionToServer); } + + /// Specifies that this NetConnection instance is a connection to a "client." + void setIsConnectionToClient() { mTypeFlags.set(ConnectionToClient); } + + /// Returns true if this is a connection to a "client." + bool isConnectionToClient() { return mTypeFlags.test(ConnectionToClient); } + + /// Returns true if the remote side of this connection is a NetConnection instance in on the same host. + bool isLocalConnection() { return !mRemoteConnection.isNull(); } + + /// Returns true if the remote side if this connection is on a remote host. + bool isNetworkConnection() { return mRemoteConnection.isNull(); } + + /// Returns the running average packet round trip time. + F32 getRoundTripTime() + { return mRoundTripTime; } + + /// Returns have of the average of the round trip packet time. + F32 getOneWayTime() + { return mRoundTripTime * 0.5f; } + + /// Returns the remote address of the host we're connected or trying to connect to. + const Address &getNetAddress(); + + /// Returns the remote address in string form. + const char *getNetAddressString() const { return mNetAddress.toString(); } + + /// Sets the address of the remote host we want to connect to. + void setNetAddress(const Address &address); + + /// Sends a packet that was written into a BitStream to the remote host, or the mRemoteConnection on this host. + NetError sendPacket(BitStream *stream); + + /// Checks to see if the connection has timed out, possibly sending a ping packet to the remote host. Returns true if the connection timed out. + bool checkTimeout(U32 time); + + /// Checks to see if a packet should be sent at the currentTime to the remote host. + /// + /// If force is true and there is space in the window, it will always send a packet. + void checkPacketSend(bool force, U32 currentTime); + + /// Connection state flags for a NetConnection instance. + enum NetConnectionState { + NotConnected=0, ///< Initial state of a NetConnection instance - not connected. + AwaitingChallengeResponse, ///< We've sent a challenge request, awaiting the response. + SendingPunchPackets, ///< The state of a pending arranged connection when both sides haven't heard from the other yet + ComputingPuzzleSolution, ///< We've received a challenge response, and are in the process of computing a solution to its puzzle. + AwaitingConnectResponse, ///< We've received a challenge response and sent a connect request. + ConnectTimedOut, ///< The connection timed out during the connection process. + ConnectRejected, ///< The connection was rejected. + Connected, ///< We've accepted a connect request, or we've received a connect response accept. + Disconnected, ///< The connection has been disconnected. + TimedOut, ///< The connection timed out. + StateCount, + }; + + NetConnectionState mConnectionState; ///< Current state of this NetConnection. + + /// Sets the current connection state of this NetConnection. + void setConnectionState(NetConnectionState state) { mConnectionState = state; } + + /// Gets the current connection state of this NetConnection. + NetConnectionState getConnectionState() { return mConnectionState; } + + /// Returns true if the connection handshaking has completed successfully. + bool isEstablished() { return mConnectionState == Connected; } + + /// @name Adaptive Protocol + /// + /// Functions and state for the adaptive rate protocol. + /// + /// TNL's adaptive rate uses rate control algorithms similar to + /// TCP/IP's. + /// + /// There are a few state variables here that aren't documented. + /// + /// @{ + +public: + + /// Enables the adaptive protocol. + /// + /// By default NetConnection operates with a fixed rate protocol - that is, it sends a + /// packet every few milliseconds, based on some configuration parameters. However, + /// it is possible to use an adaptive rate protocol that attempts to maximize thoroughput + /// over the connection. + /// + /// Calling this function enables this behavior. + void setIsAdaptive(); + + /// sets the fixed rate send and receive data sizes, and sets the connection to not behave as an adaptive rate connection + void setFixedRateParameters( U32 minPacketSendPeriod, U32 minPacketRecvPeriod, U32 maxSendBandwidth, U32 maxRecvBandwidth ); + + /// Query the adaptive status of the connection. + bool isAdaptive() { return mTypeFlags.test(ConnectionAdaptive | ConnectionRemoteAdaptive); } + + /// Returns true if this connection has data to transmit. + /// + /// The adaptive rate protocol needs to be able to tell if there is data + /// ready to be sent, so that it can avoid sending unnecessary packets. + /// Each subclass of NetConnection may need to send different data - events, + /// ghost updates, or other things. Therefore, this hook is provided so + /// that child classes can overload it and let the adaptive protocol + /// function properly. + /// + /// @note Make sure this calls to its parents - the accepted idiom is: + /// @code + /// return Parent::isDataToTransmit() || localConditions(); + /// @endcode + virtual bool isDataToTransmit() { return false; } + + +private: + F32 cwnd; + F32 ssthresh; + U32 mLastSeqRecvdAck; + U32 mLastAckTime; + + /// @} +private: + ConnectionStringTable *mStringTable; ///< Helper for managing translation between global NetStringTable ids to local ids for this connection. +public: + /// Enables string tag translation on this connection. + void setTranslatesStrings(); +}; + +static const U32 MinimumPaddingBits = 128; ///< Padding space that is required at the end of each packet for bit flag writes and such. + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlNetEvent.h b/tnl-1.5.0/tnl/tnl/tnlNetEvent.h new file mode 100644 index 0000000000000000000000000000000000000000..370ea1d18c6808b8f4ba27262f545a9a094d47ad --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNetEvent.h @@ -0,0 +1,281 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NETEVENT_H_ +#define _TNL_NETEVENT_H_ + +#ifndef _TNL_NETBASE_H_ +#include "tnlNetBase.h" +#endif + +namespace TNL { + +//---------------------------------------------------------------------------- + +class EventConnection; +class BitStream; + +/// An event to be sent over the network. +/// +/// @note TNL implements two methods of network data passing; this is one of them. +/// See GhostConnection for details of the other, which is referred to as ghosting. +/// +/// TNL lets you pass NetEvent objects across EventConnection instances. There are three +/// types of events: +/// - Unguaranteed events are events which are sent once. If they don't +/// make it through the link, they are not resent. This is good for quick, +/// frequent status updates which are of transient interest, like voice +/// communication fragments. +/// - Guaranteed events are events which are guaranteed to be +/// delivered. If they don't make it through the link, they are sent as +/// needed. This is good for important, one-time information, +/// like which team a user wants to play on, or the current weather. +/// Guaranteed events are processed when they are received, so they may be processed +/// in a different order than they were sent in. +/// - GuaranteedOrdered events are events which are guaranteed to be +/// delivered, and whose process methods will be executed in the order the events were sent. +/// This is good for information which is not only important, but also order-critical, like +/// chat messages or file transfers. +/// +/// There are 3 methods that you need to implement if you want to make a +/// basic NetEvent subclass, and 2 macros you need to call. +/// +/// @code +/// // A simple NetEvent to transmit a string over the network. +/// class SimpleMessageEvent : public NetEvent +/// { +/// typedef NetEvent Parent; +/// char *msg; +/// public: +/// SimpleMessageEvent(const char *message = NULL); +/// ~SimpleMessageEvent(); +/// +/// virtual void pack (EventConnection *conn, BitStream *bstream) +/// virtual void unpack (EventConnection *conn, BitStream *bstream); +/// virtual void process(EventConnection *conn); +/// +/// TNL_DECLARE_CLASS(SimpleMessageEvent); +/// }; +/// +/// TNL_IMPLEMENT_NETEVENT(SimpleMessageEvent, NetClassGroupGameMask,0); +/// @endcode +/// +/// The first macro called, TNL_DECLARE_CLASS() registers the static class functions and NetClassRep object that will assign +/// this class a network ID and allow instances to be constructed by ID. +/// +/// The second, TNL_IMPLEMENT_NETEVENT(), instantiates the NetClassRep and +/// tells it that the instances are NetEvent objects in the Game group. The final +/// parameter to the TNL_IMPLEMENT_NETEVENT macro is the version number of the event +/// class. Versioning allows a server to offer new event services without forcing +/// older clients to be updated. +/// +/// In the constructor for the event the guarantee type of the event and the direction it will be +/// allowed to travel over the connection, must be specified by way of the constructor +/// for the base NetEvent class. The guarantee type can be one of: +/// - NetEvent::GuaranteedOrdered, for guaranteed, ordered events +/// - NetEvent::Guaranteed, for guaranteed events +/// - NetEvent::Unguaranteed, for unguaranteed events +/// +/// It is also a good idea to clearly specify which direction the event is allowed to travel. +/// If the program has a certain set of message events that are only sent from server to client, +/// then the network system can enforce that error checking automatically, in order to prevent hacks that may +/// otherwise crash or compromise the program. The valid event directions are: +/// - NetEvent::DirAny, this event can be sent from server to client +/// or from client to server +/// - NetEvent::DirServerToClient, this event can only be sent from +/// server to client. If the server receives an event of this type, it will +/// signal an error on the connection. +/// - NetEvent::DirClientToServer, this event can only be sent from client +/// to server. If the client receives an event of this type, it will signal an +/// error on the connection. +/// +/// @note TNL allows you to call NetConnection::setLastError() on the EventConnection passed to +/// the NetEvent. This will cause the connection to abort if invalid data is received, specifying +/// a reason to the user. +/// +/// Of the 5 methods declared above; the constructor and destructor need only do +/// whatever book-keeping is needed for the specific implementation, in addition to calling +/// the NetEvent constructor with the direction and type information that the networking system +/// needs to function. In this case, the SimpleMessageEvent simply allocates/deallocates the space for the string, +/// and specifies the event as guaranteed ordered and bidirectional. +/// +/// @code +/// SimpleMessageEvent::SimpleMessageEvent(const char *message = NULL) +/// : NetEvent(NetEvent::GuaranteedOrdered, NetEvent::DirAny) +/// { +/// // we marked this event as GuaranteedOrdered, and it can be sent in any direction +/// if(message) +/// msg = strdup(message); +/// else +/// msg = NULL; +/// } +/// +/// SimpleMessageEvent::~SimpleMessageEvent() +/// { +/// free(msg); +/// } +/// @endcode +/// +/// The 3 other functions that must be overridden for evern NetEvent are pack(), unpack() and process(). +/// +/// pack() is responsible for packing the event over the wire: +/// +/// @code +/// void SimpleMessageEvent::pack(EventConnection* conn, BitStream *bstream) +/// { +/// bstream->writeString(msg); +/// } +/// @endcode +/// +/// unpack() is responsible for unpacking the event on the other end: +/// +/// @code +/// // The networking layer takes care of instantiating a new +/// // SimpleMessageEvent, which saves us a bit of effort. +/// void SimpleMessageEvent::unpack(EventConnection *conn, BitStream *bstream) +/// { +/// char buf[256]; +/// bstream->readString(buf); +/// msg = strdup(buf); +/// } +/// @endcode +/// +/// process() is called when the network layer is finished with things. +/// A typical case is that a GuaranteedOrdered event is unpacked and stored, but +/// not processed until the events preceding it in the sequence have been process()'d. +/// +/// @code +/// // This just prints the event in the log. You might +/// // want to do something more clever here. +/// void SimpleMessageEvent::process(EventConnection *conn) +/// { +/// logprintf("Received a SimpleMessageEvent: %s", msg); +/// +/// // An example of something more clever - kick people who say bad words. +/// // if(isBadWord(msg)) conn->setLastError("No swearing, naughtypants!"); +/// } +/// @endcode +/// +/// Posting an event to the remote host on a connection is simple: +/// +/// @code +/// EventConnection *conn; // We assume you have filled this in. +/// +/// conn->postNetEvent(new SimpleMessageEvent("This is a test!")); +/// @endcode +/// +/// Finally, for more advanced applications, notifyPosted() is called when the event is posted +/// into the send queue, notifySent() is called whenever the event is +/// sent over the wire, in EventConnection::eventWritePacket(). notifyDelivered() is called +/// when the packet is finally received or (in the case of Unguaranteed packets) dropped. +/// +/// @note the TNL_IMPLEMENT_NETEVENT groupMask specifies which "group" of EventConnections +/// the event can be sent over. See TNL::Object for a further discussion of this. +class NetEvent : public Object +{ + friend class EventConnection; +public: + enum EventDirection { + DirUnset, ///< Default value - NetConnection will Assert if an event is posted without a valid direction set. + DirAny, ///< This event can be sent from the server or the client + DirServerToClient, ///< This event can only be sent from the server to the client + DirClientToServer, ///< This event can only be sent from the client to the server + } mEventDirection; ///< Direction this event is allowed to travel in the network + + enum GuaranteeType { + GuaranteedOrdered = 0, ///< Event delivery is guaranteed and will be processed in the order it + /// was sent relative to other ordered events. + Guaranteed = 1, ///< Event delivery is guaranteed and will be processed in the order it + /// was received. + Unguaranteed = 2 ///< Event delivery is not guaranteed - however, the event will remain + /// ordered relative to other unguaranteed events. + } mGuaranteeType; ///< Type of data guarantee this event supports + + /// Constructor - should always be called by subclasses. + /// + /// Subclasses MUST pass in an event direction and guarantee type, or else the network + /// system will error on the event. Events are by default GuaranteedOrdered, however, + /// the default direction is unset which will result in asserts. + NetEvent(GuaranteeType gType = GuaranteedOrdered, EventDirection evDir = DirUnset) + { + mGuaranteeType = gType; + mEventDirection = evDir; + } + + /// Pack is called on the origin side of the connection to write an event's + /// data into a packet. + virtual void pack(EventConnection *ps, BitStream *bstream) = 0; + + /// Unpack is called on the destination side of the connection to read an event's + /// data out of a packet. + virtual void unpack(EventConnection *ps, BitStream *bstream) = 0; + + /// Process is called to process the event data when it has been unpacked. + /// + /// For a guaranteed, ordered event, process is called only once all prior events + /// have been received and processed. For unguaranteed events, process is called + /// immediately after unpack. + virtual void process(EventConnection *ps) = 0; + + /// notifyPosted is called on an event when it is posted to a particular EventConnection, before it is added to the send queue. + /// This allows events to post additional events to the connection that will be send _before_ this event + virtual void notifyPosted(EventConnection *ps) {} + + /// notifySent is called on each event after all of the events for a packet have + /// been written into the packet stream. + virtual void notifySent(EventConnection *ps) {} + + /// notifyDelivered is called on the source event after it has been received + /// and processed by the other side of the connection. + /// + /// If the packet delivery fails on an unguaranteed event, madeIt will be + /// false, otherwise it will be true. + virtual void notifyDelivered(EventConnection *ps, bool madeIt) {} + + /// getEventDirection returns the direction this event is allowed to travel in on a connection + EventDirection getEventDirection() + { + return mEventDirection; + } + + /// getDebugName is used to construct event names for packet + /// logging in debug mode. + virtual const char *getDebugName() + { + return getClassName(); + } +}; + + +/// The IMPLEMENT_NETEVENT macro is used for implementing events +/// that can be sent from server to client or from client to server +#define TNL_IMPLEMENT_NETEVENT(className,groupMask,classVersion) \ + TNL::NetClassRep* className::getClassRep() const { return &className::dynClassRep; } \ + TNL::NetClassRepInstance className::dynClassRep(#className,groupMask, TNL::NetClassTypeEvent, classVersion) + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlNetInterface.h b/tnl-1.5.0/tnl/tnl/tnlNetInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..1e4e611e9997a0041328e82962ee34b53f661eb4 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNetInterface.h @@ -0,0 +1,386 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NETINTERFACE_H_ +#define _TNL_NETINTERFACE_H_ + +#ifndef _TNL_VECTOR_H_ +#include "tnlVector.h" +#endif + +#ifndef _TNL_NETBASE_H_ +#include "tnlNetBase.h" +#endif + +#include "tnlClientPuzzle.h" + +#ifndef _TNL_NETOBJECT_H_ +#include "tnlNetObject.h" +#endif + +#ifndef _TNL_NETCONNECTION_H_ +#include "tnlNetConnection.h" +#endif + +namespace TNL { + +class AsymmetricKey; +class Certificate; +struct ConnectionParameters; + +/// NetInterface class. +/// +/// Manages all valid and pending notify protocol connections for a port/IP. If you are +/// providing multiple services or servicing multiple networks, you may have more than +/// one NetInterface. +/// +/// Connection handshaking basic overview: +/// +/// TNL does a two phase connect handshake to prevent a several types of +/// Denial-of-Service (DoS) attacks. +/// +/// The initiator of the connection (client) starts the connection by sending +/// a unique random nonce (number, used once) value to the server as part of +/// the ConnectChallengeRequest packet. +/// C->S: ConnectChallengeRequest, Nc +/// +/// The server responds to the ConnectChallengeRequest with a "Client Puzzle" +/// that has the property that verifying a solution to the puzzle is computationally +/// simple, but can be of a specified computational, brute-force difficulty to +/// compute the solution itself. The client puzzle is of the form: +/// secureHash(Ic, Nc, Ns, X) = Y >> k, where Ic is the identity of the client, +/// and X is a value computed by the client such that the high k bits of the value +/// y are all zero. The client identity is computed by the server as a partial hash +/// of the client's IP address and port and some random data on the server. +/// its current nonce (Ns), Nc, k, and the server's authentication certificate. +/// S->C: ConnectChallengeResponse, Nc, Ns, Ic, Cs +/// +/// The client, upon receipt of the ConnectChallengeResponse, validates the packet +/// sent by the server and computes a solution to the puzzle the server sent. If +/// the connection is to be authenticated, the client can also validate the server's +/// certificate (if it's been signed by a Certificate Authority), and then generates +/// a shared secret from the client's key pair and the server's public key. The client +/// response to the server consists of: +/// C->S: ConnectRequest, Nc, Ns, X, Cc, sharedSecret(key1, sequence1, NetConnectionClass, class-specific sendData) +/// +/// The server then can validation the solution to the puzzle the client submitted, along +/// with the client identity (Ic). +/// Until this point the server has allocated no memory for the client and has +/// verified that the client is sending from a valid IP address, and that the client +/// has done some amount of work to prove its willingness to start a connection. +/// As the server load increases, the server may choose to increase the difficulty (k) of +/// the client puzzle, thereby making a resource depletion DoS attack successively more +/// difficult to launch. +/// +/// If the server accepts the connection, it sends a connect accept packet that is +/// encrypted and hashed using the shared secret. The contents of the packet are +/// another sequence number (sequence2) and another key (key2). The sequence numbers +/// are the initial send and receive sequence numbers for the connection, and the +/// key2 value becomes the IV of the symmetric cipher. The connection subclass is +/// also allowed to write any connection specific data into this packet. +/// +/// This system can operate in one of 3 ways: unencrypted, encrypted key exchange (ECDH), +/// or encrypted key exchange with server and/or client signed certificates (ECDSA). +/// +/// The unencrypted communication mode is NOT secure. Packets en route between hosts +/// can be modified without detection by the hosts at either end. Connections using +/// the secure key exchange are still vulnerable to Man-in-the-middle attacks, but still +/// much more secure than the unencrypted channels. Using certificate(s) signed by a +/// trusted certificate authority (CA), makes the communications channel as securely +/// trusted as the trust in the CA. +/// +/// Arranged Connection handshaking: +/// +/// NetInterface can also facilitate "arranged" connections. Arranged connections are +/// necessary when both parties to the connection are behind firewalls or NAT routers. +/// Suppose there are two clients, A and B that want to esablish a direct connection with +/// one another. If A and B are both logged into some common server S, then S can send +/// A and B the public (NAT'd) address, as well as the IP addresses each client detects +/// for itself. +/// +/// A and B then both send "Punch" packets to the known possible addresses of each other. +/// The punch packet client A sends enables the punch packets client B sends to be +/// delivered through the router or firewall since it will appear as though it is a service +/// response to A's initial packet. +/// +/// Upon receipt of the Punch packet by the "initiator" +/// of the connection, an ArrangedConnectRequest packet is sent. +/// if the non-initiator of the connection gets an ArrangedPunch +/// packet, it simply sends another Punch packet to the +/// remote host, but narrows down its Address range to the address +/// it received the packet from. +/// The ArrangedPunch packet from the intiator contains the nonce +/// for the non-initiator, and the nonce for the initiator encrypted +/// with the shared secret. +/// The ArrangedPunch packet for the receiver of the connection +/// contains all that, plus the public key/keysize or the certificate +/// of the receiver. + + +class NetInterface : public Object +{ + friend class NetConnection; +public: + /// PacketType is encoded as the first byte of each packet. + /// + /// Subclasses of NetInterface can add custom, non-connected data + /// packet types starting at FirstValidInfoPacketId, and overriding + /// handleInfoPacket to process them. + /// + /// Packets that arrive with the high bit of the first byte set + /// (i.e. the first unsigned byte is greater than 127), are + /// assumed to be connected protocol packets, and are dispatched to + /// the appropriate connection for further processing. + + enum PacketType + { + ConnectChallengeRequest = 0, ///< Initial packet of the two-phase connect process + ConnectChallengeResponse = 1, ///< Response packet to the ChallengeRequest containing client identity, a client puzzle, and possibly the server's public key. + ConnectRequest = 2, ///< A connect request packet, including all puzzle solution data and connection initiation data. + ConnectReject = 3, ///< A packet sent to notify a host that a ConnectRequest was rejected. + ConnectAccept = 4, ///< A packet sent to notify a host that a connection was accepted. + Disconnect = 5, ///< A packet sent to notify a host that the specified connection has terminated. + Punch = 6, ///< A packet sent in order to create a hole in a firewall or NAT so packets from the remote host can be received. + ArrangedConnectRequest = 7, ///< A connection request for an "arranged" connection. + FirstValidInfoPacketId = 8, ///< The first valid ID for a NetInterface subclass's info packets. + }; + +protected: + Vector mConnectionList; ///< List of all the connections that are in a connected state on this NetInterface. + Vector mConnectionHashTable; ///< A resizable hash table for all connected connections. This is a flat hash table (no buckets). + + Vector mPendingConnections; ///< List of connections that are in the startup state, where the remote host has not fully + /// validated the connection. + + RefPtr mPrivateKey; ///< The private key used by this NetInterface for secure key exchange. + RefPtr mCertificate; ///< A certificate, signed by some Certificate Authority, to authenticate this host. + ClientPuzzleManager mPuzzleManager; ///< The object that tracks the current client puzzle difficulty, current puzzle and solutions for this NetInterface. + + /// @name NetInterfaceSocket Socket + /// + /// State regarding the socket this NetInterface controls. + /// + /// @{ + + /// + Socket mSocket; ///< Network socket this NetInterface communicates over. + + /// @} + + U32 mCurrentTime; ///< Current time tracked by this NetInterface. + bool mRequiresKeyExchange; ///< True if all connections outgoing and incoming require key exchange. + U32 mLastTimeoutCheckTime; ///< Last time all the active connections were checked for timeouts. + U8 mRandomHashData[12]; ///< Data that gets hashed with connect challenge requests to prevent connection spoofing. + bool mAllowConnections; ///< Set if this NetInterface allows connections from remote instances. + + /// Structure used to track packets that are delayed in sending for simulating a high-latency connection. + /// + /// The DelaySendPacket is allocated as sizeof(DelaySendPacket) + packetSize; + struct DelaySendPacket + { + DelaySendPacket *nextPacket; ///< The next packet in the list of delayed packets. + Address remoteAddress; ///< The address to send this packet to. + U32 sendTime; ///< Time when we should send the packet. + U32 packetSize; ///< Size, in bytes, of the packet data. + U8 packetData[1]; ///< Packet data. + }; + DelaySendPacket *mSendPacketList; ///< List of delayed packets pending to send. + + enum NetInterfaceConstants { + ChallengeRetryCount = 4, ///< Number of times to send connect challenge requests before giving up. + ChallengeRetryTime = 2500, ///< Timeout interval in milliseconds before retrying connect challenge. + + ConnectRetryCount = 4, ///< Number of times to send connect requests before giving up. + ConnectRetryTime = 2500, ///< Timeout interval in milliseconds before retrying connect request. + + PunchRetryCount = 6, ///< Number of times to send groups of firewall punch packets before giving up. + PunchRetryTime = 2500, ///< Timeout interval in milliseconds before retrying punch sends. + + TimeoutCheckInterval = 1500, ///< Interval in milliseconds between checking for connection timeouts. + PuzzleSolutionTimeout = 30000, ///< If the server gives us a puzzle that takes more than 30 seconds, time out. + }; + + /// Computes an identity token for the connecting client based on the address of the client and the + /// client's unique nonce value. + U32 computeClientIdentityToken(const Address &theAddress, const Nonce &theNonce); + + /// Finds a connection instance that this NetInterface has initiated. + NetConnection *findPendingConnection(const Address &address); + + /// Adds a connection the list of pending connections. + void addPendingConnection(NetConnection *conn); + + /// Removes a connection from the list of pending connections. + void removePendingConnection(NetConnection *conn); + + /// Finds a connection by address from the pending list and removes it. + void findAndRemovePendingConnection(const Address &address); + + /// Adds a connection to the internal connection list. + void addConnection(NetConnection *connection); + + /// Remove a connection from the list. + void removeConnection(NetConnection *connection); + + /// Begins the connection handshaking process for a connection. Called from NetConnection::connect() + void startConnection(NetConnection *conn); + + /// Sends a connect challenge request on behalf of the connection to the remote host. + void sendConnectChallengeRequest(NetConnection *conn); + + /// Handles a connect challenge request by replying to the requestor of a connection with a + /// unique token for that connection, as well as (possibly) a client puzzle (for DoS prevention), + /// or this NetInterface's public key. + void handleConnectChallengeRequest(const Address &addr, BitStream *stream); + + /// Sends a connect challenge request to the specified address. This can happen as a result + /// of receiving a connect challenge request, or during an "arranged" connection for the non-initiator + /// of the connection. + void sendConnectChallengeResponse(const Address &addr, Nonce &clientNonce, bool wantsKeyExchange, bool wantsCertificate); + + /// Processes a ConnectChallengeResponse, by issueing a connect request if it was for + /// a connection this NetInterface has pending. + void handleConnectChallengeResponse(const Address &address, BitStream *stream); + + /// Continues computation of the solution of a client puzzle, and issues a connect request + /// when the solution is found. + void continuePuzzleSolution(NetConnection *conn); + + /// Sends a connect request on behalf of a pending connection. + void sendConnectRequest(NetConnection *conn); + + /// Handles a connection request from a remote host. + /// + /// This will verify the validity of the connection token, as well as any solution + /// to a client puzzle this NetInterface sent to the remote host. If those tests + /// pass, it will construct a local connection instance to handle the rest of the + /// connection negotiation. + void handleConnectRequest(const Address &address, BitStream *stream); + + /// Sends a connect accept packet to acknowledge the successful acceptance of a connect request. + void sendConnectAccept(NetConnection *conn); + + /// Handles a connect accept packet, putting the connection associated with the + /// remote host (if there is one) into an active state. + void handleConnectAccept(const Address &address, BitStream *stream); + + /// Sends a connect rejection to a valid connect request in response to possible error + /// conditions (server full, wrong password, etc). + void sendConnectReject(ConnectionParameters *theParams, const Address &theAddress, const char *reason); + + /// Handles a connect rejection packet by notifying the connection object + /// that the connection was rejected. + void handleConnectReject(const Address &address, BitStream *stream); + + /// Begins the connection handshaking process for an arranged connection. + void startArrangedConnection(NetConnection *conn); + + /// Sends Punch packets to each address in the possible connection address list. + void sendPunchPackets(NetConnection *conn); + + /// Handles an incoming Punch packet from a remote host. + void handlePunch(const Address &theAddress, BitStream *stream); + + /// Sends an arranged connect request. + void sendArrangedConnectRequest(NetConnection *conn); + + /// Handles an incoming connect request from an arranged connection. + void handleArrangedConnectRequest(const Address &theAddress, BitStream *stream); + + /// Dispatches a disconnect packet for a specified connection. + void handleDisconnect(const Address &address, BitStream *stream); + + /// Handles an error reported while reading a packet from this remote connection. + void handleConnectionError(NetConnection *theConnection, const char *errorString); + + /// Disconnects the given connection and removes it from the NetInterface + void disconnect(NetConnection *conn, NetConnection::TerminationReason reason, const char *reasonString); + /// @} +public: + /// @param bindAddress Local network address to bind this interface to. + NetInterface(const Address &bindAddress); + ~NetInterface(); + + /// Returns the address of the first network interface in the list that the socket on this NetInterface is bound to. + Address getFirstBoundInterfaceAddress(); + + /// Sets the private key this NetInterface will use for authentication and key exchange + void setPrivateKey(AsymmetricKey *theKey); + + /// Requires that all connections use encryption and key exchange + void setRequiresKeyExchange(bool requires) { mRequiresKeyExchange = requires; } + + /// Sets the public certificate that validates the private key and stores + /// information about this host. If no certificate is set, this interface can + /// still initiate and accept encrypted connections, but they will be vulnerable to + /// man in the middle attacks, unless the remote host can validate the public key + /// in another way. + void setCertificate(Certificate *theCertificate); + + /// Returns whether or not this NetInterface allows connections from remote hosts. + bool doesAllowConnections() { return mAllowConnections; } + + /// Sets whether or not this NetInterface allows connections from remote hosts. + void setAllowsConnections(bool conn) { mAllowConnections = conn; } + + /// Returns the Socket associated with this NetInterface + Socket &getSocket() { return mSocket; } + + /// Sends a packet to the remote address over this interface's socket. + NetError sendto(const Address &address, BitStream *stream); + + /// Sends a packet to the remote address after millisecondDelay time has elapsed. + /// + /// This is used to simulate network latency on a LAN or single computer. + void sendtoDelayed(const Address &address, BitStream *stream, U32 millisecondDelay); + + /// Dispatch function for processing all network packets through this NetInterface. + void checkIncomingPackets(); + + /// Processes a single packet, and dispatches either to handleInfoPacket or to + /// the NetConnection associated with the remote address. + virtual void processPacket(const Address &address, BitStream *packetStream); + + /// Handles all packets that don't fall into the category of connection handshake or game data. + virtual void handleInfoPacket(const Address &address, U8 packetType, BitStream *stream); + + /// Checks all connections on this interface for packet sends, and for timeouts and all valid + /// and pending connections. + void processConnections(); + + /// Returns the list of connections on this NetInterface. + Vector &getConnectionList() { return mConnectionList; } + + /// looks up a connected connection on this NetInterface + NetConnection *findConnection(const Address &remoteAddress); + + /// returns the current process time for this NetInterface + U32 getCurrentTime() { return mCurrentTime; } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlNetObject.h b/tnl-1.5.0/tnl/tnl/tnlNetObject.h new file mode 100644 index 0000000000000000000000000000000000000000..02be77b82d6681050c5f6998c2a1fdf3ae20d540 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNetObject.h @@ -0,0 +1,421 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NETOBJECT_H_ +#define _TNL_NETOBJECT_H_ + +#ifndef _TNL_NETBASE_H_ +#include "tnlNetBase.h" +#endif + +#ifndef _TNL_BITSTREAM_H_ +#include "tnlBitStream.h" +#endif + +#ifndef _TNL_RPC_H_ +#include "tnlRPC.h" +#endif + +namespace TNL { +//---------------------------------------------------------------------------- +class GhostConnection; +class NetInterface; +class NetObjectRPCEvent; + +struct GhostInfo; + +//----------------------------------------------------------------------------- +/// Superclass for ghostable networked objects. +/// +/// @section NetObject_intro Introduction To NetObject And Ghosting +/// +/// One of the most powerful aspects of the Torque Network Library is its support +/// for ghosting and prioritized, most-recent-state network updates. The way +/// this works is a bit complex, but it is immensely efficient. Let's run +/// through the steps that the server goes through for each client in this part +/// of TNL's architecture: +/// - First, the server determines what objects are in-scope for the client. +/// This is done by calling performScopeQuery() on the object which is +/// considered the "scope" object. This could be a simulation avatar of the character, +/// a flyby camera, a vehicle the user is controlling, or something else. +/// - Second, it instructs the client to create "ghost" instances of those objects +/// to represent the source objects on the server. Finally, it sends updates +/// to the ghosts of those objects whose state has been updated on the server, +/// prioritizing the updates based on how relevant the object is to that particular client. +/// +/// There several significant advantages to using this networking system: +/// - Efficient network usage, since we only send data that has changed. In addition, +/// since we only care about most-recent data, if a packet is dropped, we don't waste +/// effort trying to deliver stale data. +/// - Cheating protection; since TNL doesn't deliver information about game objects which +/// aren't "in scope", the ability for clients to learn about objects outside their immediate +/// perceptions can be curtailed by an agressive scoping function. +/// +/// @section NetObject_Implementation An Example Implementation +/// +/// The basis of the ghost implementation in TNL is NetObject. Each NetObject maintains an updateMask, +/// a 32 bit word representing up to 32 independent states for the object. When a NetObject's state changes +/// it calls the setMaskBits method to notify the network layer that the state has changed and needs to be +/// updated on all clients that have that NetObject in scope. +/// +/// Using a NetObject is very simple; let's go through a simple example implementation: +/// +/// @code +/// class SimpleNetObject : public NetObject +/// { +/// public: +/// typedef NetObject Parent; +/// TNL_DECLARE_CLASS(SimpleNetObject); +/// @endcode +/// +/// Above is the standard boilerplate code for a NetObject subclass. +/// +/// @code +/// char message1[256]; +/// char message2[256]; +/// enum States { +/// Message1Mask = BIT(0), +/// Message2Mask = BIT(1), +/// }; +/// @endcode +/// +/// The example class has two object "states" that each instance keeps track of, message1 and message2. +/// A real game object might have states for health, velocity and position, or some other set of fields. +/// Each class has 32 bits to work with, so it's possible to be very specific when defining states. +/// In general, individual state bits should be assigned only to things that are updated independently - +/// so if you update the position field and the velocity at the same time always, you could use a single +/// bit to represent that state change. +/// +/// @code +/// SimpleNetObject() +/// { +/// // in order for an object to be considered by the network system, +/// // the Ghostable net flag must be set. +/// // the ScopeAlways flag indicates that the object is always scoped +/// // on all active connections. +/// mNetFlags.set(ScopeAlways | Ghostable); +/// strcpy(message1, "Hello World 1!"); +/// strcpy(message2, "Hello World 2!"); +/// } +/// @endcode +/// +/// Here is the constructor. The code initializes the net flags, indicating that +/// the SimpleNetObject should always be scoped, and that it can be ghosted to remote hosts +/// +/// @code +/// U32 packUpdate(GhostConnection *, U32 mask, BitStream *stream) +/// { +/// // check which states need to be updated, and write updates +/// if(stream->writeFlag(mask & Message1Mask)) +/// stream->writeString(message1); +/// if(stream->writeFlag(mask & Message2Mask)) +/// stream->writeString(message2); +/// +/// // the return value from packUpdate can set which states still +/// // need to be updated for this object. +/// return 0; +/// } +/// @endcode +/// +/// Here's half of the meat of the networking code, the packUpdate() function. (The other half, unpackUpdate(), +/// is shown below.) The comments in the code pretty much explain everything, however, notice that the +/// code follows a pattern of if(writeFlag(mask & StateMask)) { ... write data ... }. The packUpdate()/unpackUpdate() +/// functions are responsible for reading and writing the update flags to the BitStream. This means the GhostConnection +/// doesn't have to send the 32 bit updateMask with every packet. +/// +/// @code +/// void unpackUpdate(GhostConnection *, BitStream *stream) +/// { +/// // the unpackUpdate function must be symmetrical to packUpdate +/// if(stream->readFlag()) +/// { +/// stream->readString(message1); +/// logprintf("Got message1: %s", message1); +/// } +/// if(stream->readFlag()) +/// { +/// stream->readString(message2); +/// logprintf("Got message2: %s", message2); +/// } +/// } +/// @endcode +/// +/// The other half of the networking code in any NetObject, unpackUpdate(). In SimpleNetObject, all +/// the code does is print the new messages to the log; however, in a more advanced object, the code might +/// trigger animations, update complex object properties, or even spawn new objects, based on what packet +/// data is unpacked. +/// +/// @code +/// void setMessage1(const char *msg) +/// { +/// setMaskBits(Message1Mask); +/// strcpy(message1, msg); +/// } +/// void setMessage2(const char *msg) +/// { +/// setMaskBits(Message2Mask); +/// strcpy(message2, msg); +/// } +/// @endcode +/// +/// Here are the accessors for the two properties. It is good to encapsulate state +/// variables, so that you don't have to remember to make a call to setMaskBits every time you change +/// anything; the accessors can do it for you. In a more complex object, you might need to set +/// multiple mask bits when you change something; this can be done using the | operator, for instance, +/// setMaskBits( Message1Mask | Message2Mask ); if you changed both messages. +/// +/// @code +/// TNL_IMPLEMENT_NETOBJECT(SimpleNetObject); +/// @endcode +/// +/// Finally, we use the NetObject implementation macro, TNL_IMPLEMENT_NETOBJECT(), to implement our +/// NetObject. It is important that we use this, as it makes TNL perform certain initialization tasks +/// that allow us to send the object over the network. TNL_IMPLEMENT_CLASS() doesn't perform these tasks, see +/// the documentation on NetClassRep for more details. +/// +/// @nosubgrouping + +class NetObject : public Object +{ + friend class GhostConnection; + friend class GhostAlwaysObjectEvent; + friend class NetObjectRPCEvent; + + typedef Object Parent; + + NetObject *mPrevDirtyList; + NetObject *mNextDirtyList; + U32 mDirtyMaskBits; + + static NetObject *mDirtyList; + U32 mNetIndex; ///< The index of this ghost on the other side of the connection. + GhostInfo *mFirstObjectRef; ///< Head of the linked list of GhostInfos for this object. + + static bool mIsInitialUpdate; ///< Managed by GhostConnection - set to true when this is an initial update + SafePtr mServerObject; ///< Direct pointer to the parent object on the server if it is a local connection + GhostConnection *mOwningConnection; ///< The connection that owns this ghost, if it's a ghost +protected: + enum NetFlag + { + IsGhost = BIT(1), ///< Set if this is a ghost. + ScopeLocal = BIT(2), ///< If set, this object ghosts only to the local client. + Ghostable = BIT(3), ///< Set if this object can ghost at all. + MaxNetFlagBit = 15 + }; + + BitSet32 mNetFlags; ///< Flags field describing this object, from NetFlag. + + /// RPC method source connection + static GhostConnection *mRPCSourceConnection; + + /// NetObject RPC method destination connection. + static GhostConnection *mRPCDestConnection; + + /// Returns true if this pack/unpackUpdate is the initial one for the object + bool isInitialUpdate() { return mIsInitialUpdate; } +public: + NetObject(); + ~NetObject(); + + /// collapseDirtyList pushes all the mDirtyMaskBits down into + /// the GhostInfo's for each object, and clears out the dirty + /// list. + static void collapseDirtyList(); + + /// Returns the connection from which the current RPC method originated, + /// or NULL if not currently within the processing of an RPC method call. + static GhostConnection *getRPCSourceConnection() { return mRPCSourceConnection; } + + /// Sets the connection to which all NetObject RPCs will be destined. Calling this function + /// with a NULL value will target NetObject RPCs to every connection for which that object is + /// currently ghosted. + static void setRPCDestConnection(GhostConnection *destConnection) { mRPCDestConnection = destConnection; } + + /// Returns the connection that serves as the destination of NetObject RPC method calls. + static GhostConnection *getRPCDestConnection() { return mRPCDestConnection; } + + /// onGhostAdd is called on the client side of a connection after + /// the constructor and after the first call to unpackUpdate (the + /// initial call). Returning true signifies no error - returning + /// false causes the connection to abort. + virtual bool onGhostAdd(GhostConnection *theConnection); + + /// onGhostRemove is called on the client side before the destructor + /// when ghost has gone out of scope and is about to be deleted from the client. + virtual void onGhostRemove(); + + /// onGhostAvailable is called on the server side after the server knows that + /// the ghost is available and addressable via the getGhostIndex(). + virtual void onGhostAvailable(GhostConnection *theConnection); + + /// Notify the network system that one or more of this object's states have + /// been changed. + /// + /// @note This is a server side call. It has no meaning for ghosts. + void setMaskBits(U32 orMask); + + /// Notify the network system that one or more of its states does not + /// need to be updated. + /// + /// @note This is a server side call. It has no meaning for ghosts. + void clearMaskBits(U32 orMask); + + /// Called to determine the relative update priority of an object. + /// + /// All objects that are in scope and that have out of date + /// states are queried and sorted by priority before being updated. If there + /// is not enough room in a single packet for all out of date objects, the skipped + /// objects will have an incremented updateSkips the next time that connection + /// prepares to send a packet. Typically the update priority is scaled by + /// updateSkips so that as data becomes stale, it becomes more of a priority to + /// update. + virtual F32 getUpdatePriority(NetObject *scopeObject, U32 updateMask, S32 updateSkips); + + /// Write the object's state to a packet. + /// + /// packUpdate is called on an object when it is to be written into a + /// packet stream for transmission to the client. The updateMask parameter + /// contains the out-of-date state mask for the object. The initial update mask + /// for any object to a client will always be 0xFFFFFFFF, signifying that all + /// states are out of date. It is often useful to check for this mask, to write + /// one-time initialization information for that object. + virtual U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + + /// Unpack data written by packUpdate(). + /// + /// unpackUpdate is called on the client to read an update out of a + /// packet's bit stream. Because the update mask is not encoded by + /// the network system directly, each unpack update function will have + /// to determine from the bit stream which states are being updated. + virtual void unpackUpdate(GhostConnection *connection, BitStream *stream); + + /// For a scope object, determine what is in scope. + /// + /// performScopeQuery is called on a NetConnection's scope object + /// to determine which objects in the world are in scope for that + /// connection. + virtual void performScopeQuery(GhostConnection *connection); + + /// getNetIndex returns the index tag used to identify the server copy + /// of a client object. + U32 getNetIndex() { return mNetIndex; } + + /// isGhost returns true if this object is a ghost of a server object. + bool isGhost() const; + + /// isScopeLocal returns true if this object is scoped always to the + /// local client. + bool isScopeLocal() const; + + /// isGhostable returns true if this object can be ghosted to any clients. + bool isGhostable() const; + + /// Return a hash for this object. + /// + /// @note This is based on its location in memory. + U32 getHashId() const; + + /// Internal method called by NetObject RPC events when they are packed. + void postRPCEvent(NetObjectRPCEvent *theEvent); + +}; + +inline bool NetObject::isGhost() const +{ + return mNetFlags.test(IsGhost); +} + +inline bool NetObject::isScopeLocal() const +{ + return mNetFlags.test(ScopeLocal); +} + +inline bool NetObject::isGhostable() const +{ + return mNetFlags.test(Ghostable); +} + +inline U32 NetObject::getHashId() const +{ + const NetObject *ret = this; + return *((U32 *) &ret); +} + +/// The TNL_IMPLEMENT_NETOBJECT macro should be used for all subclasses of NetObject that +/// will be transmitted with the ghosting system. +#define TNL_IMPLEMENT_NETOBJECT(className) \ + TNL::NetClassRep* className::getClassRep() const { return &className::dynClassRep; } \ + TNL::NetClassRepInstance className::dynClassRep(#className, TNL::NetClassGroupGameMask, TNL::NetClassTypeObject, 0) + +/// Direction that a NetObject RPC method call should travel. +enum NetObjectRPCDirection { + RPCToGhost = 1, + RPCToGhostParent = 2, +}; + +/// Event class for handling RPC method invocations on NetObjects. +/// +/// When an RPC method is called on the server side NetObject, it +/// is broadcast to all connections that have that NetObject in scope. +/// When an RPC method is called on a ghost (on the client), it is +/// handled by the originating server object. +class NetObjectRPCEvent : public RPCEvent +{ +public: + /// Destination object of the RPC invocation + SafePtr mDestObject; + + /// Direction this RPC should travel + NetObjectRPCDirection mRPCDirection; + + /// Constructor - initializes the base class's data + NetObjectRPCEvent(NetObject *destObject, RPCGuaranteeType type, NetObjectRPCDirection dir) : + RPCEvent(type, RPCDirAny) { mDestObject = destObject; mRPCDirection = dir; } + void pack(EventConnection *ps, BitStream *bstream); + void unpack(EventConnection *ps, BitStream *bstream); + void process(EventConnection *ps); +}; + +/// Macro used to declare the implementation of an RPC method on a NetObject subclass. +/// +/// The macro should be used in place of a member function parameter declaration, +/// with the body code (to be executed on the remote side of the RPC) immediately +/// following the TNL_IMPLEMENT_NETOBJECT_RPC macro call. +#define TNL_IMPLEMENT_NETOBJECT_RPC(className, name, args, argNames, groupMask, guaranteeType, eventDirection, rpcVersion) \ +class RPCEV_##className##_##name : public TNL::NetObjectRPCEvent { \ +public: \ + TNL::FunctorDecl mFunctorDecl;\ + RPCEV_##className##_##name(TNL::NetObject *theObject = NULL) : TNL::NetObjectRPCEvent(theObject, guaranteeType, eventDirection), mFunctorDecl(&className::name##_remote) { mFunctor = &mFunctorDecl; } \ + TNL_DECLARE_CLASS( RPCEV_##className##_##name ); \ + bool checkClassType(TNL::Object *theObject) { return dynamic_cast(theObject) != NULL; } }; \ + TNL_IMPLEMENT_NETEVENT( RPCEV_##className##_##name, groupMask, rpcVersion ); \ + void className::name args { RPCEV_##className##_##name *theEvent = new RPCEV_##className##_##name(this); theEvent->mFunctorDecl.set argNames ; postRPCEvent(theEvent); } \ + TNL::NetEvent * className::name##_construct args { RPCEV_##className##_##name *theEvent = new RPCEV_##className##_##name(this); theEvent->mFunctorDecl.set argNames ; return theEvent; } \ + void className::name##_remote args + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlNetStringTable.h b/tnl-1.5.0/tnl/tnl/tnlNetStringTable.h new file mode 100644 index 0000000000000000000000000000000000000000..3d8228ac17a1277a8bd335c45d066385aa6a07d4 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNetStringTable.h @@ -0,0 +1,186 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NETSTRINGTABLE_H_ +#define _TNL_NETSTRINGTABLE_H_ + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +namespace TNL { + + +typedef U32 StringTableEntryId; + +//-------------------------------------- +/// A global table for the hashing and tracking of network strings. +/// +namespace StringTable +{ + /// Adds a string to the string table, and returns the id of the string. + /// + /// @param string String to check in the table (and add). + /// @param caseSens Determines whether case matters. + StringTableEntryId insert(const char *string, bool caseSens = true); + + /// Adds a string to the string table, and returns the id of the string. + /// + /// @param string String to check in the table (and add). + /// @param len Length of the string in bytes. + /// @param caseSens Determines whether case matters. + StringTableEntryId insertn(const char *string, S32 len, bool caseSens = true); + + /// Determines if a string is in the string table, and returns the id of the string, or 0 if the string is not in the table. + /// + /// @param string String to check in the table (but not add). + /// @param caseSens Determines whether case matters. + StringTableEntryId lookup(const char *string, bool caseSens = true); + + /// Determines if a string is in the string table, and returns the id of the string, or 0 if the string is not in the table. + /// + /// @param string String to check in the table (but not add). + /// @param len Length of string in bytes. + /// @param caseSens Determines whether case matters. + StringTableEntryId lookupn(const char *string, S32 len, bool caseSens = true); + + /// Hash a string into a U32. + U32 hashString(const char* in_pString); + + /// Hash a string of given length into a U32. + U32 hashStringn(const char* in_pString, S32 len); + + void incRef(StringTableEntryId index); + void decRef(StringTableEntryId index); + const char *getString(StringTableEntryId index); +}; + +/// The StringTableEntry class encapsulates an entry in the network StringTable. +/// StringTableEntry instances offer several benefits over normal strings in +/// a networked simulation. First, the ConnectionStringTable class is able to +/// cache string transfers, meaning that recently used strings will be transmitted +/// as string data once and then referred to by a short id bitfield thereafter. +/// String comparison operations are also much less expensive with StringTableEntry +/// instances as they result in just a single integer comparison. + +class StringTableEntry { +private: + StringTableEntryId mIndex; ///< index of the string table entry in the master pointer list +public: + /// empty constructor gets NULL string automatically. + inline StringTableEntry() + { + mIndex = 0; + } + inline StringTableEntry(const char *string, bool caseSensitive = true) + { + mIndex = StringTable::insert(string, caseSensitive); + } + inline StringTableEntry(const StringTableEntry &theString) + { + mIndex = theString.mIndex; + incRef(); + } + StringTableEntry &operator= (const StringTableEntry &s) + { + decRef(); + mIndex = s.mIndex; + incRef(); + return *this; + } + StringTableEntry &operator= (const char *string) + { + decRef(); + mIndex = StringTable::insert(string); + return *this; + } + + inline void set(const char *string, bool caseSensitive = true) + { + decRef(); + mIndex = StringTable::insert(string, caseSensitive); + } + + inline void setn(const char *string, U32 len, bool caseSensitive = true) + { + decRef(); + mIndex = StringTable::insertn(string, len, caseSensitive); + } + + bool operator== (const StringTableEntry &s) const + { + return s.mIndex == mIndex; + } + bool operator!= (const StringTableEntry &s) const + { + return s.mIndex != mIndex; + } + inline bool isNull() const + { + return mIndex == 0; + } + inline bool isNotNull() const + { + return mIndex != 0; + } + inline bool isValid() const + { + return mIndex != 0; + } + + operator bool () const + { + return mIndex != 0; + } + + inline void decRef() + { + if(mIndex) + StringTable::decRef(mIndex); + } + + inline void incRef() + { + if(mIndex) + StringTable::incRef(mIndex); + } + + inline U32 getIndex() const + { + return mIndex; + } + + inline const char *getString() const + { + return StringTable::getString(mIndex); + } +}; + +typedef const StringTableEntry &StringTableEntryRef; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlNonce.h b/tnl-1.5.0/tnl/tnl/tnlNonce.h new file mode 100644 index 0000000000000000000000000000000000000000..834d38808ebec36ec8c70c33a9e717826ba602b2 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlNonce.h @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_NONCE_H_ +#define _TNL_NONCE_H_ + +#ifndef _TNL_BITSTREAM_H_ +#include "tnlBitStream.h" +#endif + +#ifndef _TNL_RANDOM_H_ +#include "tnlRandom.h" +#endif + +namespace TNL +{ + +struct Nonce +{ + enum { + NonceSize = 8, + }; + U8 data[NonceSize]; + + Nonce() {} + Nonce(const U8 *ptr) { memcpy(data, ptr, NonceSize); } + + bool operator==(const Nonce &theOtherNonce) const { return !memcmp(data, theOtherNonce.data, NonceSize); } + bool operator!=(const Nonce &theOtherNonce) const { return memcmp(data, theOtherNonce.data, NonceSize) != 0; } + + void operator=(const Nonce &theNonce) { memcpy(data, theNonce.data, NonceSize); } + + void read(BitStream *stream) { stream->read(NonceSize, data); } + void write(BitStream *stream) const { stream->write(NonceSize, data); } + void getRandom() { Random::read(data, NonceSize); } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlPlatform.h b/tnl-1.5.0/tnl/tnl/tnlPlatform.h new file mode 100644 index 0000000000000000000000000000000000000000..4385fb5a71f79416a12f283da905d6b543a66798 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlPlatform.h @@ -0,0 +1,128 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_PLATFORM_H_ +#define _TNL_PLATFORM_H_ + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +namespace TNL { + +/// Platform specific functionality is gathered here to enable easier porting. +/// +/// If you are embedding TNL in a complex application, you may want to replace +/// these with hooks to your own code - for instance the alerts really should +/// bring up an actual message box; currently they just emit a log item. +namespace Platform +{ + /// Prints a string to the OS specific debug log. + void outputDebugString(const char *string); + + /// Stops the program in the debugger, if it is being debugged. + void debugBreak(); + + /// Forces the program to exit immediately. + /// + /// @note This is probably a bit strong for a networking library. -- BJG + void forceQuit(); + + /// Brings up a dialog window with a message and an "OK" button + void AlertOK(const char *windowTitle, const char *message); + + /// Brings up a dialog window with the message, and "OK" and "Cancel" buttons + bool AlertOKCancel(const char *windowTitle, const char *message); + + /// Brings up a dialog window with the message, and "Retry" and "Cancel" buttons + bool AlertRetry(const char *windowTitle, const char *message); + + /// Elapsed time in milliseconds. + /// + /// Usually since last reboot, but it varies from platform to platform. It is + /// guaranteed to always increase, however, up to the limit of a U32 - about + /// 7 weeks worth of time. If you are developing a server you want to run for longer + /// than that, prepared to see wraparounds. + U32 getRealMilliseconds(); + + /// Returns a high-precision time value, in a platform-specific time value + S64 getHighPrecisionTimerValue(); + + /// Converts a high precision timer delta into milliseconds + F64 getHighPrecisionMilliseconds(S64 timerDelta); + + /// Put the process to sleep for the specified millisecond interva. + void sleep(U32 msCount); + + /// checks the status of the memory allocation heap + bool checkHeap(); +}; + + +#define TIME_BLOCK(name,block) { S64 st = Platform::getHighPrecisionTimerValue(); {block} S64 delta = Platform::getHighPrecisionTimerValue() - st; F64 ms = Platform::getHighPrecisionMilliseconds(delta); logprintf("Timer: %s Elapsed: %g ms", #name, ms); } + +#if defined (TNL_SUPPORTS_VC_INLINE_X86_ASM) || defined (TNL_SUPPORTS_MWERKS_INLINE_X86_ASM) +#define TNL_DEBUGBREAK() { __asm { int 3 }; } +#elif defined(TNL_SUPPORTS_GCC_INLINE_X86_ASM) +#define TNL_DEBUGBREAK() { asm ( "int $3"); } +#else +/// Macro to do in-line debug breaks, used for asserts. Does inline assembly where appropriate +#define TNL_DEBUGBREAK() Platform::debugBreak(); +#endif + +#define TNL_CHECK_HEAP() { bool status = TNL::Platform::checkHeap(); if(!status) TNL_DEBUGBREAK(); } + +extern bool atob(const char *str); ///< String to boolean conversion. + +/// Printf into string with a buffer size. +/// +/// This will print into the specified string until the buffer size is reached. +extern int dSprintf(char *buffer, U32 bufferSize, const char *format, ...); + +/// Vsprintf with buffer size argument. +/// +/// This will print into the specified string until the buffer size is reached. +extern int dVsprintf(char *buffer, U32 bufferSize, const char *format, void *arglist); ///< compiler independent + +inline char dToupper(const char c) { if (c >= char('a') && c <= char('z')) return char(c + 'A' - 'a'); else return c; } ///< Converts an ASCII character to upper case. +inline char dTolower(const char c) { if (c >= char('A') && c <= char('Z')) return char(c - 'A' + 'a'); else return c; } ///< Converts an ASCII character to lower case. + +#define QSORT_CALLBACK FN_CDECL + +}; + +#include +#include + +#if defined (__GNUC__) + +int stricmp(const char *str1, const char *str2); +int strnicmp(const char *str1, const char *str2, unsigned int len); + +#endif + + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlRPC.h b/tnl-1.5.0/tnl/tnl/tnlRPC.h new file mode 100644 index 0000000000000000000000000000000000000000..d1a2b4a68dd86acdb7305ca27dc1393290ac3783 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlRPC.h @@ -0,0 +1,200 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_RPC_H_ +#define _TNL_RPC_H_ + +#ifndef _TNL_NETEVENT_H_ +#include "tnlNetEvent.h" +#endif + +#ifndef _TNL_METHODDISPATCH_H_ +#include "tnlMethodDispatch.h" +#endif + +namespace TNL { + +/*! @page rpcdesc RPC in the Torque Network Library + +The Torque Network Library has a powerful, yet simple to use Remote +Procedure Call framework for passing information through a network +connection. Subclasses of EventConnection and NetObject can declare +member functions using the RPC macros so that when called the function +arguments are sent to the remote EventConnection or NetObject(s) associated +with that object. + +For example, suppose you have a connection class called SimpleEventConnection: +@code +class SimpleEventConnection : public EventConnection +{ +public: + TNL_DECLARE_RPC(rpcPrintString, (StringPtr theString, U32 messageCount)); +}; + +TNL_IMPLEMENT_RPC(SimpleEventConnection, rpcPrintString, + (StringPtr theString, messageCount), (theString, messageCount), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirAny, 0) +{ + for(U32 i = 0; i < messageCount; i++) + printf("%s", theString.getString()); +} + + ... +void somefunction(SimpleEventConnection *connection) +{ + connection->rpcPrintString("Hello World!", 5); +} +@endcode + +In this example the class SimpleEventConnection is declared to have +a single RPC method named rpcPrintString. The TNL_DECLARE_RPC macro +can just be viewed as a different way of declaring a class's member functions, +with the name as the first argument and the parenthesized parameter list +as the second. Since RPC calls execute on a remote host, they never have +a return value - although a second RPC could be declared to pass messages +in the other direction. + +The body of the RPC method is declared using the TNL_IMPLEMENT_RPC macro, +which has some additional arguments: the named parameter list without the types, +which NetClassMask the RPC is valid in, what level of data guarantee it uses, +the direction it is allowed to be called on the connection and a version number. +The body of the function, which in this case prints the passed message "Hello, World!" 5 times +to stdout, is executed on the remote host from which the method was originally invoked. + +As the somefunction code demonstrates, RPC's are invoked in the same way +as any other member function in the class. + +RPCs behave like virtual functions in that their bodies can be overridden +in subclasses that want to implement new behavior for the message. The class +declaration for an overridden RPC should include the TNL_DECLARE_RPC_OVERRIDE +macro used for each method that will be redefined. The TNL_IMPLEMENT_RPC_OVERRIDE +macro should be used outside the declaration of the class to implement +the body of the new RPC. + +Internally the RPC macros construct new NetEvent classes and encapsulate the +function call arguments using the FunctorDecl template classes. By default +the following types are allowed as parameters to RPC methods: + + - S8, U8 + - S16, U16 + - S32, U32 + - F32 + - Int<> + - SignedInt<> + - Float<> + - SignedFloat<> + - RangedU32<> + - bool + - StringPtr + - StringTableEntry + - ByteBufferPtr + - IPAddress + - Vector<> of all the preceding types + +New types can be supported by implementing a template override for the +Types::read and Types::write functions. All arguments to RPCs must be +passed by value (ie no reference or pointer types). + +The Int, SignedInt, Float, SignedFloat and RangedU32 template types use the +template parameter(s) to specify the number of bits necessary to transmit that +variable across the network. For example: + +@code + ... + TNL_DECLARE_RPC(someTestFunction, (Int<4> fourBitInt, SignedFloat<7> aFloat, + RangedU32<100, 199> aRangedU32); + ... +@endcode +The preceding RPC method would use 4 + 7 + 7 = 18 bits to transmit the arguments +to the function over the network, not including the RPC event overhead. +*/ + +/// Enumeration for valid directions that RPC messages can travel +enum RPCDirection { + RPCDirAny = NetEvent::DirAny, ///< This RPC can be sent from the server or the client + RPCDirServerToClient = NetEvent::DirServerToClient,///< This RPC can only be sent from the server to the client + RPCDirClientToServer = NetEvent::DirClientToServer,///< This RPC can only be sent from the client to the server +}; + +/// Type of data guarantee this RPC should use +enum RPCGuaranteeType { + RPCGuaranteedOrdered = NetEvent::GuaranteedOrdered, ///< RPC event delivery is guaranteed and will be processed in the order it was sent relative to other ordered events and RPCs + RPCGuaranteed = NetEvent::Guaranteed, ///< RPC event delivery is guaranteed and will be processed in the order it was received + RPCUnguaranteed = NetEvent::Unguaranteed ///< Event delivery is not guaranteed - however, the event will remain ordered relative to other unguaranteed events +}; + +/// Macro used to declare the implementation of an RPC method on an EventConnection subclass. +/// +/// The macro should be used in place of a member function parameter declaration, +/// with the body code (to be executed on the remote side of the RPC) immediately +/// following the TNL_IMPLEMENT_RPC macro call. +#define TNL_IMPLEMENT_RPC(className, name, args, argNames, groupMask, guaranteeType, eventDirection, rpcVersion) \ +class RPC_##className##_##name : public TNL::RPCEvent { \ +public: \ + TNL::FunctorDecl mFunctorDecl;\ + RPC_##className##_##name() : TNL::RPCEvent(guaranteeType, eventDirection), mFunctorDecl(&className::name##_remote) { mFunctor = &mFunctorDecl; } \ + TNL_DECLARE_CLASS( RPC_##className##_##name ); \ + bool checkClassType(TNL::Object *theObject) { return dynamic_cast(theObject) != NULL; } }; \ + TNL_IMPLEMENT_NETEVENT( RPC_##className##_##name, groupMask, rpcVersion ); \ + void className::name args { RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->mFunctorDecl.set argNames ; postNetEvent(theEvent); } \ + TNL::NetEvent * className::name##_construct args { RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->mFunctorDecl.set argNames ; return theEvent; } \ + void className::name##_test args { RPC_##className##_##name *theEvent = new RPC_##className##_##name; theEvent->mFunctorDecl.set argNames ; TNL::PacketStream ps; theEvent->pack(this, &ps); ps.setBytePosition(0); theEvent->unpack(this, &ps); theEvent->process(this); } \ + void className::name##_remote args + +/// Base class for RPC events. +/// +/// All declared RPC methods create subclasses of RPCEvent to send data across the wire +class RPCEvent : public NetEvent +{ +public: + Functor *mFunctor; + /// Constructor call from within the rpcSomething method generated by the TNL_IMPLEMENT_RPC macro. + RPCEvent(RPCGuaranteeType gType, RPCDirection dir); + void pack(EventConnection *ps, BitStream *bstream); + void unpack(EventConnection *ps, BitStream *bstream); + virtual bool checkClassType(Object *theObject) = 0; + + void process(EventConnection *ps); +}; + +/// Declares an RPC method within a class declaration. Creates two method prototypes - one for the host side of the RPC call, and one for the receiver, which performs the actual method. +#define TNL_DECLARE_RPC(name, args) void name args; void name##_test args; virtual TNL::NetEvent * name##_construct args; virtual void name##_remote args + +/// Declares an override to an RPC method declared in a parent class. +#define TNL_DECLARE_RPC_OVERRIDE(name, args) void name##_remote args + +/// Macro used to declare the body of an overridden RPC method. +#define TNL_IMPLEMENT_RPC_OVERRIDE(className, name, args) \ + void className::name##_remote args + +/// Constructs a NetEvent that will represent the specified RPC invocation. This +/// macro is used to construct a single RPC that can then be posted to multiple +/// connections, instead of allocating an RPCEvent for each connection. +#define TNL_RPC_CONSTRUCT_NETEVENT(object, rpcMethod, args) (object)->rpcMethod##_construct args + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlRandom.h b/tnl-1.5.0/tnl/tnl/tnlRandom.h new file mode 100644 index 0000000000000000000000000000000000000000..c015a5a80b5e23babfd9ce594f53bff3c27d4d2e --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlRandom.h @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_RANDOM_H_ +#define _TNL_RANDOM_H_ + + +#ifndef _TNL_H_ +#include "tnl.h" +#endif + +namespace TNL { + +/// The Random namespace is an interface to a cryptographically secure +/// pseudo random number generator (PRNG). Internally the Random namespace +/// uses the Yarrow PRNG algorithm. +namespace Random { + +/// Adds random "seed" data to the random number generator +void addEntropy(const U8 *randomData, U32 dataLen); + +/// Reads random byte data from the random number generator +void read(U8 *outBuffer, U32 randomLen); + +/// Reads a 0...U32_MAX random number from the random number generator +U32 readI(); + +/// Reads a random number between rangeStart and rangeEnd inclusive from the random number generator +U32 readI(U32 rangeStart, U32 rangeEnd); + +/// Reads a floating point value from 0 to 1 from the random number generator +F32 readF(); + +/// Returns a single random bit. +bool readB(); + +/// Returns an opaque pointer to the random number generator's internal state +/// for use in certain encryption functions. +void *getState(); +}; + +}; + +#endif //_TNL_RANDOM_H_ diff --git a/tnl-1.5.0/tnl/tnl/tnlString.h b/tnl-1.5.0/tnl/tnl/tnlString.h new file mode 100644 index 0000000000000000000000000000000000000000..c3ffe9b06fd6e43728d36f34b152cbec13dc7103 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlString.h @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_STRING_H_ +#define _TNL_STRING_H_ + +namespace TNL +{ + +struct StringData +{ + U32 mRefCount; + char mStringData[1]; +}; + +class StringPtr +{ + StringData *mString; + void alloc(const char *string) + { + mString = (StringData *) malloc(sizeof(StringData) + strlen(string)); + strcpy(mString->mStringData, string); + mString->mRefCount = 1; + } + void decRef() + { + if(mString && !--mString->mRefCount) + free(mString); + } +public: + StringPtr() + { + mString = NULL; + } + StringPtr(const char *string) + { + alloc(string); + } + StringPtr(const StringPtr &string) + { + mString = string.mString; + if(mString) + mString->mRefCount++; + } + ~StringPtr() + { + decRef(); + } + StringPtr &operator=(const StringPtr &ref) + { + decRef(); + mString = ref.mString; + mString->mRefCount++; + return *this; + } + StringPtr &operator=(const char *string) + { + decRef(); + alloc(string); + return *this; + } + operator const char *() const + { + if(mString) + return mString->mStringData; + else + return ""; + } + const char *getString() const + { + if(mString) + return mString->mStringData; + else + return ""; + } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlSymmetricCipher.h b/tnl-1.5.0/tnl/tnl/tnlSymmetricCipher.h new file mode 100644 index 0000000000000000000000000000000000000000..0cc453d8f38f50331ef3e4280a4ec17cb380e1d0 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlSymmetricCipher.h @@ -0,0 +1,70 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_SYMMETRICCIPHER_H_ +#define _TNL_SYMMETRICCIPHER_H_ + +#ifndef _TNL_NETBASE_H_ +#include "tnlNetBase.h" +#endif + +namespace TNL +{ + +class ByteBuffer; + +/// Class for symmetric encryption of data across a connection. Internally it uses +/// the libtomcrypt AES algorithm to encrypt the data. +class SymmetricCipher : public Object +{ +public: + enum { + BlockSize = 16, + KeySize = 16, + }; +private: + struct Key + { + U32 eK[64], dK[64]; + int Nr; + }; + U32 mCounter[BlockSize >> 2]; + U32 mInitVector[BlockSize]; + U8 mPad[BlockSize]; + Key mSymmetricKey; + U32 mPadLen; +public: + SymmetricCipher(const U8 symmetricKey[KeySize], const U8 initVector[BlockSize]); + SymmetricCipher(const ByteBuffer *theByteBuffer); + + void setupCounter(U32 counterValue1, U32 counterValue2, U32 counterValue3, U32 counterValue4); + void encrypt(const U8 *plainText, U8 *cipherText, U32 len); + void decrypt(const U8 *cipherText, U8 *plainText, U32 len); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlThread.h b/tnl-1.5.0/tnl/tnl/tnlThread.h new file mode 100644 index 0000000000000000000000000000000000000000..9133ba9adf0c230047f63e73a841b8458908d7b5 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlThread.h @@ -0,0 +1,215 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNLTHREAD_H_ +#define _TNLTHREAD_H_ + +#include "tnl.h" +#include "tnlNetBase.h" +#include "tnlMethodDispatch.h" + +#if defined (TNL_OS_WIN32) +#include +#else +#include +#include +#endif + +namespace TNL +{ + +/// Platform independent semaphore class. +/// +/// The semaphore class wraps OS specific semaphore functionality for thread synchronization. +class Semaphore +{ +#ifdef TNL_OS_WIN32 + HANDLE mSemaphore; +#else + sem_t mSemaphore; +#endif +public: + /// Semaphore constructor - initialCount specifies how many wait calls + /// will be let through before an increment is required. + Semaphore(U32 initialCount = 0, U32 maximumCount = 1024); + ~Semaphore(); + + /// Thread calling wait will block as long as the semaphore's count + /// is zero. If the semaphore is incremented, one of the waiting threads + /// will be awakened and the semaphore will decrement. + void wait(); + + /// Increments the semaphore's internal count. This will wake + /// count threads that are waiting on this semaphore. + void increment(U32 count = 1); +}; + +/// Platform independent Mutual Exclusion implementation +class Mutex +{ +#ifdef TNL_OS_WIN32 + CRITICAL_SECTION mLock; +#else + pthread_mutex_t mMutex; +#endif +public: + /// Mutex constructor + Mutex(); + /// Mutex destructor + ~Mutex(); + + /// Locks the Mutex. If another thread already has this Mutex + /// locked, this call will block until it is unlocked. If the lock + /// method is called from a thread that has already locked this Mutex, + /// the call will not block and the thread will have to unlock + /// the mutex for as many calls as were made to lock before another + /// thread will be allowed to lock the Mutex. + void lock(); + + /// Unlocks the Mutex. The behavior of this method is undefined if called + /// by a thread that has not previously locked this Mutex. + void unlock(); + + /// Attempts to acquire a lock to this Mutex, without blocking. + /// Returns true if the calling thread was able to lock the Mutex and + /// false if the Mutex was already locked by another thread. + bool tryLock(); +}; + +/// Platform independent Thread class. +class Thread : public Object +{ +protected: + U32 mReturnValue; ///< Return value from thread function + +#ifdef TNL_OS_WIN32 + HANDLE mThread; +#else + pthread_t mThread; +#endif +public: + /// run function called when thread is started. + virtual U32 run() = 0; + /// Thread constructor. + Thread(); + /// Thread destructor. + ~Thread(); + + /// starts the thread's main run function. + void start(); +}; + +/// Platform independent per-thread storage class. +class ThreadStorage +{ +#ifdef TNL_OS_WIN32 + DWORD mTlsIndex; +#else + pthread_key_t mThreadKey; +#endif +public: + /// ThreadStorage constructor. + ThreadStorage(); + /// ThreadStorage destructor. + ~ThreadStorage(); + + /// returns the per-thread stored void pointer for this ThreadStorage. The default value is NULL. + void *get(); + /// sets the per-thread stored void pointer for this ThreadStorage object. + void set(void *data); +}; + +/// Managing object for a queue of worker threads that pass +/// messages back and forth to the main thread. ThreadQueue +/// methods declared with the TNL_DECLARE_THREADQ_METHOD macro +/// are special -- if they are called from the main thread, +/// they will be executed on one of the worker threads and vice +/// versa. +class ThreadQueue : public Object +{ + class ThreadQueueThread : public Thread + { + ThreadQueue *mThreadQueue; + public: + ThreadQueueThread(ThreadQueue *); + U32 run(); + }; + friend class ThreadQueueThread; + /// list of worker threads on this ThreadQueue + Vector mThreads; + /// list of calls to be processed by the worker threads + Vector mThreadCalls; + /// list of calls to be processed by the main thread + Vector mResponseCalls; + /// Synchronization variable that manages worker threads + Semaphore mSemaphore; + /// Internal Mutex for synchronizing access to thread call vectors. + Mutex mLock; + /// Storage variable that tracks whether this is the main thread or a worker thread. + ThreadStorage mStorage; +protected: + /// Locks the ThreadQueue for access to member variables. + void lock() { mLock.lock(); } + /// Unlocks the ThreadQueue. + void unlock() { mLock.unlock(); } + /// Posts a marshalled call onto either the worker thread call list or the response call list. + void postCall(Functor *theCall); + /// Dispatches the next available worker thread call. Called internally by the worker threads when they awaken from the semaphore. + void dispatchNextCall(); + /// helper function to determine if the currently executing thread is a worker thread or the main thread. + bool isMainThread() { return (bool) mStorage.get(); } + ThreadStorage &getStorage() { return mStorage; } + /// called by each worker thread when it starts for subclass initialization of worker threads. + virtual void threadStart() { } +public: + /// ThreadQueue constructor. threadCount specifies the number of worker threads that will be created. + ThreadQueue(U32 threadCount); + ~ThreadQueue(); + + /// Dispatches all ThreadQueue calls queued by worker threads. This should + /// be called periodically from a main loop. + void dispatchResponseCalls(); +}; + +/// Declares a ThreadQueue method on a subclass of ThreadQueue. +#define TNL_DECLARE_THREADQ_METHOD(func, args) \ + void func args; \ + void func##_body args + +/// Declares the implementation of a ThreadQueue method. +#define TNL_IMPLEMENT_THREADQ_METHOD(className, func, args, argNames) \ + void className::func args { \ + FunctorDecl *theCall = new FunctorDecl(&className::func##_body); \ + theCall->set argNames; \ + postCall(theCall); \ + }\ + void className::func##_body args + + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/tnl/tnlTypes.h b/tnl-1.5.0/tnl/tnl/tnlTypes.h new file mode 100644 index 0000000000000000000000000000000000000000..29b8d258507e4f90027b3e172201a946b9427998 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlTypes.h @@ -0,0 +1,446 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_TYPES_H_ +#define _TNL_TYPES_H_ + + +//-------------------------------------- +// Enable Asserts in all debug builds +#if defined(TNL_DEBUG) +#ifndef TNL_ENABLE_ASSERTS +#define TNL_ENABLE_ASSERTS +#endif +#endif +#include +//inline void* operator new(size_t size, void* ptr) { return ptr; } +#include +namespace TNL { + +#ifndef NULL +# define NULL 0 +#endif + + +//------------------------------------------------------------------------------ +//-------------------------------------- Basic Types... + +/// @defgroup BasicTypes Basic Compiler Independent Types +/// These types are defined so that we know exactly what we have, sign and bit wise. +/// +/// The number represents number of bits, the letters represent Signed, +/// Unsigned, or Floating point (implicitly signed). +/// @{ + +typedef signed char S8; ///< Compiler independent signed char (8bit integer). +typedef unsigned char U8; ///< Compiler independent unsigned char (8bit integer). + +typedef signed short S16; ///< Compiler independent signed 16-bit short integer. +typedef unsigned short U16; ///< Compiler independent unsigned 16-bit short integer. + +typedef signed int S32; ///< Compiler independent signed 32-bit integer. +typedef unsigned int U32; ///< Compiler independent unsigned 32-bit integer. + +typedef float F32; ///< Compiler independent 32-bit float. +typedef double F64; ///< Compiler independent 64-bit float. + +/// @} + +/// NetType serves as a base class for all bit-compressed versions of +/// the base types that can be transmitted using TNL's RPC mechanism. +/// In general, the type names are self-explanatory, providing simple +/// wrappers on the original base types. The template argument for bit +/// counts or numeric ranges is necessary because TNL parses the actual +/// function prototype as a string in order to determine how many bits +/// to use for each RPC parameter. +/// +/// Template parameters to the NetType templates can be either integer +/// constants or enumeration values. If enumeration values are used, +/// the TNL_DECLARE_RPC_ENUM or TNL_DECLARE_RPC_MEM enum macros must +/// be used to register the enumerations with the RPC system. +struct NetType { + +}; + +/// Unsigned integer bit-level RPC template wrapper. +/// +/// When an Int is in the parameter list for an RPC method, that parameter will +/// be transmitted using X bits. +template struct Int : NetType +{ + U32 value; + Int(U32 val=0) { value = val; } + operator U32() const { return value; } + U32 getPrecisionBits() { return bitCount; } +}; + +/// Signed integer bit-level RPC template wrapper. +/// +/// When a SignedInt is in the parameter list for an RPC method, that parameter will +/// be transmitted using X bits. +template struct SignedInt : NetType +{ + S32 value; + SignedInt(S32 val=0) { value = val; } + operator S32() const { return value; } + U32 getPrecisionBits() { return bitCount; } +}; + +/// Floating point 0...1 value bit-level RPC template wrapper. +/// +/// When a Float is in the parameter list for an RPC method, that parameter will +/// be transmitted using X bits. +template struct Float : NetType +{ + F32 value; + Float(F32 val=0) { value = val; } + operator F32() const { return value; } + U32 getPrecisionBits() { return bitCount; } +}; + +/// Floating point -1...1 value bit-level RPC template wrapper. +/// +/// When a SignedFloat is in the parameter list for an RPC method, that parameter will +/// be transmitted using X bits. +template struct SignedFloat : NetType +{ + F32 value; + SignedFloat(F32 val=0) { value = val; } + operator F32() const { return value; } + U32 getPrecisionBits() { return bitCount; } +}; + +/// Unsigned ranged integer bit-level RPC template wrapper. +/// +/// The RangedU32 is used to specify a range of valid values for the parameter +/// in the parameter list for an RPC method. +template struct RangedU32 : NetType +{ + U32 value; + RangedU32(U32 val=rangeStart) { value = val; } + operator U32() const { return value; } +}; + +//------------------------------------------------------------------------------ +//-------------------------------------- Type constants... + +/// @defgroup BasicConstants Global Constants +/// +/// Handy constants! +/// @{ + +#define __EQUAL_CONST_F F32(0.000001) ///< Constant float epsilon used for F32 comparisons + +static const F32 FloatOne = F32(1.0); ///< Constant float 1.0 +static const F32 FloatHalf = F32(0.5); ///< Constant float 0.5 +static const F32 FloatZero = F32(0.0); ///< Constant float 0.0 + +static const F32 FloatPi = F32(3.14159265358979323846); ///< Constant float PI +static const F32 Float2Pi = F32(2.0 * 3.14159265358979323846); ///< Constant float 2*PI +static const F32 FloatInversePi = F32(1.0 / 3.14159265358979323846); ///< Constant float 1 / PI +static const F32 FloatHalfPi = F32(0.5 * 3.14159265358979323846); ///< Constant float 1/2 * PI +static const F32 Float2InversePi = F32(2.0 / 3.14159265358979323846);///< Constant float 2 / PI +static const F32 FloatInverse2Pi = F32(0.5 / 3.14159265358979323846);///< Constant float 2 / PI + +static const F32 FloatSqrt2 = F32(1.41421356237309504880f); ///< Constant float sqrt(2) +static const F32 FloatSqrtHalf = F32(0.7071067811865475244008443f); ///< Constant float sqrt(0.5) + +static const S8 S8_MIN = S8(-128); ///< Constant Min Limit S8 +static const S8 S8_MAX = S8(127); ///< Constant Max Limit S8 +static const U8 U8_MAX = U8(255); ///< Constant Max Limit U8 + +static const S16 S16_MIN = S16(-32768); ///< Constant Min Limit S16 +static const S16 S16_MAX = S16(32767); ///< Constant Max Limit S16 +static const U16 U16_MAX = U16(65535); ///< Constant Max Limit U16 + +static const S32 S32_MIN = S32(-2147483647 - 1); ///< Constant Min Limit S32 +static const S32 S32_MAX = S32(2147483647); ///< Constant Max Limit S32 +static const U32 U32_MAX = U32(0xffffffff); ///< Constant Max Limit U32 + +static const F32 F32_MIN = F32(1.175494351e-38F); ///< Constant Min Limit F32 +static const F32 F32_MAX = F32(3.402823466e+38F); ///< Constant Max Limit F32 + +//---------------------------------------------------------------------------------- +// Identify the compiler and OS specific stuff we need: +//---------------------------------------------------------------------------------- + +#if defined (_MSC_VER) + +typedef signed _int64 S64; +typedef unsigned _int64 U64; + +#define TNL_COMPILER_VISUALC _MSC_VER + +#if _MSC_VER < 1200 + // No support for old compilers +# error "VC: Minimum Visual C++ 6.0 or newer required" +#else //_MSC_VER >= 1200 +# define TNL_COMPILER_STRING "VisualC++" +#endif + +#define for if(false) {} else for ///< Hack to work around Microsoft VC's non-C++ compliance on variable scoping + +// disable warning caused by memory layer +// see msdn.microsoft.com "Compiler Warning (level 1) C4291" for more details +#pragma warning(disable: 4291) +// disable performance warning of integer to bool conversions +#pragma warning(disable: 4800) + +#elif defined(__MWERKS__) && defined(_WIN32) + +typedef signed long long S64; ///< Compiler independent signed 64-bit integer +typedef unsigned long long U64; ///< Compiler independent unsigned 64-bit integer + +#define TNL_COMPILER_STRING "Metrowerks CW Win32" + +#elif defined(__GNUC__) + +typedef signed long long S64; ///< Compiler independent signed 64-bit integer +typedef unsigned long long U64; ///< Compiler independent unsigned 64-bit integer + +#if defined(__MINGW32__) +# define TNL_COMPILER_STRING "GCC (MinGW)" +# define TNL_COMPILER_MINGW +#elif defined(__CYGWIN__) +# define TNL_COMPILER_STRING "GCC (Cygwin)" +# define TNL_COMPILER_MINGW +#else +# define TNL_COMPILER_STRING "GCC " +#endif + +#else +# error "TNL: Unknown Compiler" +#endif + +//---------------------------------------------------------------------------------- +// Identify the target Operating System +//---------------------------------------------------------------------------------- + +#if defined (_XBOX) || defined(__XBOX__) +# define TNL_OS_STRING "XBox" +# define TNL_OS_XBOX +# define FN_CDECL __cdecl + +#elif defined(__WIN32__) || defined(_WIN32) || defined(__CYGWIN__) +# define TNL_OS_STRING "Win32" +# define TNL_OS_WIN32 + +#ifdef TNL_COMPILER_MINGW +# define FN_CDECL +#else +# define FN_CDECL __cdecl +#endif + +#elif defined(linux) +# define TNL_OS_STRING "Linux" +# define TNL_OS_LINUX +# define FN_CDECL + +#elif defined(__OpenBSD__) +# define TNL_OS_STRING "OpenBSD" +# define TNL_OS_OPENBSD +# define FN_CDECL + +#elif defined(__FreeBSD__) +# define TNL_OS_STRING "FreeBSD" +# define TNL_OS_FREEBSD +# define FN_CDECL + +#elif defined(__APPLE__) +# define TNL_OS_MAC +# define TNL_OS_MAC_OSX +# define FN_CDECL + +#else +# error "TNL: Unsupported Operating System" +#endif + + + +//---------------------------------------------------------------------------------- +// Identify the target CPU and assembly language options +//---------------------------------------------------------------------------------- + +#if defined(_M_IX86) || defined(i386) +# define TNL_CPU_STRING "Intel x86" +# define TNL_CPU_X86 +# define TNL_LITTLE_ENDIAN +# define TNL_SUPPORTS_NASM + +# if defined (__GNUC__) +# if __GNUC__ == 2 +# define TNL_GCC_2 +# elif __GNUC__ == 3 +# define TNL_GCC_3 +# else +# error "TNL: Unsupported version of GCC (see tnlMethodDispatch.cpp)" +# endif +# define TNL_SUPPORTS_GCC_INLINE_X86_ASM +# elif defined (__MWERKS__) +# define TNL_SUPPORTS_MWERKS_INLINE_X86_ASM +# else +# define TNL_SUPPORTS_VC_INLINE_X86_ASM +# endif + +#elif defined(__ppc__) +# define TNL_CPU_STRING "PowerPC" +# define TNL_CPU_PPC +# define TNL_BIG_ENDIAN +# ifdef __GNUC__ +# define TNL_SUPPORTS_GCC_INLINE_PPC_ASM +# endif +#else +# error "TNL: Unsupported Target CPU" +#endif + + +/// @} + +///@defgroup ObjTrickery Object Management Trickery +/// +/// These functions are to construct and destruct objects in memory +/// without causing a free or malloc call to occur. This is so that +/// we don't have to worry about allocating, say, space for a hundred +/// NetAddresses with a single malloc call, calling delete on a single +/// NetAdress, and having it try to free memory out from under us. +/// +/// @{ + +/// Constructs an object that already has memory allocated for it. +template +inline T* constructInPlace(T* p) +{ + return new(p) T; +} + +/// Copy constructs an object that already has memory allocated for it. +template +inline T* constructInPlace(T* p, const T* copy) +{ + return new(p) T(*copy); +} + +/// Destructs an object without freeing the memory associated with it. +template +inline void destructInPlace(T* p) +{ + p->~T(); +} + +/// @} + +/// @name GeneralMath Math Helpers +/// +/// Some general numeric utility functions. +/// +/// @{ + +/// Determines if number is a power of two. +inline bool isPow2(const U32 number) +{ + return (number & (number - 1)) == 0; +} + +/// Determines the binary logarithm of the input value rounded down to the nearest power of 2. +inline U32 getBinLog2(U32 value) +{ + F32 floatValue = F32(value); + return (*((U32 *) &floatValue) >> 23) - 127; +} + +/// Determines the binary logarithm of the next greater power of two of the input number. +inline U32 getNextBinLog2(U32 number) +{ + return getBinLog2(number) + (isPow2(number) ? 0 : 1); +} + +/// Determines the next greater power of two from the value. If the value is a power of two, it is returned. +inline U32 getNextPow2(U32 value) +{ + return isPow2(value) ? value : (1 << (getBinLog2(value) + 1)); +} + + +/// @defgroup MinMaxFuncs Many version of min and max +/// +/// We can't use template functions because MSVC6 chokes. +/// +/// So we have these... +/// @{ + +#define DeclareTemplatizedMinMax(type) \ + inline type getMin(type a, type b) { return a > b ? b : a; } \ + inline type getMax(type a, type b) { return a > b ? a : b; } + +DeclareTemplatizedMinMax(U32) +DeclareTemplatizedMinMax(S32) +DeclareTemplatizedMinMax(U16) +DeclareTemplatizedMinMax(S16) +DeclareTemplatizedMinMax(U8) +DeclareTemplatizedMinMax(S8) +DeclareTemplatizedMinMax(F32) +DeclareTemplatizedMinMax(F64) + +/// @} + +inline void writeU32ToBuffer(U32 value, U8 *buffer) +{ + buffer[0] = value >> 24; + buffer[1] = value >> 16; + buffer[2] = value >> 8; + buffer[3] = value; +} + +inline U32 readU32FromBuffer(const U8 *buf) +{ + return (U32(buf[0]) << 24) | + (U32(buf[1]) << 16) | + (U32(buf[2]) << 8 ) | + U32(buf[3]); +} + +inline void writeU16ToBuffer(U16 value, U8 *buffer) +{ + buffer[0] = value >> 8; + buffer[1] = (U8) value; +} + +inline U16 readU16FromBuffer(const U8 *buffer) +{ + return (U16(buffer[0]) << 8) | + U16(buffer[1]); +} + +inline U32 fourByteAlign(U32 value) +{ + return (value + 3) & ~3; +} + +#define BIT(x) (1 << (x)) ///< Returns value with bit x set (2^x) + +}; + +#endif //_TNL_TYPES_H_ diff --git a/tnl-1.5.0/tnl/tnl/tnlUDP.h b/tnl-1.5.0/tnl/tnl/tnlUDP.h new file mode 100644 index 0000000000000000000000000000000000000000..34294af22fcba4c08679bd049081e3611f61423a --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlUDP.h @@ -0,0 +1,194 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_UDP_H_ +#define _TNL_UDP_H_ + +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +#ifndef _TNL_VECTOR_H_ +#include "tnlVector.h" +#endif + +// JMQ: hate...Xwindows...headers +#if defined(TNL_OS_LINUX) && defined(None) +#undef None +#endif + + +namespace TNL { +/// @} +//------------------------------------------------------------------------------ + +/// Enumeration for transport protocols for the TNL. +/// Currently only IP and IPX are supported - the IPv6 constant +/// is for future use. +enum TransportProtocol +{ + IPProtocol, ///< The standard Internet routing protocol + TCPProtocol, ///< The standard Internet guaranteed delivery protocol + IPXProtocol, ///< Novell's IPX protocol + IPv6Protocol, ///< The next generation 128-bit address internet protocol (not currently supported by TNL) +}; + +struct IPAddress; + +/// Representation of a network address. +struct Address +{ + /// One of: IPXAddress, IPAddress + U16 transport; + U16 port; ///< For IP: sin_port For IPX: sa_socket + U32 netNum[4]; ///< Address data, sized for future IPv6 usage + + /// Constants specify + enum NamedAddress { + None, + Localhost, + Broadcast, + Any, + }; + + /// Constructs an address using a protocol, named address type and port + Address(TransportProtocol type = IPProtocol, NamedAddress name = Any, U16 port = 0); + + /// Constructs an address from a string, of the form "transport:address:port" + /// where transport is one of ip, ipx, or (in the future) ipv6 + Address(const char *string) + { + set(string); + } + + /// Constructs an address from an IP address. + Address(const IPAddress &theAddress) + { + set(theAddress); + } + + /// Sets the address to the specified string, returning true if + /// the string was a valid address. Note that this call may block + /// if the address portion of the string requires a DNS lookup. + bool set(const char *string); + + /// Sets the address to the specified IPAddress. + void set(const IPAddress &address); + + /// returns the formatted string corresponding to the address. + const char *toString() const; + + /// returns true if theAddress is equal to this. + bool operator==(const Address &theAddress) const; + + /// returns true if theAddress is not equal to this. + bool operator!=(const Address &theAddress) const { return !operator==(theAddress); } + + /// returns true if the addresses are equal, not including the port. + bool isEqualAddress(const Address &theAddress) const { + return transport == theAddress.transport && + netNum[0] == theAddress.netNum[0] && + netNum[1] == theAddress.netNum[1] && + netNum[2] == theAddress.netNum[2] && + netNum[3] == theAddress.netNum[3]; } + + + /// Returns a 32-bit hash of this network address. + U32 hash() const { return netNum[0] ^ (U32(port) << 8) ^ (netNum[1] << 16) ^ (netNum[1] >> 16) ^ (netNum[2] << 5); } + + /// Returns a packed IPAddress of this address + IPAddress toIPAddress() const; +}; + +/// Packed representaion of an IPAddress. +struct IPAddress +{ + U32 netNum; ///< Address of the host in IP address format. + U16 port; ///< Port field of the network address. +}; + +typedef const IPAddress &IPAddressRef; + +/// Packet level network constants +enum Constants { + MaxPacketDataSize = 1500, ///< The maximum size of a data packet sent through the Net::sendto and Net::recvfrom functions +}; + +/// Error conditions that can be returned by sendto and recvfrom. +enum NetError { + NoError, ///< The operation succeeded without error. + InvalidPacketProtocol, ///< The program attempted to send a packet to an address using a socket that didn't support the protocol of the address. + WouldBlock, ///< The operation would have blocked, for example if there was no data to read. + UnknownError, ///< There was some other, unknown error. +}; + +/// The Socket class encapsulates a platform's network socket. +class Socket +{ + S32 mPlatformSocket; ///< The OS-level socket + U32 mTransportProtocol; ///< The transport type this socket uses. +public: + enum { + DefaultBufferSize = 32768, ///< The default send and receive buffer sizes + }; + + /// Opens a socket on the specified address/port + /// + /// A connectPort of 0 will bind to any available port. + /// Passing a valid address for ipBindInterface will attempt to bind this socket to a particular IP address on the local machine. + Socket(const Address &bindAddress, U32 sendBufferSize = DefaultBufferSize, U32 recvBufferSize = DefaultBufferSize, bool acceptsBroadcast = true, bool nonblockingIO = true); + + /// Closes the socket. + ~Socket(); + + /// Returns true if the socket was created successfully. + bool isValid(); + + /// Sends a packet to the address through sourceSocket. + NetError sendto(const Address &address, const U8 *buffer, S32 bufferSize); + + /// Read an incoming packet. + /// + /// @param address Address originating the packet. + /// @param buffer Buffer in to which to read the packet. + /// @param bufferSize Size of the buffer (this prevents buffer overflows!). + /// @param bytesRead Specifies the number of bytes which were actually in the packet. + NetError recvfrom(Address *address, U8 *buffer, S32 bufferSize, S32 *bytesRead); + + /// Returns the Address corresponding to this socket, as bound on the local machine. + Address getBoundAddress(); + + /// Returns the list of network addresses this host can be bound to. Currently this only + /// returns IP addresses, with the port field set to 0. + static void getInterfaceAddresses(Vector
*addressVector); + + NetError connect(const Address &theAddress); + NetError recv(U8 *buffer, S32 bufferSize, S32 *bytesRead); + NetError send(const U8 *buffer, S32 bufferSize); +}; + +}; +#endif diff --git a/tnl-1.5.0/tnl/tnl/tnlVector.h b/tnl-1.5.0/tnl/tnl/tnlVector.h new file mode 100644 index 0000000000000000000000000000000000000000..0e0c4d75d1ffa51bb679a1796ea0786a8fb015c8 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/tnlVector.h @@ -0,0 +1,398 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TNL_VECTOR_H_ +#define _TNL_VECTOR_H_ + +//Includes +#ifndef _TNL_TYPES_H_ +#include "tnlTypes.h" +#endif + +#ifndef _TNL_PLATFORM_H_ +#include "tnlPlatform.h" +#endif + +#define VectorBlockSize 16 + +namespace TNL { + +//----------------------------------------------------------------------------- + +/// VectorRep is an image of a Vector template object that is used +/// for marshalling and unmarshalling Vectors across RPCs. +struct VectorRep +{ + U32 elementCount; + U32 arraySize; + U8 *array; +}; + +// ============================================================================= + +/// A dynamic array template class. +/// +/// The vector grows as you insert or append +/// elements. Insertion is fastest at the end of the array. Resizing +/// of the array can be avoided by pre-allocating space using the +/// reserve() method. +template class Vector +{ + protected: + U32 mElementCount; ///< Number of elements currently in the Vector. + U32 mArraySize; ///< Number of elements allocated for the Vector. + T* mArray; ///< Pointer to the Vector elements. + + void checkSize(U32 newElementCount);///< checks the element count against the array size and resizes the array if necessary + void destroy(U32 start, U32 end); ///< Destructs elements from start to end-1 + void construct(U32 start, U32 end); ///< Constructs elements from start to end-1 + void construct(U32 start, U32 end, const T* array); + public: + Vector(const U32 initialSize = 0); + Vector(const Vector&); + ~Vector(); + + /// @name VectorSTL STL interface + /// + /// @{ + + /// + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + + typedef S32 difference_type; + typedef U32 size_type; + + typedef difference_type (QSORT_CALLBACK *compare_func)(T *a, T *b); + + Vector& operator=(const Vector& p); + + S32 size() const; + bool empty() const; + + T& front(); + const T& front() const; + T& back(); + const T& back() const; + + void push_front(const T&); + void push_back(const T&); + void pop_front(); + void pop_back(); + + T& operator[](U32); + const T& operator[](U32) const; + + T& operator[](S32 i) { return operator[](U32(i)); } + const T& operator[](S32 i ) const { return operator[](U32(i)); } + + void reserve(U32); + + /// @} + + /// @name VectorExtended Extended Interface + /// + /// @{ + + /// + U32 memSize() const; + T* address() const; + U32 setSize(U32); + void insert(U32); + void erase(U32); + void erase_fast(U32); + void clear(); + void compact(); + + void sort(compare_func f); + T& first(); + T& last(); + const T& first() const; + const T& last() const; + + void set(void * addr, U32 sz); + + /// @} +}; + +template inline Vector::~Vector() +{ + destroy(0, mElementCount); + free(mArray); +} + +template inline Vector::Vector(const U32 initialSize) +{ + mArray = 0; + mElementCount = 0; + mArraySize = 0; + if(initialSize) + reserve(initialSize); +} + +template inline Vector::Vector(const Vector& p) +{ + mArray = 0; + mArraySize = 0; + mElementCount = 0; + + checkSize(p.mElementCount); + mElementCount = p.mElementCount; + construct(0, p.mElementCount, p.mArray); +} + + +template inline void Vector::destroy(U32 start, U32 end) // destroys from start to end-1 +{ + while(start < end) + destructInPlace(&mArray[start++]); +} + +template inline void Vector::construct(U32 start, U32 end) // destroys from start to end-1 +{ + while(start < end) + constructInPlace(&mArray[start++]); +} + +template inline void Vector::construct(U32 start, U32 end, const T* array) // destroys from start to end-1 +{ + while(start < end) + { + constructInPlace(&mArray[start], &array[start]); + start++; + } +} + +template inline T* Vector::address() const +{ + return mArray; +} + +template inline U32 Vector::setSize(U32 size) +{ + checkSize(size); + + if(size > mElementCount) + { + construct(mElementCount, size); + mElementCount = size; + } + else if(size < mElementCount) + { + destroy(size, mElementCount); + mElementCount = size; + if(!mElementCount) + { + free(mArray); + mArray = NULL; + mArraySize = 0; + } + } + return mElementCount; +} + +template inline void Vector::insert(U32 index) +{ + checkSize(mElementCount + 1); + constructInPlace(&mArray[mElementCount]); + mElementCount++; + + for(U32 i = mElementCount - 1; i > index; i--) + mArray[i] = mArray[i - 1]; + destructInPlace(&mArray[index]); + constructInPlace(&mArray[index]); +} + +template inline void Vector::erase(U32 index) +{ + // Assert: index >= 0 && index < mElementCount + for(U32 i = index; i < mElementCount - 1; i++) + mArray[i] = mArray[i+1]; + destructInPlace(&mArray[mElementCount - 1]); + mElementCount--; +} + +template inline void Vector::erase_fast(U32 index) +{ + // CAUTION: this operator does NOT maintain list order + // Copy the last element into the deleted 'hole' and decrement the + // size of the vector. + // Assert: index >= 0 && index < mElementCount + + if(index != mElementCount - 1) + mArray[index] = mArray[mElementCount - 1]; + destructInPlace(&mArray[mElementCount - 1]); + mElementCount--; +} + +template inline T& Vector::first() +{ + return mArray[0]; +} + +template inline const T& Vector::first() const +{ + return mArray[0]; +} + +template inline T& Vector::last() +{ + TNLAssert(mElementCount != 0, "Error, no last element of a zero sized array!"); + return mArray[mElementCount - 1]; +} + +template inline const T& Vector::last() const +{ + return mArray[mElementCount - 1]; +} + +template inline void Vector::clear() +{ + setSize(0); +} + +//----------------------------------------------------------------------------- + +template inline Vector& Vector::operator=(const Vector& p) +{ + destroy(0, mElementCount); + mElementCount = 0; + checkSize(p.mElementCount); + construct(0, p.mElementCount, p.mArray); + mElementCount = p.mElementCount; + return *this; +} + +template inline S32 Vector::size() const +{ + return (S32)mElementCount; +} + +template inline bool Vector::empty() const +{ + return (mElementCount == 0); +} + +template inline T& Vector::front() +{ + return *begin(); +} + +template inline const T& Vector::front() const +{ + return *begin(); +} + +template inline T& Vector::back() +{ + return *end(); +} + +template inline const T& Vector::back() const +{ + return *end(); +} + +template inline void Vector::push_front(const T &x) +{ + insert(0); + mArray[0] = x; +} + +template inline void Vector::push_back(const T &x) +{ + checkSize(mElementCount + 1); + mElementCount++; + constructInPlace(mArray + mElementCount - 1, &x); +} + +template inline void Vector::pop_front() +{ + erase(U32(0)); +} + +template inline void Vector::pop_back() +{ + mElementCount--; + destructInPlace(mArray + mElementCount); +} + +template inline T& Vector::operator[](U32 index) +{ + return mArray[index]; +} + +template inline const T& Vector::operator[](U32 index) const +{ + return mArray[index]; +} + +template inline void Vector::reserve(U32 size) +{ + checkSize(size); +} + +//template inline void Vector::set(void * addr, U32 sz) +//{ +// setSize(sz); +// if (addr) +// memcpy(address(),addr,sz*sizeof(T)); +//} + +//----------------------------------------------------------------------------- + +template inline void Vector::checkSize(U32 newCount) +{ + if(newCount <= mArraySize) + return; + + U32 blk = VectorBlockSize - (newCount % VectorBlockSize); + newCount += blk; + + T *newArray = (T *) malloc(sizeof(T) * newCount); + T *oldArray = mArray; + + mArray = newArray; + construct(0, mElementCount, oldArray); + mArray = oldArray; + destroy(0, mElementCount); + free(oldArray); + mArray = newArray; + mArraySize = newCount; +} + +typedef int (QSORT_CALLBACK *qsort_compare_func)(const void *, const void *); + +template inline void Vector::sort(compare_func f) +{ + qsort(address(), size(), sizeof(T), (qsort_compare_func) f); +} + +}; + +#endif //_TNL_TVECTOR_H_ + diff --git a/tnl-1.5.0/tnl/tnl/udp.cpp b/tnl-1.5.0/tnl/tnl/udp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91f7a79705784831c02286af16e6fc5d2d07f33a --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/udp.cpp @@ -0,0 +1,796 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlJournal.h" + +#if defined ( TNL_OS_XBOX ) + +#include + +typedef int socklen_t; +#define NO_IPX_SUPPORT + +#elif defined ( TNL_OS_WIN32 ) +#include +#if defined(TNL_COMPILER_MINGW) + // mingw does not include support for IPX sockets + typedef void* SOCKADDR_IPX; +# define NO_IPX_SUPPORT +#endif + +typedef int socklen_t; + +#elif defined ( TNL_OS_MAC_OSX ) + +#include +#include +#include +#include +#include +#include +#include +#include + +/* for PROTO_IPX */ +#include /* ioctl() */ +#define NO_IPX_SUPPORT +typedef sockaddr_in SOCKADDR_IN; +typedef sockaddr * PSOCKADDR; +typedef sockaddr SOCKADDR; +typedef in_addr IN_ADDR; + +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 + +#define closesocket close + +#elif defined TNL_OS_LINUX + + +#include +#include +#include +#include +#include +#include +#include +#include + +/* for PROTO_IPX */ +#include /* ioctl() */ +#define NO_IPX_SUPPORT +typedef sockaddr_in SOCKADDR_IN; +typedef sockaddr * PSOCKADDR; +typedef sockaddr SOCKADDR; +typedef in_addr IN_ADDR; + +#define INVALID_SOCKET -1 +#define SOCKET_ERROR -1 + +#define closesocket close + +#else + +#endif + + +#include + + +#if !defined(NO_IPX_SUPPORT) +# include +#endif + +#include "tnlLog.h" + +namespace TNL { + +static NetError getLastError(); +static S32 initCount = 0; + +static bool init() +{ + bool success = true; +#if defined ( TNL_OS_WIN32 ) + if(!initCount) + { + WSADATA stWSAData; + success = !WSAStartup(0x0101, &stWSAData); + + logprintf("Winsock initialization %s", success ? "succeeded." : "failed!"); + } +#elif defined( TNL_OS_XBOX ) + XNetStartupParams xnsp; + memset( &xnsp, 0, sizeof(xnsp) ); + xnsp.cfgSizeOfStruct = sizeof(xnsp); + xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY; + INT iResult = XNetStartup( &xnsp ); + if( iResult != NO_ERROR ) + success = false; + + + WSADATA WsaData; + iResult = WSAStartup( 0x0101, &WsaData ); + if( iResult != NO_ERROR ) + success = false; + + logprintf("Winsock initialization %s", success ? "succeeded." : "failed!"); +#endif + initCount++; + return success; +} + +static void shutdown() +{ + initCount--; +#ifdef TNL_OS_WIN32 + if(!initCount) + { + WSACleanup(); + } +#endif +} + +static void TNLToSocketAddress(const Address &address, SOCKADDR *sockAddr, socklen_t *addressSize) +{ + if(address.transport == IPProtocol || address.transport == TCPProtocol) + { + memset(sockAddr, 0, sizeof(SOCKADDR_IN)); + ((SOCKADDR_IN *) sockAddr)->sin_family = AF_INET; + ((SOCKADDR_IN *) sockAddr)->sin_port = htons(address.port); + ((SOCKADDR_IN *) sockAddr)->sin_addr.s_addr = htonl(address.netNum[0]); + *addressSize = sizeof(SOCKADDR_IN); + } +#ifndef NO_IPX_SUPPORT + else if(address.transport == IPXProtocol) + { + memset(sockAddr, 0, sizeof(SOCKADDR_IPX)); + ((SOCKADDR_IPX *) sockAddr)->sa_family = AF_IPX; + ((SOCKADDR_IPX *) sockAddr)->sa_socket = htons(address.port); + writeU32ToBuffer(address.netNum[0], (U8 *) ((SOCKADDR_IPX *) sockAddr)->sa_netnum); + writeU32ToBuffer(address.netNum[1], (U8 *) ((SOCKADDR_IPX *) sockAddr)->sa_nodenum); + writeU16ToBuffer(address.netNum[2], (U8 *) ((SOCKADDR_IPX *) sockAddr)->sa_nodenum+4); + *addressSize = sizeof(SOCKADDR_IPX); + } +#endif +} + +static void SocketToTNLAddress(const SOCKADDR *sockAddr, Address *address) +{ + if(sockAddr->sa_family == AF_INET) + { + address->transport = IPProtocol; + address->port = htons(((SOCKADDR_IN *) sockAddr)->sin_port); + U32 addr = htonl(((SOCKADDR_IN *) sockAddr)->sin_addr.s_addr); + address->netNum[0] = addr; + address->netNum[1] = 0; + address->netNum[2] = 0; + address->netNum[3] = 0; + } +#ifndef NO_IPX_SUPPORT + else if(sockAddr->sa_family == AF_IPX) + { + address->transport = IPXProtocol; + address->port = htons(((SOCKADDR_IPX *) sockAddr)->sa_socket); + address->netNum[0] = readU32FromBuffer((U8 *) ((SOCKADDR_IPX *) sockAddr)->sa_netnum); + address->netNum[1] = readU32FromBuffer((U8 *) ((SOCKADDR_IPX *) sockAddr)->sa_nodenum); + address->netNum[2] = readU16FromBuffer((U8 *) ((SOCKADDR_IPX *) sockAddr)->sa_nodenum+4); + address->netNum[3] = 0; + } +#endif +} + +Socket::Socket(const Address &bindAddress, U32 sendBufferSize, U32 recvBufferSize, bool acceptsBroadcast, bool nonblockingIO) +{ + TNL_JOURNAL_READ_BLOCK(Socket::Socket, + TNL_JOURNAL_READ( (&mPlatformSocket) ); + return; + ) + init(); + mPlatformSocket = INVALID_SOCKET; + mTransportProtocol = bindAddress.transport; + + const char *socketType = "UDP"; + + if(bindAddress.transport == IPProtocol) + mPlatformSocket = socket(AF_INET, SOCK_DGRAM, 0); + else if(bindAddress.transport == TCPProtocol) + { + socketType = "TCP"; + mPlatformSocket = socket(AF_INET, SOCK_STREAM, 0); + } +#if !defined(NO_IPX_SUPPORT) + else if(bindAddress.transport == IPXProtocol) + { + socketType = "IPX"; + mPlatformSocket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX); + } +#endif + else + { + TNLLogMessageV(LogUDP, ("Attempted to create a socket bound to an invalid transport.")); + } + if(mPlatformSocket != INVALID_SOCKET) + { + S32 error = 0; + SOCKADDR address; + socklen_t addressSize = sizeof(address); + + TNLToSocketAddress(bindAddress, &address, &addressSize); + error = bind(mPlatformSocket, &address, addressSize); + + Address boundAddress; + addressSize = sizeof(address); + + getsockname(mPlatformSocket, (PSOCKADDR) &address, &addressSize); + SocketToTNLAddress(&address, &boundAddress); + + TNLLogMessageV(LogUDP, ("%s socket created - bound to address: %s", socketType, boundAddress.toString())); + + // set the send and receive buffer sizes + error = setsockopt(mPlatformSocket, SOL_SOCKET, SO_RCVBUF, (char *) &recvBufferSize, sizeof(recvBufferSize)); + if(!error) + { + TNLLogMessageV(LogUDP, ("%s socket receive buffer size set to %d.", socketType, recvBufferSize)); + error = setsockopt(mPlatformSocket, SOL_SOCKET, SO_SNDBUF, (char *) &sendBufferSize, sizeof(sendBufferSize)); + } + else + TNLLogMessageV(LogUDP, ("%s socket error: unable to set the receive buffer size on socket.", socketType)); + + if(!error) + { + TNLLogMessageV(LogUDP, ("%s socket send buffer size set to %d.", socketType, recvBufferSize)); + + if(mTransportProtocol != TCPProtocol) + { + // set the broadcast allowed flag + S32 bc = acceptsBroadcast; + error = setsockopt(mPlatformSocket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc)); + } + } + else + TNLLogMessageV(LogUDP, ("%s socket error: unable to set the send buffer size on socket.", socketType)); + + + // set the nonblocking IO flag + if(!error) + { +#if defined ( TNL_OS_WIN32 ) || defined ( TNL_OS_XBOX ) + DWORD notblock = nonblockingIO; + S32 error = ioctlsocket(mPlatformSocket, FIONBIO, ¬block); +#else + U32 notblock = nonblockingIO; + S32 error = ioctl(mPlatformSocket, FIONBIO, ¬block); +#endif + } + else + { + TNLLogMessageV(LogUDP, ("%s socket error: unable to set broadcast mode on socket.", socketType)); + } + + if(!error) + { + TNLLogMessageV(LogUDP, ("%s socket non-blocking IO set. Socket initialized.", socketType)); + } + else + { + TNLLogMessageV(LogUDP, ("Error prevented successful initialization of %s socket.", socketType)); + closesocket(mPlatformSocket); + mPlatformSocket = INVALID_SOCKET; + } + } + TNL_JOURNAL_WRITE_BLOCK(Socket::Socket, + TNL_JOURNAL_WRITE( (mPlatformSocket) ); + ) +} + +Socket::~Socket() +{ + TNL_JOURNAL_READ_BLOCK(Socket::~Socket, + return; + ) + + TNL_JOURNAL_WRITE_BLOCK(Socket::~Socket, ;) + + if(mPlatformSocket != INVALID_SOCKET) + closesocket(mPlatformSocket); + shutdown(); +} + +NetError Socket::sendto(const Address &address, const U8 *buffer, S32 bufferSize) +{ + TNL_JOURNAL_READ_BLOCK(Socket::sendto, + return NoError; + ) + + TNL_JOURNAL_WRITE_BLOCK(Socket::sendto, ; + ) + + if(address.transport != mTransportProtocol) + return InvalidPacketProtocol; + + SOCKADDR destAddress; + socklen_t addressSize; + + TNLToSocketAddress(address, &destAddress, &addressSize); + if(::sendto(mPlatformSocket, (const char*)buffer, bufferSize, 0, + &destAddress, addressSize) == SOCKET_ERROR) + return getLastError(); + else + return NoError; +} + +NetError Socket::recvfrom(Address *address, U8 *buffer, S32 bufferSize, S32 *outSize) +{ + TNL_JOURNAL_READ_BLOCK(Socket::recvfrom, + bool wouldBlock; + TNL_JOURNAL_READ( (&wouldBlock) ); + if(wouldBlock) + return WouldBlock; + + TNL_JOURNAL_READ( (&address->transport) ); + TNL_JOURNAL_READ( (&address->port) ); + TNL_JOURNAL_READ( (&address->netNum[0]) ); + TNL_JOURNAL_READ( (&address->netNum[1]) ); + TNL_JOURNAL_READ( (&address->netNum[2]) ); + TNL_JOURNAL_READ( (&address->netNum[3]) ); + TNL_JOURNAL_READ( (outSize) ); + TNL_JOURNAL_READ( (*outSize, buffer) ); + return NoError; + ) + + SOCKADDR sa; + socklen_t addrLen = sizeof(sa); + S32 bytesRead = SOCKET_ERROR; + + bytesRead = ::recvfrom(mPlatformSocket, (char *) buffer, bufferSize, 0, &sa, &addrLen); + if(bytesRead == SOCKET_ERROR) + { + TNL_JOURNAL_WRITE_BLOCK(Socket::recvfrom, + TNL_JOURNAL_WRITE ( (true) ); + ) + return WouldBlock; + } + + SocketToTNLAddress(&sa, address); + + *outSize = bytesRead; + + TNL_JOURNAL_WRITE_BLOCK(Socket::recvfrom, + TNL_JOURNAL_WRITE( (false) ); + TNL_JOURNAL_WRITE( (address->transport) ); + TNL_JOURNAL_WRITE( (address->port) ); + TNL_JOURNAL_WRITE( (address->netNum[0]) ); + TNL_JOURNAL_WRITE( (address->netNum[1]) ); + TNL_JOURNAL_WRITE( (address->netNum[2]) ); + TNL_JOURNAL_WRITE( (address->netNum[3]) ); + TNL_JOURNAL_WRITE( (*outSize) ); + TNL_JOURNAL_WRITE( (*outSize, buffer) ); + ) + return NoError; +} + +NetError Socket::connect(const Address &theAddress) +{ + SOCKADDR destAddress; + socklen_t addressSize; + + TNLToSocketAddress(theAddress, &destAddress, &addressSize); + if(::connect(mPlatformSocket, &destAddress, addressSize) == -1) + return getLastError(); + return NoError; +} + +NetError Socket::send(const U8 *buffer, S32 bufferSize) +{ + if(::send(mPlatformSocket, (const char *) buffer, bufferSize, 0) == SOCKET_ERROR) + return getLastError(); + return NoError; +} + +NetError Socket::recv(U8 *buffer, S32 bufferSize, S32 *bytesRead) +{ + *bytesRead = ::recv(mPlatformSocket, (char *) buffer, bufferSize, 0); + if(*bytesRead == -1) + return getLastError(); + return NoError; +} + +Address Socket::getBoundAddress() +{ + SOCKADDR address; + Address returnAddress; + + socklen_t addressSize = sizeof(address); + getsockname(mPlatformSocket, (PSOCKADDR) &address, &addressSize); + SocketToTNLAddress(&address, &returnAddress); + + return returnAddress; +} + +bool Socket::isValid() +{ + return mPlatformSocket != INVALID_SOCKET; +} + +#if defined ( TNL_OS_WIN32 ) +void Socket::getInterfaceAddresses(Vector
*addressVector) +{ + typedef struct { + DWORD dwAddr; + DWORD dwIndex; + DWORD dwMask; + DWORD dwBCastAddr; + DWORD dwReasmSize; + unsigned short unused1; + unsigned short unused2; + } MIB_IPADDRROW; + typedef struct { + DWORD dwNumEntries; + MIB_IPADDRROW table[1]; + } MIB_IPADDRTABLE, *PMIB_IPADDRTABLE; + typedef DWORD (WINAPI *GetIPAddrTableFn_t)(PMIB_IPADDRTABLE,PULONG,BOOL); + + static GetIPAddrTableFn_t GetIpAddrTableFn = NULL; + + if(!GetIpAddrTableFn) + { + HMODULE module = LoadLibrary("iphlpapi.dll"); + if(!module) + return; + + GetIpAddrTableFn = (GetIPAddrTableFn_t) GetProcAddress(module, "GetIpAddrTable"); + } + + // Under Win32, we use the IP helper library to query all + // available network interfaces. + PMIB_IPADDRTABLE pIPAddrTable; + DWORD dwSize = 0; + + pIPAddrTable = (MIB_IPADDRTABLE*) malloc( sizeof( MIB_IPADDRTABLE) ); + + // Make an initial call to GetIpAddrTable to get the + // necessary size into the dwSize variable + if (GetIpAddrTableFn(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) + { + free( pIPAddrTable ); + pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize ); + } + + // Make a second call to GetIpAddrTable to get the + // actual data we want + DWORD dwRetVal; + if ( (dwRetVal = GetIpAddrTableFn( pIPAddrTable, &dwSize, 0 )) == NO_ERROR ) { + for(U32 i = 0; i < pIPAddrTable->dwNumEntries; i++) + { + // construct an Address for this interface + Address a; + a.transport = IPProtocol; + a.port = 0; + a.netNum[0] = htonl(pIPAddrTable->table[i].dwAddr); + a.netNum[1] = a.netNum[2] = a.netNum[3] = 0; + // don't add the loopback address or the + if(a.netNum[0] != INADDR_ANY && a.netNum[0] != 0x7F000001) + addressVector->push_back(a); + } + } + free(pIPAddrTable); +} + +#elif defined (TNL_OS_MAC_OSX) +#include + +void Socket::getInterfaceAddresses(Vector
*addressVector) +{ + struct ifaddrs *addrs; + getifaddrs(&addrs); + + for(struct ifaddrs *walk = addrs; walk; walk = walk->ifa_next) + { + Address theAddress; + SocketToTNLAddress(walk->ifa_addr, &theAddress); + if(theAddress.netNum[0] != INADDR_ANY && theAddress.netNum[0] != 0x7F000001) + { + //logprintf("found IF address %s", theAddress.toString()); + addressVector->push_back(theAddress); + } + } + + freeifaddrs(addrs); +} + +#elif defined (TNL_OS_LINUX) +#include +#include +#include +#include +#include +#include + +void Socket::getInterfaceAddresses(Vector
*addressVector) +{ + int sfd = socket(AF_INET, SOCK_STREAM, 0); + if(sfd < 0) + return; + + FILE *f = fopen("/proc/net/dev", "r"); + if(!f) + { + close(sfd); + return; + } + char buf[1024]; + fgets(buf, 1024, f); + fgets(buf, 1024, f); + + struct ifreq ifr; + struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr; + memset(&ifr, 0, sizeof(ifr)); + + + while(fgets(buf, 1024, f)) + { + char *s = buf; + while(*s == ' ') + s++; + char *end = strchr(s, ':'); + if(!end) + continue; + *end = 0; + + strcpy(ifr.ifr_name, s); + sin->sin_family = AF_INET; + if(ioctl(sfd, SIOCGIFADDR, &ifr) == 0) + { + Address theAddress; + SocketToTNLAddress((struct sockaddr *) sin, &theAddress); + if(theAddress.netNum[0] != INADDR_ANY && theAddress.netNum[0] != 0x7F000001) + { + addressVector->push_back(theAddress); + } + } + } + fclose(f); + close(sfd); +} +#endif + +bool Address::operator ==(const Address &theAddress) const +{ + return transport == theAddress.transport && + port == theAddress.port && + netNum[0] == theAddress.netNum[0] && + netNum[1] == theAddress.netNum[1] && + netNum[2] == theAddress.netNum[2] && + netNum[3] == theAddress.netNum[3]; +} + +Address::Address(TransportProtocol type, Address::NamedAddress name, U16 aPort) +{ + transport = type; + port = aPort; + if(transport == IPProtocol) + { + netNum[1] = netNum[2] = netNum[3] = 0; + switch(name) + { + case None: + netNum[0] = 0; + break; + case Localhost: + netNum[0] = htonl(0x7F000001); + break; + case Broadcast: + netNum[0] = htonl(INADDR_BROADCAST); + break; + case Any: + netNum[0] = htonl(INADDR_ANY); + break; + } + } + else if(transport == IPXProtocol) + { + for(U32 i = 0; i < 4; i++) + netNum[i] = 0xFFFFFFFF; + } +} + +void Address::set(const IPAddress &address) +{ + transport = IPProtocol; + port = address.port; + netNum[0] = address.netNum; + netNum[1] = netNum[2] = netNum[3] = 0; +} + +IPAddress Address::toIPAddress() const +{ + IPAddress ret; + ret.port = port; + ret.netNum = netNum[0]; + return ret; +} + +bool Address::set(const char *addressString) +{ + init(); + if(strnicmp(addressString, "ipx:", 4)) + { + bool isTCP = false; + // assume IP if it doesn't have ipx: at the front. + if(!strnicmp(addressString, "ip:", 3)) + addressString += 3; // eat off the ip: + else if(!strnicmp(addressString, "tcp:", 4)) + { + addressString += 4; + isTCP = true; + } + + SOCKADDR_IN ipAddr; + char remoteAddr[256]; + if(strlen(addressString) > 255) + return false; + + strcpy(remoteAddr, addressString); + + char *portString = strchr(remoteAddr, ':'); + if(portString) + *portString++ = 0; + + if(!stricmp(remoteAddr, "broadcast")) + ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); + else if(!stricmp(remoteAddr, "localhost")) + ipAddr.sin_addr.s_addr = htonl(0x7F000001); + else if(!stricmp(remoteAddr, "any")) + ipAddr.sin_addr.s_addr = htonl(INADDR_ANY); + else + { + ipAddr.sin_addr.s_addr = inet_addr(remoteAddr); + if(ipAddr.sin_addr.s_addr == INADDR_NONE) + { +#if defined (TNL_OS_XBOX) + return false; +#else + struct hostent *hp; + if((hp = gethostbyname(remoteAddr)) == NULL) + return false; + else + memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR)); +#endif + } + } + if(portString) + ipAddr.sin_port = htons(atoi(portString)); + else + ipAddr.sin_port = htons(0); + ipAddr.sin_family = AF_INET; + SocketToTNLAddress((SOCKADDR *) &ipAddr, this); + if(isTCP) + transport = TCPProtocol; + return true; + } + else + { + S32 i; + S32 aPort; + + transport = IPXProtocol; + for(i = 0; i < 4; i++) + netNum[i] = 0xFFFFFFFF; + + // it's an IPX string + addressString += 4; + if(!stricmp(addressString, "broadcast")) + { + port = 0; + return true; + } + else if(sscanf(addressString, "broadcast:%d", &aPort) == 1) + { + port = aPort; + return true; + } + else + { + U32 aNodeNum[6]; + U32 aNetNum[4]; + S32 count = sscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d", + &aNetNum[0], &aNetNum[1], &aNetNum[2], &aNetNum[3], + &aNodeNum[0], &aNodeNum[1], &aNodeNum[2], &aNodeNum[3], &aNodeNum[4], &aNodeNum[5], + &aPort); + + if(count == 10) + { + aPort = 0; + count++; + } + if(count != 11) + return false; + + netNum[0] = (aNetNum[0] << 24) | + (aNetNum[1] << 16) | + (aNetNum[2] << 8 ) | + aNetNum[3]; + netNum[1] = (aNodeNum[0] << 24) | + (aNodeNum[1] << 16) | + (aNodeNum[2] << 8 ) | + aNodeNum[3]; + netNum[2] = (aNodeNum[4] << 8) | + aNodeNum[5]; + netNum[3] = 0; + port = aPort; + return true; + } + } +} + +const char *Address::toString() const +{ + static char addressBuffer[256]; + if(transport == IPProtocol) + { + SOCKADDR_IN ipAddr; + socklen_t addrLen = sizeof(ipAddr); + TNLToSocketAddress(*this, (SOCKADDR *) &ipAddr, &addrLen); + + if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST)) + dSprintf(addressBuffer, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port)); + else if(ipAddr.sin_addr.s_addr == htonl(INADDR_ANY)) + dSprintf(addressBuffer, 256, "IP:Any:%d", ntohs(ipAddr.sin_port)); + else + dSprintf(addressBuffer, 256, "IP:%d.%d.%d.%d:%d", U8( netNum[0] >> 24 ), + U8 (netNum[0] >> 16 ), U8 (netNum[0] >> 8), U8(netNum[0]), port); + } + else + { + dSprintf(addressBuffer, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d", + U8(netNum[0] >> 24), U8(netNum[0] >> 16), U8(netNum[0] >> 8), U8(netNum[0]), + U8(netNum[1] >> 24), U8(netNum[1] >> 16), U8(netNum[1] >> 8), U8(netNum[1]), + U8(netNum[2] >> 8), U8(netNum[2]), port); + } + return addressBuffer; +} + +NetError getLastError() +{ +#if defined ( TNL_OS_WIN32 ) || defined ( TNL_OS_XBOX ) + S32 err = WSAGetLastError(); + switch(err) + { + case WSAEWOULDBLOCK: + return WouldBlock; + default: + return UnknownError; + } +#else + if(errno == EAGAIN) + return WouldBlock; + return UnknownError; +#endif +} + +}; diff --git a/tnl-1.5.0/tnl/tnl/vector.cpp b/tnl-1.5.0/tnl/tnl/vector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..56f7034f2fe9ad28294079d70f958c75b388f9c3 --- /dev/null +++ b/tnl-1.5.0/tnl/tnl/vector.cpp @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnlVector.h" + +namespace TNL { + +bool VectorResize(U32 *aSize, U32 *aCount, void **arrayPtr, U32 newCount, U32 elemSize) +{ + if (newCount > 0) { + U32 blocks = newCount / VectorBlockSize; + if (newCount % VectorBlockSize) + blocks++; + S32 mem_size = blocks * VectorBlockSize * elemSize; + *arrayPtr = *arrayPtr ? realloc(*arrayPtr,mem_size) : + malloc(mem_size); + + *aCount = newCount; + *aSize = blocks * VectorBlockSize; + return true; + } + if (*arrayPtr) { + free(*arrayPtr); + *arrayPtr = 0; + } + + *aSize = 0; + *aCount = 0; + return true; +} + +}; diff --git a/tnl-1.5.0/tnl/zap/CTFGame.cpp b/tnl-1.5.0/tnl/zap/CTFGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77852e053e7fa436ec81cf1f2cd865604575a7a0 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/CTFGame.cpp @@ -0,0 +1,176 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "CTFGame.h" +#include "ship.h" +#include "UIGame.h" +#include "flagItem.h" +#include "sfx.h" + +#include "glutInclude.h" +#include + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(CTFGameType); + +void CTFGameType::addFlag(FlagItem *theFlag) +{ + S32 i; + for(i = 0; i < mFlags.size(); i++) + { + if(mFlags[i] == NULL) + { + mFlags[i] = theFlag; + break; + } + } + if(i == mFlags.size()) + mFlags.push_back(theFlag); + + if(!isGhost()) + addItemOfInterest(theFlag); +} + +void CTFGameType::shipTouchFlag(Ship *theShip, FlagItem *theFlag) +{ + GameConnection *controlConnection = theShip->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + + if(!cl) + return; + + if(cl->teamId == theFlag->getTeam()) + { + if(!theFlag->isAtHome()) + { + static StringTableEntry returnString("%e0 returned the %e1 flag."); + Vector e; + e.push_back(cl->name); + e.push_back(mTeams[theFlag->getTeam()].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagReturn, returnString, e); + + theFlag->sendHome(); + cl->score += ReturnScore; + } + else + { + // check if this client has an enemy flag mounted + for(S32 i = 0; i < theShip->mMountedItems.size(); i++) + { + Item *theItem = theShip->mMountedItems[i]; + FlagItem *mountedFlag = dynamic_cast(theItem); + if(mountedFlag) + { + setTeamScore(cl->teamId, mTeams[cl->teamId].score + 1); + + static StringTableEntry capString("%e0 captured the %e1 flag!"); + Vector e; + e.push_back(cl->name); + e.push_back(mTeams[mountedFlag->getTeam()].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagCapture, capString, e); + + // score the flag for the client's team... + mountedFlag->dismount(); + mountedFlag->sendHome(); + cl->score += CapScore; + } + } + } + } + else + { + static StringTableEntry takeString("%e0 took the %e1 flag!"); + Vector e; + e.push_back(cl->name); + e.push_back(mTeams[theFlag->getTeam()].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagSnatch, takeString, e); + theFlag->mountToShip(theShip); + } +} + +void CTFGameType::flagDropped(Ship *theShip, FlagItem *theFlag) +{ + static StringTableEntry dropString("%e0 dropped the %e1 flag!"); + Vector e; + e.push_back(theShip->mPlayerName); + e.push_back(mTeams[theFlag->getTeam()].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagDrop, dropString, e); +} + +void CTFGameType::performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection) +{ + Parent::performProxyScopeQuery(scopeObject, connection); + S32 uTeam = scopeObject->getTeam(); + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(mFlags[i]->isAtHome() || mFlags[i]->getZone()) + connection->objectInScope(mFlags[i]); + else + { + Ship *mount = mFlags[i]->getMount(); + if(mount && mount->getTeam() == uTeam) + { + connection->objectInScope(mount); + connection->objectInScope(mFlags[i]); + } + } + } +} + + +void CTFGameType::renderInterfaceOverlay(bool scoreboardVisible) +{ + Parent::renderInterfaceOverlay(scoreboardVisible); + Ship *u = (Ship *) gClientGame->getConnectionToServer()->getControlObject(); + if(!u) + return; + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(!mFlags[i].isValid()) + continue; + + if(mFlags[i]->isMounted()) + { + Ship *mount = mFlags[i]->getMount(); + if(mount) + renderObjectiveArrow(mount, getTeamColor(mount->getTeam())); + } + else + renderObjectiveArrow(mFlags[i], getTeamColor(mFlags[i]->getTeam())); + } +} + + +}; + diff --git a/tnl-1.5.0/tnl/zap/CTFGame.h b/tnl-1.5.0/tnl/zap/CTFGame.h new file mode 100644 index 0000000000000000000000000000000000000000..38167b83e9a5f68045ac34bd195391192afb169a --- /dev/null +++ b/tnl-1.5.0/tnl/zap/CTFGame.h @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _CTFGAME_H_ +#define _CTFGAME_H_ + +#include "gameType.h" +#include "item.h" + +namespace Zap +{ + +class Ship; +class FlagItem; + +class CTFGameType : public GameType +{ + typedef GameType Parent; + enum Scores + { + KillScore = 1, + ReturnScore = 1, + CapScore = 5, + CapTeamScore = 2, + + }; + Vector > mFlags; +public: + void addFlag(FlagItem *theFlag); + void shipTouchFlag(Ship *theShip, FlagItem *theFlag); + void flagDropped(Ship *theShip, FlagItem *theFlag); + void performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection); + void renderInterfaceOverlay(bool scoreboardVisible); + const char *getGameTypeString() { return "Capture the Flag"; } + const char *getInstructionString() { return "Take the opposing team's flag and touch it to your flag!"; } + TNL_DECLARE_CLASS(CTFGameType); +}; + +}; + + +#endif + diff --git a/tnl-1.5.0/tnl/zap/HTFGame.cpp b/tnl-1.5.0/tnl/zap/HTFGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..005d9879fca9e6c4f574050a9aa5ba38cb4fd618 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/HTFGame.cpp @@ -0,0 +1,305 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "goalZone.h" +#include "gameType.h" +#include "ship.h" +#include "flagItem.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +class HTFGameType : public GameType +{ + typedef GameType Parent; + static StringTableEntry aString; + static StringTableEntry theString; + + Vector mZones; + Vector > mFlags; + enum { + CapScore = 2, + ScoreTime = 5000, + }; + Timer mScoreTimer; +public: + HTFGameType() : mScoreTimer(ScoreTime) {} + void addFlag(FlagItem *theFlag) + { + S32 i; + for(i = 0; i < mFlags.size(); i++) + { + if(mFlags[i] == NULL) + { + mFlags[i] = theFlag; + break; + } + } + if(i == mFlags.size()) + mFlags.push_back(theFlag); + + if(!isGhost()) + addItemOfInterest(theFlag); + } + + void addZone(GoalZone *zone) + { + mZones.push_back(zone); + } + + void shipTouchFlag(Ship *theShip, FlagItem *theFlag) + { + // see if the ship is already carrying a flag - can only carry one at a time + for(S32 i = 0; i < theShip->mMountedItems.size(); i++) + if(theShip->mMountedItems[i].isValid() && (theShip->mMountedItems[i]->getObjectTypeMask() & FlagType)) + return; + + S32 flagIndex; + + for(flagIndex = 0; flagIndex < mFlags.size(); flagIndex++) + if(mFlags[flagIndex] == theFlag) + break; + + GameConnection *controlConnection = theShip->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + if(!cl) + return; + + // see if this flag is already in a flag zone owned by the ship's team + if(theFlag->getZone() != NULL && theFlag->getZone()->getTeam() == theShip->getTeam()) + return; + + static StringTableEntry stealString("%e0 stole %e2 flag from team %e1!"); + static StringTableEntry takeString("%e0 of team %e1 took %e2 flag!"); + StringTableEntry r = takeString; + S32 teamIndex; + + if(theFlag->getZone() == NULL) + teamIndex = cl->teamId; + else + { + r = stealString; + teamIndex = theFlag->getZone()->getTeam(); + } + Vector e; + e.push_back(cl->name); + e.push_back(mTeams[teamIndex].name); + + if(mFlags.size() == 1) + e.push_back(theString); + else + e.push_back(aString); + + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE( + GameConnection::ColorNuclearGreen, SFXFlagSnatch, r, e); + theFlag->mountToShip(theShip); + theFlag->setZone(NULL); + } + + void flagDropped(Ship *theShip, FlagItem *theFlag) + { + static StringTableEntry aString("a"); + static StringTableEntry theString("the"); + static StringTableEntry dropString("%e0 dropped %e1 flag!"); + Vector e; + e.push_back(theShip->mPlayerName); + if(mFlags.size() == 1) + e.push_back(theString); + else + e.push_back(aString); + + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagDrop, dropString, e); + } + + void shipTouchZone(Ship *s, GoalZone *z) + { + GameConnection *controlConnection = s->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + + if(!cl) + return; + + // see if this is an opposing team's zone + if(s->getTeam() != z->getTeam()) + return; + + // see if this zone already has a flag in it... + for(S32 i = 0; i < mFlags.size(); i++) + if(mFlags[i]->getZone() == z) + return; + + // ok, it's an empty zone on our team: + // see if this ship is carrying a flag + S32 i; + for(i = 0; i < s->mMountedItems.size(); i++) + if(s->mMountedItems[i].isValid() && (s->mMountedItems[i]->getObjectTypeMask() & FlagType)) + break; + if(i == s->mMountedItems.size()) + return; + + // ok, the ship has a flag and it's on the ship... + Item *theItem = s->mMountedItems[i]; + FlagItem *mountedFlag = dynamic_cast(theItem); + if(mountedFlag) + { + static StringTableEntry capString("%e0 retrieved %e1 flag. Team %e2 holds %e1 flag!"); + + Vector e; + e.push_back(cl->name); + if(mFlags.size() == 1) + e.push_back(theString); + else + e.push_back(aString); + e.push_back(mTeams[cl->teamId].name); + + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, + SFXFlagCapture, capString, e); + + mountedFlag->dismount(); + + S32 flagIndex; + for(flagIndex = 0; flagIndex < mFlags.size(); flagIndex++) + if(mFlags[flagIndex] == mountedFlag) + break; + + mFlags[flagIndex]->setZone(z); + + mountedFlag->setActualPos(z->getExtent().getCenter()); + cl->score += CapScore; + } + } + + void idle(GameObject::IdleCallPath path) + { + Parent::idle(path); + if(path == GameObject::ServerIdleMainLoop) + { + if(!mScoreTimer.update(mCurrentMove.time)) + return; + mScoreTimer.reset(); + for(S32 flagIndex = 0; flagIndex < mFlags.size(); flagIndex++) + { + if(mFlags[flagIndex]->getZone() != NULL) + { + S32 team = mFlags[flagIndex]->getZone()->getTeam(); + setTeamScore(team, mTeams[team].score + 1); + } + } + } + } + + void performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection) + { + Parent::performProxyScopeQuery(scopeObject, connection); + S32 uTeam = scopeObject->getTeam(); + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(mFlags[i]->isAtHome() || mFlags[i]->getZone()) + connection->objectInScope(mFlags[i]); + else + { + Ship *mount = mFlags[i]->getMount(); + if(mount && mount->getTeam() == uTeam) + { + connection->objectInScope(mount); + connection->objectInScope(mFlags[i]); + } + } + } + } + + void renderInterfaceOverlay(bool scoreboardVisible) + { + Parent::renderInterfaceOverlay(scoreboardVisible); + Ship *u = (Ship *) gClientGame->getConnectionToServer()->getControlObject(); + if(!u) + return; + bool uFlag = false; + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(mFlags[i].isValid() && mFlags[i]->getMount() == u) + { + for(S32 j = 0; j < mZones.size(); j++) + { + // see if this is one of our zones and that it doesn't have a flag in it. + if(mZones[j]->getTeam() != u->getTeam()) + continue; + S32 k; + for(k = 0; k < mFlags.size(); k++) + { + if(!mFlags[k].isValid()) + continue; + if(mFlags[k]->getZone() == mZones[j]) + break; + } + if(k == mFlags.size()) + renderObjectiveArrow(mZones[j], getTeamColor(u->getTeam())); + } + uFlag = true; + break; + } + } + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(!mFlags[i].isValid()) + continue; + + if(!mFlags[i]->isMounted() && !uFlag) + { + GoalZone *gz = mFlags[i]->getZone(); + if(gz && gz->getTeam() != u->getTeam()) + renderObjectiveArrow(mFlags[i], getTeamColor(gz->getTeam())); + else if(!gz) + renderObjectiveArrow(mFlags[i], getTeamColor(-1)); + } + else + { + Ship *mount = mFlags[i]->getMount(); + if(mount && mount != u) + renderObjectiveArrow(mount, getTeamColor(mount->getTeam())); + } + } + } + + const char *getGameTypeString() { return "Hold the Flag"; } + const char *getInstructionString() { return "Hold the flags at your capture zones!"; } + TNL_DECLARE_CLASS(HTFGameType); +}; + +StringTableEntry HTFGameType::aString("a"); +StringTableEntry HTFGameType::theString("the"); + +TNL_IMPLEMENT_NETOBJECT(HTFGameType); + + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/LoadoutZone.cpp b/tnl-1.5.0/tnl/zap/LoadoutZone.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d077f22c4c1b01220698033a3080fdcef4bb9d58 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/LoadoutZone.cpp @@ -0,0 +1,140 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameObject.h" +#include "gameType.h" +#include "glutInclude.h" +#include "gameNetInterface.h" +#include "UI.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +class LoadoutZone : public GameObject +{ + typedef GameObject Parent; + Vector mPolyBounds; + enum { + MaxPoints = 10, + }; + +public: + LoadoutZone() + { + mTeam = 0; + mNetFlags.set(Ghostable); + mObjectTypeMask = LoadoutZoneType | CommandMapVisType; + } + + void render() + { + renderLoadoutZone(getGame()->getGameType()->getTeamColor(getTeam()), mPolyBounds, getExtent()); + } + + S32 getRenderSortValue() + { + return -1; + } + + void processArguments(S32 argc, const char **argv) + { + if(argc < 7) + return; + + mTeam = atoi(argv[0]); + for(S32 i = 1; i < argc; i += 2) + { + Point p; + p.x = atof(argv[i]) * getGame()->getGridSize(); + p.y = atof(argv[i+1]) * getGame()->getGridSize(); + mPolyBounds.push_back(p); + } + computeExtent(); + } + + void onAddedToGame(Game *theGame) + { + if(!isGhost()) + setScopeAlways(); + } + + void computeExtent() + { + Rect extent(mPolyBounds[0], mPolyBounds[0]); + for(S32 i = 1; i < mPolyBounds.size(); i++) + extent.unionPoint(mPolyBounds[i]); + setExtent(extent); + } + + bool getCollisionPoly(Vector &polyPoints) + { + for(S32 i = 0; i < mPolyBounds.size(); i++) + polyPoints.push_back(mPolyBounds[i]); + return true; + } + + bool collide(GameObject *hitObject) + { + if(!isGhost() && (hitObject->getTeam() == getTeam()) && (hitObject->getObjectTypeMask() & ShipType)) + getGame()->getGameType()->updateShipLoadout(hitObject); + + return false; + } + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) + { + stream->write(mTeam); + stream->writeEnum(mPolyBounds.size(), MaxPoints); + for(S32 i = 0; i < mPolyBounds.size(); i++) + { + stream->write(mPolyBounds[i].x); + stream->write(mPolyBounds[i].y); + } + return 0; + } + + void unpackUpdate(GhostConnection *connection, BitStream *stream) + { + stream->read(&mTeam); + S32 size = stream->readEnum(MaxPoints); + for(S32 i = 0; i < size; i++) + { + Point p; + stream->read(&p.x); + stream->read(&p.y); + mPolyBounds.push_back(p); + } + if(size) + computeExtent(); + } + + TNL_DECLARE_CLASS(LoadoutZone); +}; + +TNL_IMPLEMENT_NETOBJECT(LoadoutZone); + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/Makefile b/tnl-1.5.0/tnl/zap/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b39220049d8fa0e3bb5a775d75d4ce40fa35cc3f --- /dev/null +++ b/tnl-1.5.0/tnl/zap/Makefile @@ -0,0 +1,91 @@ +# TNL Makefile +# (c) 2003 GarageGames + +# +# Configuration +# +CC=g++ -g -I../tnl -I../glut -I../openal -DTNL_DEBUG -DTNL_ENABLE_LOGGING #-O2 + +OBJECTS_ZAP=\ + CTFGame.o\ + HTFGame.o\ + LoadoutZone.o\ + SweptEllipsoid.o\ + UI.o\ + UICredits.o\ + UIEditor.o\ + UIGame.o\ + UIInstructions.o\ + UIMenus.o\ + UINameEntry.o\ + UIQueryServers.o\ + barrier.o\ + controlObjectConnection.o\ + engineeredObjects.o\ + flagItem.o\ + footballGame.o\ + game.o\ + gameConnection.o\ + gameItems.o\ + gameLoader.o\ + gameNetInterface.o\ + gameObject.o\ + gameObjectRender.o\ + gameType.o\ + gameWeapons.o\ + goalZone.o\ + gridDB.o\ + huntersGame.o\ + input.o\ + item.o\ + linuxInput.o\ + loadoutSelect.o\ + main.o\ + masterConnection.o\ + moveObject.o\ + projectile.o\ + quickChat.o\ + rabbitGame.o\ + retrieveGame.o\ + sfx.o\ + ship.o\ + soccerGame.o\ + sparkManager.o\ + teleporter.o\ + voiceCodec.o\ + gsm_encode.o\ + gsm_decode.o\ + gsm_state.o\ + lpc10enc.o\ + lpc10dec.o\ + ../master/masterInterface.o + +CFLAGS= + +.c.o: + $(CC) -c $(CFLAGS) $< + +.cpp.o : + $(CC) -c $(CFLAGS) $< + +default: ../exe/zap + +zap: ../exe/zap + +zapded: ../exe/zapded + +../exe/zap: $(OBJECTS_ZAP) + $(CC) -o ../exe/zap $(OBJECTS_ZAP) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a ../openal/linux/libopenal.a -lpthread -lstdc++ -lGL -lGLU -lglut -lm + +../exe/zapded: CFLAGS=-DZAP_DEDICATED +../exe/zapded: $(OBJECTS_ZAP) + $(CC) -o ../exe/zapded $(OBJECTS_ZAP) ../tnl/libtnl.a ../libtomcrypt/libtomcrypt.a -lpthread -lstdc++ -lm + +../master/masterInterface.o: + make -C ../master + +clean: + rm -f $(OBJECTS_ZAP) ../exe/zap ../exe/zapded + +cleano: + rm -f $(OBJECTS_ZAP) diff --git a/tnl-1.5.0/tnl/zap/SweptEllipsoid.cpp b/tnl-1.5.0/tnl/zap/SweptEllipsoid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..954966f5466c34e4c9c65dbd3ad7bd9f4fb28140 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/SweptEllipsoid.cpp @@ -0,0 +1,347 @@ +// Example code for: Collision Detection with Swept Spheres and Ellipsoids +// See: http://www.three14.demon.nl/sweptellipsoid/SweptEllipsoid.pdf +// +// Copyright (C) 2003 Jorrit Rouwe +// +// 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. +// +// This is free software, you can do with it what you want. +// +// This file contains the main swept sphere / ellipsoid intersection tests. +// +// Please have a look at the notes. They indicate obvious places for optimization +// if you are using a swept ellipsoid against a large number of polygons. + +#include "point.h" +#include "SweptEllipsoid.h" + +namespace Zap +{ + +// Check if a polygon contains inPoint, returns true when it does +bool PolygonContains(const Point *inVertices, int inNumVertices, const Point &inPoint) +{ + // Loop through edges + for (const Point *v1 = inVertices, *v2 = inVertices + inNumVertices - 1; v1 < inVertices + inNumVertices; v2 = v1, ++v1) + { + // If the point is outside this edge, the point is outside the polygon + Point v1_v2 = *v2 - *v1; + Point v1_point = inPoint - *v1; + if (v1_v2.x * v1_point.y - v1_point.x * v1_v2.y > 0.0f) + return false; + } + + return true; +} + +// Check if circle at inCenter with radius^2 = inRadiusSq intersects with a polygon. +// Function returns true when it does and the intersection point is in outPoint +bool PolygonCircleIntersect(const Point *inVertices, int inNumVertices, const Point &inCenter, Point::member_type inRadiusSq, Point &outPoint) +{ + // Check if the center is inside the polygon + if (PolygonContains(inVertices, inNumVertices, inCenter)) + { + outPoint = inCenter; + return true; + } + + // Loop through edges + bool collision = false; + for (const Point *v1 = inVertices, *v2 = inVertices + inNumVertices - 1; v1 < inVertices + inNumVertices; v2 = v1, ++v1) + { + // Get fraction where the closest point to this edge occurs + Point v1_v2 = *v2 - *v1; + Point v1_center = inCenter - *v1; + Point::member_type fraction = v1_center.dot(v1_v2); + if (fraction < 0.0f) + { + // Closest point is v1 + Point::member_type dist_sq = v1_center.lenSquared(); + if (dist_sq <= inRadiusSq) + { + collision = true; + outPoint = *v1; + inRadiusSq = dist_sq; + } + } + else + { + Point::member_type v1_v2_len_sq = v1_v2.lenSquared(); + if (fraction <= v1_v2_len_sq) + { + // Closest point is on line segment + Point point = *v1 + v1_v2 * (fraction / v1_v2_len_sq); + Point::member_type dist_sq = (point - inCenter).lenSquared(); + if (dist_sq <= inRadiusSq) + { + collision = true; + outPoint = point; + inRadiusSq = dist_sq; + } + } + } + } + + return collision; +} + +void Swap(Point::member_type &f1, Point::member_type &f2) +{ + Point::member_type temp = f1; + f1 = f2; + f2 = temp; +} + +// Solve the equation inA * x^2 + inB * x + inC == 0 for the lowest x in [0, inUpperBound]. +// Returns true if there is such a solution and returns the solution in outX +bool FindLowestRootInInterval(Point::member_type inA, Point::member_type inB, Point::member_type inC, Point::member_type inUpperBound, Point::member_type &outX) +{ + // Check if a solution exists + Point::member_type determinant = inB * inB - 4.0f * inA * inC; + if (determinant < 0.0f) + return false; + + // The standard way of doing this is by computing: x = (-b +/- Sqrt(b^2 - 4 a c)) / 2 a + // is not numerically stable when a is close to zero. + // Solve the equation according to "Numerical Recipies in C" paragraph 5.6 + Point::member_type q = -0.5f * (inB + (inB < 0.0f? -1.0f : 1.0f) * sqrt(determinant)); + + // Both of these can return +INF, -INF or NAN that's why we test both solutions to be in the specified range below + Point::member_type x1 = q / inA; + Point::member_type x2 = inC / q; + + // Order the results + if (x2 < x1) + Swap(x1, x2); + + // Check if x1 is a solution + if (x1 >= 0.0f && x1 <= inUpperBound) + { + outX = x1; + return true; + } + + // Check if x2 is a solution + if (x2 >= 0.0f && x2 <= inUpperBound) + { + outX = x2; + return true; + } + + return false; +} + +// Checks intersection between a polygon an moving circle at inBegin + t * inDelta with radius^2 = inA * t^2 + inB * t + inC, t in [0, 1] +// Returns true when it does and returns the intersection position in outPoint and the intersection fraction (value for t) in outFraction +bool SweptCircleEdgeVertexIntersect(const Point *inVertices, int inNumVertices, const Point &inBegin, const Point &inDelta, Point::member_type inA, Point::member_type inB, Point::member_type inC, Point &outPoint, Point::member_type &outFraction) +{ + // Loop through edges + Point::member_type upper_bound = 1.0f; + bool collision = false; + for (const Point *v1 = inVertices, *v2 = inVertices + inNumVertices - 1; v1 < inVertices + inNumVertices; v2 = v1, ++v1) + { + Point::member_type t; + + // Check if circle hits the vertex + Point bv1 = *v1 - inBegin; + Point::member_type a1 = inA - inDelta.lenSquared(); + Point::member_type b1 = inB + 2.0f * inDelta.dot(bv1); + Point::member_type c1 = inC - bv1.lenSquared(); + if (FindLowestRootInInterval(a1, b1, c1, upper_bound, t)) + { + // We have a collision + collision = true; + upper_bound = t; + outPoint = *v1; + } + + // Check if circle hits the edge + Point v1v2 = *v2 - *v1; + Point::member_type v1v2_dot_delta = v1v2.dot(inDelta); + Point::member_type v1v2_dot_bv1 = v1v2.dot(bv1); + Point::member_type v1v2_len_sq = v1v2.lenSquared(); + Point::member_type a2 = v1v2_len_sq * a1 + v1v2_dot_delta * v1v2_dot_delta; + Point::member_type b2 = v1v2_len_sq * b1 - 2.0f * v1v2_dot_bv1 * v1v2_dot_delta; + Point::member_type c2 = v1v2_len_sq * c1 + v1v2_dot_bv1 * v1v2_dot_bv1; + if (FindLowestRootInInterval(a2, b2, c2, upper_bound, t)) + { + // Check if the intersection point is on the edge + Point::member_type f = t * v1v2_dot_delta - v1v2_dot_bv1; + if (f >= 0.0f && f <= v1v2_len_sq) + { + // We have a collision + collision = true; + upper_bound = t; + outPoint = *v1 + v1v2 * (f / v1v2_len_sq); + } + } + } + + // Check if we had a collision + if (!collision) + return false; + outFraction = upper_bound; + return true; +} + +bool PolygonSweptCircleIntersect(const Point *inVertices, int inNumVertices, const Point &inBegin, const Point &inDelta, Point::member_type inRadius, Point &outPoint, Point::member_type &outFraction) +{ + // Test if circle intersects at t = 0 + if (PolygonCircleIntersect(inVertices, inNumVertices, inBegin, inRadius * inRadius, outPoint)) + { + outFraction = 0; + return true; + } + + // Test if sphere intersects with one of the edges or vertices + if (SweptCircleEdgeVertexIntersect(inVertices, inNumVertices, inBegin, inDelta, 0, 0, inRadius * inRadius, outPoint, outFraction)) + { + return true; + } + + return false; + +} + +/* +// Test between a polygon and a swept sphere with radius inRadius moving from inBegin to inBegin + inDelta +// If there is an intersection the intersection position is returned in outPoint and the center of the +// sphere is at inBegin + outFraction * inDelta when it collides +bool PolygonSweptSphereIntersect(const Plane &inPlane, const Vector2 *inVertices, int inNumVertices, const Vector3 &inBegin, const Vector3 &inDelta, Point::member_type inRadius, Vector3 &outPoint, Point::member_type &outFraction) +{ + // Determine the range over which the sphere intersects the plane + float t1, t2; + if (!PlaneSweptSphereIntersect(inPlane, inBegin, inDelta, inRadius, t1, t2)) + return false; + + // The radius of the circle is defined as: radius^2 = (sphere radius)^2 - (distance plane to center)^2 + // this can be written as: radius^2 = a * t^2 + b * t + c + float n_dot_d = inPlane.mNormal.Dot(inDelta); + float dist_to_b = inPlane.GetSignedDistance(inBegin); + float a = -n_dot_d * n_dot_d; + float b = -2.0f * n_dot_d * dist_to_b; + float c = inRadius * inRadius - dist_to_b * dist_to_b; + + // Get basis + Vector3 u, v; + inPlane.GetBasisVectors(u, v); + + // Get begin and delta in plane space + Vector2 begin = Plane::sConvertWorldToPlane(u, v, inBegin); + Vector2 delta = Plane::sConvertWorldToPlane(u, v, inDelta); + + // Test if sphere intersects at t1 + Vector2 p; + if (PolygonCircleIntersect(inVertices, inNumVertices, begin + delta * t1, a * t1 * t1 + b * t1 + c, p)) + { + outFraction = t1; + outPoint = inPlane.ConvertPlaneToWorld(u, v, p); + return true; + } + + // Test if sphere intersects with one of the edges or vertices + if (SweptCircleEdgeVertexIntersect(inVertices, inNumVertices, begin, delta, a, b, c, p, outFraction)) + { + outPoint = inPlane.ConvertPlaneToWorld(u, v, p); + return true; + } + + return false; +} + +// Multiply matrix with 2D vector (multiply with (x, y, 0)) +Vector2 Transform2x2(const Matrix &inMatrix, const Vector2 &inVector) +{ + return Vector2(inMatrix.E(0, 0) * inVector.mX + inMatrix.E(0, 1) * inVector.mY, + inMatrix.E(1, 0) * inVector.mX + inMatrix.E(1, 1) * inVector.mY); +} + +// Test intersection with a swept ellipsoid with principal axis inAxis1, inAxis2, inAxis3 moving from inBegin to inBegin + inDelta +// If there is an intersection the intersection position is returned in outPoint and the center of the +// sphere is at inBegin + outFraction * inDelta when it collides +bool PolygonSweptEllipsoidIntersect(const Plane &inPlane, const Vector2 *inVertices, int inNumVertices, const Vector3 &inBegin, const Vector3 &inDelta, const Vector3 &inAxis1, const Vector3 &inAxis2, const Vector3 &inAxis3, Vector3 &outPoint, float &outFraction) +{ + // Compute matrix that takes a point from unit sphere space to world space + // NOTE: When colliding with lots of polygons this can be cached + Matrix unit_sphere_to_world; + unit_sphere_to_world.Column(0) = inAxis1; + unit_sphere_to_world.Column(1) = inAxis2; + unit_sphere_to_world.Column(2) = inAxis3; + + // Compute matrix that takes a point from world space to unit sphere space + // NOTE: When colliding with lots of polygons this can be cached + Matrix world_to_unit_sphere = unit_sphere_to_world.GetInversed(); + + // Compute begin and delta in unit sphere space + // NOTE: When colliding with lots of polygons this can be cached + Vector3 begin_uss = world_to_unit_sphere * inBegin; + Vector3 delta_uss = world_to_unit_sphere * inDelta; + + // Transform the plane into unit sphere local space + Plane transformed_plane; + transformed_plane = inPlane.GetTransformedByInverse(unit_sphere_to_world); + + // Determine the range over which the unit sphere intersects the transformed plane + float t1, t2; + if (!PlaneSweptSphereIntersect(transformed_plane, begin_uss, delta_uss, 1.0f, t1, t2)) + return false; + + // Get matrix that transforms a point from plane space to world space + Matrix plane_to_world = inPlane.GetPlaneToWorldMatrix(); + + // Get matrix that transforms a point from the transformed plane to unit sphere space + Matrix transformed_plane_to_unit_sphere = transformed_plane.GetPlaneToWorldMatrix(); + + // Get matrix that takes a 2d polygon vertex from the original space to the space of the + // transformed plane so that the unit sphere is still a unit sphere + Matrix plane_to_transformed_plane = transformed_plane_to_unit_sphere.GetInversed() * world_to_unit_sphere * plane_to_world; + + // The radius of the circle is defined as: radius^2 = 1 - (distance plane to center)^2 + // this can be written as: radius^2 = a * t^2 + b * t + c + float n_dot_d = transformed_plane.mNormal.Dot(delta_uss); + float dist_to_b = transformed_plane.GetSignedDistance(begin_uss); + float a = -n_dot_d * n_dot_d; + float b = -2.0f * n_dot_d * dist_to_b; + float c = 1.0f - dist_to_b * dist_to_b; + + // Get the basis vectors for the transformed plane + const Vector3 &u = transformed_plane_to_unit_sphere.Column(0); + const Vector3 &v = transformed_plane_to_unit_sphere.Column(1); + + // To avoid translating the polygon we subtract the translation from the begin point + // and then later add it to the collision result again + Vector2 trans(plane_to_transformed_plane.E(0, 3), plane_to_transformed_plane.E(1, 3)); + + // Get the equation for the intersection circle between the plane and the unit sphere: center = begin + t * delta + Vector2 begin = Plane::sConvertWorldToPlane(u, v, begin_uss) - trans; + Vector2 delta = Plane::sConvertWorldToPlane(u, v, delta_uss); + + // Transform the polygon + Vector2 *transformed_vertices = (Vector2 *)alloca(inNumVertices * sizeof(Vector2)); + for (int i = 0; i < inNumVertices; ++i) + transformed_vertices[i] = Transform2x2(plane_to_transformed_plane, inVertices[i]); + + // Test if sphere intersects at t1 + Vector2 p; + if (PolygonCircleIntersect(transformed_vertices, inNumVertices, begin + delta * t1, a * t1 * t1 + b * t1 + c, p)) + { + outFraction = t1; + outPoint = unit_sphere_to_world * (transformed_plane_to_unit_sphere * Vector3(p + trans)); + return true; + } + + // Test if sphere intersects with one of the edges or vertices + if (SweptCircleEdgeVertexIntersect(transformed_vertices, inNumVertices, begin, delta, a, b, c, p, outFraction)) + { + outPoint = unit_sphere_to_world * (transformed_plane_to_unit_sphere * Vector3(p + trans)); + return true; + } + + return false; +}*/ + + +}; + diff --git a/tnl-1.5.0/tnl/zap/SweptEllipsoid.h b/tnl-1.5.0/tnl/zap/SweptEllipsoid.h new file mode 100644 index 0000000000000000000000000000000000000000..6aee99eaafd6a2cb8d6fcc8e09f71c57d0dee49c --- /dev/null +++ b/tnl-1.5.0/tnl/zap/SweptEllipsoid.h @@ -0,0 +1,43 @@ +// Example code for: Collision Detection with Swept Spheres and Ellipsoids +// See: http://www.three14.demon.nl/sweptellipsoid/SweptEllipsoid.pdf +// +// Copyright (C) 2003 Jorrit Rouwe +// +// 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. +// +// This is free software, you can do with it what you want. +// +// This file contains the main swept sphere / ellipsoid intersection tests. +// +// Please have a look at the notes. They indicate obvious places for optimization +// if you are using a swept ellipsoid against a large number of polygons. + +// this file has been modified by Mark Frohnmayer: +// removed swept ellipsoid routine +// removed swept sphere +// removed references to vector2 and replaced with Point +// added in prototypes for circle collisions + +#ifndef _SWEPT_ELLIPSOID_H_ +#define _SWEPT_ELLIPSOID_H_ + +namespace Zap { +//#include "Vector2.h" +//#include "Plane.h" + +// Test between a polygon and a swept sphere with radius inRadius moving from inBegin to inBegin + inDelta +// If there is an intersection the intersection position is returned in outPoint and the center of the +// sphere is at inBegin + outFraction * inDelta when it collides +//bool PolygonSweptSphereIntersect(const Plane &inPlane, const Vector2 *inVertices, int inNumVertices, const Vector3 &inBegin, const Vector3 &inDelta, float inRadius, Vector3 &outPoint, float &outFraction); + +// Test intersection with a swept ellipsoid with principal axis inAxis1, inAxis2, inAxis3 moving from inBegin to inBegin + inDelta +// If there is an intersection the intersection position is returned in outPoint and the center of the +// sphere is at inBegin + outFraction * inDelta when it collides +//bool PolygonSweptEllipsoidIntersect(const Plane &inPlane, const Vector2 *inVertices, int inNumVertices, const Vector3 &inBegin, const Vector3 &inDelta, const Vector3 &inAxis1, const Vector3 &inAxis2, const Vector3 &inAxis3, Vector3 &outPoint, float &outFraction); + +bool PolygonSweptCircleIntersect(const Point *inVertices, int inNumVertices, const Point &inBegin, const Point &inDelta, Point::member_type inRadius, Point &outPoint, Point::member_type &outFraction); + +}; +#endif // _SWEPT_ELLIPSOID_H_ diff --git a/tnl-1.5.0/tnl/zap/UI.cpp b/tnl-1.5.0/tnl/zap/UI.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d40323e594cf76d966443309945b257065b1fda8 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UI.cpp @@ -0,0 +1,208 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "../tnl/tnl.h" +using namespace TNL; + +#include "UI.h" +#include "sfx.h" +#include + +#include "glutInclude.h" + +#ifdef ZAP_DEDICATED +void *glutStrokeRoman; +#endif + +namespace Zap +{ + +#ifdef TNL_OS_XBOX +S32 UserInterface::horizMargin = 50; +S32 UserInterface::vertMargin = 38; +#else +S32 UserInterface::horizMargin = 15; +S32 UserInterface::vertMargin = 15; +#endif + +S32 UserInterface::canvasWidth = 800; +S32 UserInterface::canvasHeight = 600; +S32 UserInterface::windowWidth = 800; +S32 UserInterface::windowHeight = 600; + +UserInterface *UserInterface::current = NULL; + +void UserInterface::activate() +{ + current = this; + onActivate(); +} + +void UserInterface::onActivate() +{ +} + +void UserInterface::renderCurrent() +{ + glViewport(0, 0, windowWidth, windowHeight); + + glClearColor(0, 0, 0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if(current) + current->render(); +} + +void UserInterface::drawString(S32 x, S32 y, S32 size, const char *string) +{ + F32 scaleFactor = size / 120.0f; + glPushMatrix(); + glTranslatef(x, y + size, 0); + glScalef(scaleFactor, -scaleFactor, 1); + for(S32 i = 0; string[i]; i++) + glutStrokeCharacter(GLUT_STROKE_ROMAN, string[i]); + glPopMatrix(); +} + +void UserInterface::drawCenteredString(S32 y, S32 size, const char *string) +{ + S32 x = S32( (canvasWidth - getStringWidth(size, string)) / 2); + drawString(x, y, size, string); +} + +U32 UserInterface::getStringWidth(S32 size, const char *string, U32 len) +{ + S32 width = 0; + if(!len) + len = (U32) strlen(string); + while(len--) + { + width += glutStrokeWidth(GLUT_STROKE_ROMAN, *string); + string++; + } + return U32((width * size) / 120.0f); + +} + +void UserInterface::drawStringf(S32 x, S32 y, S32 size, const char *format, ...) +{ + va_list args; + va_start(args, format); + char buffer[2048]; + + dVsprintf(buffer, sizeof(buffer), format, args); + drawString(x, y, size, buffer); +} + +void UserInterface::drawCenteredStringf(S32 y, S32 size, const char *format, ...) +{ + va_list args; + va_start(args, format); + char buffer[2048]; + + dVsprintf(buffer, sizeof(buffer), format, args); + drawCenteredString(y, size, buffer); +} + +void UserInterface::playBoop() +{ + SFXObject::play(SFXUIBoop, 1); +} + +void UserInterface::render() +{ + +} + +void UserInterface::idle(U32 timeDelta) +{ + +} + +void UserInterface::onMouseDown(S32 x, S32 y) +{ + +} + +void UserInterface::onMouseUp(S32 x, S32 y) +{ + +} + +void UserInterface::onRightMouseDown(S32 x, S32 y) +{ + +} + +void UserInterface::onRightMouseUp(S32 x, S32 y) +{ + +} + +void UserInterface::onMouseMoved(S32 x, S32 y) +{ + +} + +void UserInterface::onMouseDragged(S32 x, S32 y) +{ + +} + +void UserInterface::onKeyDown(U32 key) +{ + +} + +void UserInterface::onKeyUp(U32 key) +{ + +} + +void UserInterface::onSpecialKeyDown(U32 key) +{ + +} + +void UserInterface::onSpecialKeyUp(U32 key) +{ + +} + +void UserInterface::onModifierKeyDown(U32 key) +{ + +} + +void UserInterface::onModifierKeyUp(U32 key) +{ + +} + +}; diff --git a/tnl-1.5.0/tnl/zap/UI.h b/tnl-1.5.0/tnl/zap/UI.h new file mode 100644 index 0000000000000000000000000000000000000000..1c22187de120f2440c8634935b612fbfd2f00ebe --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UI.h @@ -0,0 +1,81 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UI_H_ +#define _UI_H_ + +#include "../tnl/tnl.h" + +using namespace TNL; + +namespace Zap +{ + +static const float DefaultLineWidth = 2.0f; + +class UserInterface +{ +public: + static UserInterface *current; + + static S32 windowWidth, windowHeight, canvasWidth, canvasHeight; + static S32 vertMargin, horizMargin; + + static void renderCurrent(); + + virtual void render(); + virtual void idle(U32 timeDelta); + virtual void onActivate(); + + void activate(); + + virtual void onMouseDown(S32 x, S32 y); + virtual void onMouseUp(S32 x, S32 y); + virtual void onRightMouseDown(S32 x, S32 y); + virtual void onRightMouseUp(S32 x, S32 y); + + virtual void onMouseMoved(S32 x, S32 y); + virtual void onMouseDragged(S32 x, S32 y); + virtual void onKeyDown(U32 key); + virtual void onKeyUp(U32 key); + virtual void onSpecialKeyDown(U32 key); + virtual void onSpecialKeyUp(U32 key); + virtual void onModifierKeyDown(U32 key); + virtual void onModifierKeyUp(U32 key); + virtual void onControllerButtonDown(U32 buttonIndex) {} + virtual void onControllerButtonUp(U32 buttonIndex) {} + + static void drawString(S32 x, S32 y, S32 size, const char *string); + static void drawCenteredString(S32 y, S32 size, const char *string); + static void drawStringf(S32 x, S32 y, S32 size, const char *fmt, ...); + static void drawCenteredStringf(S32 y, S32 size, const char *fmt, ...); + static U32 getStringWidth(S32 size, const char *string, U32 len = 0); + static void playBoop(); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/UICredits.cpp b/tnl-1.5.0/tnl/zap/UICredits.cpp new file mode 100644 index 0000000000000000000000000000000000000000..447bdce098072cb676bbdf54da1b12830f1e6773 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UICredits.cpp @@ -0,0 +1,181 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "../tnl/tnlRandom.h" +#include "UICredits.h" +#include "glutInclude.h" +#include + +namespace Zap +{ + +const char *gGameCredits[] = { + "Z A P", + "(c) 2004 GarageGames.com", + "Lead Programmer and Level Designer", + "Mark Frohnmayer", + "Linux Programmer", + "John Quigley", + "Programmer and Sound Effects Engineer", + "Ben Garney", + "Programmer", + "Robert Blanchet", + "Internal Testers", + "Alex Swanson, Brian Ramage", + "External Testers", + "Clark Fagot, Joe Maruschak, #garagegames", + NULL, +}; + +CreditsUserInterface gCreditsUserInterface; + +void CreditsUserInterface::onActivate() +{ + // construct the creditsfx objects here, they will + // get properly deleted when the CreditsUI + // destructor is envoked + + // add credits scroller first and make it active + CreditsScroller *scroller = new CreditsScroller; + scroller->setActive(true); + + // add CreditsFX effects below here, dont activate: + // + + // choose randomly another CreditsFX effect + // aside from CreditsScroller to activate + if(fxList.size() > 1) + { + U32 rand = Random::readI(0, fxList.size() - 1); + while(fxList[rand]->isActive()) + { + rand = Random::readI(0, fxList.size() - 1); + } + fxList[rand]->setActive(true); + } +} + +void CreditsUserInterface::render() +{ + // loop through all the attached effects and + // call their render function + for(S32 i = 0; i < fxList.size(); i++) + if(fxList[i]->isActive()) + fxList[i]->render(); +} + +void CreditsUserInterface::quit() +{ +#ifdef TNL_OS_XBOX + extern void xboxexit(); + xboxexit(); +#else + exit(0); +#endif +} + +//----------------------------------------------------- +// CreditsFX Objects +//----------------------------------------------------- +CreditsFX::CreditsFX() +{ + activated = false; + gCreditsUserInterface.addFX(this); +} + +CreditsScroller::CreditsScroller() +{ + mProjectInfo.titleBuf = gGameCredits[0]; + mProjectInfo.copyBuf = gGameCredits[1]; + + mProjectInfo.currPos.x = (UserInterface::canvasHeight - 100) / 2; + + // loop through each line in the credits expecting + // the credits to be listed in this order: + // 1) job + // 2) name + S32 pos = (UserInterface::canvasHeight + CreditSpace); + S32 index = 2; + while(gGameCredits[index] && gGameCredits[index+1]) + { + CreditsInfo c; + + // get job + c.jobBuf = gGameCredits[index]; + c.nameBuf = gGameCredits[index + 1]; + index += 2; + + // place credit in cache + c.currPos.x = pos; + credits.push_back(c); + + pos += CreditSpace; + } + mTotalSize = pos; +} + +void CreditsScroller::updateFX(U32 delta) +{ + // draw the project information + S32 pos = S32( mProjectInfo.currPos.x - (delta / 10) ); + if(pos < -CreditSpace) + pos += mTotalSize; + mProjectInfo.currPos.x = pos; + + // scroll the credits text from bottom to top + // based on time + for(S32 i = 0; i < credits.size(); i++) + { + pos = S32( credits[i].currPos.x - (delta / 10) ); + + // reached the top, reset + if(pos < -CreditSpace) + pos += mTotalSize; + + credits[i].currPos.x = pos; + } +} + +void CreditsScroller::render() +{ + glColor3f(1,1,1); + + // draw the project information + //glLineWidth(10); + UserInterface::drawCenteredString(S32 (mProjectInfo.currPos.x), 100, mProjectInfo.titleBuf); + //glLineWidth(1); + UserInterface::drawCenteredString(S32(mProjectInfo.currPos.x) + 120, 20, mProjectInfo.copyBuf); + + // draw the credits text + for(S32 i = 0; i < credits.size(); i++) + { + UserInterface::drawCenteredString(S32(credits[i].currPos.x), 25, credits[i].jobBuf); + UserInterface::drawCenteredString(S32(credits[i].currPos.x) + 50, 25, credits[i].nameBuf); + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/UICredits.h b/tnl-1.5.0/tnl/zap/UICredits.h new file mode 100644 index 0000000000000000000000000000000000000000..7f659c79f6c592afc8295726e2e8e0cdce95fe66 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UICredits.h @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UICREDITS_H_ +#define _UICREDITS_H_ + +#include "UI.h" +#include "game.h" + +namespace Zap +{ + +class CreditsFX +{ +protected: + bool activated; + +public: + CreditsFX(); + void setActive(bool active) { activated = active; } + bool isActive() { return activated; } + virtual void updateFX(U32 delta) = 0; + virtual void render() = 0; +}; + +class CreditsScroller : public CreditsFX +{ + //typedef CreditsFX Parent; +public: + enum Credits { + MaxCreditLen = 32, + CreditSpace = 200, + }; +private: + struct ProjectInfo { + const char *titleBuf; + const char *copyBuf; + Point currPos; + } mProjectInfo; + struct CreditsInfo { + const char *nameBuf; + const char *jobBuf; + Point currPos; + }; + Vector credits; + void readCredits(const char *file); + S32 mTotalSize; + +public: + CreditsScroller(); + void updateFX(U32 delta); + void render(); +}; + +// Credits UI +class CreditsUserInterface : public UserInterface +{ + Vector fxList; + +public: + ~CreditsUserInterface() + { + for(S32 i = 0; i < fxList.size(); i++) + { + delete fxList[i]; fxList[i] = NULL; + fxList.erase(i); + } + fxList.clear(); + } + + void onActivate(); + void addFX(CreditsFX *fx) { fxList.push_back(fx); } + void idle(U32 t) + { + for(S32 i = 0; i < fxList.size(); i++) + if(fxList[i]->isActive()) + fxList[i]->updateFX(t); + } + void render(); + void quit(); + void onControllerButtonDown(U32 button) { quit(); } + void onKeyDown(U32 key) { quit(); } // exit for now +}; +extern CreditsUserInterface gCreditsUserInterface; + +} + +#endif diff --git a/tnl-1.5.0/tnl/zap/UIEditor.cpp b/tnl-1.5.0/tnl/zap/UIEditor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3fbd78e709308eee4b020c746848f0e64eacca7 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIEditor.cpp @@ -0,0 +1,1247 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "UIEditor.h" +#include "glutInclude.h" +#include "UICredits.h" +#include +#include +#include "gameObjectRender.h" +#include "barrier.h" + +namespace Zap +{ + +bool EditorUserInterface::editorEnabled = false; + +EditorUserInterface gEditorUserInterface; + +void EditorUserInterface::setEditName(const char *name) +{ + mGridSize = Game::DefaultGridSize; + mGameType[0] = 0; + char fileBuffer[256]; + dSprintf(fileBuffer, sizeof(fileBuffer), "levels/%s", name); + initLevelFromFile(fileBuffer); + if(mTeams.size() == 0) + { + Team t; + t.color = Color(0, 0, 1); + strcpy(t.name, "Blue"); + mTeams.push_back(t); + } + mCurrentOffset.set(0,0); + mCurrentScale = 100; + mDragSelecting = false; + mUp = mDown = mLeft = mRight = mIn = mOut = false; + mCreatingPoly = false; + mCurrentTeam = 0; + + strcpy(mEditFileName, name); + mOriginalItems = mItems; +} + +struct GameItemRec +{ + const char *name; + bool hasWidth; + bool hasTeam; + bool canHaveNoTeam; + bool isPoly; + char letter; +}; + +enum GameItems +{ + ItemSpawn, + ItemSoccerBall, + ItemCTFFlag, + ItemBarrierMaker, + ItemTeleporter, + ItemRepair, + ItemTest, + ItemResource, + ItemLoadoutZone, + ItemTurret, + ItemForceField, + ItemGoalZone, +}; + +GameItemRec gGameItemRecs[] = { + { "Spawn", false, true, false, false, 'S' }, + { "SoccerBallItem", false, false, false, false, 'B' }, + { "FlagItem", false, true, true, false, 0 }, + { "BarrierMaker", true, false, false, true, 0 }, + { "Teleporter", false, false, false, true, 'T' }, + { "RepairItem", false, false, false, false, 'R' }, + { "TestItem", false, false, false, false, 't' }, + { "ResourceItem", false, false, false, false, 'r' }, + { "LoadoutZone", false, true, true, true, 0 }, + { "Turret", false, true, true, false, 'N' }, + { "ForceFieldProjector", false, true, true, false, 'P' }, + { "GoalZone", false, true, false, true, 0 }, + { NULL, false, false, false, false, 0 }, +}; + +void EditorUserInterface::processLevelLoadLine(int argc, const char **argv) +{ + U32 index; + U32 strlenCmd = (U32) strlen(argv[0]); + for(index = 0; gGameItemRecs[index].name != NULL; index++) + { + if(!strcmp(argv[0], gGameItemRecs[index].name)) + { + S32 minArgs = 3; + if(gGameItemRecs[index].isPoly) + minArgs += 2; + if(gGameItemRecs[index].hasTeam) + minArgs++; + if(argc >= minArgs) + break; + } + } + + if(gGameItemRecs[index].name) + { + WorldItem i; + i.index = index; + S32 arg = 1; + i.team = -1; + i.selected = false; + i.width = 0; + if(gGameItemRecs[index].hasWidth) + { + i.width = atof(argv[arg]); + arg++; + } + if(gGameItemRecs[index].hasTeam) + { + i.team = atoi(argv[arg]); + arg++; + } + for(;arg < argc; arg += 2) + { + Point p; + if(arg != argc - 1) + { + p.read(argv + arg); + i.verts.push_back(p); + i.vertSelected.push_back(false); + } + } + mItems.push_back(i); + } + else if(strlenCmd >= 8 && !strcmp(argv[0] + strlenCmd - 8, "GameType")) + { + strcpy(mGameType, argv[0]); + mGameType[strlenCmd - 8] = 0; + for(S32 i = 1; i < argc; i++) + mGameTypeArgs.push_back(strdup(argv[i])); + } + else if(!strcmp(argv[0], "Team") && argc == 5) + { + Team t; + strcpy(t.name, argv[1]); + t.color.read(argv + 2); + mTeams.push_back(t); + } + else + { + if(!strcmp(argv[0], "GridSize") && argc == 2) + mGridSize = atof(argv[1]); + + Vector item; + for(S32 i = 0; i < argc; i++) + item.push_back(strdup(argv[i])); + mUnknownItems.push_back(item); + } +} + +void EditorUserInterface::onActivate() +{ + editorEnabled = true; +} + +Point EditorUserInterface::snapToLevelGrid(Point p) +{ + F32 mulFactor, divFactor; + if(mCurrentScale >= 100) + { + mulFactor = 10; + divFactor = 0.1; + } + else + { + mulFactor = 2; + divFactor = 0.5; + } + + return Point(floor(p.x * mulFactor + 0.5) * divFactor, + floor(p.y * mulFactor + 0.5) * divFactor); +} + +void EditorUserInterface::render() +{ + glColor3f(0.0, 0.0, 0.0); + if(mCurrentScale >= 100) + { + F32 gridScale = mCurrentScale * 0.1; + F32 yStart = fmod(mCurrentOffset.y, gridScale); + F32 xStart = fmod(mCurrentOffset.x, gridScale); + glColor3f(0.2, 0.2, 0.2); + glBegin(GL_LINES); + while(yStart < canvasHeight) + { + glVertex2f(0, yStart); + glVertex2f(canvasWidth, yStart); + yStart += gridScale; + } + while(xStart < canvasWidth) + { + glVertex2f(xStart, 0); + glVertex2f(xStart, canvasHeight); + xStart += gridScale; + } + glEnd(); + } + + if(mCurrentScale >= 10) + { + F32 yStart = fmod(mCurrentOffset.y, mCurrentScale); + F32 xStart = fmod(mCurrentOffset.x, mCurrentScale); + glColor3f(0.4, 0.4, 0.4); + glBegin(GL_LINES); + while(yStart < canvasHeight) + { + glVertex2f(0, yStart); + glVertex2f(canvasWidth, yStart); + yStart += mCurrentScale; + } + while(xStart < canvasWidth) + { + glVertex2f(xStart, 0); + glVertex2f(xStart, canvasHeight); + xStart += mCurrentScale; + } + glEnd(); + } + glColor3f(0.7, 0.7, 0.7); + glLineWidth(3); + Point origin = convertLevelToCanvasCoord(Point(0,0)); + glBegin(GL_LINES ); + glVertex2f(0, origin.y); + glVertex2f(canvasWidth, origin.y); + glVertex2f(origin.x, 0); + glVertex2f(origin.x, canvasHeight); + glEnd(); + glLineWidth(1); + + for(S32 i = 0; i < mItems.size(); i++) + renderItem(i); + + if(mCreatingPoly) + { + Point mouseVertex = snapToLevelGrid(convertCanvasToLevelCoord(mMousePos)); + mNewItem.verts.push_back(mouseVertex); + glLineWidth(3); + glColor3f(1, 1, 0); + renderPoly(mNewItem); + glLineWidth(1); + mNewItem.verts.erase_fast(mNewItem.verts.size() - 1); + } + else + { + for(S32 i = 0; i < mItems.size(); i++) + { + if(mItems[i].selected && mItems[i].index == ItemBarrierMaker) + { + glColor3f(1,1,1); + drawStringf(680, 5, 20, "Width: %g", mItems[i].width); + break; + } + } + } + if(mDragSelecting) + { + glColor3f(1,1,1); + glBegin(GL_LINE_LOOP); + Point downPos = convertLevelToCanvasCoord(mMouseDownPos); + glVertex2f(downPos.x, downPos.y); + glVertex2f(mMousePos.x, downPos.y); + glVertex2f(mMousePos.x, mMousePos.y); + glVertex2f(downPos.x, mMousePos.y); + glEnd(); + } +} + +void EditorUserInterface::renderPoly(WorldItem &p) +{ + glBegin(GL_LINE_STRIP); + for(S32 j = 0; j < p.verts.size(); j++) + { + Point v = convertLevelToCanvasCoord(p.verts[j]); + glVertex2f(v.x, v.y); + } + glEnd(); +} + +extern void constructBarrierPoints(const Vector &vec, F32 width, Vector &barrierEnds ); + +void EditorUserInterface::renderItem(S32 index) +{ + EditorUserInterface::WorldItem &i = mItems[index]; + Point pos = convertLevelToCanvasCoord(i.verts[0]); + Color c; + + if(i.index == ItemTeleporter) + { + Point dest = convertLevelToCanvasCoord(i.verts[1]); + glColor3f(0,1,0); + + if(i.selected) + glLineWidth(3); + + glBegin(GL_POLYGON); + glVertex2f(pos.x - 5, pos.y - 5); + glVertex2f(pos.x + 5, pos.y - 5); + glVertex2f(pos.x + 5, pos.y + 5); + glVertex2f(pos.x - 5, pos.y + 5); + glEnd(); + + glBegin(GL_LINES); + glVertex2f(pos.x, pos.y); + glVertex2f(dest.x, dest.y); + glVertex2f(dest.x - 5, dest.y - 5); + glVertex2f(dest.x + 5, dest.y + 5); + glVertex2f(dest.x + 5, dest.y - 5); + glVertex2f(dest.x - 5, dest.y + 5); + glEnd(); + + glLineWidth(1); + + glColor3f(1,1,1); + if(i.vertSelected[0]) + { + glBegin(GL_LINE_LOOP); + glVertex2f(pos.x - 5, pos.y - 5); + glVertex2f(pos.x + 5, pos.y - 5); + glVertex2f(pos.x + 5, pos.y + 5); + glVertex2f(pos.x - 5, pos.y + 5); + glEnd(); + } + if(i.vertSelected[1]) + { + glBegin(GL_LINE_LOOP); + glVertex2f(dest.x - 5, dest.y - 5); + glVertex2f(dest.x + 5, dest.y - 5); + glVertex2f(dest.x + 5, dest.y + 5); + glVertex2f(dest.x - 5, dest.y + 5); + glEnd(); + } + } + else if(gGameItemRecs[i.index].isPoly) + { + Color theColor; + if(i.selected) + theColor.set(1,1,0); + else if(i.index == ItemBarrierMaker) + theColor.set(0,0,1); + else if(i.team == -1) + theColor.set(0.7, 0.7, 0.7); + else + { + Color c = mTeams[i.team].color; + theColor = c; + } + glColor(theColor); + + if(i.index != ItemBarrierMaker) + { + // render the team ones as GL_POLYGONs + glBegin(GL_POLYGON); + for(S32 j = 0; j < i.verts.size(); j++) + { + Point v = convertLevelToCanvasCoord(i.verts[j]); + glVertex2f(v.x, v.y); + } + glEnd(); + } + else + { + Vector barPoints; + constructBarrierPoints(i.verts, i.width / mGridSize, barPoints ); + + for(S32 j = 0; j < barPoints.size(); j += 2) + { + Point dir = barPoints[j+1] - barPoints[j]; + Point crossVec(dir.y, -dir.x); + crossVec.normalize(i.width * 0.5 / mGridSize); + glBegin(GL_POLYGON); + glColor3f(0.5, 0.5, 1); + glVertex(convertLevelToCanvasCoord(barPoints[j] + crossVec)); + glVertex(convertLevelToCanvasCoord(barPoints[j] - crossVec)); + glVertex(convertLevelToCanvasCoord(barPoints[j+1] - crossVec)); + glVertex(convertLevelToCanvasCoord(barPoints[j+1] + crossVec)); + glEnd(); + } + glColor(theColor); + glLineWidth(3); + renderPoly(i); + glLineWidth(1); + } + for(S32 j = 0; j < i.verts.size(); j++) + { + Point v = convertLevelToCanvasCoord(i.verts[j]); + if(i.vertSelected[j]) + glColor3f(1,1,0); + else + glColor3f(1,0,0); + glBegin(GL_LINE_LOOP); + glVertex2f(v.x - 5, v.y - 5); + glVertex2f(v.x + 5, v.y - 5); + glVertex2f(v.x + 5, v.y + 5); + glVertex2f(v.x - 5, v.y + 5); + glEnd(); + } + } + else + { + char letter = gGameItemRecs[i.index].letter; + if(i.team == -1) + c = Color(0.5, 0.5, 0.5); + else + c = mTeams[i.team].color; + if(i.index == ItemCTFFlag) + { + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + glScalef(0.6, 0.6, 1); + renderFlag(Point(0,0), c); + glPopMatrix(); + } + else + { + glColor(c); + glBegin(GL_POLYGON); + glVertex2f(pos.x - 8, pos.y - 8); + glVertex2f(pos.x + 8, pos.y - 8); + glVertex2f(pos.x + 8, pos.y + 8); + glVertex2f(pos.x - 8, pos.y + 8); + glEnd(); + } + if(i.selected) + { + Point pos = convertLevelToCanvasCoord(i.verts[0]); + glColor3f(1,1,1); + glBegin(GL_LINE_LOOP); + glVertex2f(pos.x - 10, pos.y - 10); + glVertex2f(pos.x + 10, pos.y - 10); + glVertex2f(pos.x + 10, pos.y + 10); + glVertex2f(pos.x - 10, pos.y + 10); + glEnd(); + } + if(letter) + { + glColor3f(1,1,1); + drawStringf(pos.x - 5, pos.y - 8, 15, "%c", letter); + } + } +} + +void EditorUserInterface::clearSelection() +{ + for(S32 i = 0; i < mItems.size(); i++) + { + WorldItem &itm = mItems[i]; + itm.selected = false; + for(S32 j = 0; j < itm.vertSelected.size(); j++) + itm.vertSelected[j] = false; + } +} + +S32 EditorUserInterface::countSelectedItems() +{ + S32 count = 0; + for(S32 i = 0; i < mItems.size(); i++) + if(mItems[i].selected) + count++; + return count; +} + +S32 EditorUserInterface::countSelectedVerts() +{ + S32 count = 0; + for(S32 i = 0; i < mItems.size(); i++) + for(S32 j = 0; j < mItems[i].vertSelected.size(); j++) + if(mItems[i].vertSelected[j]) + count++; + return count; +} + +void EditorUserInterface::duplicateSelection() +{ + mOriginalItems = mItems; + + S32 itemCount = mItems.size(); + for(S32 i = 0; i < itemCount; i++) + { + if(mItems[i].selected) + { + WorldItem newItem = mItems[i]; + mItems[i].selected = false; + for(S32 j = 0; j < newItem.verts.size(); j++) + newItem.verts[j] += Point(0.5, 0.5); + mItems.push_back(newItem); + } + } +} + +void EditorUserInterface::rotateSelection(F32 angle) +{ + mOriginalItems = mItems; + Point min, max; + computeSelectionMinMax(min,max); + //Point ctr = (min + max)*0.5; + //ctr.x = floor(ctr.x * 10) * 0.1f; + //ctr.y = floor(ctr.y * 10) * 0.1f; + F32 sinTheta = sin(angle * Float2Pi / 360.0f); + F32 cosTheta = cos(angle * Float2Pi / 360.0f); + for(S32 i = 0; i < mItems.size(); i++) + { + if(!mItems[i].selected) + continue; + WorldItem &itm = mItems[i]; + for(S32 j = 0; j < itm.verts.size(); j++) + { + Point v = itm.verts[j];// - ctr; + Point n(v.x * cosTheta + v.y * sinTheta, v.y * cosTheta - v.x * sinTheta); + itm.verts[j] = n;// + ctr; + } + } +} + + +void EditorUserInterface::computeSelectionMinMax(Point &min, Point &max) +{ + min.set(1000000, 1000000); + max.set(-1000000, -1000000); + + for(S32 i = 0; i < mItems.size(); i++) + { + if(!mItems[i].selected) + continue; + WorldItem &itm = mItems[i]; + for(S32 j = 0; j < itm.verts.size(); j++) + { + Point v = itm.verts[j]; + + if(v.x < min.x) + min.x = v.x; + if(v.x > max.x) + max.x = v.x; + if(v.y < min.y) + min.y = v.y; + if(v.y > max.y) + max.y = v.y; + } + } +} + +void EditorUserInterface::setCurrentTeam(S32 currentTeam) +{ + mCurrentTeam = currentTeam; + + for(S32 i = 0; i < mItems.size(); i++) + { + if(!mItems[i].selected) + continue; + if(!gGameItemRecs[mItems[i].index].hasTeam) + continue; + if(currentTeam == -1 && !gGameItemRecs[mItems[i].index].canHaveNoTeam) + continue; + mItems[i].team = mCurrentTeam; + } +} + +void EditorUserInterface::flipSelectionHorizontal() +{ + mOriginalItems = mItems; + + Point min, max; + computeSelectionMinMax(min, max); + for(S32 i = 0; i < mItems.size(); i++) + { + if(!mItems[i].selected) + continue; + + for(S32 j = 0; j < mItems[i].verts.size(); j++) + mItems[i].verts[j].x = min.x + (max.x - mItems[i].verts[j].x); + } +} + +void EditorUserInterface::flipSelectionVertical() +{ + mOriginalItems = mItems; + + Point min, max; + computeSelectionMinMax(min, max); + for(S32 i = 0; i < mItems.size(); i++) + { + if(!mItems[i].selected) + continue; + + for(S32 j = 0; j < mItems[i].verts.size(); j++) + mItems[i].verts[j].y = min.y + (max.y - mItems[i].verts[j].y); + } +} + +void EditorUserInterface::findHitVertex(Point canvasPos, S32 &hitItem, S32 &hitVertex) +{ + hitItem = -1; + hitVertex = -1; + for(S32 i = mItems.size() - 1; i >= 0; i--) + { + WorldItem &p = mItems[i]; + if(!gGameItemRecs[p.index].isPoly) + continue; + + for(S32 j = p.verts.size() - 1; j >= 0; j--) + { + Point v = convertLevelToCanvasCoord(p.verts[j]); + if(fabs(v.x - canvasPos.x) < 5 && fabs(v.y - canvasPos.y) < 5) + { + hitItem = i; + hitVertex = j; + return; + } + } + } +} + +void EditorUserInterface::findHitItemAndEdge(Point canvasPos, S32 &hitItem, S32 &hitEdge) +{ + hitItem = -1; + hitEdge = -1; + + for(S32 i = mItems.size() - 1; i >= 0; i--) + { + WorldItem &p = mItems[i]; + + if(!gGameItemRecs[mItems[i].index].isPoly) + { + Point pos = convertLevelToCanvasCoord(p.verts[0]); + if(fabs(canvasPos.x - pos.x) < 8 && fabs(canvasPos.y - pos.y) < 8) + { + hitItem = i; + return; + } + } + + Point p1 = convertLevelToCanvasCoord(p.verts[0]); + for(S32 j = 0; j < p.verts.size() - 1; j++) + { + Point p2 = convertLevelToCanvasCoord(p.verts[j+1]); + + Point edgeDelta = p2 - p1; + Point clickDelta = canvasPos - p1; + float fraction = clickDelta.dot(edgeDelta); + float lenSquared = edgeDelta.dot(edgeDelta); + if(fraction > 0 && fraction < lenSquared) + { + // compute the closest point: + Point closest = p1 + edgeDelta * (fraction / lenSquared); + float distance = (canvasPos - closest).len(); + if(distance < 5) + { + hitEdge = j; + hitItem = i; + return; + } + } + p1 = p2; + } + } +} + +void EditorUserInterface::onMouseDown(S32 x, S32 y) +{ + mMousePos = convertWindowToCanvasCoord(Point(x,y)); + if(mCreatingPoly) + { + mOriginalItems = mItems; + if(mNewItem.verts.size() > 1) + mItems.push_back(mNewItem); + mNewItem.verts.clear(); + mCreatingPoly = false; + } + + mMouseDownPos = convertCanvasToLevelCoord(mMousePos); + + // rules for mouse down: + // if the click has no shift- modifier, then + // if the click was on something that was selected + // do nothing + // else + // clear the selection + // add what was clicked to the selection + // else + // toggle the selection of what was clicked + + bool shiftKeyDown = glutGetModifiers() & GLUT_ACTIVE_SHIFT; + + S32 vertexHit, vertexHitPoly; + S32 edgeHit, itemHit; + + findHitVertex(mMousePos, vertexHitPoly, vertexHit); + findHitItemAndEdge(mMousePos, itemHit, edgeHit); + + if(!shiftKeyDown) + { + if(vertexHit != -1 && mItems[vertexHitPoly].selected) + { + vertexHit = -1; + itemHit = vertexHitPoly; + } + if(vertexHit != -1 && (itemHit == -1 || !mItems[itemHit].selected)) + { + if(!mItems[vertexHitPoly].vertSelected[vertexHit]) + { + clearSelection(); + mItems[vertexHitPoly].vertSelected[vertexHit] = true; + } + } + else if(itemHit != -1) + { + if(!mItems[itemHit].selected) + { + clearSelection(); + mItems[itemHit].selected = true; + } + } + else + { + mDragSelecting = true; + clearSelection(); + } + } + else + { + if(vertexHit != -1) + { + mItems[vertexHitPoly].vertSelected[vertexHit] = + !mItems[vertexHitPoly].vertSelected[vertexHit]; + } + else if(itemHit != -1) + mItems[itemHit].selected = !mItems[itemHit].selected; + else + mDragSelecting = true; + } + mOriginalItems = mItems; +} + +void EditorUserInterface::onMouseUp(S32 x, S32 y) +{ + mMousePos = convertWindowToCanvasCoord(Point(x,y)); + if(mDragSelecting) + { + Rect r(convertCanvasToLevelCoord(mMousePos), + mMouseDownPos); + for(S32 i = 0; i < mItems.size(); i++) + { + S32 j; + for(j = 0; j < mItems[i].verts.size(); j++) + { + if(!r.contains(mItems[i].verts[j])) + break; + } + if(j == mItems[i].verts.size()) + mItems[i].selected = true; + } + mDragSelecting = false; + } +} + +void EditorUserInterface::onMouseDragged(S32 x, S32 y) +{ + mMousePos = convertWindowToCanvasCoord(Point(x,y)); + if(mCreatingPoly || mDragSelecting) + return; + Point delta = convertCanvasToLevelCoord(mMousePos); + delta = snapToLevelGrid(delta - mMouseDownPos); + + for(S32 i = 0; i < mItems.size(); i++) + { + for(S32 j = 0; j < mItems[i].verts.size(); j++) + { + if(mItems[i].selected || mItems[i].vertSelected[j]) + mItems[i].verts[j] = mOriginalItems[i].verts[j] + delta; + } + } +} + +void EditorUserInterface::onRightMouseDown(S32 x, S32 y) +{ + mMousePos = convertWindowToCanvasCoord(Point(x,y)); + if(mCreatingPoly) + { + Point newVertex = snapToLevelGrid(convertCanvasToLevelCoord(mMousePos)); + mNewItem.verts.push_back(newVertex); + mNewItem.vertSelected.push_back(false); + return; + } + + S32 edgeHit, itemHit; + findHitItemAndEdge(mMousePos, itemHit, edgeHit); + + if(itemHit != -1 && gGameItemRecs[mItems[itemHit].index].isPoly && + mItems[itemHit].index != ItemTeleporter) + { + clearSelection(); + + Point newVertex = snapToLevelGrid(convertCanvasToLevelCoord(mMousePos)); + // insert an extra vertex at the mouse clicked point, + // and then select it. + mItems[itemHit].verts.insert(edgeHit + 1); + mItems[itemHit].verts[edgeHit + 1] = newVertex; + mItems[itemHit].vertSelected.insert(edgeHit + 1); + mItems[itemHit].vertSelected[edgeHit + 1] = true; + mMouseDownPos = newVertex; + mOriginalItems = mItems; + } + else + { + //london chikara kelly markling + mCreatingPoly = true; + mNewItem.verts.clear(); + mNewItem.index = ItemBarrierMaker; + mNewItem.width = Barrier::BarrierWidth; + mNewItem.team = -1; + mNewItem.selected = false; + mNewItem.vertSelected.clear(); + Point newVertex = snapToLevelGrid(convertCanvasToLevelCoord(mMousePos)); + mNewItem.verts.push_back(newVertex); + mNewItem.vertSelected.push_back(false); + } +} + +void EditorUserInterface::onMouseMoved(S32 x, S32 y) +{ + glutSetCursor(GLUT_CURSOR_RIGHT_ARROW); + mMousePos = convertWindowToCanvasCoord(Point(x,y)); + //bool shiftKeyDown = glutGetModifiers() & GLUT_ACTIVE_SHIFT; + + if(!mCreatingPoly)// && !shiftKeyDown) + { + S32 vertexHit, vertexHitPoly; + S32 edgeHit, itemHit; + + findHitVertex(mMousePos, vertexHitPoly, vertexHit); + findHitItemAndEdge(mMousePos, itemHit, edgeHit); + if( (vertexHit != -1 && mItems[vertexHitPoly].vertSelected[vertexHit]) || + (itemHit != -1 && mItems[itemHit].selected)) + glutSetCursor(GLUT_CURSOR_SPRAY); + } +} + +void EditorUserInterface::deleteSelection() +{ + for(S32 i = 0; i < mItems.size(); ) + { + if(mItems[i].selected) + { + mItems.erase(i); + } + else + { + for(S32 j = 0; j < mItems[i].verts.size(); ) + { + if(mItems[i].vertSelected[j]) + { + mItems[i].verts.erase(j); + mItems[i].vertSelected.erase(j); + } + else + j++; + } + + if(mItems[i].verts.size() == 0) + mItems.erase(i); + else + i++; + } + } +} + +void EditorUserInterface::incBarrierWidth() +{ + for(S32 i = 0; i < mItems.size(); i++) + { + if(mItems[i].index == ItemBarrierMaker && mItems[i].selected) + mItems[i].width += 5; + } +} + +void EditorUserInterface::decBarrierWidth() +{ + for(S32 i = 0; i < mItems.size(); i++) + { + if(mItems[i].index == ItemBarrierMaker && mItems[i].selected && mItems[i].width >= 9) + mItems[i].width -= 5; + } +} + +void EditorUserInterface::constructItem(U32 itemIndex) +{ + clearSelection(); + WorldItem w; + w.index = itemIndex; + if(gGameItemRecs[itemIndex].hasTeam) + w.team = mCurrentTeam; + else + w.team = -1; + if(w.team == -1 && gGameItemRecs[itemIndex].hasTeam && !gGameItemRecs[itemIndex].canHaveNoTeam) + w.team = 0; + + w.selected = false; + Point pos = convertCanvasToLevelCoord(mMousePos); + w.verts.push_back(snapToLevelGrid(pos)); + w.vertSelected.push_back(false); + if(itemIndex == ItemTeleporter) + { + w.verts.push_back(w.verts[0] + Point(1,1)); + w.vertSelected.push_back(false); + } + mItems.push_back(w); +} + +void EditorUserInterface::onKeyDown(U32 key) +{ + bool ctrlActive = glutGetModifiers() & GLUT_ACTIVE_CTRL; + + if(key >= '0' && key < U32('1' + mTeams.size())) + { + setCurrentTeam(S32(key) - '1'); + return; + } + + switch(tolower(key)) + { + case 0x4: // control-d + duplicateSelection(); + break; + case 'f': + flipSelectionHorizontal(); + break; + case 26: + { + Vector temp = mItems; + mItems = mOriginalItems; + mOriginalItems = temp; + break; + } + case 'v': + flipSelectionVertical(); + break; + case 'r': + if (key == 'R') + rotateSelection(15.0f); + else + rotateSelection(-15.0f); + break; + case 'z': + mCurrentOffset.set(0,0); + break; + case 'w': + mUp = true; + break; + case 's': + mDown = true; + break; + case 'a': + mLeft = true; + break; + case 'd': + mRight = true; + break; + case 'e': + mIn = true; + break; + case 'c': + mOut = true; + break; + case 't': + constructItem(ItemTeleporter); + break; + case 'g': + constructItem(ItemSpawn); + break; + case 'b': + constructItem(ItemRepair); + break; + case 'y': + constructItem(ItemTurret); + break; + case 'h': + constructItem(ItemForceField); + break; + case 8: + case 127: + deleteSelection(); + break; + case '+': + case '=': + incBarrierWidth(); + break; + case '-': + case '_': + decBarrierWidth(); + break; + case 27: + gEditorMenuUserInterface.activate(); + break; + } +} + +void EditorUserInterface::onKeyUp(U32 key) +{ + switch(tolower(key)) + { + case 'w': + mUp = false; + break; + case 's': + mDown = false; + break; + case 'a': + mLeft = false; + break; + case 'd': + mRight = false; + break; + case 'e': + mIn = false; + break; + case 'c': + mOut = false; + break; + } +} + +void EditorUserInterface::idle(U32 timeDelta) +{ + F32 pixelsToScroll = timeDelta * 0.5f; + + if(mLeft && !mRight) + mCurrentOffset.x += pixelsToScroll; + else if(mRight && !mLeft) + mCurrentOffset.x -= pixelsToScroll; + if(mUp && !mDown) + mCurrentOffset.y += pixelsToScroll; + else if(mDown && !mUp) + mCurrentOffset.y -= pixelsToScroll; + + Point mouseLevelPoint = convertCanvasToLevelCoord(mMousePos); + if(mIn && !mOut) + mCurrentScale *= 1 + timeDelta * 0.002; + if(mOut && !mIn) + mCurrentScale *= 1 - timeDelta * 0.002; + if(mCurrentScale > 200) + mCurrentScale = 200; + else if(mCurrentScale < 10) + mCurrentScale = 10; + Point newMousePoint = convertLevelToCanvasCoord(mouseLevelPoint); + mCurrentOffset += mMousePos - newMousePoint; +} + +static void escapeString(const char *src, char dest[1024]) +{ + S32 i; + for(i = 0; src[i]; i++) + if(src[i] == '\"' || src[i] == ' ' || src[i] == '\n' || src[i] == '\t') + break; + + if(!src[i]) + { + strcpy(dest, src); + return; + } + char *dptr = dest; + *dptr++ = '\"'; + char c; + while((c = *src++) != 0) + { + switch(c) + { + case '\"': + *dptr++ = '\\'; + *dptr++ = '\"'; + break; + case '\n': + *dptr++ = '\\'; + *dptr++ = 'n'; + break; + case '\t': + *dptr++ = '\\'; + *dptr++ = 't'; + break; + default: + *dptr++ = c; + } + } + *dptr++ = '\"'; + *dptr++ = 0; +} + +void EditorUserInterface::saveLevel() +{ + char fileNameBuffer[256]; + dSprintf(fileNameBuffer, sizeof(fileNameBuffer), "levels/%s", mEditFileName); + FILE *f = fopen(fileNameBuffer, "w"); + fprintf(f, "%sGameType", mGameType); + for(S32 i = 0; i < mGameTypeArgs.size(); i++) + fprintf(f, " %s", mGameTypeArgs[i]); + fprintf(f, "\n"); + for(S32 i = 0; i < mTeams.size(); i++) + { + fprintf(f, "Team %s %g %g %g\n", mTeams[i].name, + mTeams[i].color.r, mTeams[i].color.g, mTeams[i].color.b); + } + for(S32 i = 0; i < mUnknownItems.size(); i++) + { + Vector &v = mUnknownItems[i]; + for(S32 j = 0; j < v.size(); j++) + { + char outBuffer[1024]; + escapeString(v[j], outBuffer); + fputs(outBuffer, f); + if(j == v.size() - 1) + fputs("\n", f); + else + fputs(" ", f); + } + } + for(S32 i = 0; i < mItems.size(); i++) + { + WorldItem &p = mItems[i]; + fprintf(f, "%s ", gGameItemRecs[mItems[i].index].name); + if(gGameItemRecs[mItems[i].index].hasWidth) + fprintf(f, "%g ", mItems[i].width); + if(gGameItemRecs[mItems[i].index].hasTeam) + fprintf(f, "%d ", mItems[i].team); + for(S32 j = 0; j < p.verts.size(); j++) + fprintf(f, "%g %g%c", p.verts[j].x, p.verts[j].y, (j == p.verts.size() - 1) ? '\n' : ' '); + } + + fclose(f); +} + +extern void hostGame(bool dedicated, Address bindAddress); +extern const char *gLevelList; + +void EditorUserInterface::testLevel() +{ + char tmpFileName[256]; + strcpy(tmpFileName, mEditFileName); + strcpy(mEditFileName, "editor.tmp"); + saveLevel(); + strcpy(mEditFileName, tmpFileName); + const char *gLevelSave = gLevelList; + gLevelList = "editor.tmp"; + hostGame(false, Address(IPProtocol, Address::Any, 28000)); + gLevelList = gLevelSave; +} + +EditorMenuUserInterface gEditorMenuUserInterface; + +EditorMenuUserInterface::EditorMenuUserInterface() +{ + menuTitle = "EDITOR MENU:"; +} + +void EditorMenuUserInterface::onActivate() +{ + setupMenus(); +} + +void EditorMenuUserInterface::setupMenus() +{ + Parent::onActivate(); + menuItems.clear(); + menuItems.push_back(MenuItem("RETURN TO EDITOR", 0)); + if(OptionsMenuUserInterface::fullscreen) + menuItems.push_back(MenuItem("SET WINDOWED MODE", 1)); + else + menuItems.push_back(MenuItem("SET FULLSCREEN MODE", 1)); + menuItems.push_back(MenuItem("TEST LEVEL",2)); + menuItems.push_back(MenuItem("SAVE LEVEL",3)); + menuItems.push_back(MenuItem("QUIT",4)); +} + +void EditorMenuUserInterface::processSelection(U32 index) +{ + switch(index) + { + case 0: + gEditorUserInterface.activate(); + break; + case 1: + gOptionsMenuUserInterface.processSelection(1); + setupMenus(); + break; + case 2: + gEditorUserInterface.testLevel(); + break; + case 3: + gEditorUserInterface.activate(); + gEditorUserInterface.saveLevel(); + break; + case 4: + gCreditsUserInterface.activate(); + break; + } +} + +void EditorMenuUserInterface::onEscape() +{ + gEditorUserInterface.activate(); +} + +void EditorMenuUserInterface::render() +{ + gEditorUserInterface.render(); + glColor4f(0, 0, 0, 0.5); + glEnable(GL_BLEND); + glBegin(GL_POLYGON); + glVertex2f(0, 0); + glVertex2f(canvasWidth, 0); + glVertex2f(canvasWidth, canvasHeight); + glVertex2f(0, canvasHeight); + glEnd(); + glDisable(GL_BLEND); + Parent::render(); +} + +}; diff --git a/tnl-1.5.0/tnl/zap/UIEditor.h b/tnl-1.5.0/tnl/zap/UIEditor.h new file mode 100644 index 0000000000000000000000000000000000000000..af9666e50bd89283706e7188e553bb4575288b6a --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIEditor.h @@ -0,0 +1,140 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UIEDITOR_H_ +#define _UIEDITOR_H_ + +#include "UIMenus.h" +#include "gameLoader.h" +#include "point.h" + +namespace Zap +{ + +class EditorUserInterface : public UserInterface, public LevelLoader +{ + struct WorldItem + { + U32 index; + S32 team; + F32 width; + Vector verts; + bool selected; + Vector vertSelected; + }; + struct Team + { + char name[256]; + Color color; + }; + char mGameType[256]; + Vector mGameTypeArgs; + + Vector mItems; + Vector mOriginalItems; + + Vector mTeams; + + Vector > mUnknownItems; + + char mEditFileName[255]; + + WorldItem mNewItem; + F32 mCurrentScale; + Point mCurrentOffset; + Point mMousePos; + Point mMouseDownPos; + S32 mCurrentTeam; + F32 mGridSize; + + bool mCreatingPoly; + bool mDragSelecting; + + bool mUp, mDown, mLeft, mRight, mIn, mOut; + + void clearSelection(); + S32 countSelectedItems(); + S32 countSelectedVerts(); + void findHitVertex(Point canvasPos, S32 &hitItem, S32 &hitVertex); + void findHitItemAndEdge(Point canvasPos, S32 &hitItem, S32 &hitEdge); + void computeSelectionMinMax(Point &min, Point &max); + + void processLevelLoadLine(int argc, const char **argv); + void constructItem(U32 itemIndex); +public: + static bool editorEnabled; + void setEditName(const char *name); + + void render(); + void renderPoly(WorldItem &p); + void renderItem(S32 i); + void onMouseDown(S32 x, S32 y); + void onMouseUp(S32 x, S32 y); + void onMouseDragged(S32 x, S32 y); + void onRightMouseDown(S32 x, S32 y); + void onMouseMoved(S32 x, S32 y); + void onKeyDown(U32 key); + void onKeyUp(U32 key); + void onActivate(); + void idle(U32 timeDelta); + void deleteSelection(); + void duplicateSelection(); + void setCurrentTeam(S32 currentTeam); + void flipSelectionVertical(); + void flipSelectionHorizontal(); + void rotateSelection(F32 angle); + + void incBarrierWidth(); + void decBarrierWidth(); + + void saveLevel(); + void testLevel(); + + Point convertWindowToCanvasCoord(Point p) { return Point(p.x * canvasWidth / windowWidth, p.y * canvasHeight / windowHeight); } + Point convertCanvasToLevelCoord(Point p) { return (p - mCurrentOffset) * (1 / mCurrentScale); } + Point convertLevelToCanvasCoord(Point p) { return p * mCurrentScale + mCurrentOffset; } + Point snapToLevelGrid(Point p); +}; + +class EditorMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; + +public: + EditorMenuUserInterface(); + void render(); + void onActivate(); + void setupMenus(); + void processSelection(U32 index); + void onEscape(); +}; + +extern EditorUserInterface gEditorUserInterface; +extern EditorMenuUserInterface gEditorMenuUserInterface; +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/UIGame.cpp b/tnl-1.5.0/tnl/zap/UIGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..250676f17f9bd876d426a280154fc58b56ef804c --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIGame.cpp @@ -0,0 +1,834 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameConnection.h" + +#include "game.h" +#include "UIGame.h" +#include "UIMenus.h" +#include "UIInstructions.h" +#include "gameType.h" +#include "lpc10.h" +#include "tnlEndian.h" +#include "ship.h" + +#include +#include "glutInclude.h" +#include +#include +#include "gameObjectRender.h" + +namespace Zap +{ + +GameUserInterface gGameUserInterface; +Color gGlobalChatColor(0.9, 0.9, 0.9); +Color gTeamChatColor(0, 1, 0); + +GameUserInterface::GameUserInterface() +{ + mCurrentMode = PlayMode; + mInScoreboardMode = false; +#if 0 //defined(TNL_OS_XBOX) + mFPSVisible = true; +#else + mFPSVisible = false; +#endif + mFrameIndex = 0; + for(U32 i = 0; i < FPSAvgCount; i++) + mIdleTimeDelta[i] = 50; + + mChatLastBlinkTime = 0; + memset(mChatBuffer, 0, sizeof(mChatBuffer)); + mChatBlink = false; + + for(U32 i = 0; i < MessageDisplayCount; i++) + mDisplayMessage[i][0] = 0; + + mGotControlUpdate = false; +} + +void GameUserInterface::displayMessage(Color theColor, const char *format, ...) +{ + for(S32 i = MessageDisplayCount - 1; i > 0; i--) + { + strcpy(mDisplayMessage[i], mDisplayMessage[i-1]); + mDisplayMessageColor[i] = mDisplayMessageColor[i-1]; + } + va_list args; + va_start(args, format); + dVsprintf(mDisplayMessage[0], sizeof(mDisplayMessage[0]), format, args); + mDisplayMessageColor[0] = theColor; + + mDisplayMessageTimer = DisplayMessageTimeout; +} + +void GameUserInterface::idle(U32 timeDelta) +{ + if(timeDelta > mDisplayMessageTimer) + { + mDisplayMessageTimer = DisplayMessageTimeout; + for(S32 i = MessageDisplayCount - 1; i > 0; i--) + { + strcpy(mDisplayMessage[i], mDisplayMessage[i-1]); + mDisplayMessageColor[i] = mDisplayMessageColor[i-1]; + } + + mDisplayMessage[0][0] = 0; + } + else + mDisplayMessageTimer -= timeDelta; + if(mCurrentMode == ChatMode) + { + mChatLastBlinkTime += timeDelta; + if(mChatLastBlinkTime > ChatBlinkTime) + { + mChatBlink = !mChatBlink; + mChatLastBlinkTime = 0; + } + } + else if(mCurrentMode == VChatMode) + mVChat.idle(timeDelta); + else if(mCurrentMode == LoadoutMode) + mLoadout.idle(timeDelta); + mVoiceRecorder.idle(timeDelta); + mIdleTimeDelta[mFrameIndex % FPSAvgCount] = timeDelta; + mFrameIndex++; +} + +#ifdef TNL_OS_WIN32 +extern void checkMousePos(S32 maxdx, S32 maxdy); +#endif + +void GameUserInterface::render() +{ + glColor3f(0.0, 0.0, 0.0); + if(!gClientGame->isConnectedToServer()) + { + glColor3f(1,1,1); + drawCenteredString(290, 30, "Connecting to server..."); + + if(gClientGame->getConnectionToServer()) + drawCenteredString(330, 16, gConnectStatesTable[gClientGame->getConnectionToServer()->getConnectionState()]); + drawCenteredString(370, 20, "Press to abort"); + } + + gClientGame->render(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + renderReticle(); + + renderMessageDisplay(); + renderCurrentChat(); + + mVoiceRecorder.render(); + if(mFPSVisible) + { + U32 sum = 0; + for(U32 i = 0; i < FPSAvgCount; i++) + sum += mIdleTimeDelta[i]; + drawStringf(canvasWidth - horizMargin - 170, vertMargin, 30, + "%0.2g %0.2g %4.2f fps", mCurrentMove.right - mCurrentMove.left, + mCurrentMove.down - mCurrentMove.up, + (1000 * FPSAvgCount) / F32(sum)); + } + if(mCurrentMode == VChatMode) + mVChat.render(); + else if(mCurrentMode == LoadoutMode) + mLoadout.render(); + + GameType *theGameType = gClientGame->getGameType(); + + if(theGameType) + theGameType->renderInterfaceOverlay(mInScoreboardMode); + +#if 0 + // some code for outputting the position of the ship for finding good spawns + GameConnection *con = gClientGame->getConnectionToServer(); + + if(con) + { + GameObject *co = con->getControlObject(); + if(co) + { + Point pos = co->getActualPos() * F32(1 / 300.0f); + drawStringf(10, 550, 30, "%0.2g, %0.2g", pos.x, pos.y); + } + } + + if(mGotControlUpdate) + { + drawString(710, 10, 30, "CU"); + } +#endif +} + +void GameUserInterface::renderReticle() +{ + // draw the reticle + + if(OptionsMenuUserInterface::joystickType == -1) + { +#if 0 // TNL_OS_WIN32 + Point realMousePoint = mMousePoint; + if(!OptionsMenuUserInterface::controlsRelative) + { + F32 len = mMousePoint.len(); + checkMousePos(windowWidth * 100 / canvasWidth, + windowHeight * 100 / canvasHeight); + + if(len > 100) + realMousePoint *= 100 / len; + } +#endif + Point offsetMouse = mMousePoint + Point(canvasWidth / 2, canvasHeight / 2); + + glEnable(GL_BLEND); + glColor4f(0,1,0, 0.7); + glBegin(GL_LINES); + + glVertex2f(offsetMouse.x - 15, offsetMouse.y); + glVertex2f(offsetMouse.x + 15, offsetMouse.y); + glVertex2f(offsetMouse.x, offsetMouse.y - 15); + glVertex2f(offsetMouse.x, offsetMouse.y + 15); + + if(offsetMouse.x > 30) + { + glColor4f(0,1,0, 0); + glVertex2f(0, offsetMouse.y); + glColor4f(0,1,0, 0.7); + glVertex2f(offsetMouse.x - 30, offsetMouse.y); + } + if(offsetMouse.x < canvasWidth - 30) + { + glColor4f(0,1,0, 0.7); + glVertex2f(offsetMouse.x + 30, offsetMouse.y); + glColor4f(0,1,0, 0); + glVertex2f(canvasWidth, offsetMouse.y); + } + if(offsetMouse.y > 30) + { + glColor4f(0,1,0, 0); + glVertex2f(offsetMouse.x, 0); + glColor4f(0,1,0, 0.7); + glVertex2f(offsetMouse.x, offsetMouse.y - 30); + } + if(offsetMouse.y < canvasHeight - 30) + { + glColor4f(0,1,0, 0.7); + glVertex2f(offsetMouse.x, offsetMouse.y + 30); + glColor4f(0,1,0, 0); + glVertex2f(offsetMouse.x, canvasHeight); + } + + glEnd(); + glDisable(GL_BLEND); + } +} + +void GameUserInterface::renderMessageDisplay() +{ + glColor3f(1,1,1); + + U32 y = UserInterface::vertMargin; + for(S32 i = 3; i >= 0; i--) + { + if(mDisplayMessage[i][0]) + { + glColor(mDisplayMessageColor[i]); + + drawString(UserInterface::horizMargin, y, 20, mDisplayMessage[i]); + y += 24; + } + } +} + +void GameUserInterface::renderCurrentChat() +{ + if(mCurrentMode == ChatMode) + { + const char *promptStr; + if(mCurrentChatType == TeamChat) + { + glColor3f(gTeamChatColor.r, + gTeamChatColor.g, + gTeamChatColor.b); + + promptStr = "(Team): "; + } + else + { + glColor3f(gGlobalChatColor.r, + gGlobalChatColor.g, + gGlobalChatColor.b); + + promptStr = "(Global): "; + } + + U32 width = getStringWidth(20, promptStr); + + drawString(UserInterface::horizMargin, UserInterface::vertMargin + 95, 20, promptStr); + drawString(UserInterface::horizMargin + width, UserInterface::vertMargin + 95, 20, mChatBuffer); + + if(mChatBlink) + drawString(UserInterface::horizMargin + width + getStringWidth(20, mChatBuffer, mChatCursorPos), UserInterface::vertMargin + 95, 20, "_"); + } +} + +void GameUserInterface::onMouseDragged(S32 x, S32 y) +{ + onMouseMoved(x, y); +} + +void GameUserInterface::onMouseMoved(S32 x, S32 y) +{ + S32 xp = S32(x - windowWidth / 2); + S32 yp = S32(y - windowHeight / 2); + + mMousePoint = Point(x - windowWidth / 2, y - windowHeight / 2); + mMousePoint.x = mMousePoint.x * canvasWidth / windowWidth; + mMousePoint.y = mMousePoint.y * canvasHeight / windowHeight; + mCurrentMove.angle = atan2(mMousePoint.y, mMousePoint.x); +} + +void GameUserInterface::onMouseDown(S32 x, S32 y) +{ + mCurrentMove.fire = true; +} + +void GameUserInterface::onMouseUp(S32 x, S32 y) +{ + mCurrentMove.fire = false; +} + +void GameUserInterface::onRightMouseDown(S32 x, S32 y) +{ + mCurrentMove.module[1] = true; +} + +void GameUserInterface::onRightMouseUp(S32 x, S32 y) +{ + mCurrentMove.module[1] = false; +} + +void GameUserInterface::enterVChat(bool fromController) +{ + UserInterface::playBoop(); + mVChat.show(fromController); + mCurrentMode = VChatMode; +} + +void GameUserInterface::enterLoadout(bool fromController) +{ + UserInterface::playBoop(); + mLoadout.show(fromController); + mCurrentMode = LoadoutMode; +} + +void GameUserInterface::onControllerButtonDown(U32 buttonIndex) +{ + if(buttonIndex == 6) + mCurrentMove.module[1] = true; + else if(buttonIndex == 7) + mCurrentMove.module[0] = true; + else + { + if(mCurrentMode == PlayMode) + { + switch(buttonIndex) + { + case 0: + { + GameType *g = gClientGame->getGameType(); + if(g) + g->c2sAdvanceWeapon(); + break; + } + case 1: + gClientGame->zoomCommanderMap(); + break; + case 2: + enterVChat(true); + break; + case 3: + enterLoadout(true); + break; + case 4: + { + mInScoreboardMode = true; + GameType *g = gClientGame->getGameType(); + if(g) + g->c2sRequestScoreboardUpdates(true); + break; + } + case 5: + mVoiceRecorder.start(); + break; + default: + logprintf("button down: %d", buttonIndex); + break; + } + } + else if(mCurrentMode == VChatMode) + { + mVChat.processKey(buttonIndex); + } + else if(mCurrentMode == LoadoutMode) + { + mLoadout.processKey(buttonIndex); + } + } +} + +void GameUserInterface::onControllerButtonUp(U32 buttonIndex) +{ + if(buttonIndex == 6) + mCurrentMove.module[1] = false; + else if(buttonIndex == 7) + mCurrentMove.module[0] = false; + else + { + if(mCurrentMode == PlayMode) + { + switch(buttonIndex) + { + case 4: + { + mInScoreboardMode = false; + GameType *g = gClientGame->getGameType(); + if(g) + g->c2sRequestScoreboardUpdates(false); + break; + } + case 5: + mVoiceRecorder.stop(); + break; + } + } + } +} + +void GameUserInterface::onModifierKeyDown(U32 key) +{ + if(mCurrentMode == LoadoutMode || + mCurrentMode == PlayMode) + { + if(key == 0) + { + mCurrentMove.module[1] = true; + } + } +} + +void GameUserInterface::onModifierKeyUp(U32 key) +{ + if(mCurrentMode == LoadoutMode || + mCurrentMode == PlayMode) + { + if(key == 0) + { + mCurrentMove.module[1] = false; + } + } +} + +void GameUserInterface::onSpecialKeyDown(U32 key) +{ + if(key == GLUT_KEY_F1) + gInstructionsUserInterface.activate(); +} + +void GameUserInterface::onKeyDown(U32 key) +{ + if(mCurrentMode == LoadoutMode) + if(mLoadout.processKey(key)) + return; + if(mCurrentMode == LoadoutMode || + mCurrentMode == PlayMode) + { + mCurrentChatType = GlobalChat; + + // the following keys are allowed in both play mode + // and in loadout or engineering menu modes if not used in the menu + // menu + switch(toupper(key)) + { + case '\t': + { + mInScoreboardMode = true; + GameType *g = gClientGame->getGameType(); + if(g) + g->c2sRequestScoreboardUpdates(true); + break; + } + case 'P': + mFPSVisible = !mFPSVisible; + break; + case 'W': + mCurrentMove.up = 1.0; + break; + case 'A': + mCurrentMove.left = 1.0; + break; + case 'S': + mCurrentMove.down = 1.0; + break; + case 'D': + mCurrentMove.right = 1.0; + break; + case ' ': + mCurrentMove.module[0] = true; + break; + case 'E': + { + GameType *g = gClientGame->getGameType(); + if(g) + g->c2sAdvanceWeapon(); + break; + } + case 27: + if(!gClientGame->isConnectedToServer()) + { + endGame(); + gMainMenuUserInterface.activate(); + } + else + gGameMenuUserInterface.activate(); + break; + case 'C': + gClientGame->zoomCommanderMap(); + break; + case 'R': + mVoiceRecorder.start(); + break; + default: + { + if(mCurrentMode == LoadoutMode) + break; + // the following keys are only allowed in play mode + switch(toupper(key)) + { + case 'T': + mCurrentChatType = TeamChat; + case 'G': + + mChatLastBlinkTime = 0; + mChatBlink = true; + mCurrentMode = ChatMode; + mCurrentMove.up = + mCurrentMove.left = + mCurrentMove.right = + mCurrentMove.down = 0; + break; + case 'V': + enterVChat(false); + break; + case 'Q': + enterLoadout(false); + break; + + } + } + } + } + else if(mCurrentMode == ChatMode) + { + if(key == '\r') + issueChat(); + else if(key == 8 || key == 127) + { + // backspace key + if(mChatCursorPos > 0) + { + mChatCursorPos--; + for(U32 i = mChatCursorPos; mChatBuffer[i]; i++) + mChatBuffer[i] = mChatBuffer[i+1]; + } + } + else if(key == 27) + { + cancelChat(); + } + else + { + for(U32 i = sizeof(mChatBuffer) - 2; i > mChatCursorPos; i--) + mChatBuffer[i] = mChatBuffer[i-1]; + if(mChatCursorPos < sizeof(mChatBuffer) - 2) + { + mChatBuffer[mChatCursorPos] = key; + mChatCursorPos++; + } + } + } + else if(mCurrentMode == VChatMode) + mVChat.processKey(key); +} + +void GameUserInterface::onKeyUp(U32 key) +{ + if(mCurrentMode == LoadoutMode || + mCurrentMode == PlayMode) + { + switch(toupper(key)) + { + case '\t': + { + mInScoreboardMode = false; + GameType *g = gClientGame->getGameType(); + if(g) + g->c2sRequestScoreboardUpdates(false); + break; + } + case 'W': + mCurrentMove.up = 0; + break; + case 'A': + mCurrentMove.left = 0; + break; + case 'S': + mCurrentMove.down = 0; + break; + case 'D': + mCurrentMove.right = 0; + break; + + case ' ': + mCurrentMove.module[0] = false; + break; + case 'R': + mVoiceRecorder.stop(); + break; + } + } + else if(mCurrentMode == ChatMode) + { + + + } +} + +Move *GameUserInterface::getCurrentMove() +{ + if(!OptionsMenuUserInterface::controlsRelative) + return &mCurrentMove; + else + { + mTransformedMove = mCurrentMove; + + Point moveDir(mCurrentMove.right - mCurrentMove.left, + mCurrentMove.up - mCurrentMove.down); + + Point angleDir(cos(mCurrentMove.angle), sin(mCurrentMove.angle)); + + Point rightAngleDir(-angleDir.y, angleDir.x); + Point newMoveDir = angleDir * moveDir.y + rightAngleDir * moveDir.x; + + if(newMoveDir.x > 0) + { + mTransformedMove.right = newMoveDir.x; + mTransformedMove.left = 0; + } + else + { + mTransformedMove.right = 0; + mTransformedMove.left = -newMoveDir.x; + } + if(newMoveDir.y > 0) + { + mTransformedMove.down = newMoveDir.y; + mTransformedMove.up = 0; + } + else + { + mTransformedMove.down = 0; + mTransformedMove.up = -newMoveDir.y; + } + if(mTransformedMove.right > 1) + mTransformedMove.right = 1; + if(mTransformedMove.left > 1) + mTransformedMove.left = 1; + if(mTransformedMove.up > 1) + mTransformedMove.up = 1; + if(mTransformedMove.down > 1) + mTransformedMove.down = 1; + + return &mTransformedMove; + } +} + +void GameUserInterface::cancelChat() +{ + memset(mChatBuffer, 0, sizeof(mChatBuffer)); + mChatCursorPos = 0; + mCurrentMode = PlayMode; +} + +void GameUserInterface::issueChat() +{ + if(mChatBuffer[0]) + { + GameType *gt = gClientGame->getGameType(); + if(gt) + gt->c2sSendChat(mCurrentChatType == GlobalChat, mChatBuffer); + } + cancelChat(); +} + +GameUserInterface::VoiceRecorder::VoiceRecorder() +{ + mRecordingAudio = false; + mMaxAudioSample = 0; + mMaxForGain = 0; + mVoiceEncoder = new LPC10VoiceEncoder; +} + +void GameUserInterface::VoiceRecorder::idle(U32 timeDelta) +{ + if(mRecordingAudio) + { + if(mVoiceAudioTimer.update(timeDelta)) + { + mVoiceAudioTimer.reset(VoiceAudioSampleTime); + process(); + } + } +} + +void GameUserInterface::VoiceRecorder::render() +{ + if(mRecordingAudio) + { + F32 amt = mMaxAudioSample / F32(0x7FFF); + U32 totalLineCount = 50; + + glColor3f(1, 1 ,1); + glBegin(GL_LINES); + glVertex2f(10, 130); + glVertex2f(10, 145); + glVertex2f(10 + totalLineCount * 2, 130); + glVertex2f(10 + totalLineCount * 2, 145); + + F32 halfway = totalLineCount * 0.5; + F32 full = amt * totalLineCount; + for(U32 i = 1; i < full; i++) + { + if(i < halfway) + glColor3f(i / halfway, 1, 0); + else + glColor3f(1, 1 - (i - halfway) / halfway, 0); + + glVertex2f(10 + i * 2, 130); + glVertex2f(10 + i * 2, 145); + } + glEnd(); + } +} + +void GameUserInterface::VoiceRecorder::start() +{ + if(!mRecordingAudio) + { + mRecordingAudio = SFXObject::startRecording(); + if(!mRecordingAudio) + return; + + mUnusedAudio = new ByteBuffer(0); + mRecordingAudio = true; + mMaxAudioSample = 0; + mVoiceAudioTimer.reset(FirstVoiceAudioSampleTime); + + // trim the start of the capture buffer: + SFXObject::captureSamples(mUnusedAudio); + mUnusedAudio->resize(0); + } +} + +void GameUserInterface::VoiceRecorder::stop() +{ + if(mRecordingAudio) + { + process(); + + mRecordingAudio = false; + SFXObject::stopRecording(); + mVoiceSfx = NULL; + mUnusedAudio = NULL; + } +} + +void GameUserInterface::VoiceRecorder::process() +{ + U32 preSampleCount = mUnusedAudio->getBufferSize() / 2; + SFXObject::captureSamples(mUnusedAudio); + + U32 sampleCount = mUnusedAudio->getBufferSize() / 2; + if(sampleCount == preSampleCount) + return; + + S16 *samplePtr = (S16 *) mUnusedAudio->getBuffer(); + mMaxAudioSample = 0; + + for(U32 i = preSampleCount; i < sampleCount; i++) + { + if(samplePtr[i] > mMaxAudioSample) + mMaxAudioSample = samplePtr[i]; + else if(-samplePtr[i] > mMaxAudioSample) + mMaxAudioSample = -samplePtr[i]; + } + mMaxForGain = U32(mMaxForGain * 0.95f); + S32 boostedMax = mMaxAudioSample + 2048; + if(boostedMax > mMaxForGain) + mMaxForGain = boostedMax; + if(mMaxForGain > MaxDetectionThreshold) + { + // apply some gain to the buffer: + F32 gain = 0x7FFF / F32(mMaxForGain); + for(U32 i = preSampleCount; i < sampleCount; i++) + { + F32 sample = gain * samplePtr[i]; + if(sample > 0x7FFF) + samplePtr[i] = 0x7FFF; + else if(sample < -0x7FFF) + samplePtr[i] = -0x7FFF; + else + samplePtr[i] = S16(sample); + } + mMaxAudioSample = U32(mMaxAudioSample * gain); + } + + ByteBufferPtr sendBuffer = mVoiceEncoder->compressBuffer(mUnusedAudio); + + if(sendBuffer.isValid()) + { + GameType *gt = gClientGame->getGameType(); + if(gt) + gt->c2sVoiceChat(OptionsMenuUserInterface::echoVoice, sendBuffer); + } +} + +}; diff --git a/tnl-1.5.0/tnl/zap/UIGame.h b/tnl-1.5.0/tnl/zap/UIGame.h new file mode 100644 index 0000000000000000000000000000000000000000..63c146b1f1bac85201ca2209dfb8d39aa3cf9218 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIGame.h @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UIGAME_H_ +#define _UIGAME_H_ + +#include "UI.h" +#include "point.h" +#include "gameConnection.h" +#include "quickChat.h" +#include "loadoutSelect.h" +#include "timer.h" +#include "sfx.h" +#include "voiceCodec.h" + +namespace Zap +{ + +class GameUserInterface : public UserInterface +{ + Move mCurrentMove; + Move mTransformedMove; + + Point mMousePoint; + enum { + DisplayMessageTimeout = 2500, + }; + + enum { + MessageDisplayCount = 4, + }; + + Color mDisplayMessageColor[MessageDisplayCount]; + char mDisplayMessage[MessageDisplayCount][2048]; + + + U32 mDisplayMessageTimer; + enum Mode { + PlayMode, + ChatMode, + VChatMode, + LoadoutMode, + }; + enum ChatType { + GlobalChat, + TeamChat, + }; + enum { + ChatBlinkTime = 100, + FPSAvgCount = 32, + }; + Mode mCurrentMode; + ChatType mCurrentChatType; + + char mChatBuffer[50]; + U32 mChatCursorPos; + bool mChatBlink; + U32 mChatLastBlinkTime; + bool mInScoreboardMode; + bool mGotControlUpdate; + + bool mFPSVisible; + U32 mIdleTimeDelta[FPSAvgCount]; + U32 mFrameIndex; + + VChatHelper mVChat; + LoadoutHelper mLoadout; + + struct VoiceRecorder + { + enum { + FirstVoiceAudioSampleTime = 250, + VoiceAudioSampleTime = 100, + MaxDetectionThreshold = 2048, + }; + + Timer mVoiceAudioTimer; + RefPtr mVoiceSfx; + RefPtr mVoiceEncoder; + bool mRecordingAudio; + S32 mMaxAudioSample; + S32 mMaxForGain; + ByteBufferPtr mUnusedAudio; + + VoiceRecorder(); + + void idle(U32 timeDelta); + void process(); + void start(); + void stop(); + void render(); + + } mVoiceRecorder; + + void enterVChat(bool fromController); + void enterLoadout(bool fromController); +public: + GameUserInterface(); + + void displayMessage(Color messageColor, const char *format, ...); + + void render(); + void renderReticle(); + void renderMessageDisplay(); + void renderCurrentChat(); + void setPlayMode() { mCurrentMode = PlayMode; } + + void idle(U32 timeDelta); + + void issueChat(); + void cancelChat(); + + void onMouseMoved(S32 x, S32 y); + void onMouseDragged(S32 x, S32 y); + void onMouseDown(S32 x, S32 y); + void onMouseUp(S32 x, S32 y); + void onRightMouseDown(S32 x, S32 y); + void onRightMouseUp(S32 x, S32 y); + void onKeyDown(U32 key); + void onKeyUp(U32 key); + void onModifierKeyDown(U32 key); + void onModifierKeyUp(U32 key); + void onSpecialKeyDown(U32 key); + void onControllerButtonDown(U32 buttonIndex); + void onControllerButtonUp(U32 buttonIndex); + + void receivedControlUpdate(bool recvd) { mGotControlUpdate = recvd; } + + Move *getCurrentMove(); +}; + +extern GameUserInterface gGameUserInterface; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/UIInstructions.cpp b/tnl-1.5.0/tnl/zap/UIInstructions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0478e2b44ed5484490d708b012cc2a3749b31899 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIInstructions.cpp @@ -0,0 +1,452 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "UIInstructions.h" +#include "UIMenus.h" +#include "UIGame.h" +#include "game.h" +#include "glutInclude.h" +#include "gameObjectRender.h" +#include "ship.h" +#include "teleporter.h" +#include "engineeredObjects.h" +#include "input.h" + +namespace Zap +{ + +InstructionsUserInterface gInstructionsUserInterface; + +void InstructionsUserInterface::onActivate() +{ + mCurPage = 1; +} + +enum { + NumPages = 5, +}; + +const char *pageHeaders[] = { + "CONTROLS", + "LOADOUT SELECTION", + "WEAPON PROJECTILES", + "GAME OBJECTS", + "GAME OBJECTS", +}; + +void InstructionsUserInterface::render() +{ + if(gClientGame->isConnectedToServer()) + { + gGameUserInterface.render(); + glEnable(GL_BLEND); + glBegin(GL_POLYGON); + glColor4f(0, 0, 0, 0.7); + glVertex2f(0,0); + glVertex2f(canvasWidth, 0); + glVertex2f(canvasWidth, canvasHeight); + glVertex2f(0, canvasHeight); + glEnd(); + glDisable(GL_BLEND); + } + + glColor3f(1,1,1); + drawStringf(3, 3, 25, "INSTRUCTIONS - %s", pageHeaders[mCurPage - 1]); + drawStringf(650, 3, 25, "PAGE %d/%d", mCurPage, NumPages); + drawCenteredString(571, 20, "LEFT - previous page RIGHT, SPACE - next page ESC exits"); + glColor3f(0.7, 0.7, 0.7); + glBegin(GL_LINES); + glVertex2f(0, 31); + glVertex2f(800, 31); + glVertex2f(0, 569); + glVertex2f(800, 569); + glEnd(); + switch(mCurPage) + { + case 1: + renderPage1(); + break; + case 2: + renderPage2(); + break; + case 3: + renderPageObjectDesc(0); + break; + case 4: + renderPageObjectDesc(1); + break; + case 5: + renderPageObjectDesc(2); + break; + } +} + +struct ControlString +{ + const char *controlString; + const char *primaryControl; +}; + +static ControlString gControlsKeyboard[] = { + { "Move ship up (forward)", "W" }, + { "Move ship down (backward)", "S" }, + { "Move ship left (strafe left)", "A" }, + { "Move ship right (strafe right)", "D" }, + { "Aim ship", "MOUSE" }, + { "Fire weapon", "MOUSE BUTTON 1" }, + { "Activate primary module", "SPACE" }, + { "Activate secondary module", "SHIFT, MOUSE BUTTON 2" }, + { "Cycle current weapon", "E" }, + { "Open loadout selection menu", "Q" }, + { "Toggle map view", "C" }, + { "Chat to team", "T" }, + { "Chat to everyone", "G" }, + { "Open QuickChat menu", "V" }, + { "Record voice chat", "R" }, + { "Show scoreboard", "TAB" }, + { NULL, NULL }, +}; + +static ControlString gControlsGamepad[] = { + { "Move Ship", "Left Stick" }, + { "Aim Ship/Fire Weapon", "Right Stick" }, + { "Activate primary module", "Left Trigger" }, + { "Activate secondary module", "Right Trigger" }, + { "Cycle current weapon", "" }, + { "Toggle map view", "" }, + { "Open QuickChat menu", "" }, + { "Open loadout selection menu", "" }, + { "Show scoreboard", "" }, + { "Record voice chat", "" }, + { "Chat to team", "Keyboard T" }, + { "Chat to everyone", "Keyboard G" }, + { NULL, NULL }, +}; + +extern void renderControllerButton(F32 x, F32 y, U32 buttonIndex, U32 keyIndex); + +void InstructionsUserInterface::renderPage1() +{ + U32 y = 75; + U32 col1 = 50; + U32 col2 = 400; + glBegin(GL_LINES); + glVertex2f(col1, y + 26); + glVertex2f(750, y + 26); + glEnd(); + glColor3f(1,1,1); + ControlString *controls; + bool gamepad = false; + + if(OptionsMenuUserInterface::joystickType == -1) + controls = gControlsKeyboard; + else + { + gamepad = true; + controls = gControlsGamepad; + } + + drawString(col1, y, 20, "Action"); + drawString(col2, y, 20, "Control"); + y += 28; + for(S32 i = 0; controls[i].controlString; i++) + { + glColor3f(1,1,1); + drawString(col1, y, 20, controls[i].controlString); + if((OptionsMenuUserInterface::joystickType == LogitechDualAction || OptionsMenuUserInterface::joystickType == PS2DualShock) && (i == 2 || i == 3)) + renderControllerButton(col2, y + 4, i + 4, i + 4); + else if(gamepad && !controls[i].primaryControl[0]) + renderControllerButton(col2, y + 4, i - 4, i - 4); + else + drawString(col2, y, 20, controls[i].primaryControl); + y += 26; + } +} + +static const char *loadoutInstructions[] = { + "Players can outfit their ships with 3 weapons and 2 modules.", + "Pressing the loadout selection menu key brings up a menu that", + "allows the player to choose the next loadout for his or her ship.", + "This loadout will not be active on the ship until the player", + "flies over a Loadout Zone object.", + "", + "The available modules and their functions are described below:", + NULL, +}; + +static const char *moduleDescriptions[] = { + "Boost - Boosts movement speed", + "Shield - Reflects incoming projectiles", + "Repair - Repairs self and nearby damaged objects", + "Sensor - Increases visible distance and reveals hidden objects", + "Cloak - Turns the ship invisible", +}; + +void InstructionsUserInterface::renderPage2() +{ + S32 y = 75; + glColor3f(1,1,1); + for(S32 i = 0; loadoutInstructions[i]; i++) + { + drawCenteredString(y, 20, loadoutInstructions[i]); + y += 26; + } + + y += 30; + for(S32 i = 0; i < 5; i++) + { + glColor3f(1,1,1); + drawString(105, y, 20, moduleDescriptions[i]); + glPushMatrix(); + glTranslatef(60, y + 10, 0); + glScalef(0.7, 0.7, 1); + glRotatef(-90, 0, 0, 1); + static F32 thrusts[4] = { 1, 0, 0, 0 }; + static F32 thrustsBoost[4] = { 1.3, 0, 0, 0 }; + + switch(i) + { + case 0: + renderShip(Color(0,0,1), 1, thrustsBoost, 1, Ship::CollisionRadius, false, false); + glBegin(GL_LINES); + glColor3f(1,1,0); + glVertex2f(-20, -17); + glColor3f(0,0,0); + glVertex2f(-20, -50); + glColor3f(1,1,0); + glVertex2f(20, -17); + glColor3f(0,0,0); + glVertex2f(20, -50); + glEnd(); + break; + case 1: + renderShip(Color(0,0,1), 1, thrusts, 1, Ship::CollisionRadius, false, true); + break; + case 2: + { + F32 health = (gClientGame->getCurrentTime() & 0x7FF) * 0.0005f; + + renderShip(Color(0,0,1), 1, thrusts, health, Ship::CollisionRadius, false, false); + glLineWidth(3); + glColor3f(1,0,0); + drawCircle(Point(0,0), Ship::RepairDisplayRadius); + glLineWidth(DefaultLineWidth); + } + break; + case 3: + { + renderShip(Color(0,0,1), 1, thrusts, 1, Ship::CollisionRadius, false, false); + F32 radius = (gClientGame->getCurrentTime() & 0x1FF) * 0.002; + drawCircle(Point(), radius * Ship::CollisionRadius + 4); + } + break; + case 4: + { + U32 ct = gClientGame->getCurrentTime(); + F32 frac = ct & 0x3FF; + F32 alpha; + if((ct & 0x400) != 0) + alpha = frac * 0.001; + else + alpha = 1 - (frac * 0.001); + renderShip(Color(0,0,1), alpha, thrusts, 1, Ship::CollisionRadius, false, false); + } + break; + } + + glPopMatrix(); + y += 60; + } +} + +enum { + GameObjectCount = 14, +}; + +const char *gGameObjectInfo[] = { + "Phaser","The default weapon", + "Bouncer","Bounces off walls", + "Triple","Fires three diverging shots", + "Burst","Explosive projectile", + "Friendly Mine","Team's mines show trigger radius", + "Opponent Mine","These are much harder to see", + + "RepairItem","Repairs damage done to a ship", + "Loadout Zone","Updates ship loadout", + "Neutral Turret","Repair to take team ownership", + "Active Turret","Fires at enemy team", + "Neutral Emitter", "Repair to take team ownership", + "Force Field Emitter","Allows only one team to pass", + "Teleporter","Warps ship to another location", + "Flag","Objective item in some game types", +}; + +void InstructionsUserInterface::renderPageObjectDesc(U32 index) +{ + //Point start(105, 75); + //Point objStart(60, 85); + + U32 objectsPerPage = 6; + U32 startIndex = index * objectsPerPage; + U32 endIndex = startIndex + objectsPerPage; + if(endIndex > GameObjectCount) + endIndex = GameObjectCount; + + for(U32 i = startIndex; i < endIndex; i++) + { + glColor3f(1,1,1); + const char *text = gGameObjectInfo[i * 2]; + const char *desc = gGameObjectInfo[i * 2 + 1]; + U32 index = i - startIndex; + + Point objStart((index & 1) * 400, (index >> 1) * 165); + objStart += Point(200, 90); + Point start = objStart + Point(0, 55); + + renderCenteredString(start, 20, text); + renderCenteredString(start + Point(0, 25), 20, desc); + //drawString(start.x, start.y, 20, text); + + glPushMatrix(); + glTranslatef(objStart.x, objStart.y, 0); + glScalef(0.7, 0.7, 1); + + switch(i) + { + case 0: + renderProjectile(Point(0,0), 0, gClientGame->getCurrentTime()); + break; + case 1: + renderProjectile(Point(0,0), 1, gClientGame->getCurrentTime()); + break; + case 2: + renderProjectile(Point(0,0), 2, gClientGame->getCurrentTime()); + break; + case 3: + renderGrenade(Point(0,0)); + break; + case 4: + renderMine(Point(0,0), true, true); + break; + case 5: + renderMine(Point(0,0), true, false); + break; + + case 6: + renderRepairItem(Point(0, 0)); + break; + case 7: + { + Vector p; + p.push_back(Point(-150, -30)); + p.push_back(Point(150, -30)); + p.push_back(Point(150, 30)); + p.push_back(Point(-150, 30)); + Rect ext(p[0], p[2]); + renderLoadoutZone(Color(0,0,1), p, ext); + } + break; + case 8: + renderTurret(Color(1,1,1), Point(0, 15), Point(0, -1), false, 0, 0, Turret::TurretAimOffset); + break; + case 9: + renderTurret(Color(0,0,1), Point(0, 15), Point(0, -1), true, 1, 0, Turret::TurretAimOffset); + break; + + case 10: + renderForceFieldProjector(Point(-7.5, 0), Point(1, 0), Color(1,1,1), false); + break; + case 11: + renderForceFieldProjector(Point(-50, 0), Point(1, 0), Color(1,0,0), true); + renderForceField(Point(-35, 0), Point(50, 0), Color(1,0,0), true); + break; + case 12: + renderTeleporter(Point(0, 0), 0, true, gClientGame->getCurrentTime(), 1, Teleporter::TeleporterRadius, 1); + break; + case 13: + renderFlag(Point(0,0), Color(1, 0, 0)); + break; + } + glPopMatrix(); + objStart.y += 75; + start.y += 75; + } +} + +void InstructionsUserInterface::nextPage() +{ + mCurPage++; + if(mCurPage > NumPages) + mCurPage = 1; +} + +void InstructionsUserInterface::prevPage() +{ + if(mCurPage > 1) + mCurPage--; + else + mCurPage = NumPages; +} + +void InstructionsUserInterface::exitInstructions() +{ + if(gClientGame->isConnectedToServer()) + gGameUserInterface.activate(); + else + gMainMenuUserInterface.activate(); +} + +void InstructionsUserInterface::onSpecialKeyDown(U32 key) +{ + switch(key) + { + case GLUT_KEY_LEFT: + prevPage(); + break; + case GLUT_KEY_RIGHT: + nextPage(); + break; + case GLUT_KEY_F1: + exitInstructions(); + break; + } +} + +void InstructionsUserInterface::onKeyDown(U32 key) +{ + switch(key) + { + case ' ': + nextPage(); + break; + case '\r': + case 27: + exitInstructions(); + break; + } +} + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/UIInstructions.h b/tnl-1.5.0/tnl/zap/UIInstructions.h new file mode 100644 index 0000000000000000000000000000000000000000..7ebe86d4034adc3255937230d0bed477440e3a9c --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIInstructions.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UIINSTRUCTIONS_H_ +#define _UIINSTRUCTIONS_H_ + +#include "UI.h" + +namespace Zap +{ + +class InstructionsUserInterface : public UserInterface +{ + U32 mCurPage; +public: + void render(); + void renderPage1(); + void renderPage2(); + void renderPageObjectDesc(U32 index); + void nextPage(); + void prevPage(); + void onSpecialKeyDown(U32 key); + void onKeyDown(U32 key); + void onActivate(); + void exitInstructions(); +}; + +extern InstructionsUserInterface gInstructionsUserInterface; + +}; + +#endif \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/UIMenus.cpp b/tnl-1.5.0/tnl/zap/UIMenus.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e33019a61cdb1fd2019d2ee018a12846f8492d9 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIMenus.cpp @@ -0,0 +1,548 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "UIMenus.h" +#include "UINameEntry.h" +#include "UIGame.h" +#include "UIQueryServers.h" +#include "UICredits.h" +#include "game.h" +#include "gameType.h" +#include "UIEditor.h" +#include "UIInstructions.h" +#include "input.h" + +#include "glutInclude.h" + +namespace Zap +{ + +MenuUserInterface::MenuUserInterface() +{ + menuTitle = "Menu"; + menuSubTitle = ""; + menuFooter = "UP, DOWN to choose ENTER to select ESC exits menu"; + selectionIndex = 0; +} + +void MenuUserInterface::render() +{ + if(gClientGame->getConnectionToServer()) + { + gGameUserInterface.render(); + glColor4f(0, 0, 0, 0.6); + glEnable(GL_BLEND); + glBegin(GL_POLYGON); + glVertex2f(0, 0); + glVertex2f(canvasWidth, 0); + glVertex2f(canvasWidth, canvasHeight); + glVertex2f(0, canvasHeight); + glEnd(); + glDisable(GL_BLEND); + } + + glColor3f(1,1,1); + drawCenteredString( vertMargin, 30, menuTitle); + drawCenteredString( vertMargin + 35, 18, menuSubTitle); + drawCenteredString( canvasHeight - vertMargin - 20, 18, menuFooter); + + if(selectionIndex >= menuItems.size()) + selectionIndex = 0; + + S32 offset = 0; + S32 count = menuItems.size(); + + if(count > 7) + { + count = 7; + offset = selectionIndex - 3; + if(offset < 0) + offset = 0; + else if(offset + count >= menuItems.size()) + offset = menuItems.size() - count; + } + + U32 yStart = (canvasHeight - count * 45) / 2; + //glColor3f(0,1,0); + + for(S32 i = 0; i < count; i++) + { + U32 y = yStart + i * 45; + + if(selectionIndex == i + offset) + { + glColor3f(0,0,0.4); + glBegin(GL_POLYGON); + glVertex2f(0, y - 2); + glVertex2f(800, y - 2); + glVertex2f(800, y + 25 + 5); + glVertex2f(0, y + 25 + 5); + glEnd(); + glColor3f(0,0,1); + glBegin(GL_LINES); + glVertex2f(0, y - 2); + glVertex2f(799, y - 2); + glVertex2f(799, y + 25 + 5); + glVertex2f(0, y + 25 + 5); + glEnd(); + } + glColor3f(1,1,1); + drawCenteredString(y, 25, menuItems[i+offset].mText); + } +} + +void MenuUserInterface::onSpecialKeyDown(U32 key) +{ + if(key == GLUT_KEY_UP) + { + selectionIndex--; + if(selectionIndex < 0) + { + if(menuItems.size() > 7) + { + selectionIndex = 0; + return; + } + else + selectionIndex = menuItems.size() - 1; + } + UserInterface::playBoop(); + } + else if(key == GLUT_KEY_DOWN) + { + selectionIndex++; + if(selectionIndex >= menuItems.size()) + { + if(menuItems.size() > 7) + { + selectionIndex = menuItems.size() - 1; + return; + } + else + selectionIndex = 0; + } + + UserInterface::playBoop(); + } +} + +void MenuUserInterface::onControllerButtonDown(U32 buttonIndex) +{ + if(buttonIndex == 0) + { + UserInterface::playBoop(); + processSelection(menuItems[selectionIndex].mIndex); + } + else if(buttonIndex == 1) + { + UserInterface::playBoop(); + onEscape(); + } +} + +void MenuUserInterface::onKeyDown(U32 key) +{ + if(key == '\r') + { + UserInterface::playBoop(); + processSelection(menuItems[selectionIndex].mIndex); + } + else if(key == 27) + { + UserInterface::playBoop(); + onEscape(); + } +} + +void MenuUserInterface::onEscape() +{ + +} + +MainMenuUserInterface gMainMenuUserInterface; + +MainMenuUserInterface::MainMenuUserInterface() +{ + dSprintf(titleBuffer, sizeof(titleBuffer), "%s:", ZAP_GAME_STRING); + menuTitle = titleBuffer; + motd[0] = 0; + menuSubTitle = "A TORQUE NETWORK LIBRARY GAME - WWW.OPENTNL.ORG"; + menuFooter = "(C) 2004 GARAGEGAMES.COM, INC."; + + menuItems.push_back(MenuItem("JOIN LAN/INTERNET GAME", 0)); + menuItems.push_back(MenuItem("HOST GAME",1)); + menuItems.push_back(MenuItem("INSTRUCTIONS",2)); + menuItems.push_back(MenuItem("OPTIONS",3)); + menuItems.push_back(MenuItem("QUIT",4)); +} + +void MainMenuUserInterface::setMOTD(const char *motdString) +{ + strcpy(motd, motdString); + motdArriveTime = gClientGame->getCurrentTime(); +} + +void MainMenuUserInterface::render() +{ + Parent::render(); + if(motd[0]) + { + U32 width = getStringWidth(20, motd); + glColor3f(1,1,1); + U32 totalWidth = width + canvasWidth; + U32 pixelsPerSec = 100; + U32 delta = gClientGame->getCurrentTime() - motdArriveTime; + delta = U32(delta * pixelsPerSec * 0.001) % totalWidth; + + drawString(canvasWidth - delta, 540, 20, motd); + } +} + +void MainMenuUserInterface::processSelection(U32 index) +{ + switch(index) + { + case 0: + gQueryServersUserInterface.activate(); + break; + case 1: + hostGame(false, Address(IPProtocol, Address::Any, 28000)); + break; + case 2: + gInstructionsUserInterface.activate(); + break; + case 3: + gOptionsMenuUserInterface.activate(); + break; + case 4: + gCreditsUserInterface.activate(); + break; + } +} + +void MainMenuUserInterface::onEscape() +{ + gNameEntryUserInterface.activate(); +} + + +OptionsMenuUserInterface gOptionsMenuUserInterface; + +bool OptionsMenuUserInterface::controlsRelative = false; +bool OptionsMenuUserInterface::fullscreen = true; +S32 OptionsMenuUserInterface::joystickType = -1; +bool OptionsMenuUserInterface::echoVoice = false; + +OptionsMenuUserInterface::OptionsMenuUserInterface() +{ + menuTitle = "OPTIONS MENU:"; +} + +void OptionsMenuUserInterface::onActivate() +{ + Parent::onActivate(); + setupMenus(); +} + +void OptionsMenuUserInterface::setupMenus() +{ + menuItems.clear(); + if(controlsRelative) + menuItems.push_back(MenuItem("CONTROLS: RELATIVE",0)); + else + menuItems.push_back(MenuItem("CONTROLS: ABSOLUTE",0)); + + if(fullscreen) + menuItems.push_back(MenuItem("VIDEO: FULLSCREEN",1)); + else + menuItems.push_back(MenuItem("VIDEO: WINDOW",1)); + + switch(joystickType) + { + case -1: + menuItems.push_back(MenuItem("INPUT: KEYBOARD + MOUSE",2)); + break; + case LogitechWingman: + menuItems.push_back(MenuItem("INPUT: LOGITECH WINGMAN DUAL-ANALOG",2)); + break; + case LogitechDualAction: + menuItems.push_back(MenuItem("INPUT: LOGITECH DUAL ACTION",2)); + break; + case SaitekDualAnalog: + menuItems.push_back(MenuItem("INPUT: SAITEK P-880 DUAL-ANALOG",2)); + break; + case PS2DualShock: + menuItems.push_back(MenuItem("INPUT: PS2 DUALSHOCK USB",2)); + break; + case XBoxController: + menuItems.push_back(MenuItem("INPUT: XBOX CONTROLLER USB",2)); + break; + case XBoxControllerOnXBox: + menuItems.push_back(MenuItem("INPUT: XBOX CONTROLLER",2)); + break; + default: + menuItems.push_back(MenuItem("INPUT: UNKNOWN",2)); + } + + if(echoVoice) + menuItems.push_back(MenuItem("VOICE ECHO: ENABLED",3)); + else + menuItems.push_back(MenuItem("VOICE ECHO: DISABLED",3)); +} + +void OptionsMenuUserInterface::toggleFullscreen() +{ + if(fullscreen) + { + glutPositionWindow(100, 100); + glutReshapeWindow(800, 600); + } + else + glutFullScreen(); + fullscreen = !fullscreen; +} + +void OptionsMenuUserInterface::processSelection(U32 index) +{ + switch(index) + { + case 0: + controlsRelative = !controlsRelative; + break; + case 1: + toggleFullscreen(); + break; + case 2: + joystickType++; + if(joystickType > XBoxController) + joystickType = -1; + break; + case 3: + echoVoice = !echoVoice; + break; + }; + setupMenus(); +} + +void OptionsMenuUserInterface::onEscape() +{ + if(gClientGame->getConnectionToServer()) + gGameUserInterface.activate(); + else + gMainMenuUserInterface.activate(); +} + + +GameMenuUserInterface gGameMenuUserInterface; + +GameMenuUserInterface::GameMenuUserInterface() +{ + menuTitle = "GAME MENU:"; +} + +void GameMenuUserInterface::onActivate() +{ + Parent::onActivate(); + menuItems.clear(); + menuItems.push_back(MenuItem("OPTIONS",1)); + menuItems.push_back(MenuItem("INSTRUCTIONS",2)); + GameType *theGameType = gClientGame->getGameType(); + if(theGameType) + { + mGameType = theGameType; + theGameType->addClientGameMenuOptions(menuItems); + } + GameConnection *gc = gClientGame->getConnectionToServer(); + if(gc) + { + if(gc->isAdmin()) + menuItems.push_back(MenuItem("ADMIN",4)); + else + menuItems.push_back(MenuItem("ENTER ADMIN PASSWORD",5)); + } + menuItems.push_back(MenuItem("LEAVE GAME",3)); +} + +void GameMenuUserInterface::processSelection(U32 index) +{ + switch(index) + { + case 1: + gOptionsMenuUserInterface.activate(); + break; + case 2: + gInstructionsUserInterface.activate(); + break; + case 3: + endGame(); + if(EditorUserInterface::editorEnabled) + gEditorUserInterface.activate(); + else + gMainMenuUserInterface.activate(); + break; + case 4: + gAdminMenuUserInterface.activate(); + break; + case 5: + gAdminPasswordEntryUserInterface.activate(); + break; + default: + gGameUserInterface.activate(); + if(mGameType.isValid()) + mGameType->processClientGameMenuOption(index); + break; + } +} + +void GameMenuUserInterface::onEscape() +{ + gGameUserInterface.activate(); +} + +LevelMenuUserInterface gLevelMenuUserInterface; + +void LevelMenuUserInterface::onActivate() +{ + Parent::onActivate(); + mTypeSelectDone = false; + menuTitle = "CHOOSE LEVEL TYPE:"; + + GameConnection *gc = gClientGame->getConnectionToServer(); + if(!gc || !gc->mLevelTypes.size()) + return; + + menuItems.clear(); + menuItems.push_back(MenuItem(gc->mLevelTypes[0].getString(),0)); + + for(S32 i = 1; i < gc->mLevelTypes.size();i++) + { + S32 j; + for(j = 0;j < menuItems.size();j++) + if(!stricmp(gc->mLevelTypes[i].getString(),menuItems[j].mText)) + break; + if(j == menuItems.size()) + { + menuItems.push_back(MenuItem(gc->mLevelTypes[i].getString(), i)); + } + } +} + +void LevelMenuUserInterface::processSelection(U32 index) +{ + Parent::onActivate(); + GameConnection *gc = gClientGame->getConnectionToServer(); + if(mTypeSelectDone) + { + // The selection index is the level to load. + logprintf("load level %s", gc->mLevelNames[index].getString()); + gc->c2sRequestLevelChange(index); + gGameUserInterface.activate(); + } + else + { + mTypeSelectDone = true; + StringTableEntry s = gc->mLevelTypes[index]; + menuItems.clear(); + for(S32 i = 0; i < gc->mLevelTypes.size();i++) + { + if(gc->mLevelTypes[i] == s) + menuItems.push_back(MenuItem(gc->mLevelNames[i].getString(), i)); + } + } +} + +void LevelMenuUserInterface::onEscape() +{ + gGameUserInterface.activate(); +} + +AdminMenuUserInterface gAdminMenuUserInterface; + +void AdminMenuUserInterface::onActivate() +{ + menuTitle = "ADMINISTRATOR OPTIONS:"; + menuItems.clear(); + menuItems.push_back(MenuItem("CHANGE LEVEL",0)); + menuItems.push_back(MenuItem("CHANGE A PLAYER'S TEAM",1)); + menuItems.push_back(MenuItem("KICK A PLAYER",2)); +} + +void AdminMenuUserInterface::onEscape() +{ + gGameUserInterface.activate(); +} + +void AdminMenuUserInterface::processSelection(U32 index) +{ + switch(index) + { + case 0: + gLevelMenuUserInterface.activate(); + break; + case 1: + gPlayerMenuUserInterface.action = PlayerMenuUserInterface::ChangeTeam; + gPlayerMenuUserInterface.activate(); + break; + case 2: + gPlayerMenuUserInterface.action = PlayerMenuUserInterface::Kick; + gPlayerMenuUserInterface.activate(); + break; + } +} + +PlayerMenuUserInterface gPlayerMenuUserInterface; + +void PlayerMenuUserInterface::render() +{ + menuItems.clear(); + GameType *gt = gClientGame->getGameType(); + if(gt) + { + for(S32 i = 0; i < gt->mClientList.size(); i++) + menuItems.push_back(MenuItem(gt->mClientList[i]->name.getString(), i)); + } + if(action == Kick) + menuTitle = "CHOOSE PLAYER TO KICK:"; + else if(action == ChangeTeam) + menuTitle = "CHOOSE PLAYER WHOSE TEAM TO CHANGE:"; + Parent::render(); +} + +void PlayerMenuUserInterface::onEscape() +{ + gGameUserInterface.activate(); +} + +void PlayerMenuUserInterface::processSelection(U32 index) +{ + StringTableEntry e(menuItems[index].mText); + GameConnection *gc = gClientGame->getConnectionToServer(); + if(gc) + gc->c2sAdminPlayerAction(e, action); + gGameUserInterface.activate(); +} + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/UIMenus.h b/tnl-1.5.0/tnl/zap/UIMenus.h new file mode 100644 index 0000000000000000000000000000000000000000..b5c604994462a07a741d1cf20bc76cabf2f7c75c --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIMenus.h @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UIMENUS_H_ +#define _UIMENUS_H_ + +#include "tnlNetBase.h" +#include "UI.h" + +namespace Zap +{ +struct MenuItem +{ + const char *mText; + U32 mIndex; + MenuItem(const char *text = 0, U32 index = 0) + { + mText = text; + mIndex = index; + } +}; + +class MenuUserInterface : public UserInterface +{ +public: + Vector menuItems; + const char *menuTitle; + const char *menuSubTitle; + const char *menuFooter; + + S32 selectionIndex; + + MenuUserInterface(); + + void render(); + void onSpecialKeyDown(U32 key); + void onKeyDown(U32 key); + void onControllerButtonDown(U32 buttonIndex); + void onActivate() { selectionIndex = 0; } + + virtual void onEscape(); + virtual void processSelection(U32 index) = 0; +}; + +class MainMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; + char titleBuffer[256]; + char motd[256]; + U32 motdArriveTime; +public: + MainMenuUserInterface(); + void processSelection(U32 index); + void onEscape(); + void render(); + void setMOTD(const char *motdString); +}; + +extern MainMenuUserInterface gMainMenuUserInterface; + +class OptionsMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; +public: + static bool controlsRelative; + static bool fullscreen; + static S32 joystickType; + static bool echoVoice; + + OptionsMenuUserInterface(); + void processSelection(U32 index); + void onEscape(); + void setupMenus(); + void onActivate(); + void toggleFullscreen(); +}; + +extern OptionsMenuUserInterface gOptionsMenuUserInterface; + +class GameType; + +class GameMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; + SafePtr mGameType; +public: + GameMenuUserInterface(); + + void onActivate(); + void processSelection(U32 index); + void onEscape(); +}; + +extern GameMenuUserInterface gGameMenuUserInterface; + +class LevelMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; + bool mTypeSelectDone; +public: + void onActivate(); + void processSelection(U32 index); + void onEscape(); +}; + +extern LevelMenuUserInterface gLevelMenuUserInterface; + +class AdminMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; +public: + void onActivate(); + void processSelection(U32 index); + void onEscape(); +}; + +extern AdminMenuUserInterface gAdminMenuUserInterface; + +class PlayerMenuUserInterface : public MenuUserInterface +{ + typedef MenuUserInterface Parent; +public: + enum Action { + Kick, + ChangeTeam, + ActionCount, + } action; + void render(); + void processSelection(U32 index); + void onEscape(); +}; + +extern PlayerMenuUserInterface gPlayerMenuUserInterface; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/UINameEntry.cpp b/tnl-1.5.0/tnl/zap/UINameEntry.cpp new file mode 100644 index 0000000000000000000000000000000000000000..77c8206c2be46583539ce6b9bbf9e8850cbbb739 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UINameEntry.cpp @@ -0,0 +1,192 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "UINameEntry.h" +#include "UIMenus.h" +#include "UIGame.h" +#include "game.h" +#include "gameConnection.h" + +#include "glutInclude.h" + +namespace Zap +{ + +void TextEntryUserInterface::onActivate() +{ + if(resetOnActivate) + { + buffer[0] = 0; + cursorPos = 0; + } +} + +void TextEntryUserInterface::render() +{ + glColor3f(1,1,1); + + U32 y = (canvasHeight / 2) - 20; + + drawCenteredString(y, 20, title); + y += 45; + + char astbuffer[MaxTextLen+1]; + const char *renderBuffer=buffer; + if(secret) + { + + S32 i; + for(i = 0; i < MaxTextLen;i++) + { + if(!buffer[i]) + break; + astbuffer[i] = '*'; + } + astbuffer[i] = 0; + renderBuffer = astbuffer; + } + drawCenteredString(y, 30, renderBuffer); + + U32 width = getStringWidth(30, renderBuffer); + U32 x = (canvasWidth - width) / 2; + + if(blink) + drawString(x + getStringWidth(30, renderBuffer, cursorPos), y, 30, "_"); +} + +void TextEntryUserInterface::idle(U32 t) +{ + if(mBlinkTimer.update(t)) + { + mBlinkTimer.reset(BlinkTime); + blink = !blink; + } +} + +void TextEntryUserInterface::onKeyDown(U32 key) +{ + if(key == '\r') + onAccept(buffer); + else if(key == 8 || key == 127) + { + // backspace key + if(cursorPos > 0) + { + cursorPos--; + for(U32 i = cursorPos; buffer[i]; i++) + buffer[i] = buffer[i+1]; + } + } + else if(key == 27) + { + onEscape(); + } + else + { + for(U32 i = MaxTextLen - 1; i > cursorPos; i--) + buffer[i] = buffer[i-1]; + if(cursorPos < MaxTextLen-1) + { + buffer[cursorPos] = key; + cursorPos++; + } + } +} + +void TextEntryUserInterface::onKeyUp(U32 key) +{ + +} + +void TextEntryUserInterface::setText(const char *text) +{ + if(strlen(text) > MaxTextLen) + { + strncpy(buffer, text, MaxTextLen); + buffer[MaxTextLen] = 0; + } + else + strcpy(buffer, text); +} + + +NameEntryUserInterface gNameEntryUserInterface; + +void NameEntryUserInterface::onEscape() +{ +} + +void NameEntryUserInterface::onAccept(const char *text) +{ + gMainMenuUserInterface.activate(); +} + +PasswordEntryUserInterface gPasswordEntryUserInterface; + +void PasswordEntryUserInterface::onEscape() +{ + gMainMenuUserInterface.activate(); +} + +void PasswordEntryUserInterface::onAccept(const char *text) +{ + joinGame(connectAddress, false, false); +} + +AdminPasswordEntryUserInterface gAdminPasswordEntryUserInterface; + +void AdminPasswordEntryUserInterface::render() +{ + gGameUserInterface.render(); + glColor4f(0, 0, 0, 0.5); + glEnable(GL_BLEND); + glBegin(GL_POLYGON); + glVertex2f(0, 0); + glVertex2f(canvasWidth, 0); + glVertex2f(canvasWidth, canvasHeight); + glVertex2f(0, canvasHeight); + glEnd(); + glDisable(GL_BLEND); + Parent::render(); +} + +void AdminPasswordEntryUserInterface::onEscape() +{ + gGameUserInterface.activate(); +} + +void AdminPasswordEntryUserInterface::onAccept(const char *text) +{ + gGameUserInterface.activate(); + GameConnection *gc = gClientGame->getConnectionToServer(); + if(gc) + gc->c2sAdminPassword(text); +} + + + +}; + diff --git a/tnl-1.5.0/tnl/zap/UINameEntry.h b/tnl-1.5.0/tnl/zap/UINameEntry.h new file mode 100644 index 0000000000000000000000000000000000000000..5da380efaf73f8534f5cf1c06e65691e5958328d --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UINameEntry.h @@ -0,0 +1,124 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UINAMEENTRY_H_ +#define _UINAMEENTRY_H_ + +#include "UI.h" +#include "timer.h" + +namespace Zap +{ + +class TextEntryUserInterface : public UserInterface +{ + enum { + MaxTextLen = 32, + BlinkTime = 100, + }; + char buffer[MaxTextLen+1]; + U32 cursorPos; + bool blink; + Timer mBlinkTimer; + +protected: + const char *title; + bool secret; + bool resetOnActivate; +public: + TextEntryUserInterface() : mBlinkTimer(BlinkTime) + { + title = "ENTER TEXT:"; + buffer[0] = 0; + memset(buffer, 0, sizeof(buffer)); + blink = false; + secret = false; + cursorPos = 0; + resetOnActivate = true; + } + + void onActivate(); + void render(); + void idle(U32 t); + + void onKeyDown(U32 key); + void onKeyUp(U32 key); + + virtual void onAccept(const char *text) = 0; + virtual void onEscape() = 0; + const char *getText() { return buffer; } + void setText(const char *text); +}; + +class NameEntryUserInterface : public TextEntryUserInterface +{ +public: + NameEntryUserInterface() + { + title = "ENTER YOUR NAME:"; + resetOnActivate = false; + } + virtual void onAccept(const char *text); + virtual void onEscape(); +}; + +extern NameEntryUserInterface gNameEntryUserInterface; + +class PasswordEntryUserInterface : public TextEntryUserInterface +{ + Address connectAddress; +public: + PasswordEntryUserInterface() + { + title = "ENTER SERVER PASSWORD:"; + secret = true; + } + void onAccept(const char *text); + void onEscape(); + void setConnectServer(const Address &addr) { connectAddress = addr; } +}; + +extern PasswordEntryUserInterface gPasswordEntryUserInterface; + +class AdminPasswordEntryUserInterface : public TextEntryUserInterface +{ + typedef TextEntryUserInterface Parent; +public: + AdminPasswordEntryUserInterface() + { + title = "ENTER ADMIN PASSWORD:"; + secret = true; + } + void onAccept(const char *text); + void onEscape(); + void render(); +}; + +extern AdminPasswordEntryUserInterface gAdminPasswordEntryUserInterface; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/UIQueryServers.cpp b/tnl-1.5.0/tnl/zap/UIQueryServers.cpp new file mode 100644 index 0000000000000000000000000000000000000000..936c75f67c66e85208f4bd8c0e08e7e613f6fd9d --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIQueryServers.cpp @@ -0,0 +1,590 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "UIQueryServers.h" +#include "UIMenus.h" +#include "tnlRandom.h" +#include "masterConnection.h" +#include "gameNetInterface.h" +#include "glutInclude.h" +#include "game.h" + +namespace Zap +{ + +QueryServersUserInterface gQueryServersUserInterface; + +void QueryServersUserInterface::onActivate() +{ + servers.clear(); + /*for(U32 i = 0;i < 512; i++) + { + ServerRef s; + dSprintf(s.serverName, MaxServerNameLen, "Svr%8x", Random::readI()); + s.id = i; + s.pingTime = Random::readF() * 512; + s.serverAddress.port = 28000; + s.serverAddress.netNum[0] = Random::readI(); + s.maxPlayers = Random::readF() * 16 + 8; + s.playerCount = Random::readF() * s.maxPlayers; + servers.push_back(s); + }*/ + sortColumn = 0; + pendingPings = 0; + pendingQueries = 0; + sortAscending = true; + mNonce.getRandom(); + + logprintf("pinging broadcast servers..."); + Address broadcastAddress(IPProtocol, Address::Broadcast, 28000); + broadcastPingSendTime = Platform::getRealMilliseconds(); + + gClientGame->getNetInterface()->sendPing(broadcastAddress, mNonce); + if(gClientGame->getConnectionToMaster()) + gClientGame->getConnectionToMaster()->startGameTypesQuery(); +} + +void QueryServersUserInterface::addPingServers(const Vector &ipList) +{ + for(S32 i = 0; i < ipList.size(); i++) + { + ServerRef s; + s.state = ServerRef::Start; + s.id = ++lastUsedServerId; + s.sendNonce.getRandom(); + s.serverAddress.set(ipList[i]); + s.sendCount = 0; + s.pingTime = 9999; + s.playerCount = s.maxPlayers = -1; + s.isFromMaster = true; + strcpy(s.serverName, "Internet Server"); + servers.push_back(s); + } +} + +void QueryServersUserInterface::gotPingResponse(const Address &theAddress, const Nonce &theNonce, U32 clientIdentityToken) +{ + // see if this ping is a server from the local broadcast ping: + if(mNonce == theNonce) + { + for(S32 i = 0; i < servers.size(); i++) + if(servers[i].sendNonce == theNonce && servers[i].serverAddress == theAddress) + return; + + // it was from a local ping + ServerRef s; + s.pingTime = Platform::getRealMilliseconds() - broadcastPingSendTime; + s.state = ServerRef::ReceivedPing; + s.id = ++lastUsedServerId; + s.sendNonce = theNonce; + s.identityToken = clientIdentityToken; + s.serverAddress = theAddress; + s.sendCount = 0; + s.playerCount = -1; + s.maxPlayers = -1; + s.isFromMaster = false; + strcpy(s.serverName, "LAN Server"); + servers.push_back(s); + return; + } + + // see if this ping is in the list: + for(S32 i = 0; i < servers.size(); i++) + { + ServerRef &s = servers[i]; + if(s.sendNonce == theNonce && s.serverAddress == theAddress && + s.state == ServerRef::SentPing) + { + s.pingTime = Platform::getRealMilliseconds() - s.lastSendTime; + s.state = ServerRef::ReceivedPing; + s.identityToken = clientIdentityToken; + pendingPings--; + break; + } + } + shouldSort = true; +} + +void QueryServersUserInterface::gotQueryResponse(const Address &theAddress, const Nonce &clientNonce, const char *serverName, U32 playerCount, U32 maxPlayers, bool dedicated, bool passwordRequired) +{ + for(S32 i = 0; i < servers.size(); i++) + { + ServerRef &s = servers[i]; + if(s.sendNonce == clientNonce && s.serverAddress == theAddress && + s.state == ServerRef::SentQuery) + { + s.playerCount = playerCount; + s.maxPlayers = maxPlayers; + s.dedicated = dedicated; + s.passwordRequired = passwordRequired; + + dSprintf(s.serverName, sizeof(s.serverName), "%s", serverName); + s.state = ServerRef::ReceivedQuery; + pendingQueries--; + } + } + shouldSort = true; + // find this +} + +void QueryServersUserInterface::idle(U32 t) +{ + U32 time = Platform::getRealMilliseconds(); + + for(S32 i = 0; i < servers.size(); i++) + { + ServerRef &s = servers[i]; + + if(s.state == ServerRef::SentPing && (time - s.lastSendTime) > PingQueryTimeout) + { + s.state = ServerRef::Start; + pendingPings--; + } + else if(s.state == ServerRef::SentQuery && (time - s.lastSendTime) > PingQueryTimeout) + { + s.state = ServerRef::ReceivedPing; + pendingQueries--; + } + } + if(pendingPings < MaxPendingPings) + { + for(S32 i = 0; i < servers.size() ; i++) + { + ServerRef &s = servers[i]; + if(s.state == ServerRef::Start) + { + s.sendCount++; + if(s.sendCount > PingQueryRetryCount) + { + s.pingTime = 999; + strcpy(s.serverName, "PingTimedOut"); + s.playerCount = 0; + s.maxPlayers = 0; + s.state = ServerRef::ReceivedQuery; + shouldSort = true; + } + else + { + s.state = ServerRef::SentPing; + s.lastSendTime = time; + s.sendNonce.getRandom(); + gClientGame->getNetInterface()->sendPing(s.serverAddress, s.sendNonce); + pendingPings++; + if(pendingPings >= MaxPendingPings) + break; + } + } + } + } + if(pendingPings == 0 && (pendingQueries < MaxPendingQueries)) + { + for(S32 i = 0; i < servers.size(); i++) + { + ServerRef &s = servers[i]; + if(s.state == ServerRef::ReceivedPing) + { + s.sendCount++; + if(s.sendCount > PingQueryRetryCount) + { + strcpy(s.serverName, "QueryTimedOut"); + s.playerCount = s.maxPlayers = 0; + s.state = ServerRef::ReceivedQuery; + shouldSort = true; + } + else + { + s.state = ServerRef::SentQuery; + s.lastSendTime = time; + gClientGame->getNetInterface()->sendQuery(s.serverAddress, s.sendNonce, s.identityToken); + pendingQueries++; + if(pendingQueries >= MaxPendingQueries) + break; + } + } + } + } +} + +QueryServersUserInterface::QueryServersUserInterface() +{ + + lastUsedServerId = 0; + sortColumn = 0; + lastSortColumn = 0; + sortAscending = true; + + columns.push_back(ColumnInfo("SERVER NAME", 3)); + columns.push_back(ColumnInfo("STAT", 250)); + columns.push_back(ColumnInfo("PING", 330)); + columns.push_back(ColumnInfo("PLAYERS", 420)); + columns.push_back(ColumnInfo("ADDRESS", 550)); + + selectedId = 0xFFFFFF; + + sort(); + shouldSort = false; +} + +S32 QueryServersUserInterface::findSelectedIndex() +{ + for(S32 i = 0; i < servers.size(); i++) + if(servers[i].id == selectedId) + return i; + return -1; +} + +static void renderDedicatedIcon() +{ + glBegin(GL_LINE_LOOP); + glVertex2f(0,0); + glVertex2f(0,4); + glVertex2f(3,4); + glVertex2f(3,0); + glEnd(); + + glBegin(GL_LINES); + glVertex2f(0.6, 1); + glVertex2f(2.4, 1); + glVertex2f(0.6, 2); + glVertex2f(2.4, 2); + glVertex2f(0.6, 3); + glVertex2f(2.4, 3); + glEnd(); +} + +static void renderLockIcon() +{ + glBegin(GL_LINE_LOOP); + glVertex2f(0,2); + glVertex2f(0,4); + glVertex2f(3,4); + glVertex2f(3,2); + glEnd(); + + glBegin(GL_LINE_STRIP); + glVertex2f(2.6, 2); + glVertex2f(2.6, 1.3); + glVertex2f(2.4, 0.9); + glVertex2f(1.9, 0.6); + glVertex2f(1.1, 0.6); + glVertex2f(0.6, 0.9); + glVertex2f(0.4, 1.3); + glVertex2f(0.4, 2); + glEnd(); + +} + +void QueryServersUserInterface::render() +{ + if(shouldSort) + { + shouldSort = false; + sort(); + } + glColor3f(1,1,1); + + drawCenteredString(vertMargin, 25, "CHOOSE A SERVER TO JOIN:"); + drawCenteredString(canvasHeight - vertMargin - 40, 18, "UP, DOWN, PAGEUP, PAGEDOWN to select, ENTER to join."); + drawCenteredString(canvasHeight - vertMargin - 20, 18, "LEFT, RIGHT select sort column, SPACE to sort. ESC exits."); + + U32 top = vertMargin + 45; + U32 bottom = canvasHeight - vertMargin - 60; + + for(S32 i = 0; i < columns.size(); i++) + { + drawString(columns[i].xStart, top, 24, columns[i].name); + } + + S32 x1 = columns[sortColumn].xStart - 2; + S32 x2; + if(sortColumn == columns.size() - 1) + x2 = 799; + else + x2 = columns[sortColumn+1].xStart - 6; + + glBegin(GL_LINE_LOOP); + glVertex2f(x1, top - 2); + glVertex2f(x2, top - 2); + glVertex2f(x2, top + 26); + glVertex2f(x1, top + 26); + glEnd(); + top += 30; + + U32 totalRows = (bottom - top) / 24; + if(!(totalRows & 1)) + totalRows--; + bottom = top + totalRows * 24; + + U32 serversAboveBelow = totalRows >> 1; + + if(servers.size()) + { + S32 selectedIndex = findSelectedIndex(); + if(selectedIndex == -1) + selectedIndex = 0; + + S32 firstServer = selectedIndex - serversAboveBelow; + S32 lastServer = selectedIndex + serversAboveBelow; + + if(firstServer < 0) + { + lastServer -= firstServer; + firstServer = 0; + } + if(lastServer >= servers.size()) + { + lastServer = servers.size() - 1; + } + + for(S32 i = firstServer; i <= lastServer; i++) + { + U32 y = top + (i - firstServer) * 24; + U32 fontSize = 21; + ServerRef &s = servers[i]; + + if(i == selectedIndex) + { + glColor3f(0,0,0.4); + glBegin(GL_POLYGON); + glVertex2f(0, y); + glVertex2f(799, y); + glVertex2f(799, y + 23); + glVertex2f(0, y + 23); + glEnd(); + glColor3f(0,0,1.0); + glBegin(GL_LINE_LOOP); + glVertex2f(0, y); + glVertex2f(799, y); + glVertex2f(799, y + 23); + glVertex2f(0, y + 23); + glEnd(); + } + + glColor3f(1,1,1); + drawString(columns[0].xStart, y, fontSize, s.serverName); + + glColor3f(0,1,0); + if(s.dedicated) + { + glPushMatrix(); + glTranslatef(columns[1].xStart+5, y+2, 0); + glScalef(5, 5, 1); + renderDedicatedIcon(); + glPopMatrix(); + } + if(s.passwordRequired) + { + glPushMatrix(); + glTranslatef(columns[1].xStart + 25, y+2, 0); + glScalef(5, 5, 1); + renderLockIcon(); + glPopMatrix(); + } + + if(s.pingTime < 100) + glColor3f(0,1,0); + else if(s.pingTime < 250) + glColor3f(1,1,0); + else + glColor3f(1,0,0); + drawStringf(columns[2].xStart, y, fontSize, "%d", s.pingTime); + + if(s.playerCount == s.maxPlayers) + glColor3f(1,0,0); + else if(s.playerCount == 0) + glColor3f(1,1,0); + else + glColor3f(0,1,0); + if(s.playerCount < 0) + drawString(columns[3].xStart, y, fontSize, "?? / ??"); + else + drawStringf(columns[3].xStart, y, fontSize, "%d / %d", s.playerCount, s.maxPlayers); + glColor3f(1,1,1); + drawString(columns[4].xStart, y, fontSize, s.serverAddress.toString()); + } + } + glColor3f(0.7, 0.7, 0.7); + for(S32 i = 1; i < columns.size(); i++) + { + glBegin(GL_LINES); + glVertex2f(columns[i].xStart - 4, top - 30); + glVertex2f(columns[i].xStart - 4, bottom); + glEnd(); + } + glBegin(GL_LINES); + glVertex2f(0, top - 3); + glVertex2f(800, top - 3); + glEnd(); +} + +void QueryServersUserInterface::onControllerButtonDown(U32 buttonIndex) +{ + if(buttonIndex == 0) + onKeyDown('\r'); + else if(buttonIndex == 1) + onKeyDown(27); +} + +void QueryServersUserInterface::onKeyDown(U32 key) +{ + switch(key) + { + case ' ': + if(lastSortColumn == sortColumn) + sortAscending = !sortAscending; + else + { + lastSortColumn = sortColumn; + sortAscending = true; + } + sort(); + break; + case '\r': + { + S32 currentIndex = findSelectedIndex(); + if(currentIndex == -1) + currentIndex = 0; + + if(servers.size() > currentIndex) + { + // join the selected game + joinGame(servers[currentIndex].serverAddress, servers[currentIndex].isFromMaster, false); + + // and clear out the servers, so that we don't do any more pinging + servers.clear(); + } + } + break; + case 27: + gMainMenuUserInterface.activate(); + break; + } +} + +void QueryServersUserInterface::onSpecialKeyDown(U32 key) +{ + if(!servers.size()) + return; + + S32 currentIndex = findSelectedIndex(); + if(currentIndex == -1) + currentIndex = 0; + + switch(key) + { + case GLUT_KEY_PAGE_UP: + currentIndex -= ServersPerScreen - 1; + break; + case GLUT_KEY_PAGE_DOWN: + currentIndex += ServersPerScreen - 1; + break; + case GLUT_KEY_UP: + currentIndex--; + break; + case GLUT_KEY_DOWN: + currentIndex++; + break; + case GLUT_KEY_LEFT: + sortColumn--; + if(sortColumn < 0) + sortColumn = 0; + break; + case GLUT_KEY_RIGHT: + sortColumn++; + if(sortColumn >= columns.size()) + sortColumn = columns.size() - 1; + break; + } + if(currentIndex < 0) + currentIndex = 0; + if(currentIndex >= servers.size()) + currentIndex = servers.size() - 1; + + selectedId = servers[currentIndex].id; +} + +static S32 QSORT_CALLBACK compareFuncName(const void *a, const void *b) +{ + return stricmp(((QueryServersUserInterface::ServerRef *) a)->serverName, + ((QueryServersUserInterface::ServerRef *) b)->serverName); +} + +static S32 QSORT_CALLBACK compareFuncPing(const void *a, const void *b) +{ + return S32(((QueryServersUserInterface::ServerRef *) a)->pingTime - + ((QueryServersUserInterface::ServerRef *) b)->pingTime); +} + +static S32 QSORT_CALLBACK compareFuncPlayers(const void *a, const void *b) +{ + S32 pc = S32(((QueryServersUserInterface::ServerRef *) a)->playerCount - + ((QueryServersUserInterface::ServerRef *) b)->playerCount); + if(pc) + return pc; + + return S32(((QueryServersUserInterface::ServerRef *) a)->maxPlayers - + ((QueryServersUserInterface::ServerRef *) b)->maxPlayers); +} + +static S32 QSORT_CALLBACK compareFuncAddress(const void *a, const void *b) +{ + return S32(((QueryServersUserInterface::ServerRef *) a)->serverAddress.netNum[0] - + ((QueryServersUserInterface::ServerRef *) b)->serverAddress.netNum[0]); +} + +void QueryServersUserInterface::sort() +{ + switch(sortColumn) + { + case 0: + qsort(servers.address(), servers.size(), sizeof(ServerRef), compareFuncName); + break; + case 2: + qsort(servers.address(), servers.size(), sizeof(ServerRef), compareFuncPing); + break; + case 3: + qsort(servers.address(), servers.size(), sizeof(ServerRef), compareFuncPlayers); + break; + case 4: + qsort(servers.address(), servers.size(), sizeof(ServerRef), compareFuncAddress); + break; + } + if(!sortAscending) + { + S32 size = servers.size() / 2; + S32 totalSize = servers.size(); + + for(S32 i = 0; i < size; i++) + { + ServerRef temp = servers[i]; + servers[i] = servers[totalSize - i - 1]; + servers[totalSize - i - 1] = temp; + } + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/UIQueryServers.h b/tnl-1.5.0/tnl/zap/UIQueryServers.h new file mode 100644 index 0000000000000000000000000000000000000000..d389cb3a78a8ce6cf6831ed6341ea946134a4592 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/UIQueryServers.h @@ -0,0 +1,117 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UIQUERYSERVERS_H_ +#define _UIQUERYSERVERS_H_ + +#include "UI.h" +#include "tnlNonce.h" + +namespace Zap +{ + +class QueryServersUserInterface : public UserInterface +{ +public: + U32 selectedId; + S32 sortColumn; + S32 lastSortColumn; + bool sortAscending; + bool shouldSort; + Nonce mNonce; + U32 pendingPings; + U32 pendingQueries; + U32 broadcastPingSendTime; + U32 lastUsedServerId; + + enum { + MaxServerNameLen = 20, + ServersPerScreen = 21, + ServersAbove = 9, + ServersBelow = 9, + MaxPendingPings = 15, + MaxPendingQueries = 10, + PingQueryTimeout = 1500, + PingQueryRetryCount = 3, + }; + struct ServerRef + { + enum State + { + Start, + SentPing, + ReceivedPing, + SentQuery, + ReceivedQuery, + }; + U32 state; + U32 id; + U32 pingTime; + U32 identityToken; + U32 lastSendTime; + U32 sendCount; + bool isFromMaster; + bool dedicated; + bool passwordRequired; + Nonce sendNonce; + char serverName[MaxServerNameLen+1]; + Address serverAddress; + S32 playerCount, maxPlayers; + }; + struct ColumnInfo + { + const char *name; + U32 xStart; + ColumnInfo(const char *nm = NULL, U32 xs = 0) { name = nm; xStart = xs; } + }; + Vector servers; + Vector columns; + + QueryServersUserInterface(); + + S32 findSelectedIndex(); + + void onKeyDown(U32 key); + void onSpecialKeyDown(U32 key); + void onControllerButtonDown(U32 buttonIndex); + + void onActivate(); + void idle(U32 t); + void render(); + + void addPingServers(const Vector &ipList); + + void sort(); + + void gotPingResponse(const Address &theAddress, const Nonce &clientNonce, U32 clientIdentityToken); + void gotQueryResponse(const Address &theAddress, const Nonce &clientNonce, const char *serverName, U32 playerCount, U32 maxPlayers, bool dedicated, bool passwordRequired); +}; + +extern QueryServersUserInterface gQueryServersUserInterface; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/ZAP.rc b/tnl-1.5.0/tnl/zap/ZAP.rc new file mode 100644 index 0000000000000000000000000000000000000000..20ffd6b514df492747e28fa4c709acbaa3099c55 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/ZAP.rc @@ -0,0 +1,72 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "zap_win_icon.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/tnl-1.5.0/tnl/zap/ZAP.vcproj b/tnl-1.5.0/tnl/zap/ZAP.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..d43d525638cbe182ccea480bb6e3db006acb53b3 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/ZAP.vcproj @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tnl-1.5.0/tnl/zap/barrier.cpp b/tnl-1.5.0/tnl/zap/barrier.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fed10d2da668191efe92491b739c17f33e279feb --- /dev/null +++ b/tnl-1.5.0/tnl/zap/barrier.cpp @@ -0,0 +1,258 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "barrier.h" +#include "glutInclude.h" +#include "gameLoader.h" +#include "gameNetInterface.h" +#include +#include "gameObjectRender.h" + +using namespace TNL; + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(Barrier); + +U32 Barrier::mBarrierChangeIndex = 1; + +void constructBarrierPoints(const Vector &vec, F32 width, Vector &barrierEnds ) +{ + bool loop = vec[0] == vec[vec.size() - 1]; + + Vector edgeVector; + for(S32 i = 0; i < vec.size() - 1; i++) + { + Point e = vec[i+1] - vec[i]; + e.normalize(); + edgeVector.push_back(e); + } + + Point lastEdge = edgeVector[edgeVector.size() - 1]; + Vector extend; + for(S32 i = 0; i < edgeVector.size(); i++) + { + Point curEdge = edgeVector[i]; + double cosTheta = curEdge.dot(lastEdge); + + if(cosTheta >= -0.01) + { + F32 extendAmt = width * 0.5 * tan( acos(cosTheta) / 2 ); + if(extendAmt > 0.01) + extendAmt -= 0.01; + extend.push_back(extendAmt); + } + else + extend.push_back(0); + lastEdge = curEdge; + } + F32 first = extend[0]; + extend.push_back(first); + + for(S32 i = 0; i < edgeVector.size(); i++) + { + F32 extendBack = extend[i]; + F32 extendForward = extend[i+1]; + if(i == 0 && !loop) + extendBack = 0; + if(i == edgeVector.size() - 1 && !loop) + extendForward = 0; + + Point start = vec[i] - edgeVector[i] * extendBack; + Point end = vec[i+1] + edgeVector[i] * extendForward; + barrierEnds.push_back(start); + barrierEnds.push_back(end); + } +} + +void constructBarriers(Game *theGame, const Vector &barrier, F32 width) +{ + Vector vec; + + for(S32 i = 1; i < barrier.size(); i += 2) + { + float x = barrier[i-1]; + float y = barrier[i]; + vec.push_back(Point(x,y)); + } + if(vec.size() <= 1) + return; + + Vector barrierEnds; + constructBarrierPoints(vec, width, barrierEnds); + for(S32 i = 0; i < barrierEnds.size(); i += 2) + { + Barrier *b = new Barrier(barrierEnds[i], barrierEnds[i+1], width); + b->addToGame(theGame); + } +} + +Barrier::Barrier(Point st, Point e, F32 width) +{ + mObjectTypeMask = BarrierType | CommandMapVisType; + start = st; + end = e; + Rect r(start, end); + mWidth = width; + r.expand(Point(width, width)); + setExtent(r); + mLastBarrierChangeIndex = 0; +} + +void Barrier::onAddedToGame(Game *theGame) +{ +} + +bool Barrier::getCollisionPoly(Vector &polyPoints) +{ + Point vec = end - start; + Point crossVec(vec.y, -vec.x); + crossVec.normalize(mWidth * 0.5); + + polyPoints.push_back(Point(start.x + crossVec.x, start.y + crossVec.y)); + polyPoints.push_back(Point(end.x + crossVec.x, end.y + crossVec.y)); + polyPoints.push_back(Point(end.x - crossVec.x, end.y - crossVec.y)); + polyPoints.push_back(Point(start.x - crossVec.x, start.y - crossVec.y)); + return true; +} + +void Barrier::clipRenderLinesToPoly(Vector &polyPoints) +{ + //return; + Vector clippedSegments; + + + for(S32 i = 0; i < mRenderLineSegments.size(); i+= 2) + { + Point rp1 = mRenderLineSegments[i]; + Point rp2 = mRenderLineSegments[i + 1]; + + Point cp1 = polyPoints[polyPoints.size() - 1]; + for(S32 j = 0; j < polyPoints.size(); j++) + { + Point cp2 = polyPoints[j]; + Point ce = cp2 - cp1; + Point n(-ce.y, ce.x); + + n.normalize(); + F32 distToZero = n.dot(cp1); + + F32 d1 = n.dot(rp1); + F32 d2 = n.dot(rp2); + + bool d1in = d1 >= distToZero; + bool d2in = d2 >= distToZero; + + if(!d1in && !d2in) // both points are outside this edge of the poly, so... + { + // add them to the render poly + clippedSegments.push_back(rp1); + clippedSegments.push_back(rp2); + break; + } + else if((d1in && !d2in) || (d2in && !d1in)) + { + // find the clip intersection point: + F32 t = (distToZero - d1) / (d2 - d1); + Point clipPoint = rp1 + (rp2 - rp1) * t; + + if(d1in) + { + clippedSegments.push_back(clipPoint); + clippedSegments.push_back(rp2); + rp2 = clipPoint; + } + else + { + clippedSegments.push_back(rp1); + clippedSegments.push_back(clipPoint); + rp1 = clipPoint; + } + } + + // if both are in, just go to the next edge. + cp1 = cp2; + } + } + mRenderLineSegments = clippedSegments; +} + +void Barrier::render(U32 layerIndex) +{ + Color b(0,0,0.15), f(0,0,1); + //Color b(0.0,0.0,0.075), f(.3 ,0.3,0.8); + + if(layerIndex == 0) + { + Vector colPoly; + getCollisionPoly(colPoly); + glColor(b); + glBegin(GL_POLYGON); + for(S32 i = 0; i < colPoly.size(); i++) + glVertex2f(colPoly[i].x, colPoly[i].y); + glEnd(); + } + else if(layerIndex == 1) + { + if(mLastBarrierChangeIndex != mBarrierChangeIndex) + { + mLastBarrierChangeIndex = mBarrierChangeIndex; + mRenderLineSegments.clear(); + + Vector colPoly; + getCollisionPoly(colPoly); + S32 last = colPoly.size() - 1; + for(S32 i = 0; i < colPoly.size(); i++) + { + mRenderLineSegments.push_back(colPoly[last]); + mRenderLineSegments.push_back(colPoly[i]); + last = i; + } + static Vector fillObjects; + fillObjects.clear(); + + Rect bounds(start, end); + bounds.expand(Point(mWidth, mWidth)); + findObjects(BarrierType, fillObjects, bounds); + + for(S32 i = 0; i < fillObjects.size(); i++) + { + colPoly.clear(); + if(fillObjects[i] != this && fillObjects[i]->getCollisionPoly(colPoly)) + clipRenderLinesToPoly(colPoly); + } + } + glColor(f); + glBegin(GL_LINES); + for(S32 i = 0; i < mRenderLineSegments.size(); i++) + glVertex2f(mRenderLineSegments[i].x, mRenderLineSegments[i].y); + glEnd(); + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/barrier.h b/tnl-1.5.0/tnl/zap/barrier.h new file mode 100644 index 0000000000000000000000000000000000000000..05d6d06839f4bae76eaf372f283b60a9a7b6483f --- /dev/null +++ b/tnl-1.5.0/tnl/zap/barrier.h @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "point.h" +#include "gameConnection.h" +#include "gameObject.h" +#include "../tnl/tnlNetObject.h" + +namespace Zap +{ + +/// The Barrier class represents rectangular barriers that player controlled +/// Ship instances cannot pass through. Barrier objects, once created, never +/// change state, simplifying the pack/unpack update methods. Barriers are +/// constructed as an expanded line segment. +class Barrier : public GameObject +{ +public: + Point start; ///< The start point of the barrier + Point end; ///< The end point of the barrier + F32 mWidth; + + enum { + BarrierWidth = 50, ///< The width, in game units of the barrier. + }; + + static U32 mBarrierChangeIndex; ///< Global counter that is incremented every time a new barrier is added on the client. + U32 mLastBarrierChangeIndex; ///< Index to check against the global counter - if it is different, then this barrier's polygon outline will be clipped against all adjacent barriers. + + Vector mRenderLineSegments; ///< The clipped line segments representing this barrier. + + /// Barrier constructor. + Barrier(Point st = Point(), Point e = Point(), F32 width = BarrierWidth); + + /// Adds the server object to the net interface's scope always list + void onAddedToGame(Game *theGame); + + /// renders this barrier by drawing the render line segments, + void render(U32 layer); + + /// returns a sorting key for the object. Barriers should sort behind other objects + S32 getRenderSortValue() { return -1; } + + /// returns the collision polygon of this barrier, which is the boundary extruded from the start,end line segment. + bool getCollisionPoly(Vector &polyPoints); + + /// collide always returns true for Barrier objects. + bool collide(GameObject *otherObject) { return true; } + + /// clips the current set of render lines against the polygon passed as polyPoints. + void clipRenderLinesToPoly(Vector &polyPoints); + + TNL_DECLARE_CLASS(Barrier); +}; + +}; + diff --git a/tnl-1.5.0/tnl/zap/controlObjectConnection.cpp b/tnl-1.5.0/tnl/zap/controlObjectConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d361dad5e64851bb5c2d10f33bc2057cf2bdcf8 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/controlObjectConnection.cpp @@ -0,0 +1,266 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameObject.h" +#include "controlObjectConnection.h" +#include "UIGame.h" + +namespace Zap +{ + +ControlObjectConnection::ControlObjectConnection() +{ + highSendIndex[0] = 0; + highSendIndex[1] = 0; + highSendIndex[2] = 0; + mLastClientControlCRC = 0; + firstMoveIndex = 1; + mMoveTimeCredit = 0; +} + +void ControlObjectConnection::setControlObject(GameObject *theObject) +{ + if(controlObject.isValid()) + controlObject->setControllingClient(NULL); + + controlObject = theObject; + + if(theObject) + theObject->setControllingClient((GameConnection *) this); +} + +void ControlObjectConnection::packetReceived(PacketNotify *notify) +{ + for(; firstMoveIndex < ((GamePacketNotify *) notify)->firstUnsentMoveIndex; firstMoveIndex++) + pendingMoves.erase(U32(0)); + mServerPosition = ((GamePacketNotify *) notify)->lastControlObjectPosition; + Parent::packetReceived(notify); +} + +U32 ControlObjectConnection::getControlCRC() +{ + PacketStream stream; + GameObject *co = getControlObject(); + + if(!co) + return 0; + + stream.writeInt(getGhostIndex(co), GhostConnection::GhostIdBitSize); + co->writeControlState(&stream); + stream.zeroToByteBoundary(); + return stream.calculateCRC(0, stream.getBytePosition()); +} + +void ControlObjectConnection::writePacket(BitStream *bstream, PacketNotify *notify) +{ + if(isConnectionToServer()) + { + U32 firstSendIndex = highSendIndex[0]; + if(firstSendIndex < firstMoveIndex) + firstSendIndex = firstMoveIndex; + + bstream->write(getControlCRC()); + + bstream->write(firstSendIndex); + U32 skipCount = firstSendIndex - firstMoveIndex; + U32 moveCount = pendingMoves.size() - skipCount; + + bstream->writeRangedU32(moveCount, 0, MaxPendingMoves); + Move dummy; + Move *lastMove = &dummy; + for(S32 i = skipCount; i < pendingMoves.size(); i++) + { + pendingMoves[i].pack(bstream, lastMove, true); + lastMove = &pendingMoves[i]; + } + ((GamePacketNotify *) notify)->firstUnsentMoveIndex = firstMoveIndex + pendingMoves.size(); + if(controlObject.isValid()) + ((GamePacketNotify *) notify)->lastControlObjectPosition = controlObject->getActualPos(); + + highSendIndex[0] = highSendIndex[1]; + highSendIndex[1] = highSendIndex[2]; + highSendIndex[2] = ((GamePacketNotify *) notify)->firstUnsentMoveIndex; + } + else + { + S32 ghostIndex = -1; + if(controlObject.isValid()) + { + ghostIndex = getGhostIndex(controlObject); + mServerPosition = controlObject->getActualPos(); + } + + // we only compress points relative if we know that the + // remote side has a copy of the control object already + mCompressPointsRelative = bstream->writeFlag(ghostIndex != -1); + + if(bstream->writeFlag(getControlCRC() != mLastClientControlCRC)) + { + if(ghostIndex != -1) + { + bstream->writeInt(ghostIndex, GhostConnection::GhostIdBitSize); + controlObject->writeControlState(bstream); + } + } + } + Parent::writePacket(bstream, notify); +} + +void ControlObjectConnection::readPacket(BitStream *bstream) +{ + // we only replay control object moves if we got an update + // from the server. However, we wait until after the super + // class connection objects have a chance to process so + // that ghosts of other objects can be updated first. + // This way the control object won't get ahead of objects + // it is pushing in a laggy situation. + + bool replayControlObjectMoves = false; + + if(isConnectionToClient()) + { + bstream->read(&mLastClientControlCRC); + + U32 firstMove; + bstream->read(&firstMove); + U32 count = bstream->readRangedU32(0, MaxPendingMoves); + + Move theMove; + for(; firstMove < firstMoveIndex && count > 0; firstMove++) + { + count--; + theMove.unpack(bstream, true); + } + for(; count > 0; count--) + { + theMove.unpack(bstream, true); + // process the move, including crediting time to the client + // and all that joy. + // The time crediting prevents clients from hacking speed cheats + // that feed more moves to the server than are allowed. + if(mMoveTimeCredit >= theMove.time && controlObject.isValid() && !(controlObject->getObjectTypeMask() & DeletedType)) + { + mMoveTimeCredit -= theMove.time; + controlObject->setCurrentMove(theMove); + controlObject->idle(GameObject::ServerIdleControlFromClient); + } + firstMoveIndex++; + } + } + else + { + bool controlObjectValid = bstream->readFlag(); + + mCompressPointsRelative = controlObjectValid; + + gGameUserInterface.receivedControlUpdate(false); + // CRC mismatch... + if(bstream->readFlag()) + { + if(controlObjectValid) + { + U32 ghostIndex = bstream->readInt(GhostConnection::GhostIdBitSize); + controlObject = (GameObject *) resolveGhost(ghostIndex); + controlObject->readControlState(bstream); + mServerPosition = controlObject->getActualPos(); + replayControlObjectMoves = true; + gGameUserInterface.receivedControlUpdate(true); + } + else + controlObject = NULL; + } + } + Parent::readPacket(bstream); + + if(replayControlObjectMoves && controlObject.isValid()) + { + for(S32 i = 0; i < pendingMoves.size(); i++) + { + Move theMove = pendingMoves[i]; + theMove.prepare(); + controlObject->setCurrentMove(theMove); + controlObject->idle(GameObject::ClientIdleControlReplay); + } + controlObject->controlMoveReplayComplete(); + } +} + +void ControlObjectConnection::writeCompressedPoint(Point &p, BitStream *stream) +{ + if(!mCompressPointsRelative) + { + stream->write(p.x); + stream->write(p.y); + return; + } + + Point delta = p - mServerPosition; + S32 dx = S32(delta.x + Game::PlayerHorizVisDistance + Game::PlayerScopeMargin); + S32 dy = S32(delta.y + Game::PlayerVertVisDistance + Game::PlayerScopeMargin); + + S32 maxx = (Game::PlayerHorizVisDistance + Game::PlayerScopeMargin) * 2; + S32 maxy = (Game::PlayerVertVisDistance + Game::PlayerScopeMargin) * 2; + + if(stream->writeFlag(dx >= 0 && dx <= maxx && dy >= 0 && dy <= maxy)) + { + stream->writeRangedU32(dx, 0, maxx); + stream->writeRangedU32(dy, 0, maxy); + } + else + { + stream->write(p.x); + stream->write(p.y); + } +} + +void ControlObjectConnection::readCompressedPoint(Point &p, BitStream *stream) +{ + if(!mCompressPointsRelative) + { + stream->read(&p.x); + stream->read(&p.y); + return; + } + if(stream->readFlag()) + { + U32 maxx = (Game::PlayerHorizVisDistance + Game::PlayerScopeMargin) * 2; + U32 maxy = (Game::PlayerVertVisDistance + Game::PlayerScopeMargin) * 2; + + F32 dx = F32(stream->readRangedU32(0, maxx)) - (Game::PlayerHorizVisDistance + Game::PlayerScopeMargin); + F32 dy = F32(stream->readRangedU32(0, maxy)) - (Game::PlayerVertVisDistance + Game::PlayerScopeMargin); + + Point delta(dx, dy); + p = mServerPosition + delta; + } + else + { + stream->read(&p.x); + stream->read(&p.y); + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/controlObjectConnection.h b/tnl-1.5.0/tnl/zap/controlObjectConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..64d3de9b4e9414f41f293df005efa71303737f1d --- /dev/null +++ b/tnl-1.5.0/tnl/zap/controlObjectConnection.h @@ -0,0 +1,105 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _CONTROLOBJECTCONNECTION_H_ +#define _CONTROLOBJECTCONNECTION_H_ + +#include "tnl.h" +#include "tnlGhostConnection.h" +#include "gameObject.h" +#include "point.h" +#include "move.h" + +using namespace TNL; + +namespace Zap +{ + +class GameObject; + +class ControlObjectConnection : public GhostConnection +{ + typedef GhostConnection Parent; + // move management + enum { + MaxPendingMoves = 63, + MaxMoveTimeCredit = 512, + }; + Vector pendingMoves; + SafePtr controlObject; + + U32 mLastClientControlCRC; + Point mServerPosition; + bool mCompressPointsRelative; + + U32 firstMoveIndex; + U32 highSendIndex[3]; + U32 mMoveTimeCredit; + +public: + ControlObjectConnection(); + + void setControlObject(GameObject *theObject); + GameObject *getControlObject() { return controlObject; } + U32 getControlCRC(); + + void addPendingMove(Move *theMove) + { + if(pendingMoves.size() < MaxPendingMoves) + pendingMoves.push_back(*theMove); + } + + struct GamePacketNotify : public GhostConnection::GhostPacketNotify + { + U32 firstUnsentMoveIndex; + Point lastControlObjectPosition; + GamePacketNotify() { firstUnsentMoveIndex = 0; } + }; + PacketNotify *allocNotify() { return new GamePacketNotify; } + + void writePacket(BitStream *bstream, PacketNotify *notify); + void readPacket(BitStream *bstream); + + void packetReceived(PacketNotify *notify); + void processMoveServer(Move *theMove); + void addToTimeCredit(U32 timeAmount) + { + mMoveTimeCredit += timeAmount; + if(mMoveTimeCredit > MaxMoveTimeCredit) + mMoveTimeCredit = MaxMoveTimeCredit; + } + + bool isDataToTransmit() { return true; } + + void writeCompressedPoint(Point &p, BitStream *stream); + void readCompressedPoint(Point &p, BitStream *stream); +}; + + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/engineeredObjects.cpp b/tnl-1.5.0/tnl/zap/engineeredObjects.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f7e78edc1a63bffe61c3fd17fc69cf306e9be010 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/engineeredObjects.cpp @@ -0,0 +1,711 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "engineeredObjects.h" +#include "ship.h" +#include "glutInclude.h" +#include "projectile.h" +#include "gameType.h" +#include "gameWeapons.h" +#include "sfx.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +static Vector fillVector; + +void engClientCreateObject(GameConnection *connection, U32 object) +{ + Ship *ship = (Ship *) connection->getControlObject(); + if(!ship) + return; + + if(!ship->carryingResource()) + return; + + Point startPoint = ship->getActualPos(); + Point endPoint = startPoint + ship->getAimVector() * Ship::MaxEngineerDistance; + + F32 collisionTime; + Point collisionNormal; + + GameObject *hitObject = ship->findObjectLOS(BarrierType, + MoveObject::ActualState, startPoint, endPoint, collisionTime, collisionNormal); + + if(!hitObject) + return; + + Point deployPosition = startPoint + (endPoint - startPoint) * collisionTime; + + // move the deploy point away from the wall by one unit... + deployPosition += collisionNormal; + + EngineeredObject *deployedObject = NULL; + switch(object) + { + case EngineeredTurret: + deployedObject = new Turret(ship->getTeam(), deployPosition, collisionNormal); + break; + case EngineeredForceField: + deployedObject = new ForceFieldProjector(ship->getTeam(), deployPosition, collisionNormal); + break; + } + deployedObject->setOwner(ship); + + deployedObject->computeExtent(); + if(!deployedObject || !deployedObject->checkDeploymentPosition()) + { + static StringTableEntry message("Unable to deploy in that location."); + + connection->s2cDisplayMessage(GameConnection::ColorAqua, SFXNone, message); + delete deployedObject; + return; + } + if(!ship->engineerBuildObject()) + { + static StringTableEntry message("Not enough energy to build object."); + + connection->s2cDisplayMessage(GameConnection::ColorAqua, SFXNone, message); + delete deployedObject; + return; + } + deployedObject->addToGame(gServerGame); + deployedObject->onEnabled(); + Item *theItem = ship->unmountResource(); + + deployedObject->setResource(theItem); +} + +EngineeredObject::EngineeredObject(S32 team, Point anchorPoint, Point anchorNormal) +{ + mHealth = 1.f; + mTeam = team; + mOriginalTeam = mTeam; + mAnchorPoint = anchorPoint; + mAnchorNormal= anchorNormal; + mObjectTypeMask = EngineeredType | CommandMapVisType; + mIsDestroyed = false; +} + +void EngineeredObject::processArguments(S32 argc, const char **argv) +{ + if(argc != 3) + return; + Point p; + mTeam = atoi(argv[0]); + mOriginalTeam = mTeam; + if(mTeam == -1) + mHealth = 0; + p.read(argv + 1); + p *= getGame()->getGridSize(); + + // find the mount point: + F32 minDist = 1000; + Point normal; + Point anchor; + + for(F32 theta = 0; theta < Float2Pi; theta += FloatPi * 0.125) + { + Point dir(cos(theta), sin(theta)); + dir *= 100; + + F32 t; + Point n; + if(findObjectLOS(BarrierType, 0, p, p + dir, t, n)) + { + if(t < minDist) + { + anchor = p + dir * t; + normal = n; + minDist = t; + } + } + } + if(minDist > 1) + return; + mAnchorPoint = anchor + normal; + mAnchorNormal = normal; + computeExtent(); + if(mHealth != 0) + onEnabled(); +} + +void EngineeredObject::setOwner(Ship *owner) +{ + mOwner = owner; +} + +void EngineeredObject::setResource(Item *resource) +{ + TNLAssert(resource->isMounted() == false, "Doh!"); + mResource = resource; + mResource->removeFromDatabase(); +} + +static const F32 disabledLevel = 0.25; + +bool EngineeredObject::isEnabled() +{ + return mHealth >= disabledLevel; +} + +void EngineeredObject::damageObject(DamageInfo *di) +{ + F32 prevHealth = mHealth; + + if(di->damageAmount > 0) + mHealth -= di->damageAmount * .25f; + else + mHealth -= di->damageAmount; + + if(mHealth < 0) + mHealth = 0; + if(prevHealth == mHealth) + return; + + setMaskBits(HealthMask); + + if(prevHealth >= disabledLevel && mHealth < disabledLevel) + { + if(mTeam != mOriginalTeam) + { + mTeam = mOriginalTeam; + setMaskBits(TeamMask); + } + onDisabled(); + } + else if(prevHealth < disabledLevel && mHealth >= disabledLevel) + { + if(mTeam == -1) + { + if(di->damagingObject) + { + mTeam = di->damagingObject->getTeam(); + setMaskBits(TeamMask); + } + } + onEnabled(); + } + + if(mHealth == 0 && mResource.isValid()) + { + mIsDestroyed = true; + onDestroyed(); + + mResource->addToDatabase(); + mResource->setActualPos(mAnchorPoint + mAnchorNormal * mResource->getRadius()); + + deleteObject(500); + } +} + +void EngineeredObject::computeExtent() +{ + Vector v; + getCollisionPoly(v); + Rect r(v[0], v[0]); + for(S32 i = 1; i < v.size(); i++) + r.unionPoint(v[i]); + setExtent(r); +} + +void EngineeredObject::explode() +{ + enum { + NumShipExplosionColors = 12, + }; + + static Color ShipExplosionColors[NumShipExplosionColors] = { + Color(1, 0, 0), + Color(0.9, 0.5, 0), + Color(1, 1, 1), + Color(1, 1, 0), + Color(1, 0, 0), + Color(0.8, 1.0, 0), + Color(1, 0.5, 0), + Color(1, 1, 1), + Color(1, 0, 0), + Color(0.9, 0.5, 0), + Color(1, 1, 1), + Color(1, 1, 0), + }; + + SFXObject::play(SFXShipExplode, getActualPos(), Point()); + + F32 a, b; + a = Random::readF() * 0.4 + 0.5; + b = Random::readF() * 0.2 + 0.9; + + F32 c, d; + c = Random::readF() * 0.15 + 0.125; + d = Random::readF() * 0.2 + 0.9; + + FXManager::emitExplosion(getActualPos(), 0.65, ShipExplosionColors, NumShipExplosionColors); + FXManager::emitBurst(getActualPos(), Point(a,c) * 0.6, Color(1,1,0.25), Color(1,0,0)); + FXManager::emitBurst(getActualPos(), Point(b,d) * 0.6, Color(1,1,0), Color(0,1,1)); + + disableCollision(); +} + +bool PolygonsIntersect(Vector &p1, Vector &p2) +{ + Point rp1 = p1[p1.size() - 1]; + for(S32 i = 0; i < p1.size(); i++) + { + Point rp2 = p1[i]; + + Point cp1 = p2[p2.size() - 1]; + for(S32 j = 0; j < p2.size(); j++) + { + Point cp2 = p2[j]; + Point ce = cp2 - cp1; + Point n(-ce.y, ce.x); + + F32 distToZero = n.dot(cp1); + + F32 d1 = n.dot(rp1); + F32 d2 = n.dot(rp2); + + bool d1in = d1 >= distToZero; + bool d2in = d2 >= distToZero; + + if(!d1in && !d2in) // both points are outside this edge of the poly, so... + break; + else if((d1in && !d2in) || (d2in && !d1in)) + { + // find the clip intersection point: + F32 t = (distToZero - d1) / (d2 - d1); + Point clipPoint = rp1 + (rp2 - rp1) * t; + + if(d1in) + rp2 = clipPoint; + else + rp1 = clipPoint; + } + else if(j == p2.size() - 1) + return true; + + // if both are in, just go to the next edge. + cp1 = cp2; + } + rp1 = rp2; + } + return false; +} + +bool EngineeredObject::checkDeploymentPosition() +{ + Vector go; + Vector polyBounds; + getCollisionPoly(polyBounds); + + Rect queryRect = getExtent(); + gServerGame->getGridDatabase()->findObjects(BarrierType | EngineeredType, go, queryRect); + for(S32 i = 0; i < go.size(); i++) + { + Vector compareBounds; + go[i]->getCollisionPoly(compareBounds); + if(PolygonsIntersect(polyBounds, compareBounds)) + return false; + } + return true; +} + +U32 EngineeredObject::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + if(stream->writeFlag(updateMask & InitialMask)) + { + stream->write(mAnchorPoint.x); + stream->write(mAnchorPoint.y); + stream->write(mAnchorNormal.x); + stream->write(mAnchorNormal.y); + } + if(stream->writeFlag(updateMask & TeamMask)) + stream->write(mTeam); + + if(stream->writeFlag(updateMask & HealthMask)) + { + stream->writeFloat(mHealth, 6); + stream->writeFlag(mIsDestroyed); + } + return 0; +} + +void EngineeredObject::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + bool initial = false; + if(stream->readFlag()) + { + initial = true; + stream->read(&mAnchorPoint.x); + stream->read(&mAnchorPoint.y); + stream->read(&mAnchorNormal.x); + stream->read(&mAnchorNormal.y); + computeExtent(); + } + if(stream->readFlag()) + stream->read(&mTeam); + if(stream->readFlag()) + { + mHealth = stream->readFloat(6); + bool wasDestroyed = mIsDestroyed; + mIsDestroyed = stream->readFlag(); + if(mIsDestroyed && !wasDestroyed && !initial) + explode(); + } +} + +TNL_IMPLEMENT_NETOBJECT(ForceFieldProjector); + +void ForceFieldProjector::onDisabled() +{ + if(mField.isValid()) + mField->deleteObject(0); +} + +void ForceFieldProjector::onEnabled() +{ + Point start = mAnchorPoint + mAnchorNormal * 15; + Point end = mAnchorPoint + mAnchorNormal * 500; + + F32 t; + Point n; + + if(findObjectLOS(BarrierType, 0, start, end, t, n)) + end = start + (end - start) * t; + + mField = new ForceField(mTeam, start, end); + mField->addToGame(getGame()); +} + +bool ForceFieldProjector::getCollisionPoly(Vector &polyPoints) +{ + Point cross(mAnchorNormal.y, -mAnchorNormal.x); + polyPoints.push_back(mAnchorPoint + cross * 12); + polyPoints.push_back(mAnchorPoint + mAnchorNormal * 15); + polyPoints.push_back(mAnchorPoint - cross * 12); + return true; +} + +void ForceFieldProjector::render() +{ + renderForceFieldProjector(mAnchorPoint, mAnchorNormal, getGame()->getGameType()->getTeamColor(getTeam()), isEnabled()); +} + +TNL_IMPLEMENT_NETOBJECT(ForceField); + +ForceField::ForceField(S32 team, Point start, Point end) +{ + mTeam = team; + mStart = start; + mEnd = end; + + Rect extent(mStart, mEnd); + extent.expand(Point(5,5)); + setExtent(extent); + + mFieldUp = true; + mObjectTypeMask = ForceFieldType | CommandMapVisType; + mNetFlags.set(Ghostable); +} + +bool ForceField::collide(GameObject *hitObject) +{ + if(!mFieldUp) + return false; + + if(!(hitObject->getObjectTypeMask() & ShipType)) + return true; + + if(hitObject->getTeam() == mTeam) + { + if(!isGhost()) + { + mFieldUp = false; + mDownTimer.reset(FieldDownTime); + setMaskBits(StatusMask); + } + return false; + } + return true; +} + +void ForceField::idle(GameObject::IdleCallPath path) +{ + if(path == ServerIdleMainLoop) + { + if(mDownTimer.update(mCurrentMove.time)) + { + // do an LOS test to see if anything is in the field: + F32 t; + Point n; + if(!findObjectLOS(ShipType | ItemType, 0, mStart, mEnd, t, n)) + { + mFieldUp = true; + setMaskBits(StatusMask); + } + else + mDownTimer.reset(10); + } + } +} + +U32 ForceField::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + if(stream->writeFlag(updateMask & InitialMask)) + { + stream->write(mStart.x); + stream->write(mStart.y); + stream->write(mEnd.x); + stream->write(mEnd.y); + stream->write(mTeam); + } + stream->writeFlag(mFieldUp); + return 0; +} + +void ForceField::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + bool initial = false; + if(stream->readFlag()) + { + initial = true; + stream->read(&mStart.x); + stream->read(&mStart.y); + stream->read(&mEnd.x); + stream->read(&mEnd.y); + stream->read(&mTeam); + + Rect extent(mStart, mEnd); + extent.expand(Point(5,5)); + setExtent(extent); + } + bool wasUp = mFieldUp; + mFieldUp = stream->readFlag(); + + if(initial || (wasUp != mFieldUp)) + SFXObject::play(mFieldUp ? SFXForceFieldUp : SFXForceFieldDown, mStart, Point()); +} + +bool ForceField::getCollisionPoly(Vector &p) +{ + Point normal(mEnd.y - mStart.y, mStart.x - mEnd.x); + normal.normalize(2.5); + + p.push_back(mStart + normal); + p.push_back(mEnd + normal); + p.push_back(mEnd - normal); + p.push_back(mStart - normal); + return true; +} + +void ForceField::render() +{ + Color c = getGame()->getGameType()->getTeamColor(mTeam); + renderForceField(mStart, mEnd, c, mFieldUp); +} + +TNL_IMPLEMENT_NETOBJECT(Turret); + +Turret::Turret(S32 team, Point anchorPoint, Point anchorNormal) : + EngineeredObject(team, anchorPoint, anchorNormal) +{ + mNetFlags.set(Ghostable); +} + + +bool Turret::getCollisionPoly(Vector &polyPoints) +{ + Point cross(mAnchorNormal.y, -mAnchorNormal.x); + polyPoints.push_back(mAnchorPoint + cross * 25); + polyPoints.push_back(mAnchorPoint + cross * 10 + mAnchorNormal * 45); + polyPoints.push_back(mAnchorPoint - cross * 10 + mAnchorNormal * 45); + polyPoints.push_back(mAnchorPoint - cross * 25); + return true; +} + +void Turret::onAddedToGame(Game *theGame) +{ + Parent::onAddedToGame(theGame); + mCurrentAngle = atan2(mAnchorNormal.y, mAnchorNormal.x); +} + +void Turret::render() +{ + Color c, lightColor; + + if(mTeam != -1 && gClientGame->getGameType()) + c = gClientGame->getGameType()->mTeams[mTeam].color; + else + c = Color(1,1,1); + + renderTurret(c, mAnchorPoint, mAnchorNormal, isEnabled(), mHealth, mCurrentAngle, TurretAimOffset); +} + +U32 Turret::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + U32 ret = Parent::packUpdate(connection, updateMask, stream); + if(stream->writeFlag(updateMask & AimMask)) + stream->write(mCurrentAngle); + + return ret; +} + +void Turret::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + Parent::unpackUpdate(connection, stream); + if(stream->readFlag()) + stream->read(&mCurrentAngle); +} + +extern bool FindLowestRootInInterval(Point::member_type inA, Point::member_type inB, Point::member_type inC, Point::member_type inUpperBound, Point::member_type &outX); + +void Turret::idle(IdleCallPath path) +{ + if(path != ServerIdleMainLoop || !isEnabled()) + return; + + mFireTimer.update(mCurrentMove.time); + + // Choose best target: + + Point aimPos = mAnchorPoint + mAnchorNormal * TurretAimOffset; + Point cross(mAnchorNormal.y, -mAnchorNormal.x); + + Rect queryRect(aimPos, aimPos); + queryRect.unionPoint(aimPos + cross * TurretPerceptionDistance); + queryRect.unionPoint(aimPos - cross * TurretPerceptionDistance); + queryRect.unionPoint(aimPos + mAnchorNormal * TurretPerceptionDistance); + fillVector.clear(); + findObjects(TurretTargetType, fillVector, queryRect); + + GameObject * bestTarget = NULL; + F32 bestRange = 10000.f; + Point bestDelta; + + Point delta; + + F32 timeScale = F32(mCurrentMove.time) * 0.001f; + + for(S32 i=0; igetObjectTypeMask() & ShipType) + { + Ship *potential = (Ship*)fillVector[i]; + + // Is it dead or cloaked? + if((potential->isCloakActive() && !potential->areItemsMounted()) || potential->hasExploded) + continue; + } + GameObject *potential = fillVector[i]; + + // Is it on our team? + if(potential->getTeam() == mTeam) + continue; + + // Calculate where we have to shoot to hit this... + const F32 projVel = TurretProjectileVelocity; + Point Vs = potential->getActualVel(); + F32 S = gWeapons[WeaponTurretBlaster].projVelocity; + Point d = potential->getRenderPos() - aimPos; + + F32 t; + if(!FindLowestRootInInterval(Vs.dot(Vs) - S * S, 2 * Vs.dot(d), d.dot(d), gWeapons[WeaponTurretBlaster].projLiveTime * 0.001f, t)) + continue; + + Point leadPos = potential->getRenderPos() + Vs * t; + + // Calculate distance + delta = (leadPos - aimPos); + + Point angleCheck = delta; + angleCheck.normalize(); + // Check that we're facing it... + if(angleCheck.dot(mAnchorNormal) <= -0.1f) + continue; + + // See if we can see it... + Point n; + if(findObjectLOS(BarrierType, 0, aimPos, potential->getActualPos(), t, n)) + continue; + + // See if we're gonna clobber our own stuff... + disableCollision(); + Point delta2 = delta; + delta2.normalize(TurretRange); + GameObject *hitObject = findObjectLOS(ShipType | BarrierType | EngineeredType, 0, aimPos, aimPos + delta2, t, n); + enableCollision(); + + if(hitObject && hitObject->getTeam() == mTeam) + continue; + + F32 dist = delta.len(); + + if(dist < bestRange) + { + bestDelta = delta; + bestRange = dist; + bestTarget = potential; + } + } + + if(!bestTarget) + return; + + // ok, now change our aim to be towards the best target: + F32 destAngle = atan2(bestDelta.y, bestDelta.x); + + F32 angleDelta = destAngle - mCurrentAngle; + if(angleDelta > FloatPi) + angleDelta -= Float2Pi; + if(angleDelta < -FloatPi) + angleDelta += Float2Pi; + + bool canFire = false; + F32 maxTurn = TurretTurnRate * mCurrentMove.time * 0.001f; + if(angleDelta != 0) + setMaskBits(AimMask); + + if(angleDelta > maxTurn) + mCurrentAngle += maxTurn; + else if(angleDelta < -maxTurn) + mCurrentAngle -= maxTurn; + else + { + mCurrentAngle = destAngle; + + if(mFireTimer.getCurrent() == 0) + { + bestDelta.normalize(); + Point velocity; + createWeaponProjectiles(WeaponTurretBlaster, bestDelta, aimPos, velocity, 30.0f, this); + mFireTimer.reset(TurretFireDelay); + } + } +} + +}; diff --git a/tnl-1.5.0/tnl/zap/engineeredObjects.h b/tnl-1.5.0/tnl/zap/engineeredObjects.h new file mode 100644 index 0000000000000000000000000000000000000000..51934deac084dae5f2a9d7e092afea9445afb04e --- /dev/null +++ b/tnl-1.5.0/tnl/zap/engineeredObjects.h @@ -0,0 +1,163 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _ENGINEEREDOBJECTS_H_ +#define _ENGINEEREDOBJECTS_H_ + +#include "gameObject.h" +#include "item.h" +#include "barrier.h" + +namespace Zap +{ + +extern void engClientCreateObject(GameConnection *connection, U32 object); + +class EngineeredObject : public GameObject +{ + typedef GameObject Parent; +protected: + F32 mHealth; + Color mTeamColor; + SafePtr mResource; + SafePtr mOwner; + Point mAnchorPoint; + Point mAnchorNormal; + bool mIsDestroyed; + S32 mOriginalTeam; + + enum MaskBits + { + InitialMask = BIT(0), + HealthMask = BIT(1), + TeamMask = BIT(2), + NextFreeMask = BIT(3), + }; + +public: + EngineeredObject(S32 team = -1, Point anchorPoint = Point(), Point anchorNormal = Point()); + void setResource(Item *resource); + bool checkDeploymentPosition(); + void computeExtent(); + virtual void onDestroyed() {} + virtual void onDisabled() {} + virtual void onEnabled() {} + bool isEnabled(); + + void processArguments(S32 argc, const char **argv); + + void explode(); + bool isDestroyed() { return mIsDestroyed; } + void setOwner(Ship *owner); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + void damageObject(DamageInfo *damageInfo); + bool collide(GameObject *hitObject) { return true; } + F32 getHealth() { return mHealth; } +}; + +class ForceField : public GameObject +{ + Point mStart, mEnd; + Timer mDownTimer; + bool mFieldUp; + +public: + enum Constants + { + InitialMask = BIT(0), + StatusMask = BIT(1), + + FieldDownTime = 250, + }; + + ForceField(S32 team = -1, Point start = Point(), Point end = Point()); + bool collide(GameObject *hitObject); + void idle(GameObject::IdleCallPath path); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + bool getCollisionPoly(Vector &polyPoints); + void render(); + S32 getRenderSortValue() { return -1; } + + TNL_DECLARE_CLASS(ForceField); +}; + +class ForceFieldProjector : public EngineeredObject +{ + typedef EngineeredObject Parent; + + SafePtr mField; +public: + ForceFieldProjector(S32 team = -1, Point anchorPoint = Point(), Point anchorNormal = Point()) : + EngineeredObject(team, anchorPoint, anchorNormal) { mNetFlags.set(Ghostable); } + + bool getCollisionPoly(Vector &polyPoints); + void render(); + void onEnabled(); + void onDisabled(); + TNL_DECLARE_CLASS(ForceFieldProjector); +}; + +class Turret : public EngineeredObject +{ + typedef EngineeredObject Parent; + Timer mFireTimer; + F32 mCurrentAngle; + +public: + enum { + TurretAimOffset = 15, + TurretRange = 600, + TurretPerceptionDistance = 800, + TurretProjectileVelocity = 600, + TurretTurnRate = 4, + TurretFireDelay = 150, + + AimMask = EngineeredObject::NextFreeMask, + }; + +public: + Turret(S32 team = -1, Point anchorPoint = Point(), Point anchorNormal = Point(1, 0)); + + bool getCollisionPoly(Vector &polyPoints); + void render(); + void idle(IdleCallPath path); + void onAddedToGame(Game *theGame); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + TNL_DECLARE_CLASS(Turret); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/flagItem.cpp b/tnl-1.5.0/tnl/zap/flagItem.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c00941a48946a9818b34ca88c9618d02a47812e5 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/flagItem.cpp @@ -0,0 +1,133 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "flagItem.h" +#include "gameType.h" +#include "ship.h" +#include "glutInclude.h" + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(FlagItem); + +FlagItem::FlagItem(Point pos) : Item(pos, false, 20) +{ + mTeam = 0; + mNetFlags.set(Ghostable); + mObjectTypeMask |= FlagType | CommandMapVisType; +} + +void FlagItem::onAddedToGame(Game *theGame) +{ + theGame->getGameType()->addFlag(this); +} + + +void FlagItem::processArguments(S32 argc, const char **argv) +{ + if(argc < 3) + return; + + mTeam = atoi(argv[0]); + Parent::processArguments(argc-1, argv+1); + initialPos = mMoveState[ActualState].pos; +} + +U32 FlagItem::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + if(stream->writeFlag(updateMask & InitialMask)) + stream->writeInt(mTeam + 1, 4); + return Parent::packUpdate(connection, updateMask, stream); +} + +void FlagItem::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + if(stream->readFlag()) + mTeam = stream->readInt(4) - 1; + Parent::unpackUpdate(connection, stream); +} + +bool FlagItem::isAtHome() +{ + return mMoveState[ActualState].pos == initialPos; +} + +void FlagItem::sendHome() +{ + mMoveState[ActualState].pos = mMoveState[RenderState].pos = initialPos; + mMoveState[ActualState].vel = Point(0,0); + setMaskBits(PositionMask); + updateExtent(); +} + +void FlagItem::renderItem(Point pos) +{ + Point offset; + + if(mIsMounted) + offset.set(15, -15); + + Color c; + GameType *gt = getGame()->getGameType(); + + c = gt->getTeamColor(getTeam()); + + renderFlag(pos + offset, c); +} + +bool FlagItem::collide(GameObject *hitObject) +{ + if(mIsMounted) + return false; + if(hitObject->getObjectTypeMask() & (BarrierType | ForceFieldType)) + return true; + if(!(hitObject->getObjectTypeMask() & ShipType)) + return false; + + if(isGhost() || ((Ship *) hitObject)->hasExploded) + return false; + + GameType *gt = getGame()->getGameType(); + if(gt) + gt->shipTouchFlag((Ship *) hitObject, this); + return false; +} + +void FlagItem::onMountDestroyed() +{ + GameType *gt = getGame()->getGameType(); + if(!gt) + return; + + if(!mMount.isValid()) + return; + + gt->flagDropped(mMount, this); + dismount(); +} + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/flagItem.h b/tnl-1.5.0/tnl/zap/flagItem.h new file mode 100644 index 0000000000000000000000000000000000000000..63476f05bc954d5b3d8bf44830e3bfd44626d7a7 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/flagItem.h @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _FLAGITEM_H_ +#define _FLAGITEM_H_ + +#include "item.h" + +namespace Zap +{ + +class FlagItem : public Item +{ + typedef Item Parent; + Point initialPos; +public: + FlagItem(Point pos = Point()); + void onAddedToGame(Game *theGame); + void processArguments(S32 argc, const char **argv); + void renderItem(Point pos); + void sendHome(); + + void onMountDestroyed(); + bool collide(GameObject *hitObject); + bool isAtHome(); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + TNL_DECLARE_CLASS(FlagItem); +}; + +extern void renderFlag(Point pos, Color c); + +}; + +#endif \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/footballGame.cpp b/tnl-1.5.0/tnl/zap/footballGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9517c0dd444985fce9b679ae8badf47db75f7c83 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/footballGame.cpp @@ -0,0 +1,242 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "goalZone.h" +#include "gameType.h" +#include "ship.h" +#include "flagItem.h" +#include "gameObjectRender.h" + +namespace Zap +{ +class Ship; + +class ZoneControlGameType : public GameType +{ + typedef GameType Parent; + + Vector mZones; + SafePtr mFlag; + S32 mFlagTeam; +public: + ZoneControlGameType() + { + mFlagTeam = -1; + } + + void onGhostAvailable(GhostConnection *theConnection) + { + Parent::onGhostAvailable(theConnection); + NetObject::setRPCDestConnection(theConnection); + s2cSetFlagTeam(mFlagTeam); + NetObject::setRPCDestConnection(NULL); + } + + void shipTouchFlag(Ship *theShip, FlagItem *theFlag); + void flagDropped(Ship *theShip, FlagItem *theFlag); + void addZone(GoalZone *z); + void addFlag(FlagItem *theFlag) + { + mFlag = theFlag; + addItemOfInterest(theFlag); + } + void shipTouchZone(Ship *s, GoalZone *z); + const char *getGameTypeString() { return "Zone Control"; } + const char *getInstructionString() { return "Carry the flag into each of the capture zones!"; } + void renderInterfaceOverlay(bool scoreboardVisible); + void performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection); + + TNL_DECLARE_RPC(s2cSetFlagTeam, (S32 newFlagTeam)); + TNL_DECLARE_CLASS(ZoneControlGameType); +}; + +TNL_IMPLEMENT_NETOBJECT(ZoneControlGameType); + +GAMETYPE_RPC_S2C(ZoneControlGameType, s2cSetFlagTeam, (S32 flagTeam), (flagTeam)) +{ + mFlagTeam = flagTeam; +} + +void ZoneControlGameType::shipTouchFlag(Ship *theShip, FlagItem *theFlag) +{ + GameConnection *controlConnection = theShip->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + if(!cl) + return; + + static StringTableEntry takeString("%e0 of team %e1 has the flag!"); + Vector e; + e.push_back(cl->name); + e.push_back(mTeams[cl->teamId].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagSnatch, takeString, e); + theFlag->mountToShip(theShip); + mFlagTeam = theShip->getTeam(); + s2cSetFlagTeam(mFlagTeam); +} + +void ZoneControlGameType::flagDropped(Ship *theShip, FlagItem *theFlag) +{ + s2cSetFlagTeam(-1); + static StringTableEntry dropString("%e0 dropped the flag!"); + Vector e; + e.push_back(theShip->mPlayerName); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagDrop, dropString, e); +} + +void ZoneControlGameType::addZone(GoalZone *z) +{ + mZones.push_back(z); +} + +void ZoneControlGameType::shipTouchZone(Ship *s, GoalZone *z) +{ + if(z->getTeam() == s->getTeam()) + return; + + S32 i; + for(i = 0; i < s->mMountedItems.size(); i++) + if(s->mMountedItems[i].isValid() && (s->mMountedItems[i]->getObjectTypeMask() & FlagType)) + break; + if(i == s->mMountedItems.size()) + return; + + S32 oldTeam = z->getTeam(); + if(oldTeam != -1) + { + static StringTableEntry takeString("%e0 captured a zone from team %e1!"); + Vector e; + e.push_back(s->mPlayerName); + e.push_back(mTeams[oldTeam].name); + + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagSnatch, takeString, e); + setTeamScore(oldTeam, mTeams[oldTeam].score - 1); + } + else + { + static StringTableEntry takeString("%e0 captured an unclaimed zone!"); + Vector e; + e.push_back(s->mPlayerName); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagSnatch, takeString, e); + } + setTeamScore(s->getTeam(), mTeams[s->getTeam()].score + 1); + z->setTeam(s->getTeam()); + for(S32 i = 0; i < mZones.size(); i++) + { + if(mZones[i]->getTeam() != s->getTeam()) + return; + } + + static StringTableEntry tdString("Team %e0 scored a touchdown!"); + Vector e; + e.push_back(mTeams[s->getTeam()].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagCapture, tdString, e); + + for(S32 i = 0; i < mZones.size(); i++) + mZones[i]->setTeam(-1); + for(S32 i = 0; i < s->mMountedItems.size(); i++) + { + Item *theItem = s->mMountedItems[i]; + FlagItem *mountedFlag = dynamic_cast(theItem); + if(mountedFlag) + { + mountedFlag->dismount(); + mountedFlag->sendHome(); + } + } + mFlagTeam = -1; + s2cSetFlagTeam(-1); +} + +void ZoneControlGameType::performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection) +{ + Parent::performProxyScopeQuery(scopeObject, connection); + S32 uTeam = scopeObject->getTeam(); + if(mFlag.isValid()) + { + if(mFlag->isAtHome()) + connection->objectInScope(mFlag); + else + { + Ship *mount = mFlag->getMount(); + if(mount && mount->getTeam() == uTeam) + { + connection->objectInScope(mount); + connection->objectInScope(mFlag); + } + } + } +} + +void ZoneControlGameType::renderInterfaceOverlay(bool scoreboardVisible) +{ + Parent::renderInterfaceOverlay(scoreboardVisible); + Ship *u = (Ship *) gClientGame->getConnectionToServer()->getControlObject(); + if(!u) + return; + + bool hasFlag = mFlag.isValid() && mFlag->getMount() == u; + + // first render all zones that are not yet taken by the flag holding team + if(mFlagTeam != -1) + { + for(S32 i = 0; i < mZones.size(); i++) + { + if(mZones[i]->getTeam() != mFlagTeam) + renderObjectiveArrow(mZones[i], getTeamColor(mZones[i]), hasFlag ? 1.0 : 0.4); + else if(mZones[i]->didRecentlyChangeTeam() && mZones[i]->getTeam() != -1 && u->getTeam() != mFlagTeam) + { + // render a blinky arrow for a recently taken zone + Color c = getTeamColor(mZones[i]); + if(mZones[i]->isFlashing()) + c *= 0.7; + renderObjectiveArrow(mZones[i], c); + } + } + + } + if(!hasFlag) + { + if(mFlag.isValid()) + { + if(!mFlag->isMounted()) + renderObjectiveArrow(mFlag, getTeamColor(mFlag)); + else + { + Ship *mount = mFlag->getMount(); + if(mount) + renderObjectiveArrow(mount, getTeamColor(mount)); + } + } + } +} + + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/ftol.h b/tnl-1.5.0/tnl/zap/ftol.h new file mode 100644 index 0000000000000000000000000000000000000000..3bc7253724b2515884d72b154c52036457a5e898 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/ftol.h @@ -0,0 +1,35 @@ +#ifdef _MSC_VER + +__inline int lrintf(float flt) +{ + int intgr; + + _asm + { + fld flt + fistp intgr + }; + + return intgr ; +} +#else +#ifdef __GNUC__ +/* must define _GNU_SOURCE here or in the makefile */ +#include +#else +#if !defined(__MWERKS__) + +#define FP_BITS(fp) (*(int *)&(fp)) +#define FIST_FLOAT_MAGIC_S (float)(7.0f * 2097152.0f) + +static int lrintf(float inval) +{ + float tmp = FIST_FLOAT_MAGIC_S + inval; + int res = ((FP_BITS(tmp)<<10)-0x80000000); + return res>>10; +} + +#endif // __MWERKS__ +#endif +#endif + diff --git a/tnl-1.5.0/tnl/zap/game.cpp b/tnl-1.5.0/tnl/zap/game.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ecedb9886fcf3429fc641cf0a8ee77a5515d0c34 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/game.cpp @@ -0,0 +1,773 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "game.h" +#include "../tnl/tnl.h" +#include "../tnl/tnlRandom.h" +#include "../tnl/tnlGhostConnection.h" +#include "../tnl/tnlNetInterface.h" +#include "gameNetInterface.h" +#include "masterConnection.h" +#include "glutInclude.h" + +using namespace TNL; +#include "gameObject.h" +#include "ship.h" +#include "UIGame.h" +#include "UIMenus.h" +#include "SweptEllipsoid.h" +#include "sparkManager.h" +#include "barrier.h" +#include "gameLoader.h" +#include "gameType.h" +#include "sfx.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +// global Game objects +ServerGame *gServerGame = NULL; +ClientGame *gClientGame = NULL; + +//----------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------- + +Game::Game(const Address &theBindAddress) +{ + mNextMasterTryTime = 0; + mCurrentTime = 0; + + mNetInterface = new GameNetInterface(theBindAddress, this); +} + +void Game::setScopeAlwaysObject(GameObject *theObject) +{ + mScopeAlwaysList.push_back(theObject); +} + +GameNetInterface *Game::getNetInterface() +{ + return mNetInterface; +} + +MasterServerConnection *Game::getConnectionToMaster() +{ + return mConnectionToMaster; +} + +GameType *Game::getGameType() +{ + return mGameType; +} + +U32 Game::getTeamCount() +{ + if(mGameType.isValid()) + return mGameType->mTeams.size(); + return 0; +} + +void Game::setGameType(GameType *theGameType) +{ + mGameType = theGameType; +} + +void Game::checkConnectionToMaster(U32 timeDelta) +{ + if(!mConnectionToMaster.isValid()) + { + if(gMasterAddress == Address()) + return; + if(mNextMasterTryTime < timeDelta) + { + mConnectionToMaster = new MasterServerConnection(isServer()); + mConnectionToMaster->connect(mNetInterface, gMasterAddress); + mNextMasterTryTime = MasterServerConnectAttemptDelay; + } + else + mNextMasterTryTime -= timeDelta; + } +} + +Game::DeleteRef::DeleteRef(GameObject *o, U32 d) +{ + theObject = o; + delay = d; +} + +void Game::addToDeleteList(GameObject *theObject, U32 delay) +{ + mPendingDeleteObjects.push_back(DeleteRef(theObject, delay)); +} + +void Game::processDeleteList(U32 timeDelta) +{ + for(S32 i = 0; i < mPendingDeleteObjects.size(); ) + { + if(timeDelta > mPendingDeleteObjects[i].delay) + { + GameObject *g = mPendingDeleteObjects[i].theObject; + delete g; + mPendingDeleteObjects.erase_fast(i); + } + else + { + mPendingDeleteObjects[i].delay -= timeDelta; + i++; + } + } +} + +void Game::addToGameObjectList(GameObject *theObject) +{ + mGameObjects.push_back(theObject); +} + +void Game::removeFromGameObjectList(GameObject *theObject) +{ + for(S32 i = 0; i < mGameObjects.size(); i++) + { + if(mGameObjects[i] == theObject) + { + mGameObjects.erase_fast(i); + return; + } + } + TNLAssert(0, "Object not in game's list!"); +} + +void Game::deleteObjects(U32 typeMask) +{ + for(S32 i = 0; i < mGameObjects.size(); i++) + if(mGameObjects[i]->getObjectTypeMask() & typeMask) + mGameObjects[i]->deleteObject(0); +} + +Rect Game::computeWorldObjectExtents() +{ + if(!mGameObjects.size()) + return Rect(); + + Rect theRect = mGameObjects[0]->getExtent(); + for(S32 i = 0; i < mGameObjects.size(); i++) + theRect.unionRect(mGameObjects[i]->getExtent()); + return theRect; +} + +//----------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------- + +ServerGame::ServerGame(const Address &theBindAddress, U32 maxPlayers, const char *hostName) + : Game(theBindAddress) +{ + mPlayerCount = 0; + mMaxPlayers = maxPlayers; + mHostName = hostName; + + mNetInterface->setAllowsConnections(true); +} + +void ServerGame::setLevelList(const char *levelList) +{ + for(;;) + { + const char *firstSpace = strchr(levelList, ' '); + StringTableEntry st; + if(firstSpace) + st.setn(levelList, firstSpace - levelList); + else + st.set(levelList); + + if(st.getString()[0]) + mLevelList.push_back(st); + if(!firstSpace) + break; + levelList = firstSpace + 1; + } + for(S32 i = 0; i < mLevelList.size(); i++) + { + loadLevel(mLevelList[i].getString()); + StringTableEntry name = getGameType()->mLevelName; + StringTableEntry type(getGameType()->getGameTypeString()); + mLevelNames.push_back(name); + mLevelTypes.push_back(type); + // delete any objects that may exist + while(mGameObjects.size()) + delete mGameObjects[0]; + + mScopeAlwaysList.clear(); + logprintf ("Added level %s of type %s", name.getString(), type.getString()); + } + + mCurrentLevelIndex = mLevelList.size() - 1; + cycleLevel(); +} + +StringTableEntry ServerGame::getLevelName(S32 index) +{ + if(index < 0 || index >= mLevelNames.size()) + return StringTableEntry(); + return mLevelNames[index]; +} + +void ServerGame::cycleLevel(S32 nextLevel) +{ + // delete any objects on the delete list: + processDeleteList(0xFFFFFFFF); + + // delete any objects that may exist + while(mGameObjects.size()) + delete mGameObjects[0]; + + mScopeAlwaysList.clear(); + + for(GameConnection *walk = GameConnection::getClientList(); walk ; walk = walk->getNextClient()) + walk->resetGhosting(); + + if(nextLevel >= 0) + mCurrentLevelIndex = nextLevel; + else + mCurrentLevelIndex++; + if(S32(mCurrentLevelIndex) >= mLevelList.size()) + mCurrentLevelIndex = 0; + loadLevel(mLevelList[mCurrentLevelIndex].getString()); + Vector connectionList; + + for(GameConnection *walk = GameConnection::getClientList(); walk ; walk = walk->getNextClient()) + connectionList.push_back(walk); + + // now add the connections to the game type, in a random order + while(connectionList.size()) + { + U32 index = Random::readI() % connectionList.size(); + GameConnection *gc = connectionList[index]; + connectionList.erase(index); + + if(mGameType.isValid()) + mGameType->serverAddClient(gc); + gc->activateGhosting(); + } +} + +void ServerGame::loadLevel(const char *fileName) +{ + mGridSize = DefaultGridSize; + char fileBuffer[256]; +#ifdef TNL_OS_XBOX + dSprintf(fileBuffer, sizeof(fileBuffer), "d:\\media\\levels\\%s", fileName); +#else + dSprintf(fileBuffer, sizeof(fileBuffer), "levels/%s", fileName); +#endif + initLevelFromFile(fileBuffer); + if(!getGameType()) + { + GameType *g = new GameType; + g->addToGame(this); + } +} + +void ServerGame::processLevelLoadLine(int argc, const char **argv) +{ + if(!stricmp(argv[0], "GridSize")) + { + if(argc < 2) + return; + mGridSize = atof(argv[1]); + } + else if(mGameType.isNull() || !mGameType->processLevelItem(argc, argv)) + { + TNL::Object *theObject = TNL::Object::create(argv[0]); + GameObject *object = dynamic_cast(theObject); + if(!object) + { + logprintf("Invalid object type in level file: %s", argv[0]); + delete theObject; + } + else + { + object->addToGame(this); + object->processArguments(argc - 1, argv + 1); + } + } +} + +void ServerGame::addClient(GameConnection *theConnection) +{ + for(S32 i = 0; i < mLevelList.size();i++) + theConnection->s2cAddLevel(mLevelNames[i], mLevelTypes[i]); + + if(mGameType.isValid()) + mGameType->serverAddClient(theConnection); + mPlayerCount++; +} + +void ServerGame::removeClient(GameConnection *theConnection) +{ + if(mGameType.isValid()) + mGameType->serverRemoveClient(theConnection); + mPlayerCount--; +} + +void ServerGame::idle(U32 timeDelta) +{ + mCurrentTime += timeDelta; + mNetInterface->checkBanlistTimeouts(timeDelta); + mNetInterface->checkIncomingPackets(); + Game::checkConnectionToMaster(timeDelta); + for(GameConnection *walk = GameConnection::getClientList(); walk ; walk = walk->getNextClient()) + walk->addToTimeCredit(timeDelta); + + for(S32 i = 0; i < mGameObjects.size(); i++) + { + if(mGameObjects[i]->getObjectTypeMask() & DeletedType) + continue; + + Move thisMove = mGameObjects[i]->getCurrentMove(); + thisMove.time = timeDelta; + mGameObjects[i]->setCurrentMove(thisMove); + mGameObjects[i]->idle(GameObject::ServerIdleMainLoop); + } + + processDeleteList(timeDelta); + mNetInterface->processConnections(); + + if(mLevelSwitchTimer.update(timeDelta)) + cycleLevel(); +} + +void ServerGame::gameEnded() +{ + mLevelSwitchTimer.reset(LevelSwitchTime); +} + +//----------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------- + +ClientGame::ClientGame(const Address &bindAddress) + : Game(bindAddress) +{ + mInCommanderMap = false; + mCommanderZoomDelta = 0; + // create random stars + for(U32 i = 0; i < NumStars; i++) + { + mStars[i].x = Random::readF(); + mStars[i].y = Random::readF(); + } +} + +bool ClientGame::hasValidControlObject() +{ + return mConnectionToServer.isValid() && mConnectionToServer->getControlObject(); +} + +bool ClientGame::isConnectedToServer() +{ + return mConnectionToServer.isValid() && mConnectionToServer->getConnectionState() == NetConnection::Connected; +} + +GameConnection *ClientGame::getConnectionToServer() +{ + return mConnectionToServer; +} + +void ClientGame::setConnectionToServer(GameConnection *theConnection) +{ + TNLAssert(mConnectionToServer.isNull(), "Error, a connection already exists here."); + mConnectionToServer = theConnection; +} + +extern void JoystickUpdateMove( Move *theMove ); + +void ClientGame::idle(U32 timeDelta) +{ + mCurrentTime += timeDelta; + mNetInterface->checkIncomingPackets(); + + Game::checkConnectionToMaster(timeDelta); + + // only update at most MaxMoveTime milliseconds; + if(timeDelta > Move::MaxMoveTime) + timeDelta = Move::MaxMoveTime; + + if(!mInCommanderMap && mCommanderZoomDelta != 0) + { + if(timeDelta > mCommanderZoomDelta) + mCommanderZoomDelta = 0; + else + mCommanderZoomDelta -= timeDelta; + } + else if(mInCommanderMap && mCommanderZoomDelta != CommanderMapZoomTime) + { + mCommanderZoomDelta += timeDelta; + if(mCommanderZoomDelta > CommanderMapZoomTime) + mCommanderZoomDelta = CommanderMapZoomTime; + } + + Move *theMove = gGameUserInterface.getCurrentMove(); + + if(OptionsMenuUserInterface::joystickType != -1) + JoystickUpdateMove(theMove); + + theMove->time = timeDelta; + + if(mConnectionToServer.isValid()) + { + mConnectionToServer->addPendingMove(theMove); + GameObject *controlObject = mConnectionToServer->getControlObject(); + + theMove->prepare(); + + for(S32 i = 0; i < mGameObjects.size(); i++) + { + if(mGameObjects[i]->getObjectTypeMask() & DeletedType) + continue; + + if(mGameObjects[i] == controlObject) + { + mGameObjects[i]->setCurrentMove(*theMove); + mGameObjects[i]->idle(GameObject::ClientIdleControlMain); + } + else + { + Move m = mGameObjects[i]->getCurrentMove(); + m.time = timeDelta; + mGameObjects[i]->setCurrentMove(m); + mGameObjects[i]->idle(GameObject::ClientIdleMainRemote); + } + } + + if(controlObject) + SFXObject::setListenerParams(controlObject->getRenderPos(),controlObject->getRenderVel()); + } + processDeleteList(timeDelta); + FXManager::tick((F32)timeDelta * 0.001f); + SFXObject::process(); + + mNetInterface->processConnections(); +} + +void ClientGame::zoomCommanderMap() +{ + mInCommanderMap = !mInCommanderMap; + if(mInCommanderMap) + SFXObject::play(SFXUICommUp); + else + SFXObject::play(SFXUICommDown); + + + GameConnection *conn = getConnectionToServer(); + + if(conn) + { + if(mInCommanderMap) + conn->c2sRequestCommanderMap(); + else + conn->c2sReleaseCommanderMap(); + } +} + +void ClientGame::drawStars(F32 alphaFrac, Point cameraPos, Point visibleExtent) +{ + F32 starChunkSize = 1024; + + Point upperLeft = cameraPos - visibleExtent * 0.5f; + Point lowerRight = cameraPos + visibleExtent * 0.5f; + + upperLeft *= 1 / starChunkSize; + lowerRight *= 1 / starChunkSize; + + upperLeft.x = floor(upperLeft.x); + upperLeft.y = floor(upperLeft.y); + + lowerRight.x = floor(lowerRight.x) + 0.5; + lowerRight.y = floor(lowerRight.y) + 0.5; + + // render the stars + glPointSize( 1.0f ); + glColor3f(0.8 * alphaFrac, 0.8 * alphaFrac, 1.0 * alphaFrac); + + glPointSize(1); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, sizeof(Point), &mStars[0]); + + for(F32 xPage = upperLeft.x; xPage < lowerRight.x; xPage++) + { + for(F32 yPage = upperLeft.y; yPage < lowerRight.y; yPage++) + { + glPushMatrix(); + glScalef(starChunkSize, starChunkSize, 1); + glTranslatef(xPage, yPage, 0); + //glTranslatef(-xPage * starChunkSize, -yPage * starChunkSize, 0); + glDrawArrays(GL_POINTS, 0, NumStars); + glPopMatrix(); + } + } + + glDisableClientState(GL_VERTEX_ARRAY); +} + +S32 QSORT_CALLBACK renderSortCompare(GameObject **a, GameObject **b) +{ + return (*a)->getRenderSortValue() - (*b)->getRenderSortValue(); +} + +Point ClientGame::computePlayerVisArea(Ship *player) +{ + F32 fraction = player->getSensorZoomFraction(); + bool sensActive = player->isSensorActive(); + + Point ret; + Point regVis(PlayerHorizVisDistance, PlayerVertVisDistance); + Point sensVis(PlayerSensorHorizVisDistance, PlayerSensorVertVisDistance); + if(sensActive) + return regVis + (sensVis - regVis) * fraction; + else + return sensVis + (regVis - sensVis) * fraction; +} + +Point ClientGame::worldToScreenPoint(Point p) +{ + GameObject *controlObject = mConnectionToServer->getControlObject(); + Ship *u = (Ship *) controlObject; + Point position = u->getRenderPos(); + + if(mCommanderZoomDelta) + { + F32 zoomFrac = getCommanderZoomFraction(); + Point worldCenter = mWorldBounds.getCenter(); + Point worldExtents = mWorldBounds.getExtents(); + worldExtents.x *= UserInterface::canvasWidth / F32(UserInterface::canvasWidth - (UserInterface::horizMargin * 2)); + worldExtents.y *= UserInterface::canvasHeight / F32(UserInterface::canvasHeight - (UserInterface::vertMargin * 2)); + + F32 aspectRatio = worldExtents.x / worldExtents.y; + F32 screenAspectRatio = UserInterface::canvasWidth / F32(UserInterface::canvasHeight); + if(aspectRatio > screenAspectRatio) + worldExtents.y *= aspectRatio / screenAspectRatio; + else + worldExtents.x *= screenAspectRatio / aspectRatio; + + Point offset = (worldCenter - position) * zoomFrac + position; + Point visSize = computePlayerVisArea(u) * 2; + Point modVisSize = (worldExtents - visSize) * zoomFrac + visSize; + + Point visScale(UserInterface::canvasWidth / modVisSize.x, + UserInterface::canvasHeight / modVisSize.y ); + + Point ret = (p - offset) * visScale + Point(400, 300); + return ret; + } + else + { + Point visExt = computePlayerVisArea((Ship *) u); + Point scaleFactor(400 / visExt.x, 300 / visExt.y); + Point ret = (p - position) * scaleFactor + Point(400, 300); + return ret; + } +} + +void ClientGame::renderCommander() +{ + GameObject *controlObject = mConnectionToServer->getControlObject(); + Ship *u = (Ship *) controlObject; + + Point position = u->getRenderPos(); + + F32 zoomFrac = getCommanderZoomFraction(); + // Set up the view to show the whole level. + Rect worldBounds = computeWorldObjectExtents(); + mWorldBounds = worldBounds; + + Point worldCenter = worldBounds.getCenter(); + Point worldExtents = worldBounds.getExtents(); + worldExtents.x *= UserInterface::canvasWidth / F32(UserInterface::canvasWidth - (UserInterface::horizMargin * 2)); + worldExtents.y *= UserInterface::canvasHeight / F32(UserInterface::canvasHeight - (UserInterface::vertMargin * 2)); + + F32 aspectRatio = worldExtents.x / worldExtents.y; + F32 screenAspectRatio = UserInterface::canvasWidth / F32(UserInterface::canvasHeight); + if(aspectRatio > screenAspectRatio) + worldExtents.y *= aspectRatio / screenAspectRatio; + else + worldExtents.x *= screenAspectRatio / aspectRatio; + + Point offset = (worldCenter - position) * zoomFrac + position; + Point visSize = computePlayerVisArea(u) * 2; + Point modVisSize = (worldExtents - visSize) * zoomFrac + visSize; + + Point visScale(UserInterface::canvasWidth / modVisSize.x, + UserInterface::canvasHeight / modVisSize.y ); + + glPushMatrix(); + glTranslatef(400, 300, 0); + + glScalef(visScale.x, visScale.y, 1); + glTranslatef(-offset.x, -offset.y, 0); + + if(zoomFrac < 0.95) + drawStars(1 - zoomFrac, offset, modVisSize); + + // render the objects + Vector renderObjects; + mDatabase.findObjects( CommandMapVisType, renderObjects, worldBounds); + + // Deal with rendering sensor volumes + + // get info about the current player + GameType *gt = gClientGame->getGameType(); + + if(gt) + { + S32 playerTeam = u->getTeam(); + Color teamColor = gt->getTeamColor(playerTeam); + + F32 colorFactor = zoomFrac * 0.35; + + glColor(teamColor * colorFactor); + + for(S32 i = 0; i < renderObjects.size(); i++) + { + // If it's a ship, add it to the list. + + if(renderObjects[i]->getObjectTypeMask() & ShipType) + { + Ship * so = (Ship*)(renderObjects[i]); + // Get team of this object. + S32 ourTeam = so->getTeam(); + + if(ourTeam == playerTeam) + { + Point p = so->getRenderPos(); + Point visExt = computePlayerVisArea(so); + + glBegin(GL_POLYGON); + glVertex2f(p.x - visExt.x, p.y - visExt.y); + glVertex2f(p.x + visExt.x, p.y - visExt.y); + glVertex2f(p.x + visExt.x, p.y + visExt.y); + glVertex2f(p.x - visExt.x, p.y + visExt.y); + glEnd(); + + } + } + } + } + + renderObjects.sort(renderSortCompare); + + for(S32 i = 0; i < renderObjects.size(); i++) + renderObjects[i]->render(0); + for(S32 i = 0; i < renderObjects.size(); i++) + renderObjects[i]->render(1); + + glPopMatrix(); +} + +void ClientGame::renderNormal() +{ + GameObject *u = mConnectionToServer->getControlObject(); + Point position = u->getRenderPos(); + + glPushMatrix(); + glTranslatef(400, 300, 0); + + Point visExt = computePlayerVisArea((Ship *) u); + glScalef(400 / visExt.x, 300 / visExt.y, 1); + + glTranslatef(-position.x, -position.y, 0); + + drawStars(1.0, position, visExt * 2); + + // render the objects + Vector renderObjects; + + Point screenSize = visExt; + Rect extentRect(position - screenSize, position + screenSize); + mDatabase.findObjects(AllObjectTypes, renderObjects, extentRect); // + + renderObjects.sort(renderSortCompare); + + for(S32 i = 0; i < renderObjects.size(); i++) + renderObjects[i]->render(0); + FXManager::render(0); + for(S32 i = 0; i < renderObjects.size(); i++) + renderObjects[i]->render(1); + FXManager::render(1); + + FXTrail::renderTrails(); + + glPopMatrix(); + + // Render current ship's energy, too. + if(mConnectionToServer.isValid()) + { + Ship *s = dynamic_cast(mConnectionToServer->getControlObject()); + if(s) + { + //static F32 curEnergy = 0.f; + + //curEnergy = (curEnergy + s->mEnergy) * 0.5f; + F32 energy = s->mEnergy / F32(Ship::EnergyMax); + U32 totalLineCount = 100; + + F32 full = energy * totalLineCount; + glBegin(GL_POLYGON); + glColor3f(0, 0, 1); + glVertex2f(UserInterface::horizMargin, UserInterface::canvasHeight - UserInterface::vertMargin - 20); + glVertex2f(UserInterface::horizMargin, UserInterface::canvasHeight - UserInterface::vertMargin); + glColor3f(0, 1, 1); + glVertex2f(UserInterface::horizMargin + full * 2, UserInterface::canvasHeight - UserInterface::vertMargin); + glVertex2f(UserInterface::horizMargin + full * 2, UserInterface::canvasHeight - UserInterface::vertMargin - 20); + glEnd(); + + glColor3f(1, 1 ,1); + glBegin(GL_LINES); + glVertex2f(UserInterface::horizMargin, UserInterface::canvasHeight - UserInterface::vertMargin - 20); + glVertex2f(UserInterface::horizMargin, UserInterface::canvasHeight - UserInterface::vertMargin); + glVertex2f(UserInterface::horizMargin + totalLineCount * 2, UserInterface::canvasHeight - UserInterface::vertMargin - 20); + glVertex2f(UserInterface::horizMargin + totalLineCount * 2, UserInterface::canvasHeight - UserInterface::vertMargin); + // Show safety line. + glColor3f(1, 1, 0); + F32 cutoffx = (Ship::EnergyCooldownThreshold * totalLineCount * 2) / Ship::EnergyMax; + glVertex2f(UserInterface::horizMargin + cutoffx, UserInterface::canvasHeight - UserInterface::vertMargin - 23); + glVertex2f(UserInterface::horizMargin + cutoffx, UserInterface::canvasHeight - UserInterface::vertMargin + 4); + glEnd(); + } + } +} + +void ClientGame::render() +{ + if(!hasValidControlObject()) + return; + + if(mCommanderZoomDelta) + renderCommander(); + else + renderNormal(); +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/game.h b/tnl-1.5.0/tnl/zap/game.h new file mode 100644 index 0000000000000000000000000000000000000000..a8dab7f75f12a2c91be7015a01abfc8c28ac415b --- /dev/null +++ b/tnl-1.5.0/tnl/zap/game.h @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAME_H_ +#define _GAME_H_ + +#include "point.h" +#include "gameConnection.h" +#include "tnlNetObject.h" +#include "gridDB.h" +#include "timer.h" +#include "gameLoader.h" + +/// +/// Zap - a 2D space game demonstrating the full capabilities of the +/// Torque Network Library. +/// +/// The Zap example game is a 2D vector-graphics game that utilizes +/// some of the more advanced features of the TNL. Zap also demonstrates +/// the use of client-side prediction, and interpolation to present +/// a consistent simulation to clients over a connection with perceptible +/// latency. +/// +/// Zap can run in 3 modes - as a client, a client and server, or a dedicated +/// server. The dedicated server option is available only as a launch +/// parameter from the command line. +/// +/// If it is run as a client, Zap uses the GLUT library to perform +/// cross-platform window intialization, event processing and OpenGL setup. +/// +/// Zap implements a simple game framework. The GameObject class is +/// the root class for all of the various objects in the Zap world, including +/// Ship, Barrier and Projectile instances. The Game class, which is instanced +/// once for the client and once for the server, manages the current +/// list of GameObject instances. +/// +/// Zap clients can connect to servers directly that are on the same LAN +/// or for which the IP address is known. Zap is also capable of talking +/// to the TNL master server and using its arranged connection functionality +/// to talk to servers. +/// +/// The simplified user interface for Zap is managed entirely through +/// subclasses of the UserInterface class. Each UserInterface subclass +/// represents one "screen" in the UI. The GameUserInterface is the most complicated, +/// being responsible for the user interface while the client is actually +/// playing a game. The only other somewhat complicated UI is the +/// QueryServersUserInterface class, which implements a full server browser +/// for choosing from a list of LAN and master server queried servers. +/// +/// +namespace Zap +{ + +class MasterServerConnection; +class GameNetInterface; +class GameType; +class GameObject; +class GameConnection; + +/// Base class for server and client Game subclasses. The Game +/// base class manages all the objects in the game simulation on +/// either the server or the client, and is responsible for +/// managing the passage of time as well as rendering. + +class Game +{ +protected: + U32 mNextMasterTryTime; + F32 mGridSize; + + struct DeleteRef + { + SafePtr theObject; + U32 delay; + + DeleteRef(GameObject *o = NULL, U32 d = 0); + }; + + GridDatabase mDatabase; + Vector mGameObjects; + Vector mPendingDeleteObjects; + Vector > mScopeAlwaysList; + U32 mCurrentTime; + + RefPtr mNetInterface; + + SafePtr mConnectionToMaster; + SafePtr mGameType; +public: + enum + { + DefaultGridSize = 256, + PlayerHorizVisDistance = 600, + PlayerVertVisDistance = 450, + PlayerScopeMargin = 150, + PlayerSensorHorizVisDistance = 1060, + PlayerSensorVertVisDistance = 795, + MasterServerConnectAttemptDelay = 60000, + }; + + Game(const Address &theBindAddress); + virtual ~Game() {} + + Rect computeWorldObjectExtents(); + + void addToDeleteList(GameObject *theObject, U32 delay); + + void addToGameObjectList(GameObject *theObject); + void removeFromGameObjectList(GameObject *theObject); + void deleteObjects(U32 typeMask); + + void setGridSize(F32 gridSize) { mGridSize = gridSize; } + + F32 getGridSize() { return mGridSize; } + U32 getCurrentTime() { return mCurrentTime; } + virtual bool isServer() = 0; + virtual void idle(U32 timeDelta) = 0; + + void checkConnectionToMaster(U32 timeDelta); + MasterServerConnection *getConnectionToMaster(); + + GameNetInterface *getNetInterface(); + GridDatabase *getGridDatabase() { return &mDatabase; } + + const Vector > &getScopeAlwaysList() { return mScopeAlwaysList; } + + void setScopeAlwaysObject(GameObject *theObject); + GameType *getGameType(); + U32 getTeamCount(); + + void setGameType(GameType *theGameType); + + void processDeleteList(U32 timeDelta); +}; + +class ServerGame : public Game, public LevelLoader +{ + enum { + LevelSwitchTime = 5000, + }; + + U32 mPlayerCount; + U32 mMaxPlayers; + const char *mHostName; + Vector mLevelList; + Vector mLevelNames; + Vector mLevelTypes; + + U32 mCurrentLevelIndex; + Timer mLevelSwitchTimer; +public: + U32 getPlayerCount() { return mPlayerCount; } + U32 getMaxPlayers() { return mMaxPlayers; } + const char *getHostName() { return mHostName; } + bool isFull() { return mPlayerCount == mMaxPlayers; } + + void addClient(GameConnection *theConnection); + void removeClient(GameConnection *theConnection); + ServerGame(const Address &theBindAddress, U32 maxPlayers, const char *hostName); + + void setLevelList(const char *levelList); + void loadLevel(const char *fileName); + void cycleLevel(S32 newLevelIndex = -1); + StringTableEntry getLevelName(S32 index); + + void processLevelLoadLine(int argc, const char **argv); + bool isServer() { return true; } + void idle(U32 timeDelta); + void gameEnded(); +}; + +class Ship; +class ClientGame : public Game +{ + enum { + NumStars = 256, + }; + Point mStars[NumStars]; + Rect mWorldBounds; + + SafePtr mConnectionToServer; // If this is a client game, this is the connection to the server + bool mInCommanderMap; + enum { + CommanderMapZoomTime = 350, + }; + U32 mCommanderZoomDelta; +public: + ClientGame(const Address &bindAddress); + + bool hasValidControlObject(); + bool isConnectedToServer(); + + F32 getCommanderZoomFraction() { return mCommanderZoomDelta / F32(CommanderMapZoomTime); } + Point worldToScreenPoint(Point p); + void setConnectionToServer(GameConnection *connection); + void drawStars(F32 alphaFrac, Point cameraPos, Point visibleExtent); + GameConnection *getConnectionToServer(); + void render(); + void renderNormal(); + void renderCommander(); + bool isServer() { return false; } + void idle(U32 timeDelta); + void zoomCommanderMap(); + Point computePlayerVisArea(Ship *player); +}; + +extern ServerGame *gServerGame; +extern ClientGame *gClientGame; +extern Address gMasterAddress; + +extern void hostGame(bool dedicated, Address bindAddress); +extern void joinGame(Address remoteAddress, bool isFromMaster, bool local = false); +extern void endGame(); + +#define ZAP_GAME_STRING "ZAP 1.5.0" +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/gameConnection.cpp b/tnl-1.5.0/tnl/zap/gameConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ff170459f12a2ad93404fe763c5423b7f1f86aa8 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameConnection.cpp @@ -0,0 +1,440 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameConnection.h" +#include "game.h" +#include "gameType.h" +#include "gameNetInterface.h" + +#include "UIGame.h" +#include "UIMenus.h" +#include "UINameEntry.h" + +namespace Zap +{ +// Global list of clients (if we're a server). +GameConnection GameConnection::gClientList; + +extern const char *gServerPassword; +extern const char *gAdminPassword; + +TNL_IMPLEMENT_NETCONNECTION(GameConnection, NetClassGroupGame, true); + +GameConnection::GameConnection() +{ + mNext = mPrev = this; + setTranslatesStrings(); + mInCommanderMap = false; + mIsAdmin = false; +} + +GameConnection::~GameConnection() +{ + // unlink ourselves if we're in the client list + mPrev->mNext = mNext; + mNext->mPrev = mPrev; + + // Tell the user... + logprintf("%s disconnected", getNetAddress().toString()); +} + +/// Adds this connection to the doubly linked list of clients. +void GameConnection::linkToClientList() +{ + mNext = gClientList.mNext; + mPrev = gClientList.mNext->mPrev; + mNext->mPrev = this; + mPrev->mNext = this; +} + +GameConnection *GameConnection::getClientList() +{ + return gClientList.getNextClient(); +} + +GameConnection *GameConnection::getNextClient() +{ + if(mNext == &gClientList) + return NULL; + return mNext; +} + +void GameConnection::setClientRef(ClientRef *theRef) +{ + mClientRef = theRef; +} + +ClientRef *GameConnection::getClientRef() +{ + return mClientRef; +} + +TNL_IMPLEMENT_RPC(GameConnection, c2sAdminPassword, (StringPtr pass), (pass), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 1) +{ + if(gAdminPassword && !strcmp(gAdminPassword, pass)) + { + setIsAdmin(true); + static StringTableEntry msg("Administrator access granted."); + s2cDisplayMessage(ColorAqua, SFXIncomingMessage, msg); + s2cSetIsAdmin(); + } +} + +TNL_IMPLEMENT_RPC(GameConnection, c2sAdminPlayerAction, + (StringTableEntry playerName, U32 actionIndex), (playerName, actionIndex), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 1) +{ + if(isAdmin()) + { + GameConnection *theClient; + for(theClient = getClientList(); theClient; theClient = theClient->getNextClient()) + if(theClient->getClientName() == playerName) + break; + + if(!theClient) + return; + + StringTableEntry msg; + static StringTableEntry kickMessage("%e0 was kicked from the game by %e1."); + static StringTableEntry changeTeamMessage("%e0 was team changed by %e1."); + Vector e; + e.push_back(theClient->getClientName()); + e.push_back(getClientName()); + + switch(actionIndex) + { + case PlayerMenuUserInterface::ChangeTeam: + msg = changeTeamMessage; + { + GameType *gt = gServerGame->getGameType(); + gt->changeClientTeam(theClient); + } + break; + case PlayerMenuUserInterface::Kick: + { + msg = kickMessage; + if(theClient->isAdmin()) + { + static StringTableEntry nokick("Administrators cannot be kicked."); + s2cDisplayMessage(ColorAqua, SFXIncomingMessage, nokick); + return; + } + ConnectionParameters &p = theClient->getConnectionParameters(); + if(p.mIsArranged) + gServerGame->getNetInterface()->banHost(p.mPossibleAddresses[0], 30000); + gServerGame->getNetInterface()->banHost(theClient->getNetAddress(), 30000); + + theClient->disconnect("You were kicked from the game."); + break; + } + default: + return; + } + for(GameConnection *walk = getClientList(); walk; walk = walk->getNextClient()) + walk->s2cDisplayMessageE(ColorAqua, SFXIncomingMessage, msg, e); + } +} + +TNL_IMPLEMENT_RPC(GameConnection, s2cSetIsAdmin, (), (), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 1) +{ + setIsAdmin(true); +} + +TNL_IMPLEMENT_RPC(GameConnection, c2sRequestCommanderMap, (), (), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 1) +{ + mInCommanderMap = true; +} + +TNL_IMPLEMENT_RPC(GameConnection, c2sReleaseCommanderMap, (), (), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 1) +{ + mInCommanderMap = false; +} + +TNL_IMPLEMENT_RPC(GameConnection, c2sRequestLoadout, (Vector loadout), (loadout), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 1) +{ + mLoadout = loadout; + GameType *gt = gServerGame->getGameType(); + if(gt) + gt->clientRequestLoadout(this, mLoadout); +} + +static void displayMessage(U32 colorIndex, U32 sfxEnum, const char *message) +{ + static Color colors[] = + { + Color(1,1,1), + Color(1,0,0), + Color(0,1,0), + Color(0,0,1), + Color(0,1,1), + Color(1,1,0), + Color(0.6f, 1, 0.8f), + }; + gGameUserInterface.displayMessage(colors[colorIndex], "%s", message); + if(sfxEnum != SFXNone) + SFXObject::play(sfxEnum); +} + +TNL_IMPLEMENT_RPC(GameConnection, s2cDisplayMessageESI, + (RangedU32<0, GameConnection::ColorCount> color, RangedU32<0, NumSFXBuffers> sfx, StringTableEntry formatString, + Vector e, Vector s, Vector i), + (color, sfx, formatString, e, s, i), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 1) +{ + char outputBuffer[256]; + S32 pos = 0; + const char *src = formatString.getString(); + while(*src) + { + if(src[0] == '%' && (src[1] == 'e' || src[1] == 's' || src[1] == 'i') && (src[2] >= '0' && src[2] <= '9')) + { + S32 index = src[2] - '0'; + switch(src[1]) + { + case 'e': + if(index < e.size()) + pos += dSprintf(outputBuffer + pos, 256 - pos, "%s", e[index].getString()); + break; + case 's': + if(index < s.size()) + pos += dSprintf(outputBuffer + pos, 256 - pos, "%s", s[index].getString()); + break; + case 'i': + if(index < i.size()) + pos += dSprintf(outputBuffer + pos, 256 - pos, "%d", i[index]); + break; + } + src += 3; + } + else + outputBuffer[pos++] = *src++; + + if(pos >= 255) + break; + } + outputBuffer[pos] = 0; + displayMessage(color, sfx, outputBuffer); +} + +TNL_IMPLEMENT_RPC(GameConnection, s2cDisplayMessageE, + (RangedU32<0, GameConnection::ColorCount> color, RangedU32<0, NumSFXBuffers> sfx, StringTableEntry formatString, + Vector e), (color, sfx, formatString, e), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 1) +{ + char outputBuffer[256]; + S32 pos = 0; + const char *src = formatString.getString(); + while(*src) + { + if(src[0] == '%' && (src[1] == 'e') && (src[2] >= '0' && src[2] <= '9')) + { + S32 index = src[2] - '0'; + switch(src[1]) + { + case 'e': + if(index < e.size()) + pos += dSprintf(outputBuffer + pos, 256 - pos, "%s", e[index].getString()); + break; + } + src += 3; + } + else + outputBuffer[pos++] = *src++; + + if(pos >= 255) + break; + } + outputBuffer[pos] = 0; + displayMessage(color, sfx, outputBuffer); +} + +TNL_IMPLEMENT_RPC(GameConnection, s2cDisplayMessage, + (RangedU32<0, GameConnection::ColorCount> color, RangedU32<0, NumSFXBuffers> sfx, StringTableEntry formatString), + (color, sfx, formatString), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 1) +{ + char outputBuffer[256]; + S32 pos = 0; + const char *src = formatString.getString(); + while(*src) + { + outputBuffer[pos++] = *src++; + + if(pos >= 255) + break; + } + outputBuffer[pos] = 0; + displayMessage(color, sfx, outputBuffer); +} + + +TNL_IMPLEMENT_RPC(GameConnection, s2cAddLevel, (StringTableEntry name, StringTableEntry type), (name, type), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirServerToClient, 1) +{ + mLevelNames.push_back(name); + mLevelTypes.push_back(type); +} + +TNL_IMPLEMENT_RPC(GameConnection, c2sRequestLevelChange, (S32 newLevelIndex), (newLevelIndex), NetClassGroupGameMask, RPCGuaranteedOrdered, RPCDirClientToServer, 1) +{ + if(mIsAdmin) + { + static StringTableEntry msg("%e0 changed the level to %e1."); + Vector e; + e.push_back(getClientName()); + e.push_back(gServerGame->getLevelName(newLevelIndex)); + + gServerGame->cycleLevel(newLevelIndex); + for(GameConnection *walk = getClientList(); walk; walk = walk->getNextClient()) + walk->s2cDisplayMessageE(ColorYellow, SFXNone, msg, e); + + } +} + +void GameConnection::writeConnectRequest(BitStream *stream) +{ + Parent::writeConnectRequest(stream); + + stream->writeString(gPasswordEntryUserInterface.getText()); + stream->writeString(mClientName.getString()); +} + +bool GameConnection::readConnectRequest(BitStream *stream, const char **errorString) +{ + if(!Parent::readConnectRequest(stream, errorString)) + return false; + + if(gServerGame->isFull()) + { + *errorString = "Server Full."; + return false; + } + + // first read out the password. + char buf[256]; + + stream->readString(buf); + if(gServerPassword && stricmp(buf, gServerPassword)) + { + *errorString = "PASSWORD"; + return false; + } + + //now read the player name + stream->readString(buf); + size_t len = strlen(buf); + + if(len > 30) + len = 30; + + // strip leading and trailing spaces... + char *name = buf; + while(len && *name == ' ') + { + name++; + len--; + } + while(len && name[len-1] == ' ') + len--; + + // remove invisible chars + for(size_t i = 0; i < len; i++) + if(name[i] < ' ' || name[i] > 127) + name[i] = 'X'; + + name[len] = 0; + + U32 index = 0; + +checkPlayerName: + for(GameConnection *walk = getClientList(); walk; walk = walk->getNextClient()) + { + if(!strcmp(walk->mClientName.getString(), name)) + { + dSprintf(name + len, 3, ".%d", index); + index++; + goto checkPlayerName; + } + } + + mClientName = name; + return true; +} + +void GameConnection::onConnectionEstablished() +{ + Parent::onConnectionEstablished(); + + if(isInitiator()) + { + setGhostFrom(false); + setGhostTo(true); + logprintf("%s - connected to server.", getNetAddressString()); + setFixedRateParameters(50, 50, 2000, 2000); + } + else + { + linkToClientList(); + gServerGame->addClient(this); + setGhostFrom(true); + setGhostTo(false); + activateGhosting(); + logprintf("%s - client \"%s\" connected.", getNetAddressString(), mClientName.getString()); + setFixedRateParameters(50, 50, 2000, 2000); + } +} + +void GameConnection::onConnectionTerminated(NetConnection::TerminationReason r, const char *reason) +{ + if(isInitiator()) + { + gMainMenuUserInterface.activate(); + } + else + { + gServerGame->removeClient(this); + } +} + +void GameConnection::onConnectTerminated(TerminationReason r, const char *string) +{ + if(isInitiator()) + { + if(!strcmp(string, "PASSWORD")) + { + gPasswordEntryUserInterface.setConnectServer(getNetAddress()); + gPasswordEntryUserInterface.activate(); + } + else + gMainMenuUserInterface.activate(); + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/gameConnection.h b/tnl-1.5.0/tnl/zap/gameConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..68bf35616a64a2c8c75149a013c4e6eb8e38e236 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameConnection.h @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAMECONNECTION_H_ +#define _GAMECONNECTION_H_ + +#include "controlObjectConnection.h" +#include "sfx.h" + +namespace Zap +{ + +static char *gConnectStatesTable[] = { + "Not connected...", + "Sending challenge request.", + "Punching through firewalls.", + "Computing puzzle solution.", + "Sent connect request.", + "Connection timed out.", + "Connection rejected.", + "Connected.", + "Disconnected.", + "Connection timed out.", + "" +}; + +class ClientRef; + +class GameConnection : public ControlObjectConnection +{ + typedef ControlObjectConnection Parent; + + // The server maintains a linked list of clients... + GameConnection *mNext; + GameConnection *mPrev; + static GameConnection gClientList; + + bool mInCommanderMap; + bool mIsAdmin; + StringTableEntry mClientName; + Vector mLoadout; + SafePtr mClientRef; + + void linkToClientList(); +public: + Vector mLevelNames; + Vector mLevelTypes; + + enum MessageColors + { + ColorWhite, + ColorRed, + ColorGreen, + ColorBlue, + ColorAqua, + ColorYellow, + ColorNuclearGreen, + ColorCount, + }; + + GameConnection(); + ~GameConnection(); + + void setClientName(const char *string) { mClientName = string; } + void setClientRef(ClientRef *theRef); + ClientRef *getClientRef(); + + StringTableEntryRef getClientName() { return mClientName; } + + bool isAdmin() { return mIsAdmin; } + void setIsAdmin(bool admin) { mIsAdmin = admin; } + TNL_DECLARE_RPC(c2sAdminPassword, (StringPtr pass)); + TNL_DECLARE_RPC(s2cSetIsAdmin, ()); + TNL_DECLARE_RPC(c2sAdminPlayerAction, (StringTableEntry playerName, U32 actionIndex)); + + bool isInCommanderMap() { return mInCommanderMap; } + TNL_DECLARE_RPC(c2sRequestCommanderMap, ()); + TNL_DECLARE_RPC(c2sReleaseCommanderMap, ()); + + TNL_DECLARE_RPC(c2sRequestLoadout, (Vector loadout)); + + TNL_DECLARE_RPC(s2cDisplayMessageESI, (RangedU32<0, ColorCount> color, RangedU32<0, NumSFXBuffers> sfx, StringTableEntry formatString, + Vector e, Vector s, Vector i)); + TNL_DECLARE_RPC(s2cDisplayMessageE, (RangedU32<0, ColorCount> color, RangedU32<0, NumSFXBuffers> sfx, StringTableEntry formatString, + Vector e)); + TNL_DECLARE_RPC(s2cDisplayMessage, (RangedU32<0, ColorCount> color, RangedU32<0, NumSFXBuffers> sfx, StringTableEntry formatString)); + TNL_DECLARE_RPC(s2cAddLevel, (StringTableEntry name, StringTableEntry type)); + TNL_DECLARE_RPC(c2sRequestLevelChange, (S32 newLevelIndex)); + + static GameConnection *getClientList(); + GameConnection *getNextClient(); + + const Vector &getLoadout() { return mLoadout; } + void writeConnectRequest(BitStream *stream); + bool readConnectRequest(BitStream *stream, const char **errorString); + + void onConnectionEstablished(); + + void onConnectTerminated(TerminationReason r, const char *); + + void onConnectionTerminated(TerminationReason r, const char *string); + + TNL_DECLARE_NETCONNECTION(GameConnection); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/gameItems.cpp b/tnl-1.5.0/tnl/zap/gameItems.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36bbcf44245bdb60b4d61346ad76b36b1d0bdae3 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameItems.cpp @@ -0,0 +1,190 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "item.h" +#include "ship.h" +#include "glutInclude.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +class RepairItem : public PickupItem +{ +private: + typedef PickupItem Parent; + +public: + RepairItem(Point p = Point()) : PickupItem(p, 20) + { + mNetFlags.set(Ghostable); + } + + bool pickup(Ship *theShip) + { + if(theShip->getHealth() >= 1) + return false; + + DamageInfo di; + di.damageAmount = -0.5f; + di.damageType = 0; + di.damagingObject = this; + + theShip->damageObject(&di); + return true; + } + + void onClientPickup() + { + SFXObject::play(SFXShipHeal, getRenderPos(), getRenderVel()); + } + + U32 getRepopDelay() + { + return 20000; + } + + void renderItem(Point pos) + { + if(!isVisible()) + return; + renderRepairItem(pos); + } + + TNL_DECLARE_CLASS(RepairItem); +}; + +TNL_IMPLEMENT_NETOBJECT(RepairItem); + +class TestItem : public Item +{ +public: + TestItem() : Item(Point(0,0), true, 60, 4) + { + mNetFlags.set(Ghostable); + mObjectTypeMask |= TestItemType; + } + + void renderItem(Point pos) + { + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + + glColor3f(1, 1, 0); + glBegin(GL_LINE_LOOP); + + glVertex2f(-60, 0); + glVertex2f(-40, 40); + glVertex2f(0, 60); + glVertex2f(40, 40); + glVertex2f(60, 0); + glVertex2f(40, -40); + glVertex2f(0, -60); + glVertex2f(-40, -40); + + glEnd(); + glPopMatrix(); + } + + void damageObject(DamageInfo *theInfo) + { + // compute impulse direction + Point dv = theInfo->impulseVector - mMoveState[ActualState].vel; + Point iv = mMoveState[ActualState].pos - theInfo->collisionPoint; + iv.normalize(); + mMoveState[ActualState].vel += iv * dv.dot(iv) * 0.3; + } + + TNL_DECLARE_CLASS(TestItem); +}; + +TNL_IMPLEMENT_NETOBJECT(TestItem); + +class ResourceItem : public Item +{ +public: + ResourceItem() : Item(Point(0,0), true, 20, 1) + { + mNetFlags.set(Ghostable); + mObjectTypeMask |= ResourceItemType; + } + + void renderItem(Point pos) + { + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + + glColor3f(1,1,1); + glBegin(GL_LINE_LOOP); + glVertex2f(-8, 8); + glVertex2f(0, 20); + glVertex2f(8, 8); + glVertex2f(20, 0); + glVertex2f(8, -8); + glVertex2f(0, -20); + glVertex2f(-8, -8); + glVertex2f(-20, 0); + glEnd(); + + glPopMatrix(); + } + + bool collide(GameObject *hitObject) + { + if(mIsMounted) + return false; + + if(!(hitObject->getObjectTypeMask() & ShipType)) + return true; + + Ship *ship = (Ship *) hitObject; + if(ship->hasExploded) + return false; + + if(ship->hasEngineeringModule() && !ship->carryingResource()) + { + if(!isGhost()) + mountToShip(ship); + return false; + } + return true; + } + + void damageObject(DamageInfo *theInfo) + { + // compute impulse direction + Point dv = theInfo->impulseVector - mMoveState[ActualState].vel; + Point iv = mMoveState[ActualState].pos - theInfo->collisionPoint; + iv.normalize(); + mMoveState[ActualState].vel += iv * dv.dot(iv) * 0.3; + } + TNL_DECLARE_CLASS(ResourceItem); +}; + +TNL_IMPLEMENT_NETOBJECT(ResourceItem); + +}; + diff --git a/tnl-1.5.0/tnl/zap/gameLoader.cpp b/tnl-1.5.0/tnl/zap/gameLoader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5f27ea83934567f7069982adea0920a948a40b02 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameLoader.cpp @@ -0,0 +1,187 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameLoader.h" +#include "tnl.h" +#include "tnlLog.h" + +#include + +using namespace TNL; +namespace Zap +{ + +enum { + MaxArgc = 128, + MaxArgLen = 100, +}; + +static char *argv[MaxArgc]; +static char argv_buffer[MaxArgc][MaxArgLen]; +static int argc; +static int argLen = 0; +static const char *argString; + +inline char getNextChar() +{ + while(*argString == '\r') + argString++; + return *argString++; +} + +inline void addCharToArg(char c) +{ + if(argc < MaxArgc && argLen < MaxArgLen-1) + { + argv[argc][argLen] = c; + argLen++; + } +} + +inline void addArg() +{ + if(argc < MaxArgc) + { + argv[argc][argLen] = 0; + argc++; + argLen = 0; + } +} + +int LevelLoader::parseArgs(const char *string) +{ + int numObjects = 0; + + argc = 0; + argLen = 0; + argString = string; + char c; + + for(U32 i = 0; i < MaxArgc; i++) + argv[i] = argv_buffer[i]; + +stateEatingWhitespace: + c = getNextChar(); + if(c == ' ' || c == '\t') + goto stateEatingWhitespace; + if(c == '\n' || !c) + goto stateLineParseDone; + if(c == '\"') + goto stateReadString; + if(c == '#') + goto stateEatingComment; +stateAddCharToIdent: + addCharToArg(c); + c = getNextChar(); + if(c == ' ' || c == '\t') + { + addArg(); + goto stateEatingWhitespace; + } + if(c == '\n' || !c) + { + addArg(); + goto stateLineParseDone; + } + if(c == '\"') + { + addArg(); + goto stateReadString; + } + goto stateAddCharToIdent; +stateReadString: + c = getNextChar(); + if(c == '\"') + { + addArg(); + goto stateEatingWhitespace; + } + if(c == '\n' || !c) + { + addArg(); + goto stateLineParseDone; + } + if(c == '\\') + { + c = getNextChar(); + if(c == 'n') + { + addCharToArg('\n'); + goto stateReadString; + } + if(c == 't') + { + addCharToArg('\t'); + goto stateReadString; + } + if(c == '\\') + { + addCharToArg('\\'); + goto stateReadString; + } + if(c == '\n' || !c) + { + addArg(); + goto stateLineParseDone; + } + } + addCharToArg(c); + goto stateReadString; +stateEatingComment: + c = getNextChar(); + if(c != '\n' && c) + goto stateEatingComment; +stateLineParseDone: + if(argc) + processLevelLoadLine(argc, (const char **) argv); + argc = 0; + argLen = 0; + if(c) + goto stateEatingWhitespace; + return numObjects; +} + +void LevelLoader::initLevelFromFile(const char *file) +{ + FILE *f = fopen(file, "r"); + if(!f) + { + logprintf("Unable to open level file %s!!", file); + return; + } + + char fileData[32768]; + + size_t bytesRead = fread(fileData, 1, sizeof(fileData), f); + fileData[bytesRead] = 0; + + parseArgs(fileData); + + fclose(f); +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/gameLoader.h b/tnl-1.5.0/tnl/zap/gameLoader.h new file mode 100644 index 0000000000000000000000000000000000000000..ea355aecbc4220940ff557f9c1e3e36faa7c07d6 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameLoader.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ +#ifndef _GAMELOADER_H_ +#define _GAMELOADER_H_ + +namespace Zap +{ + +class LevelLoader +{ +protected: + virtual void processLevelLoadLine(int argc, const char **argv) = 0; + + int parseArgs(const char *string); +public: + void initLevelFromFile(const char *file); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/gameNetInterface.cpp b/tnl-1.5.0/tnl/zap/gameNetInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09446ae5673884674cdd05170145dd1d54777da9 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameNetInterface.cpp @@ -0,0 +1,178 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameNetInterface.h" +#include "UIQueryServers.h" +#include "game.h" + +namespace Zap +{ + +extern const char *gServerPassword; +extern bool gDedicatedServer; + +GameNetInterface::GameNetInterface(const Address &bindAddress, Game *theGame) + : NetInterface(bindAddress) +{ + mGame = theGame; +}; + +void GameNetInterface::banHost(const Address &bannedAddress, U32 bannedMilliseconds) +{ + BannedHost h; + h.theAddress = bannedAddress; + h.banDuration = bannedMilliseconds; + mBanList.push_back(h); +} + +bool GameNetInterface::isHostBanned(const Address &theAddress) +{ + for(S32 i = 0; i < mBanList.size(); i++) + if(theAddress.isEqualAddress(mBanList[i].theAddress)) + return true; + return false; +} + +void GameNetInterface::processPacket(const Address &sourceAddress, BitStream *pStream) +{ + for(S32 i = 0; i < mBanList.size(); i++) + if(sourceAddress.isEqualAddress(mBanList[i].theAddress)) + return; + Parent::processPacket(sourceAddress, pStream); +} + +void GameNetInterface::checkBanlistTimeouts(U32 timeElapsed) +{ + for(S32 i = 0; i < mBanList.size(); ) + { + if(mBanList[i].banDuration < timeElapsed) + mBanList.erase_fast(i); + else + { + mBanList[i].banDuration -= timeElapsed; + i++; + } + } +} + +void GameNetInterface::handleInfoPacket(const Address &remoteAddress, U8 packetType, BitStream *stream) +{ + switch(packetType) + { + case Ping: + logprintf("Got ping packet from %s", remoteAddress.toString()); + if(mGame->isServer()) + { + Nonce clientNonce; + clientNonce.read(stream); + char string[256]; + stream->readString(string); + if(strcmp(string, ZAP_GAME_STRING)) + break; + + U32 token = computeClientIdentityToken(remoteAddress, clientNonce); + PacketStream pingResponse; + pingResponse.write(U8(PingResponse)); + clientNonce.write(&pingResponse); + pingResponse.write(token); + pingResponse.sendto(mSocket, remoteAddress); + } + break; + case PingResponse: + { + logprintf("Got ping response from %s", remoteAddress.toString()); + Nonce theNonce; + U32 clientIdentityToken; + theNonce.read(stream); + stream->read(&clientIdentityToken); + gQueryServersUserInterface.gotPingResponse(remoteAddress, theNonce, clientIdentityToken); + } + break; + case Query: + { + logprintf("Got query from %s", remoteAddress.toString()); + Nonce theNonce; + U32 clientIdentityToken; + theNonce.read(stream); + stream->read(&clientIdentityToken); + if(clientIdentityToken == computeClientIdentityToken(remoteAddress, theNonce)) + { + PacketStream queryResponse; + queryResponse.write(U8(QueryResponse)); + theNonce.write(&queryResponse); + queryResponse.writeString(gServerGame->getHostName(), QueryServersUserInterface::MaxServerNameLen); + queryResponse.write(gServerGame->getPlayerCount()); + queryResponse.write(gServerGame->getMaxPlayers()); + queryResponse.writeFlag(gDedicatedServer); + queryResponse.writeFlag(gServerPassword != NULL); + + queryResponse.sendto(mSocket, remoteAddress); + } + } + break; + case QueryResponse: + { + logprintf("Got query response from %s", remoteAddress.toString()); + Nonce theNonce; + char nameString[256]; + U32 playerCount, maxPlayers; + bool dedicated, passwordRequired; + theNonce.read(stream); + stream->readString(nameString); + stream->read(&playerCount); + stream->read(&maxPlayers); + dedicated = stream->readFlag(); + passwordRequired = stream->readFlag(); + gQueryServersUserInterface.gotQueryResponse(remoteAddress, theNonce, nameString, playerCount, maxPlayers, dedicated, passwordRequired); + } + break; + } +} + +void GameNetInterface::sendPing(const Address &theAddress, const Nonce &clientNonce) +{ + logprintf("pinging server %s...", theAddress.toString()); + + PacketStream packet; + packet.write(U8(Ping)); + clientNonce.write(&packet); + packet.writeString(ZAP_GAME_STRING); + packet.sendto(mSocket, theAddress); +} + +void GameNetInterface::sendQuery(const Address &theAddress, const Nonce &clientNonce, U32 identityToken) +{ + logprintf("querying server %s...", theAddress.toString()); + + PacketStream packet; + packet.write(U8(Query)); + clientNonce.write(&packet); + packet.write(identityToken); + packet.sendto(mSocket, theAddress); +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/gameNetInterface.h b/tnl-1.5.0/tnl/zap/gameNetInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..054c46a7236226431e60623f418b8ffd8dc995bb --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameNetInterface.h @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAMENETINTERFACE_H_ +#define _GAMENETINTERFACE_H_ + +#include "../tnl/tnlNetInterface.h" + +using namespace TNL; + +namespace Zap +{ + +class Game; + +class GameNetInterface : public NetInterface +{ + typedef NetInterface Parent; + Game *mGame; + + struct BannedHost { + Address theAddress; + U32 banDuration; + }; + Vector mBanList; +public: + enum PacketType + { + Ping = FirstValidInfoPacketId, + PingResponse, + Query, + QueryResponse, + }; + GameNetInterface(const Address &bindAddress, Game *theGame); + void handleInfoPacket(const Address &remoteAddress, U8 packetType, BitStream *stream); + void sendPing(const Address &theAddress, const Nonce &clientNonce); + void sendQuery(const Address &theAddress, const Nonce &clientNonce, U32 identityToken); + void processPacket(const Address &sourceAddress, BitStream *pStream); + void banHost(const Address &bannedAddress, U32 bannedMilliseconds); + void checkBanlistTimeouts(U32 timeElapsed); + bool isHostBanned(const Address &theAddress); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/gameObject.cpp b/tnl-1.5.0/tnl/zap/gameObject.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2e63953d6adf053c1bec918305c6d8b8631ccea3 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameObject.cpp @@ -0,0 +1,378 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameObject.h" +#include "gameType.h" +#include "glutInclude.h" + +using namespace TNL; + +namespace Zap +{ + +GameObject::GameObject() +{ + mGame = NULL; + mTeam = -1; + mLastQueryId = 0; + mObjectTypeMask = UnknownType; + mDisableCollisionCount = 0; + mInDatabase = false; + mCreationTime = 0; +} + +void GameObject::setOwner(GameConnection *c) +{ + mOwner = c; +} + +GameConnection *GameObject::getOwner() +{ + return mOwner; +} + +void GameObject::setControllingClient(GameConnection *c) +{ + mControllingClient = c; +} + +void GameObject::deleteObject(U32 deleteTimeInterval) +{ + mObjectTypeMask = DeletedType; + if(!mGame) + delete this; + else + mGame->addToDeleteList(this, deleteTimeInterval); +} + +Point GameObject::getRenderPos() +{ + return extent.getCenter(); +} + +Point GameObject::getActualPos() +{ + return extent.getCenter(); +} + +void GameObject::setScopeAlways() +{ + getGame()->setScopeAlwaysObject(this); +} + +void GameObject::setActualPos(Point p) +{ +} + +F32 GameObject::getUpdatePriority(NetObject *scopeObject, U32 updateMask, S32 updateSkips) +{ + GameObject *so = (GameObject *) scopeObject; + + Point center = so->extent.getCenter(); + + Point nearest; + if(center.x < extent.min.x) + nearest.x = extent.min.x; + else if(center.x > extent.max.x) + nearest.x = extent.max.x; + else + nearest.x = center.x; + + if(center.y < extent.min.y) + nearest.y = extent.min.y; + else if(center.y > extent.max.y) + nearest.y = extent.max.y; + else + nearest.y = center.y; + + Point deltap = nearest - center; + + F32 distance = (nearest - center).len(); + + Point deltav = getActualVel() - so->getActualVel(); + + F32 add = 0; + + // initial scoping factor is distance based. + F32 distFactor = (500 - distance) / 500; + + // give some extra love to things that are moving towards the scope object + if(deltav.dot(deltap) < 0) + add = 0.7; + + // and a little more love if this object has not yet been scoped. + if(updateMask == 0xFFFFFFFF) + add += 0.5; + return distFactor + add + updateSkips * 0.5f; +} + +void GameObject::damageObject(DamageInfo *theInfo) +{ + +} + +static Vector fillVector; + +void GameObject::radiusDamage(Point pos, F32 innerRad, F32 outerRad, U32 typemask, DamageInfo &info, F32 force) +{ + // Check for players within range + // if so, blast them to death + Rect queryRect(pos, pos); + queryRect.expand(Point(outerRad, outerRad)); + + fillVector.clear(); + findObjects(typemask, fillVector, queryRect); + + // Ghosts can't do damage. + if(isGhost()) + info.damageAmount = 0; + + for(S32 i=0; igetActualPos(); + Point delta = objPos - pos; + + if(delta.len() > outerRad) + continue; + + // Can one damage another? + if(getGame()->getGameType()) + if(!getGame()->getGameType()->objectCanDamageObject(info.damagingObject, fillVector[i])) + continue; + + // Do an LOS check... + F32 t; + Point n; + + if(findObjectLOS(BarrierType, 0, pos, objPos, t, n)) + continue; + + // figure the impulse and damage + DamageInfo localInfo = info; + + // Figure collision forces... + localInfo.impulseVector = delta; + localInfo.impulseVector.normalize(); + + localInfo.collisionPoint = objPos; + localInfo.collisionPoint -= info.impulseVector; + + // Reuse t from above to represent interpolation based on distance. + F32 dist = delta.len(); + if(dist < innerRad) + t = 1.f; + else + t = 1.f - (dist - innerRad) / (outerRad - innerRad); + + // Scale stuff by distance. + localInfo.impulseVector *= force * t; + localInfo.damageAmount *= t; + + fillVector[i]->damageObject(&localInfo); + } +} + +GameConnection *GameObject::getControllingClient() +{ + return mControllingClient; +} + +void GameObject::setExtent(Rect &extents) +{ + if(mGame && mInDatabase) + { + // remove from the extents database for current extents + mGame->getGridDatabase()->removeFromExtents(this, extent); + // and readd for the new extent + mGame->getGridDatabase()->addToExtents(this, extents); + } + extent = extents; +} + +void GameObject::findObjects(U32 typeMask, Vector &fillVector, Rect &ext) +{ + if(!mGame) + return; + mGame->getGridDatabase()->findObjects(typeMask, fillVector, ext); +} + +GameObject *GameObject::findObjectLOS(U32 typeMask, U32 stateIndex, Point rayStart, Point rayEnd, float &collisionTime, Point &collisionNormal) +{ + if(!mGame) + return NULL; + return mGame->getGridDatabase()->findObjectLOS(typeMask, stateIndex, rayStart, rayEnd, collisionTime, collisionNormal); +} + +void GameObject::addToDatabase() +{ + if(!mInDatabase) + { + mInDatabase = true; + mGame->getGridDatabase()->addToExtents(this, extent); + } +} + +void GameObject::removeFromDatabase() +{ + if(mInDatabase) + { + mInDatabase = false; + mGame->getGridDatabase()->removeFromExtents(this, extent); + } +} + +void GameObject::addToGame(Game *theGame) +{ + TNLAssert(mGame == NULL, "Error, already in a game."); + theGame->addToGameObjectList(this); + mCreationTime = theGame->getCurrentTime(); + mGame = theGame; + addToDatabase(); + onAddedToGame(theGame); +} + +void GameObject::onAddedToGame(Game *) +{ +} + +void GameObject::removeFromGame() +{ + if(mGame) + { + removeFromDatabase(); + mGame->removeFromGameObjectList(this); + mGame = NULL; + } +} + +bool GameObject::getCollisionPoly(Vector &polyPoints) +{ + return false; +} + +bool GameObject::getCollisionCircle(U32 stateIndex, Point &point, float &radius) +{ + return false; +} + +Rect GameObject::getBounds(U32 stateIndex) +{ + Rect ret; + Point p; + float radius; + Vector bounds; + + if(getCollisionCircle(stateIndex, p, radius)) + { + ret.max = p + Point(radius, radius); + ret.min = p - Point(radius, radius); + } + else if(getCollisionPoly(bounds)) + { + ret.min = ret.max = bounds[0]; + for(S32 i = 1; i < bounds.size(); i++) + ret.unionPoint(bounds[i]); + } + return ret; +} + +void GameObject::render() +{ +} + +void GameObject::render(U32 layerIndex) +{ + if(layerIndex == 1) + render(); +} + +void GameObject::idle(IdleCallPath path) +{ +} + +void GameObject::writeControlState(BitStream *) +{ +} + +void GameObject::readControlState(BitStream *) +{ +} + +void GameObject::controlMoveReplayComplete() +{ +} + +void GameObject::writeCompressedVelocity(Point &vel, U32 max, BitStream *stream) +{ + U32 len = U32(vel.len()); + if(stream->writeFlag(len == 0)) + return; + + if(stream->writeFlag(len > max)) + { + stream->write(vel.x); + stream->write(vel.y); + } + else + { + F32 theta = atan2(vel.y, vel.x); + stream->writeFloat(theta * FloatInverse2Pi, 10); + stream->writeRangedU32(len, 0, max); + } +} + +void GameObject::readCompressedVelocity(Point &vel, U32 max, BitStream *stream) +{ + if(stream->readFlag()) + { + vel.x = vel.y = 0; + return; + } + else if(stream->readFlag()) + { + stream->read(&vel.x); + stream->read(&vel.y); + } + else + { + F32 theta = stream->readFloat(10) * Float2Pi; + F32 magnitude = stream->readRangedU32(0, max); + vel.set(cos(theta) * magnitude, sin(theta) * magnitude); + } +} + +void GameObject::processArguments(S32 argc, const char**argv) +{ +} + +bool GameObject::onGhostAdd(GhostConnection *theConnection) +{ + addToGame(gClientGame); + return true; +} + +}; diff --git a/tnl-1.5.0/tnl/zap/gameObject.h b/tnl-1.5.0/tnl/zap/gameObject.h new file mode 100644 index 0000000000000000000000000000000000000000..a32052bf9a14aa2ad8082167cc7c90368f8b2754 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameObject.h @@ -0,0 +1,191 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAMEOBJECT_H_ +#define _GAMEOBJECT_H_ + +#include "tnlTypes.h" +#include "point.h" +#include "gameConnection.h" +#include "tnlNetObject.h" +#include "game.h" +#include "move.h" + +namespace Zap +{ + +class GridDatabase; + +enum GameObjectType +{ + UnknownType = BIT(0), + ShipType = BIT(1), + BarrierType = BIT(2), + MoveableType = BIT(3), + ProjectileType = BIT(4), + ItemType = BIT(5), + ResourceItemType = BIT(6), + EngineeredType = BIT(7), + ForceFieldType = BIT(8), + LoadoutZoneType = BIT(9), + MineType = BIT(10), + TestItemType = BIT(11), + FlagType = BIT(12), + TurretTargetType = BIT(13), + + DeletedType = BIT(30), + CommandMapVisType = BIT(31), + DamagableTypes = ShipType | MoveableType | ProjectileType | ItemType | ResourceItemType | EngineeredType | MineType, + MotionTriggerTypes= ShipType | ResourceItemType | TestItemType, + AllObjectTypes = 0xFFFFFFFF, +}; + +class GameObject; +class Game; +class GameConnection; + +struct DamageInfo +{ + Point collisionPoint; + Point impulseVector; + float damageAmount; + U32 damageType; + GameObject *damagingObject; +}; + +class GameObject : public NetObject +{ + friend class GridDatabase; + + typedef NetObject Parent; + Game *mGame; + U32 mLastQueryId; + U32 mCreationTime; + SafePtr mControllingClient; + SafePtr mOwner; + U32 mDisableCollisionCount; + bool mInDatabase; + + Rect extent; +protected: + U32 mObjectTypeMask; + Move mLastMove; ///< the move for the previous update + Move mCurrentMove; ///< The move for the current update + S32 mTeam; +public: + + GameObject(); + ~GameObject() { removeFromGame(); } + + void addToGame(Game *theGame); + virtual void onAddedToGame(Game *theGame); + void removeFromGame(); + + Game *getGame() { return mGame; } + + void deleteObject(U32 deleteTimeInterval = 0); + U32 getCreationTime() { return mCreationTime; } + bool isInDatabase() { return mInDatabase; } + void setExtent(Rect &extentRect); + Rect getExtent() { return extent; } + S32 getTeam() { return mTeam; } + void findObjects(U32 typeMask, Vector &fillVector, Rect &extents); + GameObject *findObjectLOS(U32 typeMask, U32 stateIndex, Point rayStart, Point rayEnd, float &collisionTime, Point &collisionNormal); + + bool isControlled() { return mControllingClient.isValid(); } + void setControllingClient(GameConnection *c); + void setOwner(GameConnection *c); + + GameConnection *getControllingClient(); + GameConnection *getOwner(); + + U32 getObjectTypeMask() { return mObjectTypeMask; } + + F32 getUpdatePriority(NetObject *scopeObject, U32 updateMask, S32 updateSkips); + + virtual S32 getRenderSortValue() { return 0; } + virtual void render(); + + /// render is called twice for every object that is in the + /// render list. By default GameObject will call the render() + /// method one time (when layerIndex == 0). + virtual void render(U32 layerIndex); + + virtual bool getCollisionPoly(Vector &polyPoints); + virtual bool getCollisionCircle(U32 stateIndex, Point &point, float &radius); + Rect getBounds(U32 stateIndex); + + const Move &getCurrentMove() { return mCurrentMove; } + const Move &getLastMove() { return mLastMove; } + void setCurrentMove(const Move &theMove) { mCurrentMove = theMove; } + void setLastMove(const Move &theMove) { mLastMove = theMove; } + + enum IdleCallPath { + ServerIdleMainLoop, + ServerIdleControlFromClient, + ClientIdleMainRemote, + ClientIdleControlMain, + ClientIdleControlReplay, + }; + + virtual void idle(IdleCallPath path); + + virtual void writeControlState(BitStream *stream); + virtual void readControlState(BitStream *stream); + virtual F32 getHealth() { return 1; } + virtual bool isDestroyed() { return false; } + + virtual void controlMoveReplayComplete(); + + void writeCompressedVelocity(Point &vel, U32 max, BitStream *stream); + void readCompressedVelocity(Point &vel, U32 max, BitStream *stream); + + virtual Point getRenderPos(); + virtual Point getActualPos(); + virtual Point getRenderVel() { return Point(); } + virtual Point getActualVel() { return Point(); } + + virtual void setActualPos(Point p); + + virtual bool collide(GameObject *hitObject) { return false; } + + void radiusDamage(Point pos, F32 innerRad, F32 outerRad, U32 typemask, DamageInfo &info, F32 force = 2000.f); + virtual void damageObject(DamageInfo *damageInfo); + + bool onGhostAdd(GhostConnection *theConnection); + void disableCollision() { mDisableCollisionCount++; } + void enableCollision() { mDisableCollisionCount--; } + void addToDatabase(); + void removeFromDatabase(); + bool isCollisionEnabled() { return mDisableCollisionCount == 0; } + + virtual void processArguments(S32 argc, const char**argv); + void setScopeAlways(); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/gameObjectRender.cpp b/tnl-1.5.0/tnl/zap/gameObjectRender.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d6480e4f8147aa074fd2819114464e60c804d50e --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameObjectRender.cpp @@ -0,0 +1,635 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameObjectRender.h" +#include "glutInclude.h" +#include "tnlRandom.h" +#include "UI.h" +#include "projectile.h" + +namespace Zap +{ + +#ifdef TNL_OS_XBOX +const float gShapeLineWidth = 2.0f; +#else +const float gShapeLineWidth = 2.0f; +#endif + +void glVertex(Point p) +{ + glVertex2f(p.x, p.y); +} + +void glColor(Color c, float alpha) +{ + glColor4f(c.r, c.g, c.b, alpha); +} + +void drawCircle(Point pos, F32 radius) +{ + glBegin(GL_LINE_LOOP); + + for(F32 theta = 0; theta < 2 * 3.1415; theta += 0.2) + glVertex2f(pos.x + cos(theta) * radius, pos.y + sin(theta) * radius); + + glEnd(); +} + +void fillCircle(Point pos, F32 radius) +{ + glBegin(GL_POLYGON); + + for(F32 theta = 0; theta < 2 * 3.1415; theta += 0.2) + glVertex2f(pos.x + cos(theta) * radius, pos.y + sin(theta) * radius); + + glEnd(); +} + +void renderShip(Color c, F32 alpha, F32 thrusts[], F32 health, F32 radius, bool cloakActive, bool shieldActive) +{ + if(alpha != 1.0) + glEnable(GL_BLEND); + + if(cloakActive) + { + glColor4f(0,0,0, 1 - alpha); + glBegin(GL_POLYGON); + glVertex2f(-20, -15); + glVertex2f(0, 25); + glVertex2f(20, -15); + glEnd(); + } + + // first render the thrusters + + if(thrusts[0] > 0) // forward thrust: + { + glColor4f(1, 0, 0, alpha); + glBegin(GL_LINES); + glVertex2f(-8, -15); + glVertex2f(0, -15 - 20 * thrusts[0]); + glVertex2f(0, -15 - 20 * thrusts[0]); + glVertex2f(8, -15); + glEnd(); + glColor4f(1, 0.5, 0, alpha); + glBegin(GL_LINES); + glVertex2f(-6, -15); + glVertex2f(0, -15 - 15 * thrusts[0]); + glVertex2f(0, -15 - 15 * thrusts[0]); + glVertex2f(6, -15); + glEnd(); + glColor4f(1, 1, 0, alpha); + glBegin(GL_LINES); + glVertex2f(-4, -15); + glVertex2f(0, -15 - 8 * thrusts[0]); + glVertex2f(0, -15 - 8 * thrusts[0]); + glVertex2f(4, -15); + glEnd(); + } + if(thrusts[1] > 0) // back thrust + { + // two jets: + // left and right side: + // from 7.5, 10 -> 12.5, 10 and from -7.5, 10 to -12.5, 10 + glColor4f(1, 0.5, 0, alpha); + glBegin(GL_LINES); + glVertex2f(7.5, 10); + glVertex2f(10, 10 + thrusts[1] * 15); + glVertex2f(12.5, 10); + glVertex2f(10, 10 + thrusts[1] * 15); + glVertex2f(-7.5, 10); + glVertex2f(-10, 10 + thrusts[1] * 15); + glVertex2f(-12.5, 10); + glVertex2f(-10, 10 + thrusts[1] * 15); + glEnd(); + glColor4f(1,1,0, alpha); + glBegin(GL_LINES); + glVertex2f(9, 10); + glVertex2f(10, 10 + thrusts[1] * 10); + glVertex2f(11, 10); + glVertex2f(10, 10 + thrusts[1] * 10); + glVertex2f(-9, 10); + glVertex2f(-10, 10 + thrusts[1] * 10); + glVertex2f(-11, 10); + glVertex2f(-10, 10 + thrusts[1] * 10); + glEnd(); + + } + float xThrust = -12.5; + if(thrusts[3] > 0) + { + xThrust = -xThrust; + thrusts[2] = thrusts[3]; + } + if(thrusts[2] > 0) + { + glColor4f(1, 0, 0, alpha); + glBegin(GL_LINES); + glVertex2f(xThrust, 10); + glVertex2f(xThrust + thrusts[2] * xThrust * 1.5, 5); + glVertex2f(xThrust, 0); + glVertex2f(xThrust + thrusts[2] * xThrust * 1.5, 5); + glEnd(); + glColor4f(1,0.5,0, alpha); + glBegin(GL_LINES); + glVertex2f(xThrust, 8); + glVertex2f(xThrust + thrusts[2] * xThrust, 5); + glVertex2f(xThrust, 2); + glVertex2f(xThrust + thrusts[2] * xThrust, 5); + glEnd(); + glColor4f(1,1,0, alpha); + glBegin(GL_LINES); + glVertex2f(xThrust, 6); + glVertex2f(xThrust + thrusts[2] * xThrust * 0.5, 5); + glVertex2f(xThrust, 4); + glVertex2f(xThrust + thrusts[2] * xThrust * 0.5, 5); + glEnd(); + } + + // then render the ship: + glColor4f(0.5,0.5,0.5, alpha); + glBegin(GL_LINES); + glVertex2f(-12.5, 0); + glVertex2f(-12.5, 10); + glVertex2f(-12.5, 10); + glVertex2f(-7.5, 10); + glVertex2f(7.5, 10); + glVertex2f(12.5, 10); + glVertex2f(12.5, 10); + glVertex2f(12.5, 0); + glEnd(); + + glColor4f(c.r,c.g,c.b, alpha); + glBegin(GL_LINE_LOOP); + glVertex2f(-12, -13); + glVertex2f(0, 22); + glVertex2f(12, -13); + glEnd(); + + U32 lineCount = U32(14 * health); + glBegin(GL_LINES); + for(U32 i = 0; i < lineCount; i++) + { + S32 yo = i * 2; + glVertex2f(-2, -11 + yo); + glVertex2f(2, -11 + yo); + } + glEnd(); + + glColor4f(0.7,0.7,0.7, alpha); + glBegin(GL_LINE_LOOP); + glVertex2f(-20, -15); + glVertex2f(0, 25); + glVertex2f(20, -15); + glEnd(); + + // Render shield if appropriate + if(shieldActive) + { + F32 shieldRadius = radius + 3; + + glColor4f(1,1,0, alpha); + glBegin(GL_LINE_LOOP); + for(F32 theta = 0; theta <= 2 * 3.1415; theta += 0.3) + glVertex2f(cos(theta) * shieldRadius, sin(theta) * shieldRadius); + + glEnd(); + } + + + if(alpha != 1.0) + glDisable(GL_BLEND); +} + +void renderTeleporter(Point pos, U32 type, bool in, S32 time, F32 radiusFraction, F32 radius, F32 alpha) +{ + enum { + NumColors = 6, + NumTypes = 2, + NumParticles = 100, + }; + + static bool trackerInit = false; + + struct Tracker + { + F32 thetaI; + F32 thetaP; + F32 dI; + F32 dP; + U32 ci; + }; + static Tracker particles[NumParticles]; + + static float colors[NumTypes][NumColors][3] = { + { + { 0, 0.25, 0.8 }, + { 0, 0.5, 1 }, + { 0, 0, 1 }, + { 0, 1, 1 }, + { 0, 0.5, 0.5 }, + { 0, 0, 1 }, + }, + { + { 1, 0, 0.5 }, + { 1, 0, 1 }, + { 0, 0, 1 }, + { 0.5, 0, 1 }, + { 0, 0, 0.5 }, + { 1, 0, 0 }, + } + }; + if(!trackerInit) + { + trackerInit = true; + for(S32 i = 0; i < NumParticles; i++) + { + Tracker &t = particles[i]; + t.thetaI = Random::readF() * Float2Pi; + t.thetaP = Random::readF() * 2 + 0.5; + t.dP = Random::readF() * 5 + 2.5; + t.dI = Random::readF() * t.dP; + t.ci = Random::readI(0, NumColors - 1); + } + } + + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + + glEnable(GL_BLEND); + F32 arcTime = 0.5 + (1 - radiusFraction) * 0.5; + if(!in) + arcTime = -arcTime; + + Color tpColors[NumColors]; + Color white(1,1,1); + for(S32 i = 0; i < NumColors; i++) + { + Color c(colors[type][i][0], colors[type][i][1], colors[type][i][2]); + tpColors[i].interp(radiusFraction, c, white); + } + F32 beamWidth = 4; + + for(S32 i = 0; i < NumParticles; i++) + { + Tracker &t = particles[i]; + //glColor3f(t.c.r, t.c.g, t.c.b); + F32 d = (t.dP - fmod(float(t.dI + time * 0.001), (float) t.dP)) / t.dP; + F32 alphaMod = 1; + if(d > 0.9) + alphaMod = (1 - d) * 10; + + F32 theta = fmod(float( t.thetaI + time * 0.001 * t.thetaP), (float) Float2Pi); + F32 startRadius = radiusFraction * radius * d; + + Point start(cos(theta), sin(theta)); + Point n(-start.y, start.x); + + theta -= arcTime * t.thetaP * (alphaMod + 0.05); + d += arcTime / t.dP; + if(d < 0) + d = 0; + Point end(cos(theta), sin(theta)); + + F32 endRadius = radiusFraction * radius * d; + + glBegin(GL_TRIANGLE_STRIP); + glColor(tpColors[t.ci], alpha * alphaMod); + + F32 arcLength = (end * endRadius - start * startRadius).len(); + U32 vertexCount = floor(arcLength / 10) + 2; + + glVertex(start * (startRadius + beamWidth * 0.3) + n * 2); + glVertex(start * (startRadius - beamWidth * 0.3) + n * 2); + for(U32 j = 0; j <= vertexCount; j++) + { + F32 frac = j / F32(vertexCount); + F32 width = beamWidth * (1 - frac) * 0.5; + Point p = start * (1 - frac) + end * frac; + p.normalize(); + F32 rad = startRadius * (1 - frac) + endRadius * frac; + + p.normalize(); + glColor(tpColors[t.ci], alpha * alphaMod * (1 - frac)); + glVertex(p * (rad + width)); + glVertex(p * (rad - width)); + } + glEnd(); + } + glDisable(GL_BLEND); + glPopMatrix(); +} + +void renderTurret(Color c, Point anchor, Point normal, bool enabled, F32 health, F32 barrelAngle, F32 aimOffset) +{ + glColor(c); + + Point cross(normal.y, -normal.x); + Point aimCenter = anchor + normal * aimOffset; + + glBegin(GL_LINE_STRIP); + + for(S32 x = -10; x <= 10; x++) + { + F32 theta = x * FloatHalfPi * 0.1; + Point pos = normal * cos(theta) + cross * sin(theta); + glVertex(aimCenter + pos * 15); + } + glEnd(); + + glLineWidth(3); + glBegin(GL_LINES); + Point aimDelta(cos(barrelAngle), sin(barrelAngle)); + glVertex(aimCenter + aimDelta * 15); + glVertex(aimCenter + aimDelta * 30); + glEnd(); + glLineWidth(DefaultLineWidth); + + if(enabled) + glColor3f(1,1,1); + else + glColor3f(0.6, 0.6, 0.6); + glBegin(GL_LINE_LOOP); + glVertex(anchor + cross * 18); + glVertex(anchor + cross * 18 + normal * aimOffset); + glVertex(anchor - cross * 18 + normal * aimOffset); + glVertex(anchor - cross * 18); + glEnd(); + + glColor(c); + S32 lineHeight = U32(28 * health); + glBegin(GL_LINES); + for(S32 i = 0; i < lineHeight; i += 2) + { + Point lsegStart = anchor - cross * (14 - i) + normal * 5; + Point lsegEnd = lsegStart + normal * (aimOffset - 10); + glVertex(lsegStart); + glVertex(lsegEnd); + } + Point lsegStart = anchor - cross * 14 + normal * 3; + Point lsegEnd = anchor + cross * 14 + normal * 3; + Point n = normal * (aimOffset - 6); + glVertex(lsegStart); + glVertex(lsegEnd); + glVertex(lsegStart + n); + glVertex(lsegEnd + n); + glEnd(); +} + +void renderFlag(Point pos, Color c) +{ + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + + glColor3f(c.r, c.g, c.b); + glBegin(GL_LINES); + glVertex2f(-15, -15); + glVertex2f(15, -5); + + glVertex2f(15, -5); + glVertex2f(-15, 5); + + glVertex2f(-15, -10); + glVertex2f(10, -5); + + glVertex2f(10, -5); + glVertex2f(-15, 0); + glColor3f(1,1,1); + glVertex2f(-15, -15); + glVertex2f(-15, 15); + glEnd(); + + glPopMatrix(); +} + +void renderCenteredString(Point pos, U32 size, const char *string) +{ + F32 width = UserInterface::getStringWidth(size, string); + UserInterface::drawString(pos.x - width * 0.5, pos.y - size * 0.5, size, string); +} + +void renderLoadoutZone(Color theColor, Vector &bounds, Rect extent) +{ + F32 alpha = 0.5; + glColor(theColor * 0.5); + glBegin(GL_POLYGON); + for(S32 i = 0; i < bounds.size(); i++) + glVertex2f(bounds[i].x, bounds[i].y); + glEnd(); + glColor(theColor * 0.7); + glBegin(GL_LINE_LOOP); + for(S32 i = 0; i < bounds.size(); i++) + glVertex2f(bounds[i].x, bounds[i].y); + glEnd(); + + Point extents = extent.getExtents(); + Point center = extent.getCenter(); + + glPushMatrix(); + glTranslatef(center.x, center.y, 0); + if(extents.x < extents.y) + glRotatef(90, 0, 0, 1); + glColor(theColor); + renderCenteredString(Point(0,0), 25, "LOADOUT ZONE"); + glPopMatrix(); +} + +void renderProjectile(Point pos, U32 type, U32 time) +{ + ProjectileInfo *pi = gProjInfo + type; + + glColor(pi->projColors[0]); + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + glScalef(pi->scaleFactor, pi->scaleFactor, 1); + + glPushMatrix(); + glRotatef((time % 720) * 0.5, 0, 0, 1); + + glBegin(GL_LINE_LOOP); + glVertex2f(-2, 2); + glVertex2f(0, 6); + glVertex2f(2, 2); + glVertex2f(6, 0); + glVertex2f(2, -2); + glVertex2f(0, -6); + glVertex2f(-2, -2); + glVertex2f(-6, 0); + glEnd(); + + glPopMatrix(); + + glRotatef(180 - (time % 360), 0, 0, 1); + glColor(pi->projColors[1]); + glBegin(GL_LINE_LOOP); + glVertex2f(-2, 2); + glVertex2f(0, 8); + glVertex2f(2, 2); + glVertex2f(8, 0); + glVertex2f(2, -2); + glVertex2f(0, -8); + glVertex2f(-2, -2); + glVertex2f(-8, 0); + glEnd(); + + glPopMatrix(); +} + +void renderMine(Point pos, bool armed, bool visible) +{ + F32 mod = 0.3; + if(visible) + { + glColor3f(0.5,0.5,0.5); + drawCircle(pos, Mine::SensorRadius); + mod = 1.0; + } + else + glLineWidth(1); + + glColor3f(mod,mod,mod); + drawCircle(pos, 10); + + if(armed) + { + glColor3f(mod,0,0); + drawCircle(pos, 6); + } + glLineWidth(DefaultLineWidth); +} + +void renderGrenade(Point pos) +{ + glColor3f(1,1,1); + drawCircle(pos, 10); + + glColor3f(1,0,0); + drawCircle(pos, 6); +} + + +void renderRepairItem(Point pos) +{ + glPushMatrix(); + glTranslatef(pos.x, pos.y, 0); + + glColor3f(1,1,1); + glBegin(GL_LINE_LOOP); + glVertex2f(-18, -18); + glVertex2f(18, -18); + glVertex2f(18, 18); + glVertex2f(-18, 18); + glEnd(); + + glColor3f(1,0,0); + glBegin(GL_LINE_LOOP); + + float crossWidth = 4; + float crossLen = 14; + + glVertex2f(crossWidth, crossWidth); + glVertex2f(crossLen, crossWidth); + glVertex2f(crossLen, -crossWidth); + glVertex2f(crossWidth, -crossWidth); + glVertex2f(crossWidth, -crossLen); + glVertex2f(-crossWidth, -crossLen); + glVertex2f(-crossWidth, -crossWidth); + glVertex2f(-crossLen, -crossWidth); + glVertex2f(-crossLen, crossWidth); + glVertex2f(-crossWidth, crossWidth); + glVertex2f(-crossWidth, crossLen); + glVertex2f(crossWidth, crossLen); + glEnd(); + + glPopMatrix(); +} + +void renderForceFieldProjector(Point pos, Point normal, Color c, bool enabled) +{ + Point cross(normal.y, -normal.x); + if(c.r < 0.7) + c.r = 0.7; + if(c.g < 0.7) + c.g = 0.7; + if(c.b < 0.7) + c.b = 0.7; + if(enabled) + glColor(c); + else + glColor(c * 0.6); + + glBegin(GL_LINE_LOOP); + glVertex(pos + cross * 12); + glVertex(pos + normal * 15); + glVertex(pos - cross * 12); + glEnd(); +} + +void renderForceField(Point start, Point end, Color c, bool fieldUp) +{ + if(c.r < 0.5) + c.r = 0.5; + if(c.g < 0.5) + c.g = 0.5; + if(c.b < 0.5) + c.b = 0.5; + + Point normal(end.y - start.y, start.x - end.x); + normal.normalize(2.5); + + if(fieldUp) + glColor(c); + else + glColor(c * 0.5); + glBegin(GL_LINE_LOOP); + glVertex(start + normal); + glVertex(end + normal); + glVertex(end - normal); + glVertex(start - normal); + glEnd(); +} + +void renderGoalZone(Vector &bounds, Color c, bool isFlashing) +{ + F32 alpha = 0.5; + glColor(c * 0.5f); + glBegin(GL_POLYGON); + for(S32 i = 0; i < bounds.size(); i++) + glVertex(bounds[i]); + glEnd(); + if(isFlashing) + glColor(c); + else + glColor(c * 0.7); + + glBegin(GL_LINE_LOOP); + for(S32 i = 0; i < bounds.size(); i++) + glVertex(bounds[i]); + glEnd(); +} + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/gameObjectRender.h b/tnl-1.5.0/tnl/zap/gameObjectRender.h new file mode 100644 index 0000000000000000000000000000000000000000..172702331014431fa43f4fd12136d4934f347acd --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameObjectRender.h @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAMEOBJECTRENDER_H_ +#define _GAMEOBJECTRENDER_H_ + +#include "point.h" +#include "tnl.h" +using namespace TNL; + +namespace Zap +{ + +extern void glVertex(Point p); +extern void glColor(Color c, float alpha = 1); +extern void drawCircle(Point pos, F32 radius); +extern void fillCircle(Point pos, F32 radius); + +extern void renderCenteredString(Point pos, U32 size, const char *string); +extern void renderShip(Color c, F32 alpha, F32 thrusts[], F32 health, F32 radius, bool cloakActive, bool shieldActive); +extern void renderTeleporter(Point pos, U32 type, bool in, S32 time, F32 radiusFraction, F32 radius, F32 alpha); +extern void renderTurret(Color c, Point anchor, Point normal, bool enabled, F32 health, F32 barrelAngle, F32 aimOffset); +extern void renderFlag(Point pos, Color c); +extern void renderLoadoutZone(Color c, Vector &bounds, Rect extent); +extern void renderProjectile(Point pos, U32 type, U32 time); +extern void renderMine(Point pos, bool armed, bool visible); +extern void renderGrenade(Point pos); +extern void renderRepairItem(Point pos); +extern void renderForceFieldProjector(Point pos, Point normal, Color teamColor, bool enabled); +extern void renderForceField(Point start, Point end, Color c, bool fieldUp); +extern void renderGoalZone(Vector &bounds, Color c, bool isFlashing); + +}; + +#endif \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/gameType.cpp b/tnl-1.5.0/tnl/zap/gameType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7af8042e3b6567d2f2a4ebd09e2233baace7c9d --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameType.cpp @@ -0,0 +1,1073 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameType.h" +#include "ship.h" +#include "UIGame.h" +#include "UIMenus.h" +#include "UINameEntry.h" +#include "gameNetInterface.h" +#include "flagItem.h" +#include "glutInclude.h" +#include "engineeredObjects.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(GameType); + +GameType::GameType() + : mScoreboardUpdateTimer(1000) + , mGameTimer(DefaultGameTime) + , mGameTimeUpdateTimer(30000) +{ + mNetFlags.set(Ghostable); + mGameOver = false; + mTeamScoreLimit = DefaultTeamScoreLimit; +} + +void GameType::processArguments(S32 argc, const char **argv) +{ + if(argc > 0) + mGameTimer.reset(U32(atof(argv[0]) * 60 * 1000)); + if(argc > 1) + mTeamScoreLimit = atoi(argv[1]); +} + +void GameType::idle(GameObject::IdleCallPath path) +{ + U32 deltaT = mCurrentMove.time; + mLevelInfoDisplayTimer.update(deltaT); + if(isGhost()) + { + mGameTimer.update(deltaT); + return; + } + queryItemsOfInterest(); + if(mScoreboardUpdateTimer.update(deltaT)) + { + mScoreboardUpdateTimer.reset(); + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->clientConnection) + { + mClientList[i]->ping = (U32) mClientList[i]->clientConnection->getRoundTripTime(); + if(mClientList[i]->ping > MaxPing) + mClientList[i]->ping = MaxPing; + } + } + for(S32 i = 0; i < mClientList.size(); i++) + if(mGameOver || mClientList[i]->wantsScoreboardUpdates) + updateClientScoreboard(mClientList[i]); + } + + if(mGameTimeUpdateTimer.update(deltaT)) + { + mGameTimeUpdateTimer.reset(); + s2cSetTimeRemaining(mGameTimer.getCurrent()); + } + + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->respawnTimer.update(deltaT)) + spawnShip(mClientList[i]->clientConnection); + } + + if(mGameTimer.update(deltaT)) + { + gameOverManGameOver(); + } +} + +void GameType::renderInterfaceOverlay(bool scoreboardVisible) +{ + if(mLevelInfoDisplayTimer.getCurrent() != 0) + { + F32 alpha = 1; + if(mLevelInfoDisplayTimer.getCurrent() < 1000) + alpha = mLevelInfoDisplayTimer.getCurrent() * 0.001f; + + glEnable(GL_BLEND); + glColor4f(1,1,1, alpha); + UserInterface::drawCenteredStringf(UserInterface::vertMargin + 90, 30, "Level: %s", mLevelName.getString()); + UserInterface::drawCenteredStringf(UserInterface::vertMargin + 130, 30, "Game Type: %s", getGameTypeString()); + UserInterface::drawCenteredString(UserInterface::canvasHeight - UserInterface::vertMargin - 90, 20, getInstructionString()); + UserInterface::drawCenteredString(UserInterface::canvasHeight - UserInterface::vertMargin - 60, 20, mLevelDescription.getString()); + glDisable(GL_BLEND); + } + if((mGameOver || scoreboardVisible) && mTeams.size() > 0) + { + U32 totalWidth = UserInterface::canvasWidth - UserInterface::horizMargin * 2; + U32 columnCount = mTeams.size(); + if(columnCount > 2) + columnCount = 2; + + U32 teamWidth = totalWidth / columnCount; + U32 maxTeamPlayers = 0; + countTeamPlayers(); + + for(S32 i = 0; i < mTeams.size(); i++) + if(mTeams[i].numPlayers > maxTeamPlayers) + maxTeamPlayers = mTeams[i].numPlayers; + + if(!maxTeamPlayers) + return; + + U32 teamAreaHeight = 40; + if(mTeams.size() < 2) + teamAreaHeight = 0; + + U32 numTeamRows = (mTeams.size() + 1) >> 1; + + U32 totalHeight = (UserInterface::canvasHeight - UserInterface::vertMargin * 2) / numTeamRows - (numTeamRows - 1) * 2; + U32 maxHeight = (totalHeight - teamAreaHeight) / maxTeamPlayers; + if(maxHeight > 30) + maxHeight = 30; + + U32 sectionHeight = (teamAreaHeight + maxHeight * maxTeamPlayers); + totalHeight = sectionHeight * numTeamRows + (numTeamRows - 1) * 2; + + for(S32 i = 0; i < mTeams.size(); i++) + { + U32 yt = (UserInterface::canvasHeight - totalHeight) / 2 + (i >> 1) * (sectionHeight + 2); + U32 yb = yt + sectionHeight; + U32 xl = 10 + (i & 1) * teamWidth; + U32 xr = xl + teamWidth - 2; + + Color c = mTeams[i].color; + glEnable(GL_BLEND); + + glColor4f(c.r, c.g, c.b, 0.6); + glBegin(GL_POLYGON); + glVertex2f(xl, yt); + glVertex2f(xr, yt); + glVertex2f(xr, yb); + glVertex2f(xl, yb); + glEnd(); + + glDisable(GL_BLEND); + + glColor3f(1,1,1); + if(teamAreaHeight) + { + renderFlag(Point(xl + 20, yt + 18), c); + renderFlag(Point(xr - 20, yt + 18), c); + + glColor3f(1,1,1); + glBegin(GL_LINES); + glVertex2f(xl, yt + teamAreaHeight); + glVertex2f(xr, yt + teamAreaHeight); + glEnd(); + + UserInterface::drawString(xl + 40, yt + 2, 30, mTeams[i].name.getString()); + + UserInterface::drawStringf(xr - 140, yt + 2, 30, "%d", mTeams[i].score); + } + + U32 curRowY = yt + teamAreaHeight + 1; + U32 fontSize = U32(maxHeight * 0.8f); + for(S32 j = 0; j < mClientList.size(); j++) + { + if(mClientList[j]->teamId == i) + { + UserInterface::drawString(xl + 40, curRowY, fontSize, mClientList[j]->name.getString()); + + static char buff[255] = ""; + dSprintf(buff, sizeof(buff), "%d", mClientList[j]->score); + + UserInterface::drawString(xr - (120 + UserInterface::getStringWidth(fontSize, buff)), curRowY, fontSize, buff); + UserInterface::drawStringf(xr - 70, curRowY, fontSize, "%d", mClientList[j]->ping); + curRowY += maxHeight; + } + } + } + } + else if(mTeams.size() > 1) + { + for(S32 i = 0; i < mTeams.size(); i++) + { + Point pos(UserInterface::canvasWidth - UserInterface::horizMargin - 35, UserInterface::canvasHeight - UserInterface::vertMargin - 60 - i * 38); + renderFlag(pos + Point(-20, 18), mTeams[i].color); + glColor3f(1,1,1); + UserInterface::drawStringf(U32(pos.x), U32(pos.y), 32, "%d", mTeams[i].score); + } + } + renderTimeLeft(); + renderTalkingClients(); +} + +void GameType::renderObjectiveArrow(GameObject *target, Color c, F32 alphaMod) +{ + GameConnection *gc = gClientGame->getConnectionToServer(); + GameObject *co = NULL; + if(gc) + co = gc->getControlObject(); + if(!co) + return; + Rect r = target->getBounds(MoveObject::RenderState); + Point nearestPoint = co->getRenderPos(); + + if(r.max.x < nearestPoint.x) + nearestPoint.x = r.max.x; + if(r.min.x > nearestPoint.x) + nearestPoint.x = r.min.x; + if(r.max.y < nearestPoint.y) + nearestPoint.y = r.max.y; + if(r.min.y > nearestPoint.y) + nearestPoint.y = r.min.y; + + renderObjectiveArrow(nearestPoint, c, alphaMod); +} + +void GameType::renderObjectiveArrow(Point nearestPoint, Color c, F32 alphaMod) +{ + GameConnection *gc = gClientGame->getConnectionToServer(); + GameObject *co = NULL; + if(gc) + co = gc->getControlObject(); + if(!co) + return; + + Point rp = gClientGame->worldToScreenPoint(nearestPoint); + Point center(400, 300); + Point arrowDir = rp - center; + + F32 er = arrowDir.x * arrowDir.x / (350 * 350) + arrowDir.y * arrowDir.y / (250 * 250); + if(er < 1) + return; + Point np = rp; + + er = sqrt(er); + rp.x = arrowDir.x / er; + rp.y = arrowDir.y / er; + rp += center; + + F32 dist = (np - rp).len(); + + arrowDir.normalize(); + Point crossVec(arrowDir.y, -arrowDir.x); + F32 alpha = (1 - gClientGame->getCommanderZoomFraction()) * 0.6 * alphaMod; + if(!alpha) + return; + + if(dist < 50) + alpha *= dist * 0.02; + + Point p2 = rp - arrowDir * 23 + crossVec * 8; + Point p3 = rp - arrowDir * 23 - crossVec * 8; + + glEnable(GL_BLEND); + glColor(c * 0.7, alpha); + glBegin(GL_POLYGON); + glVertex(rp); + glVertex(p2); + glVertex(p3); + glEnd(); + glColor(c, alpha); + glBegin(GL_LINE_LOOP); + glVertex(rp); + glVertex(p2); + glVertex(p3); + glEnd(); + glDisable(GL_BLEND); +} + +void GameType::renderTimeLeft() +{ + glColor3f(1,1,1); + U32 timeLeft = mGameTimer.getCurrent(); + + U32 minsRemaining = timeLeft / (60000); + U32 secsRemaining = (timeLeft - (minsRemaining * 60000)) / 1000; + UserInterface::drawStringf(UserInterface::canvasWidth - UserInterface::horizMargin - 65, + UserInterface::canvasHeight - UserInterface::vertMargin - 20, 20, "%02d:%02d", minsRemaining, secsRemaining); +} + +void GameType::renderTalkingClients() +{ + S32 y = 150; + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->voiceSFX->isPlaying()) + { + Color teamColor = mTeams[mClientList[i]->teamId].color; + glColor(teamColor); + UserInterface::drawString(10, y, 20, mClientList[i]->name.getString()); + y += 25; + } + } +} + +void GameType::gameOverManGameOver() +{ + // 17 days??? We won't last 17 hours! + if (mGameOver) + return; + + mGameOver = true; + s2cSetGameOver(true); + gServerGame->gameEnded(); + + onGameOver(); +} + +void GameType::onGameOver() +{ + static StringTableEntry tieMessage("The game ended in a tie."); + static StringTableEntry winMessage("%e0%e1 wins the game!"); + static StringTableEntry teamString("Team "); + static StringTableEntry emptyString; + + bool tied = false; + Vector e; + if(mTeams.size() > 1) + { + S32 teamWinner = 0; + U32 winningScore = mTeams[0].score; + for(S32 i = 1; i < mTeams.size(); i++) + { + if(mTeams[i].score == winningScore) + tied = true; + else if(mTeams[i].score > winningScore) + { + teamWinner = i; + winningScore = mTeams[i].score; + tied = false; + } + } + if(!tied) + { + e.push_back(teamString); + e.push_back(mTeams[teamWinner].name); + } + } + else + { + if(mClientList.size()) + { + ClientRef *winningClient = mClientList[0]; + for(S32 i = 1; i < mClientList.size(); i++) + { + if(mClientList[i]->score == winningClient->score) + tied = true; + else if(mClientList[i]->score > winningClient->score) + { + winningClient = mClientList[i]; + tied = false; + } + } + if(!tied) + { + e.push_back(emptyString); + e.push_back(winningClient->name); + } + } + } + if(tied) + { + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessage(GameConnection::ColorNuclearGreen, SFXFlagDrop, tieMessage); + } + else + { + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagCapture, winMessage, e); + } +} + +TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cSetGameOver, (bool gameOver), (gameOver), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0) +{ + mGameOver = gameOver; +} + +void GameType::onAddedToGame(Game *theGame) +{ + theGame->setGameType(this); +} + +extern void constructBarriers(Game *theGame, const Vector &barrier, F32 width); + +bool GameType::processLevelItem(S32 argc, const char **argv) +{ + if(!stricmp(argv[0], "Team")) + { + if(argc < 5) + return false; + Team t; + t.numPlayers = 0; + + t.name.set(argv[1]); + t.color.read(argv + 2); + mTeams.push_back(t); + } + else if(!stricmp(argv[0], "Spawn")) + { + if(argc < 4) + return false; + S32 teamIndex = atoi(argv[1]); + Point p; + p.read(argv + 2); + p *= getGame()->getGridSize(); + if(teamIndex >= 0 && teamIndex < mTeams.size()) + mTeams[teamIndex].spawnPoints.push_back(p); + } + else if(!stricmp(argv[0], "BarrierMaker")) + { + BarrierRec barrier; + if(argc < 2) + return false; + barrier.width = atof(argv[1]); + for(S32 i = 2; i < argc; i++) + barrier.verts.push_back(atof(argv[i]) * getGame()->getGridSize()); + if(barrier.verts.size() > 3) + { + mBarriers.push_back(barrier); + constructBarriers(getGame(), barrier.verts, barrier.width); + } + } + else if(!stricmp(argv[0], "LevelName") && argc > 1) + mLevelName.set(argv[1]); + else if(!stricmp(argv[0], "LevelDescription") && argc > 1) + mLevelDescription.set(argv[1]); + else + return false; + return true; +} + +ClientRef *GameType::findClientRef(const StringTableEntry &name) +{ + for(S32 clientIndex = 0; clientIndex < mClientList.size(); clientIndex++) + if(mClientList[clientIndex]->name == name) + return mClientList[clientIndex]; + return NULL; +} + +void GameType::spawnShip(GameConnection *theClient) +{ + ClientRef *cl = theClient->getClientRef(); + S32 teamIndex = cl->teamId; + + TNLAssert(mTeams[teamIndex].spawnPoints.size(), "No spawn points!"); + + Point spawnPoint; + S32 spawnIndex = Random::readI() % mTeams[teamIndex].spawnPoints.size(); + spawnPoint = mTeams[teamIndex].spawnPoints[spawnIndex]; + + Ship *newShip = new Ship(cl->name, teamIndex, spawnPoint); + newShip->addToGame(getGame()); + theClient->setControlObject(newShip); + newShip->setOwner(theClient); + + //setClientShipLoadout(clientIndex, theClient->getLoadout()); +} + +void GameType::updateShipLoadout(GameObject *shipObject) +{ + GameConnection *gc = shipObject->getControllingClient(); + if(!gc) + return; + ClientRef *cl = gc->getClientRef(); + if(!cl) + return; + setClientShipLoadout(cl, gc->getLoadout()); +} + +void GameType::setClientShipLoadout(ClientRef *cl, const Vector &loadout) +{ + if(loadout.size() != 5) + return; + Ship *theShip = (Ship *) cl->clientConnection->getControlObject(); + + if(theShip) + theShip->setLoadout(loadout[0], loadout[1], loadout[2], loadout[3], loadout[4]); +} + +void GameType::clientRequestLoadout(GameConnection *client, const Vector &loadout) +{ + //S32 clientIndex = findClientIndexByConnection(client); + //if(clientIndex != -1) + // setClientShipLoadout(clientIndex, loadout); +} + +void GameType::performScopeQuery(GhostConnection *connection) +{ + GameConnection *gc = (GameConnection *) connection; + GameObject *co = gc->getControlObject(); + + const Vector > &scopeAlwaysList = getGame()->getScopeAlwaysList(); + + gc->objectInScope(this); + + for(S32 i = 0; i < scopeAlwaysList.size(); i++) + { + if(scopeAlwaysList[i].isNull()) + continue; + gc->objectInScope(scopeAlwaysList[i]); + } + // readyForRegularGhosts is set once all the RPCs from the GameType + // have been received and acknowledged by the client + ClientRef *cl = gc->getClientRef(); + if(cl) + { + if(cl->readyForRegularGhosts && co) + { + performProxyScopeQuery(co, (GameConnection *) connection); + gc->objectInScope(co); + } + } +} + +void GameType::addItemOfInterest(Item *theItem) +{ + ItemOfInterest i; + i.theItem = theItem; + i.teamVisMask = 0; + mItemsOfInterest.push_back(i); +} + +void GameType::queryItemsOfInterest() +{ + static Vector fillVector; + for(S32 i = 0; i < mItemsOfInterest.size(); i++) + { + ItemOfInterest &ioi = mItemsOfInterest[i]; + ioi.teamVisMask = 0; + Point pos = ioi.theItem->getActualPos(); + Point scopeRange(Game::PlayerSensorHorizVisDistance, + Game::PlayerSensorVertVisDistance); + Rect queryRect(pos, pos); + + queryRect.expand(scopeRange); + findObjects(ShipType, fillVector, queryRect); + for(S32 j = 0; j < fillVector.size(); j++) + { + Ship *theShip = (Ship *) fillVector[j]; + Point delta = theShip->getActualPos() - pos; + delta.x = fabs(delta.x); + delta.y = fabs(delta.y); + + if( (theShip->isSensorActive() && delta.x < Game::PlayerSensorHorizVisDistance && + delta.y < Game::PlayerSensorVertVisDistance) || + (delta.x < Game::PlayerHorizVisDistance && + delta.y < Game::PlayerVertVisDistance)) + ioi.teamVisMask |= (1 << theShip->getTeam()); + } + fillVector.clear(); + } +} + +void GameType::performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection) +{ + static Vector fillVector; + fillVector.clear(); + + if(mTeams.size() > 1) + { + for(S32 i = 0; i < mItemsOfInterest.size(); i++) + { + if(mItemsOfInterest[i].teamVisMask & (1 << scopeObject->getTeam())) + { + Item *theItem = mItemsOfInterest[i].theItem; + connection->objectInScope(theItem); + if(theItem->isMounted()) + connection->objectInScope(theItem->getMount()); + } + } + } + + if(connection->isInCommanderMap() && mTeams.size() > 1) + { + S32 teamId = connection->getClientRef()->teamId; + + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->teamId == teamId) + { + if(!mClientList[i]->clientConnection) + continue; + + Ship *co = (Ship *) mClientList[i]->clientConnection->getControlObject(); + if(!co) + continue; + + Point pos = co->getActualPos(); + Point scopeRange; + if(co->isSensorActive()) + scopeRange.set(Game::PlayerSensorHorizVisDistance + Game::PlayerScopeMargin, + Game::PlayerSensorVertVisDistance + Game::PlayerScopeMargin); + else + scopeRange.set(Game::PlayerHorizVisDistance + Game::PlayerScopeMargin, + Game::PlayerVertVisDistance + Game::PlayerScopeMargin); + + Rect queryRect(pos, pos); + + queryRect.expand(scopeRange); + findObjects(scopeObject == co ? AllObjectTypes : CommandMapVisType, fillVector, queryRect); + } + } + } + else + { + Point pos = scopeObject->getActualPos(); + Ship *co = (Ship *) scopeObject; + Point scopeRange; + + if(co->isSensorActive()) + scopeRange.set(Game::PlayerSensorHorizVisDistance + Game::PlayerScopeMargin, + Game::PlayerSensorVertVisDistance + Game::PlayerScopeMargin); + else + scopeRange.set(Game::PlayerHorizVisDistance + Game::PlayerScopeMargin, + Game::PlayerVertVisDistance + Game::PlayerScopeMargin); + + Rect queryRect(pos, pos); + queryRect.expand(scopeRange); + findObjects(AllObjectTypes, fillVector, queryRect); + } + + for(S32 i = 0; i < fillVector.size(); i++) + connection->objectInScope(fillVector[i]); +} + +Color GameType::getTeamColor(S32 team) +{ + if(team == -1) + return Color(0.8, 0.8, 0.8); + else + return mTeams[team].color; +} + +Color GameType::getTeamColor(GameObject *theObject) +{ + return getTeamColor(theObject->getTeam()); +} + +Color GameType::getShipColor(Ship *s) +{ + return getTeamColor(s->getTeam()); +} + +void GameType::countTeamPlayers() +{ + for(S32 i = 0; i < mTeams.size(); i ++) + mTeams[i].numPlayers = 0; + + for(S32 i = 0; i < mClientList.size(); i++) + mTeams[mClientList[i]->teamId].numPlayers++; +} + +void GameType::serverAddClient(GameConnection *theClient) +{ + theClient->setScopeObject(this); + + ClientRef *cref = allocClientRef(); + cref->name = theClient->getClientName(); + + cref->clientConnection = theClient; + countTeamPlayers(); + + U32 minPlayers = mTeams[0].numPlayers; + S32 minTeamIndex = 0; + + for(S32 i = 1; i < mTeams.size(); i++) + { + if(mTeams[i].numPlayers < minPlayers) + { + minTeamIndex = i; + minPlayers = mTeams[i].numPlayers; + } + } + cref->teamId = minTeamIndex; + mClientList.push_back(cref); + theClient->setClientRef(cref); + + s2cAddClient(cref->name, false); + s2cClientJoinedTeam(cref->name, cref->teamId); + spawnShip(theClient); +} + + +bool GameType::objectCanDamageObject(GameObject *damager, GameObject *victim) +{ + if(!damager) + return true; + + GameConnection *damagerOwner = damager->getOwner(); + GameConnection *victimOwner = victim->getOwner(); + + if(damagerOwner == victimOwner) + return true; + + if(mTeams.size() <= 1) + return true; + + return damager->getTeam() != victim->getTeam(); +} + +void GameType::controlObjectForClientKilled(GameConnection *theClient, GameObject *clientObject, GameObject *killerObject) +{ + GameConnection *killer = killerObject ? killerObject->getOwner() : NULL; + ClientRef *killerRef = killer ? killer->getClientRef() : NULL; + ClientRef *clientRef = theClient->getClientRef(); + + if(killerRef) + { + // Punish team killers slightly + if(mTeams.size() > 1 && killerRef->teamId == clientRef->teamId) + killerRef->score -= 1; + else + killerRef->score += 1; + + s2cKillMessage(clientRef->name, killerRef->name); + } + clientRef->respawnTimer.reset(RespawnDelay); +} + +void GameType::addClientGameMenuOptions(Vector &menuOptions) +{ + if(mTeams.size() > 1) + menuOptions.push_back(MenuItem("CHANGE TEAMS",1000)); +} + +void GameType::processClientGameMenuOption(U32 index) +{ + if(index == 1000) + c2sChangeTeams(); +} + +void GameType::setTeamScore(S32 teamIndex, S32 newScore) +{ + mTeams[teamIndex].score = newScore; + s2cSetTeamScore(teamIndex, newScore); + if(newScore >= mTeamScoreLimit) + gameOverManGameOver(); +} + +GAMETYPE_RPC_S2C(GameType, s2cSetLevelInfo, (StringTableEntry levelName, StringTableEntry levelDesc), (levelName, levelDesc)) +{ + mLevelName = levelName; + mLevelDescription = levelDesc; + mLevelInfoDisplayTimer.reset(LevelInfoDisplayTime); +} + +GAMETYPE_RPC_S2C(GameType, s2cSetTimeRemaining, (U32 timeLeft), (timeLeft)) +{ + mGameTimer.reset(timeLeft); +} + +GAMETYPE_RPC_C2S(GameType, c2sChangeTeams, (), ()) +{ + GameConnection *source = (GameConnection *) NetObject::getRPCSourceConnection(); + changeClientTeam(source); +} + +void GameType::changeClientTeam(GameConnection *source) +{ + if(mTeams.size() <= 1) + return; + + ClientRef *cl = source->getClientRef(); + + // destroy the old ship + GameObject *co = source->getControlObject(); + + if(co) + ((Ship *) co)->kill(); + + U32 newTeamId = (cl->teamId + 1) % mTeams.size(); + cl->teamId = newTeamId; + s2cClientJoinedTeam(cl->name, newTeamId); + spawnShip(source); +} + +GAMETYPE_RPC_S2C(GameType, s2cAddClient, (StringTableEntry name, bool isMyClient), (name, isMyClient)) +{ + ClientRef *cref = allocClientRef(); + cref->name = name; + cref->teamId = 0; + cref->decoder = new LPC10VoiceDecoder(); + + cref->voiceSFX = new SFXObject(SFXVoice, NULL, 1, Point(), Point()); + + mClientList.push_back(cref); + gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s joined the game.", name.getString()); +} + +void GameType::serverRemoveClient(GameConnection *theClient) +{ + ClientRef *cl = theClient->getClientRef(); + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i] == cl) + { + mClientList.erase(i); + break; + } + } + GameObject *theControlObject = theClient->getControlObject(); + if(theControlObject) + ((Ship *) theControlObject)->kill(); + + s2cRemoveClient(theClient->getClientName()); +} + +GAMETYPE_RPC_S2C(GameType, s2cRemoveClient, (StringTableEntry name), (name)) +{ + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->name == name) + { + mClientList.erase(i); + break; + } + } + gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s left the game.", name.getString()); +} + +GAMETYPE_RPC_S2C(GameType, s2cAddTeam, (StringTableEntry teamName, F32 r, F32 g, F32 b), (teamName, r, g, b)) +{ + Team team; + team.name = teamName; + team.color.r = r; + team.color.g = g; + team.color.b = b; + mTeams.push_back(team); +} + +GAMETYPE_RPC_S2C(GameType, s2cSetTeamScore, (U32 teamIndex, U32 score), (teamIndex, score)) +{ + mTeams[teamIndex].score = score; +} + +GAMETYPE_RPC_S2C(GameType, s2cClientJoinedTeam, (StringTableEntry name, U32 teamIndex), (name, teamIndex)) +{ + ClientRef *cl = findClientRef(name); + cl->teamId = teamIndex; + gGameUserInterface.displayMessage(Color(0.6f, 0.6f, 0.8f), "%s joined team %s.", name.getString(), mTeams[teamIndex].name.getString()); +} + +void GameType::onGhostAvailable(GhostConnection *theConnection) +{ + NetObject::setRPCDestConnection(theConnection); + + s2cSetLevelInfo(mLevelName, mLevelDescription); + + for(S32 i = 0; i < mTeams.size(); i++) + { + s2cAddTeam(mTeams[i].name, mTeams[i].color.r, mTeams[i].color.g, mTeams[i].color.b); + s2cSetTeamScore(i, mTeams[i].score); + } + + // add all the client and team information + for(S32 i = 0; i < mClientList.size(); i++) + { + s2cAddClient(mClientList[i]->name, mClientList[i]->clientConnection == theConnection); + s2cClientJoinedTeam(mClientList[i]->name, mClientList[i]->teamId); + } + + // an empty list clears the barriers + Vector v; + s2cAddBarriers(v, 0); + + for(S32 i = 0; i < mBarriers.size(); i++) + { + s2cAddBarriers(mBarriers[i].verts, mBarriers[i].width); + } + s2cSetTimeRemaining(mGameTimer.getCurrent()); + s2cSetGameOver(mGameOver); + s2cSyncMessagesComplete(theConnection->getGhostingSequence()); + + NetObject::setRPCDestConnection(NULL); +} + +GAMETYPE_RPC_S2C(GameType, s2cSyncMessagesComplete, (U32 sequence), (sequence)) +{ + c2sSyncMessagesComplete(sequence); +} + +GAMETYPE_RPC_C2S(GameType, c2sSyncMessagesComplete, (U32 sequence), (sequence)) +{ + GameConnection *source = (GameConnection *) getRPCSourceConnection(); + ClientRef *cl = source->getClientRef(); + if(sequence != source->getGhostingSequence()) + return; + cl->readyForRegularGhosts = true; +} + +GAMETYPE_RPC_S2C(GameType, s2cAddBarriers, (Vector barrier, F32 width), (barrier, width)) +{ + if(!barrier.size()) + getGame()->deleteObjects(BarrierType); + else + constructBarriers(getGame(), barrier, width); +} + +GAMETYPE_RPC_C2S(GameType, c2sSendChat, (bool global, StringPtr message), (global, message)) +{ + GameConnection *source = (GameConnection *) getRPCSourceConnection(); + ClientRef *cl = source->getClientRef(); + + RefPtr theEvent = TNL_RPC_CONSTRUCT_NETEVENT(this, + s2cDisplayChatMessage, (global, source->getClientName(), message)); + + sendChatDisplayEvent(cl, global, theEvent); +} + +GAMETYPE_RPC_C2S(GameType, c2sSendChatSTE, (bool global, StringTableEntry message), (global, message)) +{ + GameConnection *source = (GameConnection *) getRPCSourceConnection(); + ClientRef *cl = source->getClientRef(); + + RefPtr theEvent = TNL_RPC_CONSTRUCT_NETEVENT(this, + s2cDisplayChatMessageSTE, (global, source->getClientName(), message)); + + sendChatDisplayEvent(cl, global, theEvent); +} + +void GameType::sendChatDisplayEvent(ClientRef *cl, bool global, NetEvent *theEvent) +{ + S32 teamId = 0; + + if(!global) + teamId = cl->teamId; + + for(S32 i = 0; i < mClientList.size(); i++) + { + if(global || mClientList[i]->teamId == teamId) + if(mClientList[i]->clientConnection) + mClientList[i]->clientConnection->postNetEvent(theEvent); + } +} + +extern Color gGlobalChatColor; +extern Color gTeamChatColor; + +GAMETYPE_RPC_S2C(GameType, s2cDisplayChatMessage, (bool global, StringTableEntry clientName, StringPtr message), (global, clientName, message)) +{ + Color theColor = global ? gGlobalChatColor : gTeamChatColor; + + gGameUserInterface.displayMessage(theColor, "%s: %s", clientName.getString(), message.getString()); +} + +GAMETYPE_RPC_S2C(GameType, s2cDisplayChatMessageSTE, (bool global, StringTableEntry clientName, StringTableEntry message), (global, clientName, message)) +{ + Color theColor = global ? gGlobalChatColor : gTeamChatColor; + + gGameUserInterface.displayMessage(theColor, "%s: %s", clientName.getString(), message.getString()); +} + +GAMETYPE_RPC_C2S(GameType, c2sRequestScoreboardUpdates, (bool updates), (updates)) +{ + GameConnection *source = (GameConnection *) getRPCSourceConnection(); + ClientRef *cl = source->getClientRef(); + cl->wantsScoreboardUpdates = updates; + if(updates) + updateClientScoreboard(cl); +} + +GAMETYPE_RPC_C2S(GameType, c2sAdvanceWeapon, (), ()) +{ + GameConnection *source = (GameConnection *) getRPCSourceConnection(); + Ship *s = dynamic_cast(source->getControlObject()); + if(s) + s->selectWeapon(); +} + +Vector > GameType::mPingTimes; ///< Static vector used for constructing update RPCs +Vector > GameType::mScores; + +void GameType::updateClientScoreboard(ClientRef *cl) +{ + mPingTimes.clear(); + mScores.clear(); + + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->ping < MaxPing) + mPingTimes.push_back(mClientList[i]->ping); + else + mPingTimes.push_back(MaxPing); + mScores.push_back(mClientList[i]->score); + } + + NetObject::setRPCDestConnection(cl->clientConnection); + s2cScoreboardUpdate(mPingTimes, mScores); + NetObject::setRPCDestConnection(NULL); +} + +GAMETYPE_RPC_S2C(GameType, s2cScoreboardUpdate, (Vector > pingTimes, Vector > scores), (pingTimes, scores)) +{ + for(S32 i = 0; i < mClientList.size(); i++) + { + if(i >= pingTimes.size()) + break; + + mClientList[i]->ping = pingTimes[i]; + mClientList[i]->score = scores[i]; + } +} + +GAMETYPE_RPC_S2C(GameType, s2cKillMessage, (StringTableEntry victim, StringTableEntry killer), (victim, killer)) +{ + gGameUserInterface.displayMessage(Color(1.0f, 1.0f, 0.8f), + "%s zapped %s", killer.getString(), victim.getString()); +} + +TNL_IMPLEMENT_NETOBJECT_RPC(GameType, c2sVoiceChat, (bool echo, ByteBufferPtr voiceBuffer), (echo, voiceBuffer), + NetClassGroupGameMask, RPCUnguaranteed, RPCToGhostParent, 0) +{ + // Broadcast this to all clients on the same team + // Only send back to the source if echo is true. + + GameConnection *source = (GameConnection *) getRPCSourceConnection(); + ClientRef *cl = source->getClientRef(); + if(cl) + { + RefPtr event = TNL_RPC_CONSTRUCT_NETEVENT(this, s2cVoiceChat, (cl->name, voiceBuffer)); + for(S32 i = 0; i < mClientList.size(); i++) + { + if(mClientList[i]->teamId == cl->teamId && (mClientList[i] != cl || echo) && mClientList[i]->clientConnection) + mClientList[i]->clientConnection->postNetEvent(event); + } + } +} + +TNL_IMPLEMENT_NETOBJECT_RPC(GameType, s2cVoiceChat, (StringTableEntry clientName, ByteBufferPtr voiceBuffer), (clientName, voiceBuffer), + NetClassGroupGameMask, RPCUnguaranteed, RPCToGhost, 0) +{ + ClientRef *cl = findClientRef(clientName); + if(cl) + { + ByteBufferPtr playBuffer = cl->decoder->decompressBuffer(*(voiceBuffer.getPointer())); + + //logprintf("Decoded buffer size %d", playBuffer->getBufferSize()); + cl->voiceSFX->queueBuffer(playBuffer); + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/gameType.h b/tnl-1.5.0/tnl/zap/gameType.h new file mode 100644 index 0000000000000000000000000000000000000000..8ffd8ba4c8332ba6dc77eb661b3f7ef4be1d7811 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameType.h @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAMETYPE_H_ +#define _GAMETYPE_H_ + +#include "gameObject.h" +#include "timer.h" +#include "sfx.h" +#include "voiceCodec.h" + +namespace Zap +{ + +class FlagItem; +class GoalZone; +struct MenuItem; +class Item; + +class ClientRef : public Object +{ +public: + StringTableEntry name; /// Name of client - guaranteed to be unique of current clients + S32 teamId; + S32 score; + Timer respawnTimer; + + bool wantsScoreboardUpdates; + bool readyForRegularGhosts; + + SafePtr clientConnection; + RefPtr voiceSFX; + RefPtr decoder; + + U32 ping; + ClientRef() + { + ping = 0; + score = 0; + readyForRegularGhosts = false; + wantsScoreboardUpdates = false; + teamId = 0; + } +}; + +class GameType : public GameObject +{ +public: + virtual const char *getGameTypeString() { return "Zapmatch"; } + virtual const char *getInstructionString() { return "Zap as many ships as you can!"; } + enum + { + RespawnDelay = 1500, + }; + + struct BarrierRec + { + Vector verts; + F32 width; + }; + + Vector mBarriers; + Vector > mClientList; + + virtual ClientRef *allocClientRef() { return new ClientRef; } + + struct Team + { + StringTableEntry name; + Color color; + Vector spawnPoints; + U32 numPlayers; + S32 score; + Team() { numPlayers = 0; score = 0; } + }; + Vector mTeams; + + StringTableEntry mLevelName; + StringTableEntry mLevelDescription; + + struct ItemOfInterest + { + SafePtr theItem; + U32 teamVisMask; + }; + + Vector mItemsOfInterest; + + void addItemOfInterest(Item *theItem); + + Timer mScoreboardUpdateTimer; + Timer mGameTimer; + Timer mGameTimeUpdateTimer; + Timer mLevelInfoDisplayTimer; + S32 mTeamScoreLimit; + bool mGameOver; // set to true when an end condition is met + + enum { + MaxPing = 999, + DefaultGameTime = 20 * 60 * 1000, + DefaultTeamScoreLimit = 8, + LevelInfoDisplayTime = 6000, + }; + + static Vector > mPingTimes; ///< Static vector used for constructing update RPCs + static Vector > mScores; + + GameType(); + void countTeamPlayers(); + + Color getClientColor(const StringTableEntry &clientName) + { + ClientRef *cl = findClientRef(clientName); + if(cl) + return mTeams[cl->teamId].color; + return Color(); + } + + ClientRef *findClientRef(const StringTableEntry &name); + + void processArguments(S32 argc, const char **argv); + virtual bool processLevelItem(S32 argc, const char **argv); + void onAddedToGame(Game *theGame); + + void idle(GameObject::IdleCallPath path); + + void gameOverManGameOver(); + virtual void onGameOver(); + + virtual void serverAddClient(GameConnection *theClient); + virtual void serverRemoveClient(GameConnection *theClient); + + virtual bool objectCanDamageObject(GameObject *damager, GameObject *victim); + virtual void controlObjectForClientKilled(GameConnection *theClient, GameObject *clientObject, GameObject *killerObject); + + virtual void spawnShip(GameConnection *theClient); + virtual void changeClientTeam(GameConnection *theClient); + + virtual void renderInterfaceOverlay(bool scoreboardVisible); + void renderObjectiveArrow(GameObject *target, Color c, F32 alphaMod = 1.0f); + void renderObjectiveArrow(Point p, Color c, F32 alphaMod = 1.0f); + + void renderTimeLeft(); + void renderTalkingClients(); + virtual void clientRequestLoadout(GameConnection *client, const Vector &loadout); + virtual void updateShipLoadout(GameObject *shipObject); // called from LoadoutZone when a Ship touches the zone + + void setClientShipLoadout(ClientRef *cl, const Vector &loadout); + + virtual Color getShipColor(Ship *s); + Color getTeamColor(S32 team); + Color getTeamColor(GameObject *theObject); + // game type flag methods for CTF, Rabbit, Football + virtual void addFlag(FlagItem *theFlag) {} + virtual void flagDropped(Ship *theShip, FlagItem *theFlag) {} + virtual void shipTouchFlag(Ship *theShip, FlagItem *theFlag) {} + + virtual void addZone(GoalZone *theZone) {} + virtual void shipTouchZone(Ship *theShip, GoalZone *theZone) {} + + void queryItemsOfInterest(); + void performScopeQuery(GhostConnection *connection); + virtual void performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection); + + void onGhostAvailable(GhostConnection *theConnection); + TNL_DECLARE_RPC(s2cSetLevelInfo, (StringTableEntry levelName, StringTableEntry levelDesc)); + TNL_DECLARE_RPC(s2cAddBarriers, (Vector barrier, F32 width)); + TNL_DECLARE_RPC(s2cAddTeam, (StringTableEntry teamName, F32 r, F32 g, F32 b)); + TNL_DECLARE_RPC(s2cAddClient, (StringTableEntry clientName, bool isMyClient)); + TNL_DECLARE_RPC(s2cClientJoinedTeam, (StringTableEntry clientName, U32 teamIndex)); + + TNL_DECLARE_RPC(s2cSyncMessagesComplete, (U32 sequence)); + TNL_DECLARE_RPC(c2sSyncMessagesComplete, (U32 sequence)); + + TNL_DECLARE_RPC(s2cSetGameOver, (bool gameOver)); + TNL_DECLARE_RPC(s2cSetTimeRemaining, (U32 timeLeft)); + + TNL_DECLARE_RPC(s2cRemoveClient, (StringTableEntry clientName)); + + void setTeamScore(S32 teamIndex, S32 newScore); + TNL_DECLARE_RPC(s2cSetTeamScore, (U32 teamIndex, U32 score)); + + TNL_DECLARE_RPC(c2sRequestScoreboardUpdates, (bool updates)); + TNL_DECLARE_RPC(s2cScoreboardUpdate, (Vector > pingTimes, Vector > scores)); + virtual void updateClientScoreboard(ClientRef *theClient); + + TNL_DECLARE_RPC(c2sAdvanceWeapon, ()); + + virtual void addClientGameMenuOptions(Vector &menuOptions); + virtual void processClientGameMenuOption(U32 index); + TNL_DECLARE_RPC(c2sChangeTeams, ()); + + void sendChatDisplayEvent(ClientRef *cl, bool global, NetEvent *theEvent); + TNL_DECLARE_RPC(c2sSendChat, (bool global, StringPtr message)); + TNL_DECLARE_RPC(c2sSendChatSTE, (bool global, StringTableEntry ste)); + TNL_DECLARE_RPC(s2cDisplayChatMessage, (bool global, StringTableEntry clientName, StringPtr message)); + TNL_DECLARE_RPC(s2cDisplayChatMessageSTE, (bool global, StringTableEntry clientName, StringTableEntry message)); + + TNL_DECLARE_RPC(s2cKillMessage, (StringTableEntry victim, StringTableEntry killer)); + + TNL_DECLARE_RPC(c2sVoiceChat, (bool echo, ByteBufferPtr compressedVoice)); + TNL_DECLARE_RPC(s2cVoiceChat, (StringTableEntry client, ByteBufferPtr compressedVoice)); + + TNL_DECLARE_CLASS(GameType); +}; + +#define GAMETYPE_RPC_S2C(className, methodName, args, argNames) \ + TNL_IMPLEMENT_NETOBJECT_RPC(className, methodName, args, argNames, NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0) + +#define GAMETYPE_RPC_C2S(className, methodName, args, argNames) \ + TNL_IMPLEMENT_NETOBJECT_RPC(className, methodName, args, argNames, NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhostParent, 0) + + + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/gameWeapons.cpp b/tnl-1.5.0/tnl/zap/gameWeapons.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f36b66f3bdc20630006ba81f4256177d87f88890 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameWeapons.cpp @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameWeapons.h" +#include "projectile.h" +#include "ship.h" + +namespace Zap +{ + + +// do not add a weapon with a fire delay > Ship::MaxFireDelay +// or update the constant. + +ShipWeaponInfo gWeapons[] = +{ + ShipWeaponInfo(StringTableEntry("Phaser"), 100, 500, 500, 600, 1000, ProjectilePhaser ), + ShipWeaponInfo(StringTableEntry("Bouncer"), 100, 1800, 1800, 540, 1500, ProjectileBounce ), + ShipWeaponInfo(StringTableEntry("Triple"), 200, 2100, 2100, 550, 850, ProjectileTriple ), + ShipWeaponInfo(StringTableEntry("Burst"), 700, 5000, 5000, 500, 1000, 0 ), + ShipWeaponInfo(StringTableEntry("Mine"), 900, 65000, 65000, 500, 1000, 0 ), + ShipWeaponInfo(StringTableEntry("Turret"), 0, 0, 0, 800, 800, ProjectileTurret ), +}; + +ProjectileInfo gProjInfo[ProjectileTypeCount] = { + ProjectileInfo( .21f, Color(1,0,1), Color(1,1,1), Color(0,0,1), Color(1,0,0), Color(1, 0, 0.5), Color(0.5, 0, 1), 1, SFXPhaserProjectile, SFXPhaserImpact ), + ProjectileInfo( 0.15f,Color(1,1,0), Color(1,0,0), Color(1,0.5,0), Color(1,1,1), Color(1, 1, 0), Color(1, 0, 0), 1.3, SFXBounceProjectile, SFXBounceImpact ), + ProjectileInfo( .14f, Color(0,0,1), Color(0,1,0), Color(0,0.5,1), Color(0,1,0.5), Color(0, 0.5, 1), Color(0, 1, 0.5), 0.7, SFXTripleProjectile, SFXTripleImpact ), + ProjectileInfo( .11f, Color(0,1,1), Color(1,1,0), Color(0,1,0.5), Color(0.5,1,0), Color(0.5, 1, 0), Color(0, 1, 0.5), 0.6, SFXTurretProjectile, SFXTurretImpact ), +}; + +void createWeaponProjectiles(U32 weapon, Point &dir, Point &shooterPos, Point &shooterVel, F32 shooterRadius, GameObject *shooter) +{ + GameObject *proj = NULL; + ShipWeaponInfo *wi = gWeapons + weapon; + Point projVel = dir * F32(wi->projVelocity) + dir * shooterVel.dot(dir); + Point firePos = shooterPos + dir * shooterRadius; + + switch(weapon) + { + case WeaponTriple: + { + Point velPerp(projVel.y, -projVel.x); + velPerp.normalize(50.0f); + (new Projectile(wi->projectileType, firePos, projVel + velPerp, wi->projLiveTime, shooter))->addToGame(shooter->getGame()); + (new Projectile(wi->projectileType, firePos, projVel - velPerp, wi->projLiveTime, shooter))->addToGame(shooter->getGame()); + } + case WeaponPhaser: + case WeaponBounce: + case WeaponTurretBlaster: + (new Projectile(wi->projectileType, firePos, projVel, wi->projLiveTime, shooter))->addToGame(shooter->getGame()); + break; + case WeaponBurst: + (new GrenadeProjectile(firePos, projVel, wi->projLiveTime, shooter))->addToGame(shooter->getGame()); + break; + case WeaponMineLayer: + (new Mine(firePos, dynamic_cast(shooter)))->addToGame(shooter->getGame()); + break; + } +} + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/gameWeapons.h b/tnl-1.5.0/tnl/zap/gameWeapons.h new file mode 100644 index 0000000000000000000000000000000000000000..ef5e92837aec6aa317fc909199f26070c2f225cf --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gameWeapons.h @@ -0,0 +1,120 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GAMEWEAPONS_H_ +#define _GAMEWEAPONS_H_ + +#include "tnlPlatform.h" +#include "point.h" +#include "gameObject.h" + +using namespace TNL; +namespace Zap +{ + +enum WeaponTypes +{ + WeaponPhaser = 0, + WeaponBounce, + WeaponTriple, + WeaponBurst, + WeaponMineLayer, + WeaponTurretBlaster, + WeaponCount, +}; + +enum WeaponConsts +{ + MaxFireDelay = 2048, +}; + +struct ShipWeaponInfo +{ + ShipWeaponInfo(StringTableEntry _name, U32 _fireDelay, U32 _minEnergy, U32 _drainEnergy, U32 _projVelocity, U32 _projLiveTime, U32 _projectileType) + { + name = _name; + fireDelay = _fireDelay; + minEnergy = _minEnergy; + drainEnergy = _drainEnergy; + projVelocity = _projVelocity; + projLiveTime = _projLiveTime; + projectileType = _projectileType; + } + + StringTableEntry name; // Display name of the weapon. + U32 fireDelay; // Delay between shots. + U32 minEnergy; // Minimum energy to fire. + U32 drainEnergy; // Amount of energy to drain per shot. + U32 projVelocity; + U32 projLiveTime; + U32 projectileType; +}; + +extern ShipWeaponInfo gWeapons[WeaponCount]; +extern void createWeaponProjectiles(U32 weapon, Point &dir, Point &shooterPos, Point &shooterVel, F32 shooterRadius, GameObject *shooter); + +enum { + NumSparkColors = 4, +}; + +enum ProjectileType +{ + ProjectilePhaser, + ProjectileBounce, + ProjectileTriple, + ProjectileTurret, + ProjectileTypeCount, +}; + +struct ProjectileInfo +{ + ProjectileInfo(F32 _damageAmount, Color _sparkColor1, Color _sparkColor2, Color _sparkColor3, Color _sparkColor4, Color _projColor1, Color _projColor2, F32 _scaleFactor, U32 _projectileSound, U32 _impactSound ) + { + damageAmount = _damageAmount; + sparkColors[0] = _sparkColor1; + sparkColors[1] = _sparkColor2; + sparkColors[2] = _sparkColor3; + sparkColors[3] = _sparkColor4; + projColors[0] = _projColor1; + projColors[1] = _projColor2; + scaleFactor = _scaleFactor; + projectileSound = _projectileSound; + impactSound = _impactSound; + } + + F32 damageAmount; + Color sparkColors[NumSparkColors]; + Color projColors[2]; + F32 scaleFactor; + U32 projectileSound; + U32 impactSound; +}; + +extern ProjectileInfo gProjInfo[ProjectileTypeCount]; + +}; + +#endif \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/goalZone.cpp b/tnl-1.5.0/tnl/zap/goalZone.cpp new file mode 100644 index 0000000000000000000000000000000000000000..90ec044a30fa8ad4cbc4d562f6281521a213a01a --- /dev/null +++ b/tnl-1.5.0/tnl/zap/goalZone.cpp @@ -0,0 +1,161 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "goalZone.h" +#include "gameType.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(GoalZone); + +GoalZone::GoalZone() +{ + mTeam = -1; + mNetFlags.set(Ghostable); + mObjectTypeMask = CommandMapVisType; + mFlashCount = 0; +} + +void GoalZone::render() +{ + renderGoalZone(mPolyBounds, getGame()->getGameType()->getTeamColor(getTeam()), isFlashing()); +} + +S32 GoalZone::getRenderSortValue() +{ + return -1; +} + +void GoalZone::processArguments(S32 argc, const char **argv) +{ + if(argc < 7) + return; + + mTeam = atoi(argv[0]); + for(S32 i = 2; i < argc; i += 2) + { + Point p; + p.x = atof(argv[i-1]) * getGame()->getGridSize(); + p.y = atof(argv[i]) * getGame()->getGridSize(); + mPolyBounds.push_back(p); + } + computeExtent(); +} + +void GoalZone::setTeam(S32 team) +{ + mTeam = team; + setMaskBits(TeamMask); +} + +void GoalZone::onAddedToGame(Game *theGame) +{ + if(!isGhost()) + setScopeAlways(); + theGame->getGameType()->addZone(this); +} + +void GoalZone::computeExtent() +{ + Rect extent(mPolyBounds[0], mPolyBounds[0]); + for(S32 i = 1; i < mPolyBounds.size(); i++) + extent.unionPoint(mPolyBounds[i]); + setExtent(extent); +} + +bool GoalZone::getCollisionPoly(Vector &polyPoints) +{ + for(S32 i = 0; i < mPolyBounds.size(); i++) + polyPoints.push_back(mPolyBounds[i]); + return true; +} + +bool GoalZone::collide(GameObject *hitObject) +{ + if(!isGhost() && (hitObject->getObjectTypeMask() & ShipType)) + getGame()->getGameType()->shipTouchZone((Ship *) hitObject, this); + + return false; +} + +U32 GoalZone::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + if(stream->writeFlag(updateMask & InitialMask)) + { + stream->writeEnum(mPolyBounds.size(), MaxPoints); + for(S32 i = 0; i < mPolyBounds.size(); i++) + { + stream->write(mPolyBounds[i].x); + stream->write(mPolyBounds[i].y); + } + } + if(stream->writeFlag(updateMask & TeamMask)) + stream->write(mTeam); + return 0; +} + +void GoalZone::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + if(stream->readFlag()) + { + S32 size = stream->readEnum(MaxPoints); + for(S32 i = 0; i < size; i++) + { + Point p; + stream->read(&p.x); + stream->read(&p.y); + mPolyBounds.push_back(p); + } + if(size) + computeExtent(); + } + if(stream->readFlag()) + { + stream->read(&mTeam); + if(!isInitialUpdate()) + { + mFlashTimer.reset(FlashDelay); + mFlashCount = FlashCount; + } + } +} + +void GoalZone::idle(GameObject::IdleCallPath path) +{ + if(path != GameObject::ClientIdleMainRemote || mFlashCount == 0) + return; + + if(mFlashTimer.update(mCurrentMove.time)) + { + mFlashTimer.reset(FlashDelay); + mFlashCount--; + } +} + + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/goalZone.h b/tnl-1.5.0/tnl/zap/goalZone.h new file mode 100644 index 0000000000000000000000000000000000000000..d3977d8e9026685971e21df83d685c2bd5e74974 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/goalZone.h @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GOALZONE_H_ +#define _GOALZONE_H_ + +#include "gameObject.h" + +namespace Zap +{ + +class GoalZone : public GameObject +{ + typedef GameObject Parent; + Vector mPolyBounds; + enum { + MaxPoints = 10, + + FlashDelay = 500, + FlashCount = 5, + + InitialMask = BIT(0), + TeamMask = BIT(1), + }; + S32 mFlashCount; + Timer mFlashTimer; +public: + GoalZone(); + void render(); + + bool isFlashing() { return mFlashCount & 1; } + bool didRecentlyChangeTeam() { return mFlashCount != 0; } + S32 getRenderSortValue(); + void processArguments(S32 argc, const char **argv); + + void setTeam(S32 team); + void onAddedToGame(Game *theGame); + void computeExtent(); + bool getCollisionPoly(Vector &polyPoints); + bool collide(GameObject *hitObject); + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + void idle(GameObject::IdleCallPath path); + TNL_DECLARE_CLASS(GoalZone); +}; + +}; + +#endif + + diff --git a/tnl-1.5.0/tnl/zap/gridDB.cpp b/tnl-1.5.0/tnl/zap/gridDB.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6d82a229fb612efc7889bb46e67b81d920ca825 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gridDB.cpp @@ -0,0 +1,265 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gridDB.h" +#include "gameObject.h" + +namespace Zap +{ + +GridDatabase::GridDatabase() +{ + mQueryId = 0; + + for(U32 i = 0; i < BucketRowCount; i++) + for(U32 j = 0; j < BucketRowCount; j++) + mBuckets[i][j] = 0; +} + +void GridDatabase::addToExtents(GameObject *theObject, Rect &extents) +{ + S32 minx, miny, maxx, maxy; + F32 widthDiv = 1 / F32(BucketWidth); + minx = S32(extents.min.x * widthDiv); + miny = S32(extents.min.y * widthDiv); + maxx = S32(extents.max.x * widthDiv); + maxy = S32(extents.max.y * widthDiv); + + for(S32 x = minx; x <= maxx; x++) + { + for(S32 y = miny; y <= maxy; y++) + { + BucketEntry *be = mChunker.alloc(); + be->theObject = theObject; + be->nextInBucket = mBuckets[x & BucketMask][y & BucketMask]; + mBuckets[x & BucketMask][y & BucketMask] = be; + } + } +} + +void GridDatabase::removeFromExtents(GameObject *theObject, Rect &extents) +{ + S32 minx, miny, maxx, maxy; + F32 widthDiv = 1 / F32(BucketWidth); + minx = S32(extents.min.x * widthDiv); + miny = S32(extents.min.y * widthDiv); + maxx = S32(extents.max.x * widthDiv); + maxy = S32(extents.max.y * widthDiv); + + for(S32 x = minx; x <= maxx; x++) + { + for(S32 y = miny; y <= maxy; y++) + { + for(BucketEntry **walk = &mBuckets[x & BucketMask][y & BucketMask]; *walk; walk = &((*walk)->nextInBucket)) + { + if((*walk)->theObject == theObject) + { + BucketEntry *rem = *walk; + *walk = rem->nextInBucket; + mChunker.free(rem); + break; + } + } + } + } +} + +void GridDatabase::findObjects(U32 typeMask, Vector &fillVector, Rect &extents) +{ + S32 minx, miny, maxx, maxy; + F32 widthDiv = 1 / F32(BucketWidth); + minx = S32(extents.min.x * widthDiv); + miny = S32(extents.min.y * widthDiv); + maxx = S32(extents.max.x * widthDiv); + maxy = S32(extents.max.y * widthDiv); + + mQueryId++; + + for(S32 x = minx; x <= maxx; x++) + { + for(S32 y = miny; y <= maxy; y++) + { + for(BucketEntry *walk = mBuckets[x & BucketMask][y & BucketMask]; walk; walk = walk->nextInBucket) + { + GameObject *theObject = walk->theObject; + + if(theObject->mLastQueryId != mQueryId && + theObject->extent.intersects(extents) && + (theObject->getObjectTypeMask() & typeMask) ) + { + walk->theObject->mLastQueryId = mQueryId; + fillVector.push_back(walk->theObject); + } + } + } + } +} + +bool PolygonLineIntersect(Point *poly, U32 vertexCount, Point p1, Point p2, float &collisionTime, Point &normal) +{ + Point v1 = poly[vertexCount - 1]; + Point dp = p2 - p1; + + F32 currentCollisionTime = 100; + + for(U32 i = 0; i < vertexCount; i++) + { + Point v2 = poly[i]; + + // edge from v1 -> v2 + // ray from p1 -> p2 + + Point dv = v2 - v1; + + // p1.x + s * dp.x = v1.x + t * dv.x + // p1.y + s * dp.y = v1.y + t * dv.y + + // s = (v1.x - p1.x + t * dv.x) / dp.x + // p1.y + dp.y * (v1.x - p1.x + t * dv.x) / dp.x = v1.y + t * dv.y + // p1.y * dp.x + dp.y * (v1.x - p1.x) + t * dp.y * dv.x = + // v1.y * dp.x + t * dp.x * dv.y + // t * (dp.y * dv.x - dp.x * dv.y) = + // -p1.y * dp.x - dp.y * v1.x + dp.y * p1.x + v1.y * dp.x + + // t = ((p1.x - v1.x) * dp.y + (v1.y - p1.y) * dp.x) / (dp.y * dv.x - dp.x * dv.y) + + // t = (p1.x + s * dp.x - v1.x) / dv.x + // ( p1.y + s * dp.y - v1.y ) / dv.y = (p1.x + s * dp.x - v1.x) / dv.x + // s * (dp.y / dv.y) + (p1.y - v1.y) / dv.y = + // s * (dp.x / dv.x) + (p1.x - v1.x) / dv.x + // s * dp.y * dv.x + (p1.y - v1.y) * dv.x = + // s * dp.x * dv.y + (p1.x - v1.x) * dv.y + // s * ( dp.y * dv.x - dp.x * dv.y ) = (p1.x - v1.x) * dv.y - (p1.y - v1.y) * dv.x + + // s = ( (p1.x - v1.x) * dv.y + (v1.y - p1.y) * dv.x) / ( dp.y * dv.x - dp.x * dv.y) + + F32 denom = dp.y * dv.x - dp.x * dv.y; + if(denom != 0) // otherwise, the lines are parallel + { + F32 s = ( (p1.x - v1.x) * dv.y + (v1.y - p1.y) * dv.x ) / denom; + F32 t = ( (p1.x - v1.x) * dp.y + (v1.y - p1.y) * dp.x ) / denom; + + if(s >= 0 && s <= 1 && t >= 0 && t <= 1) + { + if(s < currentCollisionTime) + { + normal.set(dv.y, -dv.x); + currentCollisionTime = s; + + } + } + } + v1 = v2; + } + if(currentCollisionTime <= 1) + { + collisionTime = currentCollisionTime; + return true; + } + return false; +} + +extern bool FindLowestRootInInterval(Point::member_type inA, Point::member_type inB, Point::member_type inC, Point::member_type inUpperBound, Point::member_type &outX); + +bool CircleLineIntersect(Point center, float radius, Point rayStart, Point rayEnd, float &collisionTime) +{ + // if the point is in the circle, it's a collision at the start + Point d = center - rayStart; + Point v = rayEnd - rayStart; + + if(d.len() <= radius) + { + collisionTime = 0; + return true; + } + + // otherwise, solve the following equation for t + // (d - vt)^2 = radius^2 + + float a = v.dot(v); + float b = -2 * d.dot(v); + float c = d.dot(d) - radius * radius; + + return FindLowestRootInInterval(a, b, c, 100, collisionTime); +} + +GameObject *GridDatabase::findObjectLOS(U32 typeMask, U32 stateIndex, Point rayStart, Point rayEnd, float &collisionTime, Point &surfaceNormal) +{ + Rect queryRect(rayStart, rayEnd); + + static Vector fillVector; + + fillVector.clear(); + findObjects(typeMask, fillVector, queryRect); + Point collisionPoint; + + collisionTime = 100; + GameObject *retObject = NULL; + + for(S32 i = 0; i < fillVector.size(); i++) + { + if(!fillVector[i]->isCollisionEnabled()) + continue; + + static Vector poly; + poly.clear(); + Point center; + F32 radius; + float ct; + + if(fillVector[i]->getCollisionPoly(poly)) + { + Point normal; + if(PolygonLineIntersect(&poly[0], poly.size(), rayStart, rayEnd, ct, normal)) + { + if(ct < collisionTime) + { + collisionTime = ct; + retObject = fillVector[i]; + surfaceNormal = normal; + } + } + } + else if(fillVector[i]->getCollisionCircle(stateIndex, center, radius)) + { + if(CircleLineIntersect(center, radius, rayStart, rayEnd, ct)) + { + if(ct < collisionTime) + { + collisionTime = ct; + surfaceNormal = (rayStart + (rayEnd - rayStart) * ct) - center; + retObject = fillVector[i]; + } + } + } + } + if(retObject) + surfaceNormal.normalize(); + return retObject; +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/gridDB.h b/tnl-1.5.0/tnl/zap/gridDB.h new file mode 100644 index 0000000000000000000000000000000000000000..989eabe23f329f31774afa7f359c38d18e848ec9 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gridDB.h @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _GRIDDB_H_ +#define _GRIDDB_H_ + +#include "tnlTypes.h" +#include "point.h" +#include "tnlDataChunker.h" +#include "tnlVector.h" + +using namespace TNL; + +namespace Zap +{ + +class GameObject; + +class GridDatabase +{ +public: + enum { + BucketWidth = 256, ///< Width/height of each bucket in pixels + BucketRowCount = 16, ///< Number of buckets per grid row, and number of rows + BucketMask = BucketRowCount - 1, + }; + struct BucketEntry + { + GameObject *theObject; + BucketEntry *nextInBucket; + }; + U32 mQueryId; + BucketEntry *mBuckets[BucketRowCount][BucketRowCount]; + ClassChunker mChunker; + + GridDatabase(); + + GameObject *findObjectLOS(U32 typeMask, U32 stateIndex, Point rayStart, Point rayEnd, float &collisionTime, Point &surfaceNormal); + void findObjects(U32 typeMask, Vector &fillVector, Rect &extents); + + void addToExtents(GameObject *theObject, Rect &extents); + void removeFromExtents(GameObject *theObject, Rect &extents); +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/gsm.h b/tnl-1.5.0/tnl/zap/gsm.h new file mode 100644 index 0000000000000000000000000000000000000000..dd296cb596414563737a96abfa68a415cd304945 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gsm.h @@ -0,0 +1,58 @@ +/* + GSM voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com) + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifndef GSM_H +#define GSM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSM_SAMPLES_PER_FRAME 160 +#define GSM_ENCODED_FRAME_SIZE 33 + + +/* The GSM_OPT_LTP_CUT option speeds up encoding by using an alternate */ +/* faster algorithm to calculate the long term predictor */ +#define GSM_OPT_LTP_CUT 3 + +struct gsm_state * gsm_create(void); +void gsm_destroy(struct gsm_state *st); + +int gsm_option(struct gsm_state *st, int opt, int *val); + +int gsm_encode(struct gsm_state *st, short *in, unsigned char *out); +int gsm_decode(struct gsm_state *st, unsigned char *in, short *out); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* GSM_H */ diff --git a/tnl-1.5.0/tnl/zap/gsm_decode.c b/tnl-1.5.0/tnl/zap/gsm_decode.c new file mode 100644 index 0000000000000000000000000000000000000000..5f9f79ba4cb238a541ca9ff70bb1e4fa4c0a56d6 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gsm_decode.c @@ -0,0 +1,446 @@ +/* + GSM voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com) + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +#include "private.h" + +static gsmword gsm_FACd[8] = {18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767}; +static gsmword gsm_QLB[4] = {3277, 11469, 21299, 32767}; + +INLINE void Postprocessing(struct gsm_state *S, short *s) +{ + int k; + gsmword msr = S->msr; + longword ltmp; + + for(k = 160; k--; s++) + { + msr = *s + (gsmword)GSM_MULT_R( msr, 28672 ); /* Deemphasis */ + *s = (short)(GSM_ADD(msr, msr) & 0xFFF8); /* Truncation & Upscaling */ + } + S->msr = msr; +} + +static void APCM_quantization_xmaxc_to_exp_mant(gsmword xmaxc, gsmword *exp_out, + gsmword *mant_out) +{ + gsmword exp, mant; + + exp = 0; + if(xmaxc > 15) + exp = (gsmword)(SASR(xmaxc, 3) - 1); + mant = (gsmword)(xmaxc - SASL( exp, 3 )); + + if(mant == 0) + { + exp = -4; + mant = 7; + } + else + { + while(mant <= 7) + { + mant = (gsmword)(SASL(mant, 1) | 1); + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; +} + +static void APCM_inverse_quantization(gsmword *xMc, gsmword mant, gsmword exp, gsmword *xMp) +{ + int i; + gsmword temp, temp1, temp2, temp3; + longword ltmp; + + temp1 = gsm_FACd[ mant ]; /* see 4.2-15 for mant */ + temp2 = (gsmword)GSM_SUB( 6, exp ); /* see 4.2-15 for exp */ + temp3 = (gsmword)SASL( 1, GSM_SUB( temp2, 1 )); + + for(i = 13; i--;) + { + + temp = (gsmword)(SASL(*xMc++, 1) - 7); /* restore sign */ + + temp = (gsmword)SASL(temp, 12); /* 16 bit signed */ + temp = (gsmword)GSM_MULT_R( temp1, temp ); + temp = (gsmword)GSM_ADD( temp, temp3 ); + *xMp++ = (gsmword)SASR( temp, temp2 ); + } +} + +static void RPE_grid_positioning(gsmword Mc, gsmword *xMp, gsmword *ep) +{ + int i = 13; + + switch (Mc) { + case 3: *ep++ = 0; + case 2: do + { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + } while (--i != 0); + } + while(++Mc < 4) + *ep++ = 0; +} + +static void Gsm_RPE_Decoding(gsmword xmaxcr, gsmword Mcr, gsmword *xMcr, gsmword *erp) +{ + gsmword exp, mant; + gsmword xMp[ 13 ]; + + APCM_quantization_xmaxc_to_exp_mant(xmaxcr, &exp, &mant); + APCM_inverse_quantization(xMcr, mant, exp, xMp); + RPE_grid_positioning(Mcr, xMp, erp); +} + +static void Decoding_of_the_coded_Log_Area_Ratios(gsmword *LARc, gsmword *LARpp) +{ + gsmword temp1; + long ltmp; + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = (gsmword)(SASL( *LARc++ + MIC , 10)); \ + temp1 -= SASL( B, 1 ); \ + temp1 = (gsmword)GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = (gsmword)GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); +} + +INLINE void Coefficients_0_12(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) + { + *LARp = (gsmword)(SASR( *LARpp_j_1, 2 ) + SASR( *LARpp_j, 2 )); + *LARp += (gsmword)SASR( *LARpp_j_1, 1); + } +} + +INLINE void Coefficients_13_26(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) + *LARp = SASR( *LARpp_j_1, 1) + SASR( *LARpp_j, 1 ); +} + +INLINE void Coefficients_27_39(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) + { + *LARp = (gsmword)(SASR( *LARpp_j_1, 2 ) + SASR( *LARpp_j, 2 )); + *LARp += (gsmword)SASR( *LARpp_j, 1 ); + } +} + +INLINE void Coefficients_40_159(gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARp++, LARpp_j++) + *LARp = *LARpp_j; +} + +static void LARp_to_rp(gsmword * LARp) +{ + int i; + gsmword temp; + + for (i = 1; i <= 8; i++, LARp++) + { + + if (*LARp < 0) + { + temp = (gsmword)GSM_ABS( *LARp ); + *LARp = (gsmword)(- ((temp < 11059) ? SASL( temp, 1 ) + : ((temp < 20070) ? temp + 11059 + : ( SASR( temp, 2 ) + 26112 )))); + } + else + { + temp = *LARp; + *LARp = (gsmword)((temp < 11059) ? SASL( temp, 1 ) + : ((temp < 20070) ? temp + 11059 + : ( SASR( temp, 2 ) + 26112 ))); + } + } +} + +static void Short_term_synthesis_filtering(struct gsm_state *S, gsmword *rrp, int k, + gsmword *wt, short *sr) +{ + gsmword * v = S->v; + gsmword sri; + longword ltmp; + gsmword v0=v[0], v1=v[1], v2=v[2], v3=v[3], + v4=v[4], v5=v[5], v6=v[6], v7=v[7]; + gsmword rrp0, rrp1, rrp2, rrp3, + rrp4, rrp5, rrp6, rrp7; + + rrp0 = rrp[0]; rrp1 = rrp[1]; + rrp2 = rrp[2]; rrp3 = rrp[3]; + rrp4 = rrp[4]; rrp5 = rrp[5]; + rrp6 = rrp[6]; rrp7 = rrp[7]; + + while(k-- != 0) + { + sri = *wt++; + + sri -= (gsmword)GSM_MULT_R(rrp7, v7); + + sri -= (gsmword)GSM_MULT_R(rrp6, v6); + v7 = v6 + (gsmword)GSM_MULT_R(rrp6, sri); + + sri -= (gsmword)GSM_MULT_R(rrp5, v5); + v6 = v5 + (gsmword)GSM_MULT_R(rrp5, sri); + + sri -= (gsmword)GSM_MULT_R(rrp4, v4); + v5 = v4 + (gsmword)GSM_MULT_R(rrp4, sri); + + sri -= (gsmword)GSM_MULT_R(rrp3, v3); + v4 = v3 + (gsmword)GSM_MULT_R(rrp3, sri); + + sri -= (gsmword)GSM_MULT_R(rrp2, v2); + v3 = v2 + (gsmword)GSM_MULT_R(rrp2, sri); + + sri -= (gsmword)GSM_MULT_R(rrp1, v1); + v2 = v1 + (gsmword)GSM_MULT_R(rrp1, sri); + + sri = (gsmword)GSM_SUB( sri, (gsmword)GSM_MULT_R(rrp0, v0) ); + v1 = v0 + (gsmword)GSM_MULT_R(rrp0, sri); + + v0 = sri; + *sr++ = (short)sri; + } + v[0]=GSM_ADD(v0, 0); + v[1]=GSM_ADD(v1, 0); + v[2]=GSM_ADD(v2, 0); + v[3]=GSM_ADD(v3, 0); + v[4]=GSM_ADD(v4, 0); + v[5]=GSM_ADD(v5, 0); + v[6]=GSM_ADD(v6, 0); + v[7]=GSM_ADD(v7, 0); +} + +static void Gsm_Short_Term_Synthesis_Filter(struct gsm_state * S, gsmword *LARcr, + gsmword *wt, short *s) +{ + gsmword * LARpp_j = S->LARpp[ S->j ]; + gsmword * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; + gsmword LARp[8]; + + Decoding_of_the_coded_Log_Area_Ratios(LARcr, LARpp_j); + + Coefficients_0_12(LARpp_j_1, LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_synthesis_filtering(S, LARp, 13, wt, s); + + Coefficients_13_26(LARpp_j_1, LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_synthesis_filtering(S, LARp, 14, wt + 13, s + 13); + + Coefficients_27_39(LARpp_j_1, LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_synthesis_filtering(S, LARp, 13, wt + 27, s + 27); + + Coefficients_40_159(LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_synthesis_filtering(S, LARp, 120, wt + 40, s + 40); +} + +static void Gsm_Long_Term_Synthesis_Filtering(struct gsm_state *S, gsmword Ncr, gsmword bcr, + gsmword *erp, gsmword *drp) +{ + int k; + gsmword brp, Nr; + gsmword * pdrp; + + Nr = (gsmword)(Ncr < 40 || Ncr > 120 ? S->nrp : Ncr); + S->nrp = Nr; + + brp = gsm_QLB[ bcr ]; + pdrp = drp; + for(k = 40; k--; pdrp++) + { + *pdrp = (gsmword)(*erp++ + GSM_MULT_R( brp, pdrp[ -(Nr) ] )); + } + + memcpy(&drp[-120], &drp[-80], (sizeof(drp[0]) * 120)); +} + +static void Gsm_Decoder(struct gsm_state *S, gsmword *LARcr, gsmword *Ncr, gsmword *bcr, + gsmword *Mcr, gsmword *xmaxcr, gsmword *xMcr, short *s) +{ + int j; + gsmword erp[40], wt[160]; + gsmword * drp = S->dp0 + 120; + + for(j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) + { + Gsm_RPE_Decoding( *xmaxcr, *Mcr, xMcr, erp ); + Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); + + memcpy(&wt[ j * 40 ], drp, sizeof(drp[0]) * 40); + } + + Gsm_Short_Term_Synthesis_Filter(S, LARcr, wt, s); + Postprocessing(S, s); +} + +int gsm_decode ( struct gsm_state *s, unsigned char *c, short *target) +{ + gsmword LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + { + if(((*c >> 4) & 0x0F) != GSM_MAGIC) + return 0; + + LARc[0] = (gsmword)((*c++ & 0xF) << 2); /* 1 */ + LARc[0] |= (gsmword)((*c >> 6) & 0x3); + LARc[1] = (gsmword)(*c++ & 0x3F); + LARc[2] = (gsmword)((*c >> 3) & 0x1F); + LARc[3] = (gsmword)((*c++ & 0x7) << 2); + LARc[3] |= (gsmword)((*c >> 6) & 0x3); + LARc[4] = (gsmword)((*c >> 2) & 0xF); + LARc[5] = (gsmword)((*c++ & 0x3) << 2); + LARc[5] |= (gsmword)((*c >> 6) & 0x3); + LARc[6] = (gsmword)((*c >> 3) & 0x7); + LARc[7] = (gsmword)(*c++ & 0x7); + Nc[0] = (gsmword)((*c >> 1) & 0x7F); + bc[0] = (gsmword)((*c++ & 0x1) << 1); + bc[0] |= (gsmword)((*c >> 7) & 0x1); + Mc[0] = (gsmword)((*c >> 5) & 0x3); + xmaxc[0] = (gsmword)((*c++ & 0x1F) << 1); + xmaxc[0] |= (gsmword)((*c >> 7) & 0x1); + xmc[0] = (gsmword)((*c >> 4) & 0x7); + xmc[1] = (gsmword)((*c >> 1) & 0x7); + xmc[2] = (gsmword)((*c++ & 0x1) << 2); + xmc[2] |= (gsmword)((*c >> 6) & 0x3); + xmc[3] = (gsmword)((*c >> 3) & 0x7); + xmc[4] = (gsmword)(*c++ & 0x7); + xmc[5] = (gsmword)((*c >> 5) & 0x7); + xmc[6] = (gsmword)((*c >> 2) & 0x7); + xmc[7] = (gsmword)((*c++ & 0x3) << 1); /* 10 */ + xmc[7] |= (gsmword)((*c >> 7) & 0x1); + xmc[8] = (gsmword)((*c >> 4) & 0x7); + xmc[9] = (gsmword)((*c >> 1) & 0x7); + xmc[10] = (gsmword)((*c++ & 0x1) << 2); + xmc[10] |= (gsmword)((*c >> 6) & 0x3); + xmc[11] = (gsmword)((*c >> 3) & 0x7); + xmc[12] = (gsmword)(*c++ & 0x7); + Nc[1] = (gsmword)((*c >> 1) & 0x7F); + bc[1] = (gsmword)((*c++ & 0x1) << 1); + bc[1] |= (gsmword)((*c >> 7) & 0x1); + Mc[1] = (gsmword)((*c >> 5) & 0x3); + xmaxc[1] = (gsmword)((*c++ & 0x1F) << 1); + xmaxc[1] |= (gsmword)((*c >> 7) & 0x1); + xmc[13] = (gsmword)((*c >> 4) & 0x7); + xmc[14] = (gsmword)((*c >> 1) & 0x7); + xmc[15] = (gsmword)((*c++ & 0x1) << 2); + xmc[15] |= (gsmword)((*c >> 6) & 0x3); + xmc[16] = (gsmword)((*c >> 3) & 0x7); + xmc[17] = (gsmword)(*c++ & 0x7); + xmc[18] = (gsmword)((*c >> 5) & 0x7); + xmc[19] = (gsmword)((*c >> 2) & 0x7); + xmc[20] = (gsmword)((*c++ & 0x3) << 1); + xmc[20] |= (gsmword)((*c >> 7) & 0x1); + xmc[21] = (gsmword)((*c >> 4) & 0x7); + xmc[22] = (gsmword)((*c >> 1) & 0x7); + xmc[23] = (gsmword)((*c++ & 0x1) << 2); + xmc[23] |= (gsmword)((*c >> 6) & 0x3); + xmc[24] = (gsmword)((*c >> 3) & 0x7); + xmc[25] = (gsmword)(*c++ & 0x7); + Nc[2] = (gsmword)((*c >> 1) & 0x7F); + bc[2] = (gsmword)((*c++ & 0x1) << 1); /* 20 */ + bc[2] |= (gsmword)((*c >> 7) & 0x1); + Mc[2] = (gsmword)((*c >> 5) & 0x3); + xmaxc[2] = (gsmword)((*c++ & 0x1F) << 1); + xmaxc[2] |= (gsmword)((*c >> 7) & 0x1); + xmc[26] = (gsmword)((*c >> 4) & 0x7); + xmc[27] = (gsmword)((*c >> 1) & 0x7); + xmc[28] = (gsmword)((*c++ & 0x1) << 2); + xmc[28] |= (gsmword)((*c >> 6) & 0x3); + xmc[29] = (gsmword)((*c >> 3) & 0x7); + xmc[30] = (gsmword)(*c++ & 0x7); + xmc[31] = (gsmword)((*c >> 5) & 0x7); + xmc[32] = (gsmword)((*c >> 2) & 0x7); + xmc[33] = (gsmword)((*c++ & 0x3) << 1); + xmc[33] |= (gsmword)((*c >> 7) & 0x1); + xmc[34] = (gsmword)((*c >> 4) & 0x7); + xmc[35] = (gsmword)((*c >> 1) & 0x7); + xmc[36] = (gsmword)((*c++ & 0x1) << 2); + xmc[36] |= (gsmword)((*c >> 6) & 0x3); + xmc[37] = (gsmword)((*c >> 3) & 0x7); + xmc[38] = (gsmword)(*c++ & 0x7); + Nc[3] = (gsmword)((*c >> 1) & 0x7F); + bc[3] = (gsmword)((*c++ & 0x1) << 1); + bc[3] |= (gsmword)((*c >> 7) & 0x1); + Mc[3] = (gsmword)((*c >> 5) & 0x3); + xmaxc[3] = (gsmword)((*c++ & 0x1F) << 1); + xmaxc[3] |= (gsmword)((*c >> 7) & 0x1); + xmc[39] = (gsmword)((*c >> 4) & 0x7); + xmc[40] = (gsmword)((*c >> 1) & 0x7); + xmc[41] = (gsmword)((*c++ & 0x1) << 2); + xmc[41] |= (gsmword)((*c >> 6) & 0x3); + xmc[42] = (gsmword)((*c >> 3) & 0x7); + xmc[43] = (gsmword)(*c++ & 0x7); /* 30 */ + xmc[44] = (gsmword)((*c >> 5) & 0x7); + xmc[45] = (gsmword)((*c >> 2) & 0x7); + xmc[46] = (gsmword)((*c++ & 0x3) << 1); + xmc[46] |= (gsmword)((*c >> 7) & 0x1); + xmc[47] = (gsmword)((*c >> 4) & 0x7); + xmc[48] = (gsmword)((*c >> 1) & 0x7); + xmc[49] = (gsmword)((*c++ & 0x1) << 2); + xmc[49] |= (gsmword)((*c >> 6) & 0x3); + xmc[50] = (gsmword)((*c >> 3) & 0x7); + xmc[51] = (gsmword)(*c & 0x7); /* 33 */ + } + + Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); + + return GSM_SAMPLES_PER_FRAME; +} diff --git a/tnl-1.5.0/tnl/zap/gsm_encode.c b/tnl-1.5.0/tnl/zap/gsm_encode.c new file mode 100644 index 0000000000000000000000000000000000000000..2f077625e4f5ebbfac62eb36ef7d0db44e461ebb --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gsm_encode.c @@ -0,0 +1,1113 @@ +/* + GSM voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com) + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +#include "private.h" + +static unsigned char const bitoff[ 256 ] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static gsmword gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; +static gsmword gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; +static gsmword gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; +static gsmword gsm_DLB[4] = {6554, 16384, 26214, 32767}; + +static gsmword gsm_norm(longword a) +{ + if(a < 0) + { + if(a <= -1073741824) + return 0; + a = ~a; + } + + return (gsmword)(a & 0xffff0000 + ? ( a & 0xff000000 + ? -1 + bitoff[ 0xFF & (a >> 24) ] + : 7 + bitoff[ 0xFF & (a >> 16) ] ) + : ( a & 0xff00 + ? 15 + bitoff[ 0xFF & (a >> 8) ] + : 23 + bitoff[ 0xFF & a ] )); +} + +static void Gsm_Preprocess(struct gsm_state * S, short *s, gsmword *so) +{ + gsmword z1 = S->z1; + longword L_z2 = S->L_z2; + gsmword mp = (gsmword)S->mp; + gsmword s1; + longword L_s2; + longword L_temp; + gsmword msp; + gsmword SO; + int k = 160; + + while(k--) + { + + SO = (gsmword)(SASL( SASR( *s, 3 ), 2 )); + s++; + + s1 = (gsmword)(SO - z1); + z1 = SO; + + L_s2 = s1; + L_s2 = SASL( L_s2, 15 ); + + L_z2 += L_s2; + L_temp = L_z2 + 16384; + + msp = (gsmword)GSM_MULT_R( mp, -28672 ); + mp = (gsmword)SASR( L_temp, 15 ); + *so++ = (gsmword)(mp + msp); + } + + S->z1 = z1; + S->L_z2 = L_z2; + S->mp = mp; +} + +static void Autocorrelation(gsmword *s, longword *L_ACF) +{ + int k, i; + gsmword * sp = s; + gsmword sl; + gsmword temp, smax, scalauto; + gsmword ss[160]; + gsmword * ssp = ss; + + smax = 0; + for(k = 160; k--; sp++) + { + temp = (gsmword)GSM_ABS( *sp ); + if(temp > smax) + smax = temp; + } + + if(smax == 0) + { + scalauto = 0; + } + else { + scalauto = (gsmword)(4 - gsm_norm( SASL( (longword)smax, 16 ) ));/* sub(4,..) */ + } + + sp = s; + if(scalauto > 0) + { + for(k = 160; k--; sp++, ssp++) + *ssp = (gsmword)SASR( *sp, scalauto ); + } + else + { + memcpy(ssp, sp, sizeof(ss)); + } + +# define STEP(k) L_ACF[k] += ((longword)sl * ssp[ -(k) ]); + +# define NEXTI sl = *++ssp + + ssp = ss; + sl = *ssp; + for(k = 9; k--; L_ACF[k] = 0) ; + + STEP (0); + NEXTI; + STEP(0); STEP(1); + NEXTI; + STEP(0); STEP(1); STEP(2); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); + NEXTI; + STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); + + for(i = 8; i < 160; i++) + { + + NEXTI; + + STEP(0); + STEP(1); STEP(2); STEP(3); STEP(4); + STEP(5); STEP(6); STEP(7); STEP(8); + } + + for(k = 9; k--; L_ACF[k] *= 2) ; + +} + +static void Reflection_coefficients(longword *L_ACF, gsmword *r) +{ + int i, m, n; + gsmword temp; + gsmword ACF[9]; /* 0..8 */ + gsmword P[ 9]; /* 0..8 */ + gsmword K[ 9]; /* 2..8 */ + + if(L_ACF[0] == 0) + { + for(i = 8; i--; *r++ = 0) ; + return; + } + + temp = gsm_norm( L_ACF[0] ); + + for(i = 0; i <= 8; i++) + ACF[i] = (gsmword)SASR( SASL (L_ACF[i], temp ), 16 ); + + for(i = 1; i <= 7; i++) + K[ i ] = ACF[ i ]; + + for(i = 0; i <= 8; i++) + P[ i ] = ACF[ i ]; + + for(n = 1; n <= 8; n++, r++) + { + + temp = P[1]; + temp = (gsmword)GSM_ABS(temp); + if(P[0] < temp) + { + for(i = n; i <= 8; i++) + *r++ = 0; + return; + } + + *r = gsm_div( temp, P[0] ); + + if(P[1] > 0) + *r = (gsmword)-*r; + + if(n == 8) + return; + + temp = (gsmword)GSM_MULT_R( P[1], *r ); + P[0] += temp; + + for(m = 1; m <= 8 - n; m++) + { + P[m] = (gsmword)P[ m+1 ] + (gsmword)GSM_MULT_R( K[m], *r ); + K[m] = (gsmword)K[ m ] + (gsmword)GSM_MULT_R( P[ m+1 ], *r ); + } + } +} + +static void Transformation_to_Log_Area_Ratios(gsmword *r) +{ + gsmword temp; + int i; + + for(i = 1; i <= 8; i++, r++) + { + + temp = *r; + temp = (gsmword)GSM_ABS(temp); + + if(temp < 22118) + { + temp = (gsmword)SASR( temp, 1 ); + } + else if(temp < 31130) + { + temp -= 11059; + } + else + { + temp -= 26112; + temp = (gsmword)SASL( temp, 2 ); + } + + *r = (gsmword)(*r < 0 ? -temp : temp); + } +} + +static void Quantization_and_coding(gsmword *LAR) +{ + gsmword temp; + +# undef STEP +# define STEP( A, B, MAC, MIC ) \ + temp = (gsmword)GSM_MULT( A, *LAR ); \ + temp += B; \ + temp += 256; \ + temp = (gsmword)SASR( temp, 9 ); \ + *LAR = (gsmword)(temp>MAC ? MAC - MIC : (temp EM) + { + Mc = 1; + EM = L_result; + } + + L_result = 0; + STEP( 2, 0 ); + STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); + STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); + STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); + L_result = SASL( L_result, 1 ); + + if(L_result > EM) + { + Mc = 2; + EM = L_result; + } + + L_result = L_common_0_3; + STEP( 3, 12 ); + L_result = SASL( L_result, 1 ); + if(L_result > EM) + { + Mc = 3; + EM = L_result; + } + + for(i = 0; i <= 12; i ++) + xM[i] = x[Mc + 3*i]; + + *Mc_out = Mc; +} + +static void APCM_quantization_xmaxc_to_exp_mant(gsmword xmaxc, gsmword *exp_out, + gsmword *mant_out) +{ + gsmword exp, mant; + + exp = 0; + if(xmaxc > 15) + exp = (gsmword)(SASR(xmaxc, 3) - 1); + mant = (gsmword)(xmaxc - SASL( exp, 3 )); + + if(mant == 0) + { + exp = -4; + mant = 7; + } + else + { + while(mant <= 7) + { + mant = (gsmword)(SASL(mant, 1) | 1); + exp--; + } + mant -= 8; + } + + *exp_out = exp; + *mant_out = mant; +} + +static void APCM_quantization(gsmword *xM, gsmword *xMc, gsmword *mant_out, + gsmword *exp_out, gsmword *xmaxc_out) +{ + int i, itest; + gsmword xmax, xmaxc, temp, temp1, temp2; + gsmword exp, mant; + longword ltmp; + + xmax = 0; + for(i = 0; i <= 12; i++) + { + temp = xM[i]; + temp = (gsmword)GSM_ABS(temp); + if (temp > xmax) xmax = temp; + } + + exp = 0; + temp = (gsmword)SASR( xmax, 9 ); + itest = 0; + + for(i = 0; i <= 5; i++) + { + + itest |= (temp <= 0); + temp = (gsmword)SASR( temp, 1 ); + + if(itest == 0) + exp++; /* exp = add (exp, 1) */ + } + + temp = (gsmword)(exp + 5); + xmaxc = (gsmword)GSM_ADD( (gsmword)SASR(xmax, temp), (gsmword)SASL(exp, 3) ); + + APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); + + temp1 = (gsmword)(6 - exp); /* normalization by the exponent */ + temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ + + for(i = 0; i <= 12; i++) + { + temp = (gsmword)SASL(xM[i], temp1); + temp = (gsmword)GSM_MULT( temp, temp2 ); + temp = (gsmword)SASR(temp, 12); + xMc[i] = (gsmword)(temp + 4); + } + + *mant_out = mant; + *exp_out = exp; + *xmaxc_out = xmaxc; +} + +static void APCM_inverse_quantization(gsmword *xMc, gsmword mant, gsmword exp, gsmword *xMp) +{ + int i; + gsmword temp, temp1, temp2, temp3; + longword ltmp; + + temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ + temp2 = (gsmword)GSM_SUB( 6, exp ); /* see 4.2-15 for exp */ + temp3 = (gsmword)SASL( 1, GSM_SUB( temp2, 1 )); + + for(i = 13; i--;) + { + + temp = (gsmword)(SASL(*xMc++, 1) - 7); /* restore sign */ + + temp = (gsmword)SASL(temp, 12); /* 16 bit signed */ + temp = (gsmword)GSM_MULT_R( temp1, temp ); + temp = (gsmword)GSM_ADD( temp, temp3 ); + *xMp++ = (gsmword)SASR( temp, temp2 ); + } +} + +static void RPE_grid_positioning(gsmword Mc, gsmword *xMp, gsmword *ep) +{ + int i = 13; + + switch (Mc) { + case 3: *ep++ = 0; + case 2: do + { + *ep++ = 0; + case 1: *ep++ = 0; + case 0: *ep++ = *xMp++; + } while (--i != 0); + } + while(++Mc < 4) + *ep++ = 0; +} + +static void Gsm_RPE_Encoding(gsmword *e, gsmword *xmaxc, gsmword *Mc, gsmword *xMc) +{ + gsmword x[40]; + gsmword xM[13], xMp[13]; + gsmword mant, exp; + + Weighting_filter(e, x); + RPE_grid_selection(x, xM, Mc); + + APCM_quantization( xM, xMc, &mant, &exp, xmaxc); + APCM_inverse_quantization( xMc, mant, exp, xMp); + + RPE_grid_positioning( *Mc, xMp, e ); +} + +static void Decoding_of_the_coded_Log_Area_Ratios(gsmword *LARc, gsmword *LARpp) +{ + gsmword temp1; + longword ltmp; + +#undef STEP +#define STEP( B, MIC, INVA ) \ + temp1 = (gsmword)(SASL( *LARc++ + MIC , 10)); \ + temp1 -= SASL( B, 1 ); \ + temp1 = (gsmword)GSM_MULT_R( INVA, temp1 ); \ + *LARpp++ = (gsmword)GSM_ADD( temp1, temp1 ); + + STEP( 0, -32, 13107 ); + STEP( 0, -32, 13107 ); + STEP( 2048, -16, 13107 ); + STEP( -2560, -16, 13107 ); + + STEP( 94, -8, 19223 ); + STEP( -1792, -8, 17476 ); + STEP( -341, -4, 31454 ); + STEP( -1144, -4, 29708 ); + +} + +INLINE void Coefficients_0_12(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) + { + *LARp = (gsmword)(SASR( *LARpp_j_1, 2 ) + SASR( *LARpp_j, 2 )); + *LARp += (gsmword)SASR( *LARpp_j_1, 1); + } +} + +INLINE void Coefficients_13_26(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) + *LARp = SASR( *LARpp_j_1, 1) + SASR( *LARpp_j, 1 ); +} + +INLINE void Coefficients_27_39(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) + { + *LARp = (gsmword)(SASR( *LARpp_j_1, 2 ) + SASR( *LARpp_j, 2 )); + *LARp += (gsmword)SASR( *LARpp_j, 1 ); + } +} + +INLINE void Coefficients_40_159(gsmword * LARpp_j, gsmword * LARp) +{ + int i; + + for(i = 1; i <= 8; i++, LARp++, LARpp_j++) + *LARp = *LARpp_j; +} + +static void LARp_to_rp(gsmword * LARp) +{ + int i; + gsmword temp; + + for(i = 1; i <= 8; i++, LARp++) + { + if(*LARp < 0) + { + temp = (gsmword)GSM_ABS( *LARp ); + *LARp = (gsmword)(- ((temp < 11059) ? SASL( temp, 1 ) + : ((temp < 20070) ? temp + 11059 + : ( SASR( temp, 2 ) + 26112 )))); + } + else + { + temp = *LARp; + *LARp = (gsmword)((temp < 11059) ? SASL( temp, 1 ) + : ((temp < 20070) ? temp + 11059 + : ( SASR( temp, 2 ) + 26112 ))); + } + } +} + +static void Short_term_analysis_filtering(struct gsm_state *S, gsmword *rp, + int k_n, gsmword *s) +{ + gsmword *u = S->u; + gsmword di, ui, sav; + longword ltmp; + gsmword u0=u[0], u1=u[1], u2=u[2], u3=u[3], + u4=u[4], u5=u[5], u6=u[6], u7=u[7]; + gsmword rp0, rp1, rp2, rp3, + rp4, rp5, rp6, rp7; + + rp0 = rp[0]; rp1 = rp[1]; + rp2 = rp[2]; rp3 = rp[3]; + rp4 = rp[4]; rp5 = rp[5]; + rp6 = rp[6]; rp7 = rp[7]; + + while( k_n-- != 0) + { + + di = sav = *s; + + ui = u0; + u0 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp0, di); + di += (gsmword)GSM_MULT_R(rp0, ui); + + ui = u1; + u1 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp1, di); + di += (gsmword)GSM_MULT_R(rp1, ui); + + ui = u2; + u2 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp2, di); + di += (gsmword)GSM_MULT_R(rp2, ui); + + ui = u3; + u3 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp3, di); + di += (gsmword)GSM_MULT_R(rp3, ui); + + ui = u4; + u4 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp4, di); + di += (gsmword)GSM_MULT_R(rp4, ui); + + ui = u5; + u5 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp5,di); + di += (gsmword)GSM_MULT_R(rp5,ui); + + ui = u6; + u6 = sav; + + sav = ui + (gsmword)GSM_MULT_R(rp6,di); + di += (gsmword)GSM_MULT_R(rp6,ui); + + ui = u7; + u7 = sav; + + *s++ = (gsmword)GSM_ADD( di, (gsmword)GSM_MULT_R(rp7,ui) ); /* This GSM_ADD is needed for over/under flow */ + } + u[0]=GSM_ADD(u0, 0); + u[1]=GSM_ADD(u1, 0); + u[2]=GSM_ADD(u2, 0); + u[3]=GSM_ADD(u3, 0); + u[4]=GSM_ADD(u4, 0); + u[5]=GSM_ADD(u5, 0); + u[6]=GSM_ADD(u6, 0); + u[7]=GSM_ADD(u7, 0); +} + +static void Gsm_Short_Term_Analysis_Filter( struct gsm_state *S, gsmword *LARc, gsmword *s) +{ + gsmword * LARpp_j = S->LARpp[ S->j ]; + gsmword * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; + + gsmword LARp[8]; + + Decoding_of_the_coded_Log_Area_Ratios(LARc, LARpp_j); + + Coefficients_0_12(LARpp_j_1, LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_analysis_filtering(S, LARp, 13, s); + + Coefficients_13_26(LARpp_j_1, LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_analysis_filtering(S, LARp, 14, s + 13); + + Coefficients_27_39(LARpp_j_1, LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_analysis_filtering(S, LARp, 13, s + 27); + + Coefficients_40_159(LARpp_j, LARp); + LARp_to_rp(LARp); + Short_term_analysis_filtering(S, LARp, 120, s + 40); +} + +static void Calculation_of_the_LTP_parameters(gsmword *d, gsmword *dp, + gsmword *bc_out, gsmword *Nc_out) +{ + int k, lambda; + gsmword Nc, bc; + gsmword wt[40]; + gsmword * pwt = wt; + longword L_max, L_power; + gsmword R, S, dmax, scal; + gsmword temp; + gsmword * pd = d; + + dmax = 0; + + for (k = 0; k < 40; k+=8) + { +# undef STEP +# define STEP temp = (gsmword)GSM_ABS( *pd );\ + if (temp > dmax) dmax = temp;\ + pd++; + + STEP;STEP;STEP;STEP; + STEP;STEP;STEP;STEP; + } + + temp = 0; + if(dmax == 0) + scal = 0; + else + temp = gsm_norm( SASL( (longword)dmax, 16 ) ); + + if(temp > 6) + scal = 0; + else + scal = (gsmword)(6 - temp); + + pd = d; + for (k = 0; k < 40; k+=8) + { +# undef STEP +# define STEP *pwt = (gsmword)SASR( *pd, scal ); pd++; pwt++; + + STEP;STEP;STEP;STEP; + STEP;STEP;STEP;STEP; + } + + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + + for (lambda = 40; lambda <= 120; lambda++) + { + +# undef STEP +# define STEP(k) (longword)wt[k] * dp[k - lambda]; + + register longword L_result; + + L_result = STEP(0) ; L_result += STEP(1) ; + L_result += STEP(2) ; L_result += STEP(3) ; + L_result += STEP(4) ; L_result += STEP(5) ; + L_result += STEP(6) ; L_result += STEP(7) ; + L_result += STEP(8) ; L_result += STEP(9) ; + L_result += STEP(10) ; L_result += STEP(11) ; + L_result += STEP(12) ; L_result += STEP(13) ; + L_result += STEP(14) ; L_result += STEP(15) ; + L_result += STEP(16) ; L_result += STEP(17) ; + L_result += STEP(18) ; L_result += STEP(19) ; + L_result += STEP(20) ; L_result += STEP(21) ; + L_result += STEP(22) ; L_result += STEP(23) ; + L_result += STEP(24) ; L_result += STEP(25) ; + L_result += STEP(26) ; L_result += STEP(27) ; + L_result += STEP(28) ; L_result += STEP(29) ; + L_result += STEP(30) ; L_result += STEP(31) ; + L_result += STEP(32) ; L_result += STEP(33) ; + L_result += STEP(34) ; L_result += STEP(35) ; + L_result += STEP(36) ; L_result += STEP(37) ; + L_result += STEP(38) ; L_result += STEP(39) ; + + if (L_result > L_max) + { + + Nc = (gsmword)lambda; + L_max = L_result; + } + } + + *Nc_out = Nc; + + L_max = SASL(L_max, 1 ); + + L_max = SASR( L_max, (6 - scal) ); /* sub(6, scal) */ + + L_power = 0; + for (k = 0; k < 40; k+=4) + { + + register longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + + L_temp = SASR( dp[k + 1 - Nc], 3 ); + L_power += L_temp * L_temp; + + L_temp = SASR( dp[k + 2 - Nc], 3 ); + L_power += L_temp * L_temp; + + L_temp = SASR( dp[k + 3 - Nc], 3 ); + L_power += L_temp * L_temp; + + } + L_power = SASL( L_power, 1 ); + + if (L_max <= 0) + { + *bc_out = 0; + return; + } + if (L_max >= L_power) + { + *bc_out = 3; + return; + } + + temp = gsm_norm( L_power ); + + R = (gsmword)SASR( SASL( L_max, temp ), 16 ); + S = (gsmword)SASR( SASL( L_power, temp ), 16 ); + + for(bc = 0; bc <= 2; bc++) + { + if(R <= GSM_MULT(S, gsm_DLB[bc])) + break; + } + *bc_out = bc; +} + +static void Cut_Calculation_of_the_LTP_parameters(gsmword *d, gsmword *dp, + gsmword *bc_out, gsmword *Nc_out) +{ + int k, lambda; + gsmword Nc, bc; + + longword L_result; + longword L_max, L_power; + gsmword R, S, dmax, scal, best_k; + + gsmword temp, wt_k; + + dmax = best_k = 0; + for (k = 0; k <= 39; k++) + { + temp = (gsmword)GSM_ABS( d[k] ); + if (temp > dmax) + { + dmax = temp; + best_k = (gsmword)k; + } + } + temp = 0; + if (dmax == 0) + { + scal = 0; + } + else + { + temp = gsm_norm( (longword)dmax << 16 ); + } + if (temp > 6) scal = 0; + else scal = (gsmword)(6 - temp); + + L_max = 0; + Nc = 40; /* index for the maximum cross-correlation */ + wt_k = (gsmword)SASR(d[best_k], scal); + + for (lambda = 40; lambda <= 120; lambda++) + { + L_result = (longword)wt_k * dp[best_k - lambda]; + if (L_result > L_max) + { + Nc = (gsmword)lambda; + L_max = L_result; + } + } + *Nc_out = Nc; + L_max <<= 1; + + L_max = L_max >> (6 - scal); /* sub(6, scal) */ + + L_power = 0; + for (k = 0; k <= 39; k++) + { + longword L_temp; + + L_temp = SASR( dp[k - Nc], 3 ); + L_power += L_temp * L_temp; + } + L_power <<= 1; + + if (L_max <= 0) + { + *bc_out = 0; + return; + } + if (L_max >= L_power) + { + *bc_out = 3; + return; + } + + temp = gsm_norm(L_power); + + R = (gsmword)SASR( SASL(L_max, temp), 16 ); + S = (gsmword)SASR( SASL(L_power, temp), 16 ); + + for (bc = 0; bc <= 2; bc++) + { + if (R <= GSM_MULT(S, gsm_DLB[bc])) + break; + } + *bc_out = bc; +} + +static void Long_term_analysis_filtering(gsmword bc, gsmword Nc, gsmword *dp, gsmword *d, + gsmword *dpp, gsmword *e) +{ + int k; + + dp -= Nc; + +# undef STEP +# define STEP(BP) \ + for (k = 40; k--; e++, dpp++, d++, *dp++) { \ + *dpp = (gsmword)GSM_MULT_R( BP, *dp); \ + *e = (gsmword)( *d - *dpp ); \ + } + + switch (bc) { + case 0: STEP( 3277 ); break; + case 1: STEP( 11469 ); break; + case 2: STEP( 21299 ); break; + case 3: STEP( 32767 ); break; + } +} + +static void Gsm_Long_Term_Predictor(struct gsm_state *S, gsmword *d, gsmword *dp, gsmword *e, + gsmword *dpp, gsmword *Nc, gsmword *bc) +{ + if(S->ltp_cut != 0) + { + Cut_Calculation_of_the_LTP_parameters(d, dp, bc, Nc); + } + else + { + Calculation_of_the_LTP_parameters(d, dp, bc, Nc); + } + + Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); +} + +static void Gsm_Coder(struct gsm_state *S, short *s, gsmword *LARc, gsmword *Nc, + gsmword *bc, gsmword *Mc, gsmword *xmaxc, gsmword *xMc) +{ + int k; + gsmword *dp = S->dp0 + 120; /* [ -120...-1 ] */ + gsmword e[50]; + gsmword *pe = &e[5]; + gsmword so[160]; + + memset(e, 0, sizeof(e)); + Gsm_Preprocess(S, s, so); + Gsm_LPC_Analysis(so, LARc); + Gsm_Short_Term_Analysis_Filter (S, LARc, so); + + for (k = 0; k <= 3; k++, xMc += 13) + { + int i; + + Gsm_Long_Term_Predictor(S, so+k*40, dp, pe, dp, Nc++, bc++); + + Gsm_RPE_Encoding(pe, xmaxc++, Mc++, xMc ); + + for (i = 0; i <= 39; i++, dp++) + *dp += (gsmword)pe[i]; + } + (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), 120 * sizeof(*S->dp0) ); +} + +int gsm_encode(struct gsm_state * s, short * source, unsigned char * c) +{ + gsmword LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; + + Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); + + *c++ = (unsigned char)(((GSM_MAGIC & 0xF) << 4) /* 1 */ + | ((LARc[0] >> 2) & 0xF)); + *c++ = (unsigned char)(((LARc[0] & 0x3) << 6) + | (LARc[1] & 0x3F)); + *c++ = (unsigned char)(((LARc[2] & 0x1F) << 3) + | ((LARc[3] >> 2) & 0x7)); + *c++ = (unsigned char)(((LARc[3] & 0x3) << 6) + | ((LARc[4] & 0xF) << 2) + | ((LARc[5] >> 2) & 0x3)); + *c++ = (unsigned char)(((LARc[5] & 0x3) << 6) + | ((LARc[6] & 0x7) << 3) + | (LARc[7] & 0x7)); + *c++ = (unsigned char)(((Nc[0] & 0x7F) << 1) + | ((bc[0] >> 1) & 0x1)); + *c++ = (unsigned char)(((bc[0] & 0x1) << 7) + | ((Mc[0] & 0x3) << 5) + | ((xmaxc[0] >> 1) & 0x1F)); + *c++ = (unsigned char)(((xmaxc[0] & 0x1) << 7) + | ((xmc[0] & 0x7) << 4) + | ((xmc[1] & 0x7) << 1) + | ((xmc[2] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[2] & 0x3) << 6) + | ((xmc[3] & 0x7) << 3) + | (xmc[4] & 0x7)); + *c++ = (unsigned char)(((xmc[5] & 0x7) << 5) /* 10 */ + | ((xmc[6] & 0x7) << 2) + | ((xmc[7] >> 1) & 0x3)); + *c++ = (unsigned char)(((xmc[7] & 0x1) << 7) + | ((xmc[8] & 0x7) << 4) + | ((xmc[9] & 0x7) << 1) + | ((xmc[10] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[10] & 0x3) << 6) + | ((xmc[11] & 0x7) << 3) + | (xmc[12] & 0x7)); + *c++ = (unsigned char)(((Nc[1] & 0x7F) << 1) + | ((bc[1] >> 1) & 0x1)); + *c++ = (unsigned char)(((bc[1] & 0x1) << 7) + | ((Mc[1] & 0x3) << 5) + | ((xmaxc[1] >> 1) & 0x1F)); + *c++ = (unsigned char)(((xmaxc[1] & 0x1) << 7) + | ((xmc[13] & 0x7) << 4) + | ((xmc[14] & 0x7) << 1) + | ((xmc[15] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[15] & 0x3) << 6) + | ((xmc[16] & 0x7) << 3) + | (xmc[17] & 0x7)); + *c++ = (unsigned char)(((xmc[18] & 0x7) << 5) + | ((xmc[19] & 0x7) << 2) + | ((xmc[20] >> 1) & 0x3)); + *c++ = (unsigned char)(((xmc[20] & 0x1) << 7) + | ((xmc[21] & 0x7) << 4) + | ((xmc[22] & 0x7) << 1) + | ((xmc[23] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[23] & 0x3) << 6) + | ((xmc[24] & 0x7) << 3) + | (xmc[25] & 0x7)); + *c++ = (unsigned char)(((Nc[2] & 0x7F) << 1) /* 20 */ + | ((bc[2] >> 1) & 0x1)); + *c++ = (unsigned char)(((bc[2] & 0x1) << 7) + | ((Mc[2] & 0x3) << 5) + | ((xmaxc[2] >> 1) & 0x1F)); + *c++ = (unsigned char)(((xmaxc[2] & 0x1) << 7) + | ((xmc[26] & 0x7) << 4) + | ((xmc[27] & 0x7) << 1) + | ((xmc[28] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[28] & 0x3) << 6) + | ((xmc[29] & 0x7) << 3) + | (xmc[30] & 0x7)); + *c++ = (unsigned char)(((xmc[31] & 0x7) << 5) + | ((xmc[32] & 0x7) << 2) + | ((xmc[33] >> 1) & 0x3)); + *c++ = (unsigned char)(((xmc[33] & 0x1) << 7) + | ((xmc[34] & 0x7) << 4) + | ((xmc[35] & 0x7) << 1) + | ((xmc[36] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[36] & 0x3) << 6) + | ((xmc[37] & 0x7) << 3) + | (xmc[38] & 0x7)); + *c++ = (unsigned char)(((Nc[3] & 0x7F) << 1) + | ((bc[3] >> 1) & 0x1)); + *c++ = (unsigned char)(((bc[3] & 0x1) << 7) + | ((Mc[3] & 0x3) << 5) + | ((xmaxc[3] >> 1) & 0x1F)); + *c++ = (unsigned char)(((xmaxc[3] & 0x1) << 7) + | ((xmc[39] & 0x7) << 4) + | ((xmc[40] & 0x7) << 1) + | ((xmc[41] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[41] & 0x3) << 6) /* 30 */ + | ((xmc[42] & 0x7) << 3) + | (xmc[43] & 0x7)); + *c++ = (unsigned char)(((xmc[44] & 0x7) << 5) + | ((xmc[45] & 0x7) << 2) + | ((xmc[46] >> 1) & 0x3)); + *c++ = (unsigned char)(((xmc[46] & 0x1) << 7) + | ((xmc[47] & 0x7) << 4) + | ((xmc[48] & 0x7) << 1) + | ((xmc[49] >> 2) & 0x1)); + *c++ = (unsigned char)(((xmc[49] & 0x3) << 6) + | ((xmc[50] & 0x7) << 3) + | (xmc[51] & 0x7)); + + return GSM_ENCODED_FRAME_SIZE; +} diff --git a/tnl-1.5.0/tnl/zap/gsm_state.c b/tnl-1.5.0/tnl/zap/gsm_state.c new file mode 100644 index 0000000000000000000000000000000000000000..841f3da7027a34531b13a9d3bf69ff168871529e --- /dev/null +++ b/tnl-1.5.0/tnl/zap/gsm_state.c @@ -0,0 +1,71 @@ +/* + GSM voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com) + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + +#if !defined( MACOSX ) && !defined (__APPLE__) +#include +#endif +#include + +#include "private.h" + +struct gsm_state *gsm_create(void) +{ + struct gsm_state * r; + + r = (struct gsm_state *)malloc(sizeof(struct gsm_state)); + if (!r) return r; + + memset((char *)r, 0, sizeof(*r)); + r->nrp = 40; + + return r; +} + +void gsm_destroy(struct gsm_state *S) +{ + if(S != NULL) + free(S); +} + +int gsm_option( struct gsm_state *r, int opt, int *val) +{ + int result = -1; + + switch (opt) { + case GSM_OPT_LTP_CUT: + result = r->ltp_cut; + if(val != NULL) + r->ltp_cut = (gsmword)*val; + break; + + default: + break; + } + return result; +} diff --git a/tnl-1.5.0/tnl/zap/huntersGame.cpp b/tnl-1.5.0/tnl/zap/huntersGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fce7d4323d66ae3cb6a2887221f6115a6e5e8dd5 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/huntersGame.cpp @@ -0,0 +1,490 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "huntersGame.h" +#include "flagItem.h" +#include "glutInclude.h" +#include "UIGame.h" +#include "sfx.h" +#include "gameNetInterface.h" +#include "ship.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(HuntersGameType); + + +TNL_IMPLEMENT_NETOBJECT_RPC(HuntersGameType, s2cSetNexusTimer, + (U32 nexusTime, bool canCap), (nexusTime, canCap), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0) +{ + mNexusReturnTimer.reset(nexusTime); + mCanNexusCap = canCap; +} + +GAMETYPE_RPC_S2C(HuntersGameType, s2cAddYardSaleWaypoint, (F32 x, F32 y), (x, y)) +{ + YardSaleWaypoint w; + w.timeLeft.reset(YardSaleWaypointTime); + w.pos.set(x,y); + mYardSaleWaypoints.push_back(w); +} + +TNL_IMPLEMENT_NETOBJECT_RPC(HuntersGameType, s2cHuntersMessage, + (U32 msgIndex, StringTableEntry clientName, U32 flagCount), (msgIndex, clientName, flagCount), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0) +{ + if(msgIndex == HuntersMsgScore) + { + SFXObject::play(SFXFlagCapture); + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "%s returned %d flag(s) to the Nexus!", + clientName.getString(), + flagCount); + } + else if(msgIndex == HuntersMsgYardSale) + { + SFXObject::play(SFXFlagSnatch); + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "%s is having a YARD SALE!", + clientName.getString()); + } + else if(msgIndex == HuntersMsgGameOverWin) + { + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "Player %s wins the game!", + clientName.getString()); + SFXObject::play(SFXFlagCapture); + } + else if(msgIndex == HuntersMsgGameOverTie) + { + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "The game ended in a tie."); + SFXObject::play(SFXFlagDrop); + } +} + +HuntersGameType::HuntersGameType() : GameType() +{ + mCanNexusCap = false; + mNexusReturnDelay = 60 * 1000; + mNexusCapDelay = 15 * 1000; + mNexusReturnTimer.reset(mNexusReturnDelay); + mNexusCapTimer.reset(0); +} + +void HuntersGameType::addNexus(HuntersNexusObject *nexus) +{ + mNexus = nexus; +} + +void HuntersGameType::processArguments(S32 argc, const char **argv) +{ + if(argc > 0) + { + mGameTimer.reset(U32(atof(argv[0]) * 60 * 1000)); + if(argc > 1) + { + mNexusReturnDelay = atoi(argv[1]) * 60 * 1000; + if(argc > 2) + { + mNexusCapDelay = atoi(argv[2]) * 1000; + if(argc > 3) + mTeamScoreLimit = atoi(argv[3]); + } + } + } + mNexusReturnTimer.reset(mNexusReturnDelay); +} + +void HuntersGameType::shipTouchNexus(Ship *theShip, HuntersNexusObject *theNexus) +{ + HuntersFlagItem *theFlag = NULL; + for(S32 i = theShip->mMountedItems.size() - 1; i >= 0; i--) + { + Item *theItem = theShip->mMountedItems[i]; + theFlag = dynamic_cast(theItem); + if(theFlag) + break; + } + + U32 score = 0; + for(U32 count = 1; count < theFlag->getFlagCount() + 1; count++) + score += (count * 10); + + ClientRef *cl = theShip->getControllingClient()->getClientRef(); + cl->score += score; + + if(theFlag->getFlagCount() > 0) + s2cHuntersMessage(HuntersMsgScore, theShip->mPlayerName.getString(), theFlag->getFlagCount()); + theFlag->changeFlagCount(0); +} + +void HuntersGameType::onGhostAvailable(GhostConnection *theConnection) +{ + Parent::onGhostAvailable(theConnection); + + NetObject::setRPCDestConnection(theConnection); + if(mCanNexusCap) + s2cSetNexusTimer(mNexusCapTimer.getCurrent(), mCanNexusCap); + else + s2cSetNexusTimer(mNexusReturnTimer.getCurrent(), mCanNexusCap); + NetObject::setRPCDestConnection(NULL); +} + +void HuntersGameType::idle(GameObject::IdleCallPath path) +{ + Parent::idle(path); + + U32 deltaT = mCurrentMove.time; + if(isGhost()) + { + mNexusReturnTimer.update(deltaT); + for(S32 i = 0; i < mYardSaleWaypoints.size();) + { + if(mYardSaleWaypoints[i].timeLeft.update(deltaT)) + mYardSaleWaypoints.erase_fast(i); + else + i++; + } + return; + } + + if(mNexusReturnTimer.update(deltaT)) + { + mNexusCapTimer.reset(mNexusCapDelay); + mCanNexusCap = true; + s2cSetNexusTimer(mNexusCapTimer.getCurrent(), mCanNexusCap); + static StringTableEntry msg("The Nexus is now OPEN!"); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessage( + GameConnection::ColorNuclearGreen, SFXFlagSnatch, msg); + } + else if(mNexusCapTimer.update(deltaT)) + { + mNexusReturnTimer.reset(mNexusReturnDelay); + mCanNexusCap = false; + s2cSetNexusTimer(mNexusReturnTimer.getCurrent(), mCanNexusCap); + static StringTableEntry msg("The Nexus is now CLOSED."); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessage( + GameConnection::ColorNuclearGreen, SFXFlagDrop, msg); + } +} + +void HuntersGameType::renderInterfaceOverlay(bool scoreboardVisible) +{ + Parent::renderInterfaceOverlay(scoreboardVisible); + + glColor3f(1,1,1); + U32 timeLeft = mNexusReturnTimer.getCurrent(); + U32 minsRemaining = timeLeft / (60000); + U32 secsRemaining = (timeLeft - (minsRemaining * 60000)) / 1000; + UserInterface::drawStringf(UserInterface::canvasWidth - UserInterface::horizMargin - 65, + UserInterface::canvasHeight - UserInterface::vertMargin - 45, 20, "%02d:%02d", minsRemaining, secsRemaining); + for(S32 i = 0; i < mYardSaleWaypoints.size(); i++) + renderObjectiveArrow(mYardSaleWaypoints[i].pos, Color(1,1,1)); + renderObjectiveArrow(mNexus, mCanNexusCap ? Color(0,1,0) : Color(0.5, 0, 0)); +} + +void HuntersGameType::controlObjectForClientKilled(GameConnection *theClient, GameObject *clientObject, GameObject *killerObject) +{ + Parent::controlObjectForClientKilled(theClient, clientObject, killerObject); + + Ship *theShip = dynamic_cast(clientObject); + if(!theShip) + return; + + // check for yard sale + for(S32 i = theShip->mMountedItems.size() - 1; i >= 0; i--) + { + Item *theItem = theShip->mMountedItems[i]; + HuntersFlagItem *theFlag = dynamic_cast(theItem); + if(theFlag) + { + if(theFlag->getFlagCount() >= YardSaleCount) + { + Point pos = theFlag->getActualPos(); + s2cAddYardSaleWaypoint(pos.x, pos.y); + s2cHuntersMessage(HuntersMsgYardSale, theShip->mPlayerName.getString(), 0); + } + + return; + } + } +} + +void HuntersGameType::spawnShip(GameConnection *theClient) +{ + Parent::spawnShip(theClient); + ClientRef *cl = theClient->getClientRef(); + setClientShipLoadout(cl, theClient->getLoadout()); + + HuntersFlagItem *newFlag = new HuntersFlagItem(theClient->getControlObject()->getActualPos()); + newFlag->addToGame(getGame()); + newFlag->mountToShip((Ship *) theClient->getControlObject()); + newFlag->changeFlagCount(0); + +} + +TNL_IMPLEMENT_NETOBJECT(HuntersFlagItem); + +HuntersFlagItem::HuntersFlagItem(Point pos) : Item(pos, true, 30, 4) +{ + mObjectTypeMask |= CommandMapVisType; + mNetFlags.set(Ghostable); + mFlagCount = 0; +} + +void HuntersFlagItem::renderItem(Point pos) +{ + if(mMount.isValid() && mMount->isCloakActive()) + return; + + Point offset = pos; + + if(mIsMounted) + offset.set(pos.x + 15, pos.y - 15); + + Color c; + GameType *gt = getGame()->getGameType(); + + c = gt->mTeams[0].color; + + renderFlag(offset, c); + + if(mIsMounted) + { + if(mFlagCount) + { + if(mFlagCount > 20) + glColor3f(1, 0.5, 0.5); + else if(mFlagCount > 10) + glColor3f(1, 1, 0); + else + glColor3f(1, 1, 1); + UserInterface::drawStringf(offset.x - 5, offset.y - 30, 12, "%d", mFlagCount); + } + } +} + +void HuntersFlagItem::onMountDestroyed() +{ + if(!mMount.isValid()) + return; + + // drop at least one flag plus as many as the ship + // carries + for(U32 i = 0; i < mFlagCount + 1; i++) + { + HuntersFlagItem *newFlag = new HuntersFlagItem(mMount->getActualPos()); + newFlag->addToGame(getGame()); + + F32 th = Random::readF() * 2 * 3.14; + F32 f = (Random::readF() * 2 - 1) * 100; + Point vel(cos(th) * f, sin(th) * f); + vel += mMount->getActualVel(); + + newFlag->setActualVel(vel); + } + changeFlagCount(0); + + // now delete yourself + dismount(); + removeFromDatabase(); + deleteObject(); +} + +void HuntersFlagItem::setActualVel(Point v) +{ + mMoveState[ActualState].vel = v; + setMaskBits(WarpPositionMask | PositionMask); +} + +bool HuntersFlagItem::collide(GameObject *hitObject) +{ + if(mIsMounted || !mIsCollideable) + return false; + + if(hitObject->getObjectTypeMask() & BarrierType) + return true; + + if(isGhost() || !(hitObject->getObjectTypeMask() & ShipType)) + return false; + + Ship *theShip = static_cast(hitObject); + if(!theShip) + return false; + + if(theShip->hasExploded) + return false; + + // don't mount to ship, instead increase current mounted HuntersFlag + // flagCount, and remove collided flag from game + for(S32 i = theShip->mMountedItems.size() - 1; i >= 0; i--) + { + Item *theItem = theShip->mMountedItems[i]; + HuntersFlagItem *theFlag = dynamic_cast(theItem); + if(theFlag) + { + theFlag->changeFlagCount(theFlag->getFlagCount() + 1); + break; + } + } + + mIsCollideable = false; + removeFromDatabase(); + deleteObject(); + return true; +} + +U32 HuntersFlagItem::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + U32 retMask = Parent::packUpdate(connection, updateMask, stream); + if(stream->writeFlag(updateMask & FlagCountMask)) + stream->write(mFlagCount); + + return retMask; +} + +void HuntersFlagItem::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + Parent::unpackUpdate(connection, stream); + + if(stream->readFlag()) + stream->read(&mFlagCount); +} + +TNL_IMPLEMENT_NETOBJECT(HuntersNexusObject); + +HuntersNexusObject::HuntersNexusObject() +{ + mObjectTypeMask |= CommandMapVisType; + mNetFlags.set(Ghostable); + nexusBounds.set(Point(), Point()); +} + +void HuntersNexusObject::processArguments(S32 argc, const char **argv) +{ + if(argc < 2) + return; + + Point pos; + pos.read(argv); + pos *= getGame()->getGridSize(); + + Point ext(50, 50); + if(argc > 3) + ext.set(atoi(argv[2]), atoi(argv[3])); + + Point min(pos.x - ext.x, pos.y - ext.y); + Point max(pos.x + ext.x, pos.y + ext.y); + nexusBounds.set(min, max); + setExtent(nexusBounds); +} + +void HuntersNexusObject::onAddedToGame(Game *theGame) +{ + if(!isGhost()) + setScopeAlways(); + ((HuntersGameType *) theGame->getGameType())->addNexus(this); +} + +void HuntersNexusObject::render() +{ + Color c; + HuntersGameType *theGameType = dynamic_cast(getGame()->getGameType()); + if(theGameType && theGameType->mCanNexusCap) + c.set(0,1,0); + else + c.set(0.5, 0, 0); + + glColor(c * 0.5); + glBegin(GL_POLYGON); + glVertex2f(nexusBounds.min.x, nexusBounds.min.y); + glVertex2f(nexusBounds.min.x, nexusBounds.max.y); + glVertex2f(nexusBounds.max.x, nexusBounds.max.y); + glVertex2f(nexusBounds.max.x, nexusBounds.min.y); + glEnd(); + glColor(c); + glBegin(GL_LINE_LOOP); + glVertex2f(nexusBounds.min.x, nexusBounds.min.y); + glVertex2f(nexusBounds.min.x, nexusBounds.max.y); + glVertex2f(nexusBounds.max.x, nexusBounds.max.y); + glVertex2f(nexusBounds.max.x, nexusBounds.min.y); + glEnd(); +} + +bool HuntersNexusObject::getCollisionPoly(Vector &polyPoints) +{ + polyPoints.push_back(nexusBounds.min); + polyPoints.push_back(Point(nexusBounds.max.x, nexusBounds.min.y)); + polyPoints.push_back(nexusBounds.max); + polyPoints.push_back(Point(nexusBounds.min.x, nexusBounds.max.y)); + return true; +} + +bool HuntersNexusObject::collide(GameObject *hitObject) +{ + if(isGhost()) + return false; + + if(!(hitObject->getObjectTypeMask() & ShipType)) + return false; + + if(((Ship *) hitObject)->hasExploded) + return false; + + Ship *theShip = (Ship *)hitObject; + + HuntersGameType *theGameType = dynamic_cast(getGame()->getGameType()); + if(theGameType && theGameType->mCanNexusCap) + theGameType->shipTouchNexus(theShip, this); + + return false; +} + +U32 HuntersNexusObject::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + stream->write(nexusBounds.min.x); + stream->write(nexusBounds.min.y); + stream->write(nexusBounds.max.x); + stream->write(nexusBounds.max.y); + return 0; +} + +void HuntersNexusObject::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + stream->read(&nexusBounds.min.x); + stream->read(&nexusBounds.min.y); + stream->read(&nexusBounds.max.x); + stream->read(&nexusBounds.max.y); + setExtent(nexusBounds); +} + +}; diff --git a/tnl-1.5.0/tnl/zap/huntersGame.h b/tnl-1.5.0/tnl/zap/huntersGame.h new file mode 100644 index 0000000000000000000000000000000000000000..0b0e0c577d36843297be55860b225a982fb1790f --- /dev/null +++ b/tnl-1.5.0/tnl/zap/huntersGame.h @@ -0,0 +1,146 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _HUNTERSGAME_H_ +#define _HUNTERSGAME_H_ + +#include "gameType.h" +#include "item.h" + +namespace Zap +{ + +class Ship; +class HuntersFlagItem; +class HuntersNexusObject; + +class HuntersGameType : public GameType +{ + typedef GameType Parent; + + S32 mNexusReturnDelay; + S32 mNexusCapDelay; + Timer mNexusReturnTimer; + Timer mNexusCapTimer; + + struct YardSaleWaypoint + { + Timer timeLeft; + Point pos; + }; + Vector mYardSaleWaypoints; + SafePtr mNexus; +public: + bool mCanNexusCap; + + HuntersGameType(); + void processArguments(S32 argc, const char **argv); + + void addNexus(HuntersNexusObject *theObject); + void shipTouchNexus(Ship *theShip, HuntersNexusObject *theNexus); + void onGhostAvailable(GhostConnection *theConnection); + void idle(GameObject::IdleCallPath path); + void renderInterfaceOverlay(bool scoreboardVisible); + + void controlObjectForClientKilled(GameConnection *theClient, GameObject *clientObject, GameObject *killerObject); + void spawnShip(GameConnection *theClient); + const char *getGameTypeString() { return "Hunters"; } + const char *getInstructionString() { return "Collect flags from opposing players and bring them to the Nexus!"; } + + enum { + DefaultNexusReturnDelay = 60000, + DefaultNexusCapDelay = 15000, + YardSaleWaypointTime = 5000, + YardSaleCount = 8, + }; + enum { + HuntersMsgScore, + HuntersMsgYardSale, + HuntersMsgGameOverWin, + HuntersMsgGameOverTie, + }; + + TNL_DECLARE_RPC(s2cAddYardSaleWaypoint, (F32 x, F32 y)); + TNL_DECLARE_RPC(s2cSetNexusTimer, (U32 nexusTime, bool canCap)); + TNL_DECLARE_RPC(s2cHuntersMessage, (U32 msgIndex, StringTableEntry clientName, U32 flagCount)); + TNL_DECLARE_CLASS(HuntersGameType); +}; + +class HuntersFlagItem : public Item +{ + typedef Item Parent; + +protected: + enum MaskBits { + FlagCountMask = Parent::FirstFreeMask << 0, + FirstFreeMask = Parent::FirstFreeMask << 1, + }; + + U32 mFlagCount; + +public: + HuntersFlagItem(Point pos = Point()); + + void renderItem(Point pos); + void onMountDestroyed(); + void setActualVel(Point v); + bool collide(GameObject *hitObject); + + void changeFlagCount(U32 change) { mFlagCount = change; setMaskBits(FlagCountMask); } + U32 getFlagCount() { return mFlagCount; } + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + TNL_DECLARE_CLASS(HuntersFlagItem); +}; + +class HuntersNexusObject : public GameObject +{ + typedef GameObject Parent; + Rect nexusBounds; + +public: + HuntersNexusObject(); + + void onAddedToGame(Game *theGame); + void processArguments(S32 argc, const char **argv); + + void render(); + S32 getRenderSortValue() { return -1; } + + bool getCollisionPoly(Vector &polyPoints); + bool collide(GameObject *hitObject); + + U32 packUpdate(GhostConnection *connection, U32 mask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + TNL_DECLARE_CLASS(HuntersNexusObject); +}; + +}; + +#endif // _HUNTERSGAME_H_ diff --git a/tnl-1.5.0/tnl/zap/input.cpp b/tnl-1.5.0/tnl/zap/input.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6538f0f658584907d9cfdd0747b9c17387b9ea5e --- /dev/null +++ b/tnl-1.5.0/tnl/zap/input.cpp @@ -0,0 +1,466 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "input.h" +#include "move.h" +#include "UIMenus.h" +#include "point.h" +#include "tnlJournal.h" +#include +#include "glutInclude.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +extern void drawCircle(Point pos, F32 radius); +void renderControllerButton(F32 x, F32 y, U32 buttonIndex, U32 keyIndex) +{ + S32 joy = OptionsMenuUserInterface::joystickType; + + if(joy == -1) + UserInterface::drawStringf(x, y, 15, "%c", keyIndex); + else if(joy == LogitechWingman) + { + glColor3f(1,1,1); + const char buttons[] = "ABCXYZ"; + drawCircle(Point(x + 8, y + 8), 8); + UserInterface::drawStringf(x + 4, y + 2, 12, "%c", buttons[buttonIndex]); + } + else if(joy == LogitechDualAction) + { + glColor3f(1,1,1); + const char buttons[] = "12347856"; + drawCircle(Point(x + 8, y + 8), 8); + UserInterface::drawStringf(x + 4, y + 2, 12, "%c", buttons[buttonIndex]); + } + else if(joy == SaitekDualAnalog) + { + glColor3f(1,1,1); + const char buttons[] = "123456"; + drawCircle(Point(x + 8, y + 8), 8); + UserInterface::drawStringf(x + 4, y + 2, 12, "%c", buttons[buttonIndex]); + } + else if(joy == PS2DualShock) + { + static F32 color[6][3] = { { 0.5, 0.5, 1 }, + { 1, 0.5, 0.5 }, + { 1, 0.5, 1 }, + { 0.5, 1, 0.5 }, + { 0.7, 0.7, 0.7 }, + { 0.7, 0.7, 0.7 } + }; + Color c(color[buttonIndex][0], color[buttonIndex][1], color[buttonIndex][2]); + glColor3f(1.0, 1.0, 1.0); + Point center(x + 8, y + 8); + if(buttonIndex < 4) + { + drawCircle(center, 8); + glColor(c); + switch(buttonIndex) + { + case 0: + glBegin(GL_LINES); + glVertex(center + Point(-5, -5)); + glVertex(center + Point(5, 5)); + glVertex(center + Point(-5, 5)); + glVertex(center + Point(5, -5)); + glEnd(); + break; + case 1: + drawCircle(center, 5); + break; + case 2: + glBegin(GL_LINE_LOOP); + glVertex(center + Point(-5, -5)); + glVertex(center + Point(-5, 5)); + glVertex(center + Point(5, 5)); + glVertex(center + Point(5, -5)); + glEnd(); + break; + case 3: + glBegin(GL_LINE_LOOP); + glVertex(center + Point(0, -5)); + glVertex(center + Point(5, 3)); + glVertex(center + Point(-5, 3)); + glEnd(); + break; + } + } + else + { + glBegin(GL_LINE_LOOP); + glVertex(center + Point(-8, -8)); + glVertex(center + Point(-8, 8)); + glVertex(center + Point(10, 8)); + glVertex(center + Point(10, -8)); + glEnd(); + static const char *buttonIndexString[4] = { + "L2", "R2", "L1", "R1" + }; + UserInterface::drawString(x + 2, y + 2, 11, buttonIndexString[buttonIndex - 4]); + } + } + else if(joy == XBoxController || joy == XBoxControllerOnXBox) + { + static F32 color[6][3] = { { 0, 1, 0 }, + { 1, 0, 0 }, + { 0, 0, 1 }, + { 1, 1, 0 }, + { 1, 1, 1 }, + { 0, 0, 0} }; + Color c(color[buttonIndex][0], color[buttonIndex][1], color[buttonIndex][2]); + + glColor(c * 0.8f); + fillCircle(Point(x + 8, y + 8), 8); + const char buttons[] = "ABXY "; + glColor3f(1,1,1); + drawCircle(Point(x + 8, y + 8), 8); + glColor(c); + UserInterface::drawStringf(x + 4, y + 2, 12, "%c", buttons[buttonIndex]); + } +} + +static U32 gShootAxisRemaps[ControllerTypeCount][2] = +{ + { 5, 6 }, { 2, 5 }, { 5, 2 }, { 2, 5 }, { 3, 4 }, { 3, 4 }, +}; + +static U32 gControllerButtonRemaps[ControllerTypeCount][MaxJoystickButtons] = +{ + { // LogitechWingman + ControllerButton1, + ControllerButton2, + ControllerButton3, + ControllerButton4, + ControllerButton5, + ControllerButton6, + ControllerButtonLeftTrigger, + ControllerButtonRightTrigger, + ControllerButtonBack, + 0, + 0, + 0, + 0, + 0, + }, + { // LogitechDualAction + ControllerButton1, + ControllerButton2, + ControllerButton3, + ControllerButton4, + ControllerButtonLeftTrigger, + ControllerButtonRightTrigger, + ControllerButton5, + ControllerButton6, + ControllerButtonBack, + ControllerButtonStart, + 0, + 0, + 0, + 0, + }, + { // SaitekDualAnalog + ControllerButton1, + ControllerButton2, + ControllerButton3, + ControllerButton4, + ControllerButton5, + ControllerButton6, + ControllerButtonLeftTrigger, + ControllerButtonRightTrigger, + 0, + 0, + ControllerButtonBack, + 0, + 0, + 0, + }, + { // PS2DualShock + ControllerButton4, + ControllerButton2, + ControllerButton1, + ControllerButton3, + ControllerButton5, + ControllerButton6, + ControllerButtonLeftTrigger, + ControllerButtonRightTrigger, + ControllerButtonBack, + 0, + 0, + ControllerButtonStart, + 0, + 0, + }, + { // XBoxController + ControllerButton1, + ControllerButton2, + ControllerButton3, + ControllerButton4, + ControllerButton6, + ControllerButton5, + ControllerButtonStart, + ControllerButtonBack, + 0, + 0, + ControllerButtonLeftTrigger, + ControllerButtonRightTrigger, + 0, + 0, + }, + { // XBoxControllerOnXBox + 1 << 0, + 1 << 1, + 1 << 2, + 1 << 3, + 1 << 4, + 1 << 5, + 1 << 6, + 1 << 7, + 1 << 8, + 1 << 9, + 1 << 10, + 1 << 11, + 1 << 12, + 1 << 13, + } +}; + +static bool updateMoveInternal( Move *theMove, U32 &buttonMask ) +{ + F32 axes[MaxJoystickAxes]; + static F32 minValues[2] = { - 0.5, -0.5 }; + static F32 maxValues[2] = { 0.5, 0.5 }; + U32 hatMask = 0; + if(!ReadJoystick(axes, buttonMask, hatMask)) + return false; + + // All axes return -1 to 1 + // now we map the controls: + + F32 controls[4]; + controls[0] = axes[0]; + controls[1] = axes[1]; + + if(controls[0] < minValues[0]) + minValues[0] = controls[0]; + if(controls[0] > maxValues[0]) + maxValues[0] = controls[0]; + if(controls[1] < minValues[1]) + minValues[1] = controls[1]; + if(controls[1] > maxValues[1]) + maxValues[1] = controls[1]; + + if(controls[0] < 0) + controls[0] = - (controls[0] / minValues[0]); + else if(controls[0] > 0) + controls[0] = (controls[0] / maxValues[0]); + + if(controls[1] < 0) + controls[1] = - (controls[1] / minValues[1]); + else if(controls[1] > 0) + controls[1] = (controls[1] / maxValues[1]); + + // xbox control inputs are in a circle, not a square, which makes + // diagonal movement inputs "slower" + if(OptionsMenuUserInterface::joystickType == XBoxController || + OptionsMenuUserInterface::joystickType == XBoxControllerOnXBox) + { + Point dir(controls[0], controls[1]); + F32 absX = fabs(dir.x); + F32 absY = fabs(dir.y); + + // push out to the edge of the square (-1,-1 -> 1,1 ) + + F32 dirLen = dir.len() * 1.25; + if(dirLen > 1) + dirLen = 1; + + if(absX > absY) + dir *= F32(dirLen / absX); + else + dir *= F32(dirLen / absY); + controls[0] = dir.x; + controls[1] = dir.y; + } + controls[2] = axes[gShootAxisRemaps[OptionsMenuUserInterface::joystickType][0]]; + controls[3] = axes[gShootAxisRemaps[OptionsMenuUserInterface::joystickType][1]]; + + for(U32 i = 0; i < 4; i++) + { + F32 deadZone = i < 2 ? 0.25f : 0.03125f; + if(controls[i] < -deadZone) + controls[i] = -(-controls[i] - deadZone) / F32(1 - deadZone); + else if(controls[i] > deadZone) + controls[i] = (controls[i] - deadZone) / F32(1 - deadZone); + else + controls[i] = 0; + } + if(controls[0] < 0) + { + theMove->left = -controls[0]; + theMove->right = 0; + } + else + { + theMove->left = 0; + theMove->right = controls[0]; + } + + if(controls[1] < 0) + { + theMove->up = -controls[1]; + theMove->down = 0; + } + else + { + theMove->down = controls[1]; + theMove->up = 0; + } + + Point p(controls[2], controls[3]); + F32 plen = p.len(); + if(plen > 0.3) + { + theMove->angle = atan2(p.y, p.x); + theMove->fire = (plen > 0.5); + } + else + theMove->fire = false; + + // remap button inputs + U32 retMask = 0; + for(S32 i = 0; i < MaxJoystickButtons; i++) + if(buttonMask & (1 << i)) + retMask |= gControllerButtonRemaps[OptionsMenuUserInterface::joystickType][i]; + buttonMask = retMask | hatMask; + return true; +} + +S32 autodetectJoystickType() +{ + S32 ret = -1; + TNL_JOURNAL_READ_BLOCK(JoystickAutodetect, + TNL_JOURNAL_READ((&ret)); + return ret; + ) + const char *joystickName = GetJoystickName(); + if(!strncmp(joystickName, "WingMan", 7)) + ret = LogitechWingman; + else if(!strcmp(joystickName, "XBoxOnXBox")) + ret = XBoxControllerOnXBox; + else if(strstr(joystickName, "XBox")) + ret = XBoxController; + else if(!strcmp(joystickName, "4 axis 16 button joystick")) + ret = PS2DualShock; + else if(strstr(joystickName, "P880")) + ret = SaitekDualAnalog; + else if(strstr(joystickName, "Logitech Dual Action")) + ret = LogitechDualAction; + TNL_JOURNAL_WRITE_BLOCK(JoystickAutodetect, + TNL_JOURNAL_WRITE((ret)); + ) + return ret; +} + +static bool updateMoveJournaled( Move *theMove, U32 &buttonMask ) +{ + TNL_JOURNAL_READ_BLOCK(JoystickUpdate, + BitStream *readStream = Journal::getReadStream(); + if(!readStream->readFlag()) + return false; + + Move aMove; + aMove.unpack(readStream, false); + *theMove = aMove; + buttonMask = readStream->readInt(MaxJoystickButtons); + return true; + ) + + bool ret = updateMoveInternal(theMove, buttonMask); + + TNL_JOURNAL_WRITE_BLOCK(JoystickUpdate, + BitStream *writeStream = Journal::getWriteStream(); + if(writeStream->writeFlag(ret)) + { + Move dummy; + theMove->pack(writeStream, &dummy, false); + writeStream->writeInt(buttonMask, MaxJoystickButtons); + } + ) + return ret; +} + + + +void JoystickUpdateMove(Move *theMove) +{ + static U32 lastButtonsPressed = 0; + U32 buttonsPressed; + if(!updateMoveJournaled(theMove, buttonsPressed)) + return; + + U32 buttonDown = buttonsPressed & ~lastButtonsPressed; + U32 buttonUp = ~buttonsPressed & lastButtonsPressed; + lastButtonsPressed = buttonsPressed; + + for(U32 i = 0; i < ControllerGameButtonCount; i++) + { + U32 mask = 1 << i; + if(buttonDown & mask) + UserInterface::current->onControllerButtonDown(i); + else if(buttonUp & mask) + UserInterface::current->onControllerButtonUp(i); + } + if(buttonDown & ControllerButtonStart) + UserInterface::current->onKeyDown('\r'); + if(buttonDown & ControllerButtonBack) + UserInterface::current->onKeyDown(27); + if(buttonDown & ControllerButtonDPadUp) + UserInterface::current->onSpecialKeyDown(GLUT_KEY_UP); + if(buttonDown & ControllerButtonDPadDown) + UserInterface::current->onSpecialKeyDown(GLUT_KEY_DOWN); + if(buttonDown & ControllerButtonDPadLeft) + UserInterface::current->onSpecialKeyDown(GLUT_KEY_LEFT); + if(buttonDown & ControllerButtonDPadRight) + UserInterface::current->onSpecialKeyDown(GLUT_KEY_RIGHT); + + if(buttonUp & ControllerButtonStart) + UserInterface::current->onKeyUp('\r'); + if(buttonUp & ControllerButtonBack) + UserInterface::current->onKeyUp(27); + if(buttonUp & ControllerButtonDPadUp) + UserInterface::current->onSpecialKeyUp(GLUT_KEY_UP); + if(buttonUp & ControllerButtonDPadDown) + UserInterface::current->onSpecialKeyUp(GLUT_KEY_DOWN); + if(buttonUp & ControllerButtonDPadLeft) + UserInterface::current->onSpecialKeyUp(GLUT_KEY_LEFT); + if(buttonUp & ControllerButtonDPadRight) + UserInterface::current->onSpecialKeyUp(GLUT_KEY_RIGHT); +} + + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/input.h b/tnl-1.5.0/tnl/zap/input.h new file mode 100644 index 0000000000000000000000000000000000000000..e9854354d2c4b238217fe151ab8a6e2449dd73b3 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/input.h @@ -0,0 +1,79 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _INPUT_H_ +#define _INPUT_H_ +#include "tnl.h" +using namespace TNL; + +namespace Zap +{ + +enum ControllerTypeType +{ + LogitechWingman, + LogitechDualAction, + SaitekDualAnalog, + PS2DualShock, + XBoxController, + XBoxControllerOnXBox, + ControllerTypeCount, +}; + +enum ButtonInfo { + MaxJoystickAxes = 12, + MaxJoystickButtons = 14, + ControllerButton1 = 1 << 0, + ControllerButton2 = 1 << 1, + ControllerButton3 = 1 << 2, + ControllerButton4 = 1 << 3, + ControllerButton5 = 1 << 4, + ControllerButton6 = 1 << 5, + ControllerButtonLeftTrigger = 1 << 6, + ControllerButtonRightTrigger = 1 << 7, + ControllerGameButtonCount = 8, + ControllerButtonStart = 1 << 8, + ControllerButtonBack = 1 << 9, + ControllerButtonDPadUp = 1 << 10, + ControllerButtonDPadDown = 1 << 11, + ControllerButtonDPadLeft = 1 << 12, + ControllerButtonDPadRight = 1 << 13, +}; + +// the following functions are defined differently on each platform +// in the the platInput.cpp files. + +void getModifierState( bool &shiftDown, bool &controlDown, bool &altDown ); + +void InitJoystick(); +const char *GetJoystickName(); +S32 autodetectJoystickType(); +void ShutdownJoystick(); +bool ReadJoystick(F32 axes[MaxJoystickAxes], U32 &buttonMask, U32 &hatMask); + +}; + +#endif \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/item.cpp b/tnl-1.5.0/tnl/zap/item.cpp new file mode 100644 index 0000000000000000000000000000000000000000..322515434f0a5acd50665add329b8b6d7e1aa463 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/item.cpp @@ -0,0 +1,314 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "item.h" +#include "ship.h" +#include "goalZone.h" +#include "glutInclude.h" + +namespace Zap +{ + +Item::Item(Point p, bool collideable, float radius, float mass) : MoveObject(p, radius, mass) +{ + mIsMounted = false; + mIsCollideable = collideable; + mObjectTypeMask = MoveableType | ItemType | CommandMapVisType; +} + +void Item::processArguments(S32 argc, const char **argv) +{ + if(argc < 2) + return; + Point pos; + pos.read(argv); + pos *= getGame()->getGridSize(); + for(U32 i = 0; i < MoveStateCount; i++) + mMoveState[i].pos = pos; + updateExtent(); +} + +void Item::render() +{ + // if the item is mounted, renderItem will be called from the + // ship it is mounted to + if(mIsMounted) + return; + + renderItem(mMoveState[RenderState].pos); +} + +void Item::mountToShip(Ship *theShip) +{ + TNLAssert(isGhost() || isInDatabase(), "Error, mount item not in database."); + dismount(); + mMount = theShip; + if(theShip) + theShip->mMountedItems.push_back(this); + + mIsMounted = true; + setMaskBits(MountMask); +} + +void Item::onMountDestroyed() +{ + dismount(); +} + +void Item::dismount() +{ + if(mMount.isValid()) + { + for(S32 i = 0; i < mMount->mMountedItems.size(); i++) + { + if(mMount->mMountedItems[i].getPointer() == this) + { + mMount->mMountedItems.erase(i); + break; + } + } + } + mMount = NULL; + mIsMounted = false; + setMaskBits(MountMask); +} + +void Item::setActualPos(Point p) +{ + mMoveState[ActualState].pos = p; + mMoveState[ActualState].vel.set(0,0); + setMaskBits(WarpPositionMask | PositionMask); +} + +void Item::setActualVel(Point vel) +{ + mMoveState[ActualState].vel = vel; + setMaskBits(WarpPositionMask | PositionMask); +} + +Ship *Item::getMount() +{ + return mMount; +} + +void Item::setZone(GoalZone *theZone) +{ + mZone = theZone; + setMaskBits(ZoneMask); +} + +GoalZone *Item::getZone() +{ + return mZone; +} + +void Item::idle(GameObject::IdleCallPath path) +{ + if(!isInDatabase()) + return; + + if(mIsMounted) + { + if(mMount.isNull() || mMount->hasExploded) + { + if(!isGhost()) + dismount(); + } + else + { + mMoveState[RenderState].pos = mMount->getRenderPos(); + mMoveState[ActualState].pos = mMount->getActualPos(); + } + } + else + { + float time = mCurrentMove.time * 0.001f; + move(time, ActualState, false); + if(path == GameObject::ServerIdleMainLoop) + { + // Only update if it's actually moving... + if(mMoveState[ActualState].vel.len() > 0.001f) + setMaskBits(PositionMask); + + mMoveState[RenderState] = mMoveState[ActualState]; + + } + else + updateInterpolation(); + } + updateExtent(); +} + +U32 Item::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + U32 retMask = 0; + if(stream->writeFlag(updateMask & InitialMask)) + { + } + if(stream->writeFlag(updateMask & PositionMask)) + { + ((GameConnection *) connection)->writeCompressedPoint(mMoveState[ActualState].pos, stream); + writeCompressedVelocity(mMoveState[ActualState].vel, 511, stream); + stream->writeFlag(updateMask & WarpPositionMask); + } + if(stream->writeFlag(updateMask & MountMask) && stream->writeFlag(mIsMounted)) + { + S32 index = connection->getGhostIndex(mMount); + if(stream->writeFlag(index != -1)) + stream->writeInt(index, GhostConnection::GhostIdBitSize); + else + retMask |= MountMask; + } + if(stream->writeFlag(updateMask & ZoneMask)) + { + if(mZone.isValid()) + { + S32 index = connection->getGhostIndex(mZone); + if(stream->writeFlag(index != -1)) + stream->writeInt(index, GhostConnection::GhostIdBitSize); + else + retMask |= ZoneMask; + } + else + stream->writeFlag(false); + } + return retMask; +} + +void Item::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + bool interpolate = false; + bool positionChanged = false; + + if(stream->readFlag()) + { + } + if(stream->readFlag()) + { + ((GameConnection *) connection)->readCompressedPoint(mMoveState[ActualState].pos, stream); + readCompressedVelocity(mMoveState[ActualState].vel, 511, stream); + positionChanged = true; + interpolate = !stream->readFlag(); + } + if(stream->readFlag()) + { + bool shouldMount = stream->readFlag(); + if(shouldMount) + { + Ship *theShip = NULL; + if(stream->readFlag()) + theShip = (Ship *) connection->resolveGhost(stream->readInt(GhostConnection::GhostIdBitSize)); + mountToShip(theShip); + } + else + dismount(); + } + if(stream->readFlag()) + { + bool hasZone = stream->readFlag(); + if(hasZone) + mZone = (GoalZone *) connection->resolveGhost(stream->readInt(GhostConnection::GhostIdBitSize)); + else + mZone = NULL; + } + + if(positionChanged) + { + if(interpolate) + { + mInterpolating = true; + move(connection->getOneWayTime() * 0.001f, ActualState, false); + } + else + { + mInterpolating = false; + mMoveState[RenderState] = mMoveState[ActualState]; + } + } +} + +bool Item::collide(GameObject *otherObject) +{ + return mIsCollideable && !mIsMounted; +} + +PickupItem::PickupItem(Point p, float radius) + : Item(p, false, radius, 1) +{ + mIsVisible = true; +} + +void PickupItem::idle(GameObject::IdleCallPath path) +{ + if(!mIsVisible && path == GameObject::ServerIdleMainLoop) + { + if(mRepopTimer.update(mCurrentMove.time)) + { + setMaskBits(PickupMask); + mIsVisible = true; + } + } + updateExtent(); +} + +U32 PickupItem::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + U32 retMask = Parent::packUpdate(connection, updateMask, stream); + stream->writeFlag(updateMask & InitialMask); + stream->writeFlag(mIsVisible); + + return retMask; +} + +void PickupItem::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + Parent::unpackUpdate(connection, stream); + bool isInitial = stream->readFlag(); + bool visible = stream->readFlag(); + + if(!isInitial && !visible && mIsVisible) + onClientPickup(); + mIsVisible = visible; +} + + +bool PickupItem::collide(GameObject *otherObject) +{ + if(mIsVisible && !isGhost() && otherObject->getObjectTypeMask() & ShipType) + { + if(pickup((Ship *) otherObject)) + { + setMaskBits(PickupMask); + mRepopTimer.reset(getRepopDelay()); + mIsVisible = false; + } + } + return false; +} + + +}; + diff --git a/tnl-1.5.0/tnl/zap/item.h b/tnl-1.5.0/tnl/zap/item.h new file mode 100644 index 0000000000000000000000000000000000000000..8d3d1e721f0145a83e5bea33a4ce1791354fbff1 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/item.h @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _ITEM_H_ +#define _ITEM_H_ + +#include "moveObject.h" +#include "timer.h" + +namespace Zap +{ + +class Ship; +class GoalZone; + +class Item : public MoveObject +{ +protected: + enum MaskBits { + InitialMask = BIT(0), + PositionMask = BIT(1), + WarpPositionMask = BIT(2), + MountMask = BIT(3), + ZoneMask = BIT(4), + FirstFreeMask = BIT(5), + }; + + SafePtr mMount; + SafePtr mZone; + + bool mIsMounted; + bool mIsCollideable; +public: + void idle(GameObject::IdleCallPath path); + + void processArguments(S32 argc, const char **argv); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + Item(Point p = Point(0,0), bool collideable = false, float radius = 1, float mass = 1); + + void setActualPos(Point p); + void setActualVel(Point vel); + + void mountToShip(Ship *theShip); + bool isMounted() { return mIsMounted; } + void setZone(GoalZone *theZone); + GoalZone *getZone(); + + Ship *getMount(); + void dismount(); + void render(); + virtual void renderItem(Point pos) = 0; + + virtual void onMountDestroyed(); + + bool collide(GameObject *otherObject); +}; + +class PickupItem : public Item +{ + typedef Item Parent; + bool mIsVisible; + Timer mRepopTimer; +protected: + enum MaskBits { + PickupMask = Parent::FirstFreeMask << 0, + FirstFreeMask = Parent::FirstFreeMask << 1, + }; +public: + PickupItem(Point p = Point(), float radius = 1); + void idle(GameObject::IdleCallPath path); + bool isVisible() { return mIsVisible; } + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + bool collide(GameObject *otherObject); + virtual bool pickup(Ship *theShip) = 0; + virtual U32 getRepopDelay() = 0; + virtual void onClientPickup() = 0; +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/linuxInput.cpp b/tnl-1.5.0/tnl/zap/linuxInput.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b88f3d4d7f776ce4cf109ec14a25281f76e00275 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/linuxInput.cpp @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "input.h" + +namespace Zap +{ + +bool gJoystickInit = false; + +void getModifierState(bool &shiftDown, bool &controlDown, bool &altDown) +{ + shiftDown = controlDown = altDown = false; +} + +void InitJoystick() +{ +} + +bool ReadJoystick(F32 axes[MaxJoystickAxes], U32 &buttonMask, U32 &hatMask) +{ + return false; +} + +const char *GetJoystickName() +{ + return ""; +} + +void ShutdownJoystick() +{ +} + +}; diff --git a/tnl-1.5.0/tnl/zap/loadoutSelect.cpp b/tnl-1.5.0/tnl/zap/loadoutSelect.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b94249d16480b449a3399715668c787bf9fcd0d --- /dev/null +++ b/tnl-1.5.0/tnl/zap/loadoutSelect.cpp @@ -0,0 +1,209 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "loadoutSelect.h" +#include "UIGame.h" +#include "gameConnection.h" +#include "game.h" +#include "glutInclude.h" +#include "shipItems.h" +#include "gameWeapons.h" +#include +#include "gameObjectRender.h" + +namespace Zap +{ + +struct LoadoutItem +{ + U32 key; + U32 button; + U32 index; + const char *text; +}; + +LoadoutItem gLoadoutModules[] = { + { '1', 0, ModuleBoost, "Turbo Boost" }, + { '2', 1, ModuleShield, "Shield Generator" }, + { '3', 2, ModuleRepair, "Repair Module", }, + { '4', 3, ModuleSensor, "Enhanced Sensor" }, + { '5', 4, ModuleCloak, "Cloak Field Modulator" }, + { 0, 0, 0, NULL }, +}; + +LoadoutItem gLoadoutWeapons[] = { + { '1', 0, WeaponPhaser, "Phaser" }, + { '2', 1, WeaponBounce, "Bouncer" }, + { '3', 2, WeaponTriple, "Three-Way" }, + { '4', 3, WeaponBurst, "Burster" }, + { '5', 4, WeaponMineLayer, "Mine Dropper" }, + { 0, 0, 0, NULL }, +}; + +const char *gLoadoutTitles[] = { + "Choose Primary Module:", + "Choose Secondary Module:", + "Choose Primary Weapon:", + "Choose Secondary Weapon:", + "Choose Tertiary Weapon:", +}; + +LoadoutHelper::LoadoutHelper() +{ +} + +void LoadoutHelper::show(bool fromController) +{ + mFromController = fromController; + mCurrentIndex = 0; + mIdleTimer.reset(MenuTimeout); +} + +extern void renderControllerButton(F32 x, F32 y, U32 buttonIndex, U32 keyIndex); + +void LoadoutHelper::render() +{ + S32 curPos = 300; + const int fontSize = 15; + + glColor3f(0.8, 1, 0.8); + + UserInterface::drawStringf(UserInterface::horizMargin, curPos, fontSize, "%s", gLoadoutTitles[mCurrentIndex]); + curPos += fontSize + 4; + + LoadoutItem *list; + + if(mCurrentIndex < 2) + list = gLoadoutModules; + else + list = gLoadoutWeapons; + + for(S32 i = 0; list[i].text; i++) + { + Color c; + if((mCurrentIndex == 1 && mModule[0] == i) || + (mCurrentIndex == 3 && mWeapon[0] == i) || + (mCurrentIndex == 4 && (mWeapon[0] == i || mWeapon[1] == i))) + c.set(0.3, 0.7, 0.3); + else + c.set(0.1, 1.0, 0.1); + + glColor(c); + renderControllerButton(UserInterface::horizMargin, curPos, list[i].button, list[i].key); + + glColor(c); + UserInterface::drawStringf(UserInterface::horizMargin + 20, curPos, fontSize, "- %s", + list[i].text); + curPos += fontSize + 4; + } + +} + +void LoadoutHelper::idle(U32 delta) +{ + if(mIdleTimer.update(delta)) + gGameUserInterface.setPlayMode(); +} + +bool LoadoutHelper::processKey(U32 key) +{ + if(key == 27 || key == 8) + { + gGameUserInterface.setPlayMode(); + return true; + } + if(!mFromController) + key = toupper(key); + U32 index; + LoadoutItem *list; + if(mCurrentIndex < 2) + list = gLoadoutModules; + else + list = gLoadoutWeapons; + + for(index = 0; list[index].text; index++) + { + if(key == list[index].key || + key == list[index].button) + { + break; + } + } + if(!list[index].text) + return false; + mIdleTimer.reset(MenuTimeout); + + switch(mCurrentIndex) + { + case 0: + mModule[0] = index; + mCurrentIndex++; + break; + case 1: + if(mModule[0] != index) + { + mModule[1] = index; + mCurrentIndex++; + } + break; + case 2: + mWeapon[0] = index; + mCurrentIndex++; + break; + case 3: + if(mWeapon[0] != index) + { + mWeapon[1] = index; + mCurrentIndex++; + } + break; + case 4: + if(mWeapon[1] != index && mWeapon[0] != index) + { + mWeapon[2] = index; + mCurrentIndex++; + } + break; + } + if(mCurrentIndex == 5) + { + // do the processing thang + Vector loadout; + loadout.push_back(gLoadoutModules[mModule[0]].index); + loadout.push_back(gLoadoutModules[mModule[1]].index); + loadout.push_back(gLoadoutWeapons[mWeapon[0]].index); + loadout.push_back(gLoadoutWeapons[mWeapon[1]].index); + loadout.push_back(gLoadoutWeapons[mWeapon[2]].index); + GameConnection *gc = gClientGame->getConnectionToServer(); + if(gc) + gc->c2sRequestLoadout(loadout); + gGameUserInterface.setPlayMode(); + } + return true; +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/loadoutSelect.h b/tnl-1.5.0/tnl/zap/loadoutSelect.h new file mode 100644 index 0000000000000000000000000000000000000000..f79d77fba32133990acddbd9a7073308afdd9ab6 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/loadoutSelect.h @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _LOADOUTSELECT_H_ +#define _LOADOUTSELECT_H_ + +#include "tnlTypes.h" +using namespace TNL; +#include "timer.h" + +namespace Zap +{ + +class LoadoutHelper +{ + bool mFromController; + U32 mModule[2]; + U32 mWeapon[3]; + U32 mCurrentIndex; + Timer mIdleTimer; + enum { + MenuTimeout = 3500, + }; +public: + LoadoutHelper(); + + void render(); + void idle(U32 delta); + void show(bool fromController); + bool processKey(U32 key); +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/lpc10.h b/tnl-1.5.0/tnl/zap/lpc10.h new file mode 100644 index 0000000000000000000000000000000000000000..ee8692987d98933cdb4fc3e312f39bda1192f77b --- /dev/null +++ b/tnl-1.5.0/tnl/zap/lpc10.h @@ -0,0 +1,72 @@ +/* + LPC-10 voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2004 Phil Frisbie, Jr. (phil@hawksoft.com) + + The VBR algorithm was contributed by + Ben Appleton + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +#ifndef LPC10_H +#define LPC10_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define LPC10_SAMPLES_PER_FRAME 180 +#define LPC10_ENCODED_FRAME_SIZE 7 +/* NOTE ON FRAME SIZE +The VBR codec creates encoded frame sizes of 1, 4, or 7 bytes. +1 byte, silence frames, about 356 bps +4 bytes, unvoiced frames, about 1422 bps +7 bytes, voiced frames, about 2488 bps */ + +/* NOTE ON DECODING A VBR STREAM +The VBR decoder relies on the frame type encoded into the first +byte of the frame. If you receive a stream of more than one frame +appended together, there is no way for you to know how many times to +call vbr_lpc10_decode() before hand. Therefore, a forth parameter +has been added to vbr_lpc10_decode(), the int *p. *p returns with +a value to tell you how many bytes were in the frame that was just +processed. For example code, see the file decpacket.c, and look at +the function vbrlpc10decode(). +*/ + +typedef struct lpc10_e_state lpc10_encoder_state; +typedef struct lpc10_d_state lpc10_decoder_state; + +lpc10_encoder_state * create_lpc10_encoder_state (void); +void init_lpc10_encoder_state (lpc10_encoder_state *st); +int lpc10_encode(short *in, unsigned char *out, lpc10_encoder_state *st); +int vbr_lpc10_encode(short *in, unsigned char *out, lpc10_encoder_state *st); +void destroy_lpc10_encoder_state (lpc10_encoder_state *st); + +lpc10_decoder_state * create_lpc10_decoder_state (void); +void init_lpc10_decoder_state (lpc10_decoder_state *st); +int lpc10_decode(unsigned char *in, int inSz, short *out, lpc10_decoder_state *st); +int vbr_lpc10_decode(unsigned char *in, int inSz, short *out, lpc10_decoder_state *st, int *p); +void destroy_lpc10_decoder_state (lpc10_decoder_state *st); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LPC10_H */ diff --git a/tnl-1.5.0/tnl/zap/lpc10dec.c b/tnl-1.5.0/tnl/zap/lpc10dec.c new file mode 100644 index 0000000000000000000000000000000000000000..0afe2812c2701c36011d79cd6561a396e6f3a477 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/lpc10dec.c @@ -0,0 +1,776 @@ +/* + LPC-10 voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2004 Phil Frisbie, Jr. (phil@hawksoft.com) + + The VBR algorithm was contributed by + Ben Appleton + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +#if !defined( MACOSX ) && !defined (__APPLE__) +#include +#endif +#include +#ifdef __MWERKS__ +#include +#else +#include +#endif +#ifdef _MSC_VER +#pragma warning (disable:4711) /* to disable automatic inline warning */ +#endif +#include +#include "ftol.h" +#include "lpc10.h" + +#if __GNUC__ == 2 +#define lrintf(d) ((int) (d)) +#endif + +#define LPC10_BITS_IN_COMPRESSED_FRAME 54 + +#ifndef TRUE +#define TRUE (1) +#define FALSE (0) +#endif + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +typedef struct lpc10_d_state { + + /* State used by function decode */ + long iptold; /* initial value 60 */ + + /* State used by function synths */ + float buf[360]; + long buflen; /* initial value 180 */ + + /* State used by function pitsyn */ + long ivoico; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + long ipito; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + float rmso; /* initial value 1.f */ + float rco[10]; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + long jsamp; /* no initial value necessary as long as first_pitsyn is initially TRUE_ */ + int first_pitsyn; /* initial value TRUE_ */ + + /* State used by function bsynz */ + long ipo; + float exc[166]; + float exc2[166]; + float lpi1; + float lpi2; + float lpi3; + float hpi1; + float hpi2; + float hpi3; + float rmso_bsynz; + + /* State used by function deemp */ + float dei1; + float dei2; + float deo1; + float deo2; + float deo3; + +} lpc10_d_state_t; + + +extern long lpcbits[10]; + +/* Table of constant values */ +static long detau[128] = { 0,0,0,3,0,3,3,31,0,3,3,21,3,3,29,30,0,3,3, +20,3,25,27,26,3,23,58,22,3,24,28,3,0,3,3,3,3,39,33,32,3,37,35,36, +3,38,34,3,3,42,46,44,50,40,48,3,54,3,56,3,52,3,3,1,0,3,3,108,3,78, +100,104,3,84,92,88,156,80,96,3,3,74,70,72,66,76,68,3,62,3,60,3,64, +3,3,1,3,116,132,112,148,152,3,3,140,3,136,3,144,3,3,1,124,120,128, +3,3,3,3,1,3,3,3,1,3,1,1,1 }; + +static long rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420, +384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102, +92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15, +14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 }; + +static long detab7[32] = { 4,11,18,25,32,39,46,53,60,66,72,77,82,87,92, +96,101,104,108,111,114,115,117,119,121,122,123,124,125,126,127,127 }; + +static float descl[8] = { .6953f,.625f,.5781f,.5469f,.5312f,.5391f,.4688f,.3828f }; +static long deadd[8] = { 1152,-2816,-1536,-3584,-1280,-2432,768,-1920 }; +static long qb[8] = { 511,511,1023,1023,1023,1023,2047,4095 }; +static long nbit[10] = { 8,8,5,5,4,4,4,4,3,2 }; +static long kexc[25] = { 8,-16,26,-48,86,-162,294,-502,718,-728,184, +672,-610,-672,184,728,718,502,294,162,86,48,26,16,8 }; + +static void pitsyn(long *voice, long *pitch, float *rms, float *rc, + long *ivuv, long *ipiti, float *rmsi, float *rci, long *nout, + float *ratio, lpc10_decoder_state *st) +{ + /* Initialized data */ + + float *rmso; + + /* Local variables */ + float alrn, alro, yarc[10], prop; + long i, j, vflag, jused, lsamp; + long *jsamp; + float slope; + long *ipito; + float uvpit; + long ip, nl, ivoice; + long *ivoico; + long istart; + float *rco; + float xxy; + + + /* Function Body */ + ivoico = &(st->ivoico); + ipito = &(st->ipito); + rmso = &(st->rmso); + rco = &(st->rco[0]); + jsamp = &(st->jsamp); + + if (*rms < 1.f) { + *rms = 1.f; + } + if (*rmso < 1.f) { + *rmso = 1.f; + } + uvpit = 0.f; + *ratio = *rms / (*rmso + 8.f); + + if (st->first_pitsyn) { + lsamp = 0; + ivoice = voice[1]; + if (ivoice == 0) { + *pitch = LPC10_SAMPLES_PER_FRAME / 4; + } + *nout = LPC10_SAMPLES_PER_FRAME / *pitch; + *jsamp = LPC10_SAMPLES_PER_FRAME - *nout * *pitch; + + for (i = 0; i < *nout; ++i) { + for (j = 0; j < 10; ++j) { + rci[j + i * 10] = rc[j]; + } + ivuv[i] = ivoice; + ipiti[i] = *pitch; + rmsi[i] = *rms; + } + st->first_pitsyn = FALSE; + + } else { + vflag = 0; + lsamp = LPC10_SAMPLES_PER_FRAME + *jsamp; + slope = (*pitch - *ipito) / (float) lsamp; + *nout = 0; + jused = 0; + istart = 1; + if (voice[0] == *ivoico && voice[1] == voice[0]) { + if (voice[1] == 0) { + /* SSUV - - 0 , 0 , 0 */ + *pitch = LPC10_SAMPLES_PER_FRAME / 4; + *ipito = *pitch; + if (*ratio > 8.f) { + *rmso = *rms; + } + } + /* SSVC - - 1 , 1 , 1 */ + slope = (*pitch - *ipito) / (float) lsamp; + ivoice = voice[1]; + } else { + if (*ivoico != 1) { + if (*ivoico == voice[0]) { + /* UV2VC2 - - 0 , 0 , 1 */ + nl = lsamp - LPC10_SAMPLES_PER_FRAME / 4; + } else { + /* UV2VC1 - - 0 , 1 , 1 */ + nl = lsamp - LPC10_SAMPLES_PER_FRAME * 3 / 4; + } + ipiti[0] = nl / 2; + ipiti[1] = nl - ipiti[0]; + ivuv[0] = 0; + ivuv[1] = 0; + rmsi[0] = *rmso; + rmsi[1] = *rmso; + for (i = 0; i < 10; ++i) { + rci[i] = rco[i]; + rci[i + 10] = rco[i]; + rco[i] = rc[i]; + } + slope = 0.f; + *nout = 2; + *ipito = *pitch; + jused = nl; + istart = nl + 1; + ivoice = 1; + } else { + if (*ivoico != voice[0]) { + lsamp = LPC10_SAMPLES_PER_FRAME / 4 + *jsamp; + } else { + lsamp = LPC10_SAMPLES_PER_FRAME * 3 / 4 + *jsamp; + } + for (i = 0; i < 10; ++i) { + yarc[i] = rc[i]; + rc[i] = rco[i]; + } + ivoice = 1; + slope = 0.f; + vflag = 1; + } + } + for(;;) { + + for (i = istart; i <= lsamp; ++i) { + if (uvpit != 0.f) { + ip = lrintf(uvpit); + } + else { + ip = lrintf(*ipito + slope * i + .5f); + } + + if (ip <= i - jused) { + ipiti[*nout] = ip; + *pitch = ip; + ivuv[*nout] = ivoice; + jused += ip; + prop = (jused - ip / 2) / (float) lsamp; + for (j = 0; j < 10; ++j) { + alro = (float)log((rco[j] + 1) / (1 - rco[j])); + alrn = (float)log((rc[j] + 1) / (1 - rc[j])); + xxy = alro + prop * (alrn - alro); + xxy = (float)exp(xxy); + rci[j + *nout * 10] = (xxy - 1) / (xxy + 1); + } + rmsi[*nout] = (float)(log(*rmso) + prop * (log(*rms) - log(*rmso))); + rmsi[*nout] = (float)exp(rmsi[*nout]); + ++(*nout); + } + } + if (vflag != 1) { + break; + } + + vflag = 0; + istart = jused + 1; + lsamp = LPC10_SAMPLES_PER_FRAME + *jsamp; + slope = 0.f; + ivoice = 0; + uvpit = (float) ((lsamp - istart) / 2); + if (uvpit > 90.f) { + uvpit /= 2; + } + *rmso = *rms; + for (i = 1; i <= 10; ++i) { + rco[i - 1] = rc[i - 1] = yarc[i - 1]; + } + } + *jsamp = lsamp - jused; + } + if (*nout != 0) { + *ivoico = voice[1]; + *ipito = *pitch; + *rmso = *rms; + for (i = 0; i < 10; ++i) { + rco[i] = rc[i]; + } + } +} /* pitsyn_ */ + +#define MIDTAP 1 +#define MAXTAP 4 +static short y[MAXTAP+1]={-21161, -8478, 30892,-10216, 16950}; +static int j=MIDTAP, k=MAXTAP; + +static int random16 (void) +{ + int the_random; + + /* The following is a 16 bit 2's complement addition, + * with overflow checking disabled */ + + y[k] = (short)(y[k] + y[j]); + + the_random = y[k]; + k--; + if (k < 0) k = MAXTAP; + j--; + if (j < 0) j = MAXTAP; + + return(the_random); +} + +static void bsynz(float *coef, long ip, long *iv, + float *sout, float *rms, float *ratio, float *g2pass, + lpc10_decoder_state *st) +{ + /* Initialized data */ + + long *ipo; + float *rmso; + float *exc; + float *exc2; + float lpi1; + float lpi2; + float hpi1; + float hpi2; + + /* Local variables */ + float gain, xssq; + long i, j, k; + float pulse; + long px; + float sscale; + float xy, sum, ssq; + float lpi0, hpi0; + + /* Parameter adjustments */ + if (coef) { + --coef; + } + + /* Function Body */ + ipo = &(st->ipo); + exc = &(st->exc[0]); + exc2 = &(st->exc2[0]); + lpi1 = st->lpi1; + lpi2 = st->lpi2; + hpi1 = st->hpi1; + hpi2 = st->hpi2; + rmso = &(st->rmso_bsynz); + + /* MAXPIT+MAXORD=166 */ + /* Calculate history scale factor XY and scale filter state */ + /* Computing MIN */ + xy = min((*rmso / (*rms + 1e-6f)),8.f); + *rmso = *rms; + for (i = 0; i < 10; ++i) { + exc2[i] = exc2[*ipo + i] * xy; + } + *ipo = ip; + if (*iv == 0) { + /* Generate white noise for unvoiced */ + for (i = 0; i < ip; ++i) { + exc[10 + i] = (float) (random16() >> 6); + } + px = ((random16() + 32768) * (ip - 1) >> 16) + 10 + 1; + pulse = *ratio * 85.5f; + if (pulse > 2e3f) { + pulse = 2e3f; + } + exc[px - 1] += pulse; + exc[px] -= pulse; + /* Load voiced excitation */ + } else { + sscale = (float)sqrt((float) (ip)) * 0.144341801f; + for (i = 0; i < ip; ++i) { + float temp; + + if (i > 27) { + temp = 0.f; + } + else if (i < 25) { + lpi0 = temp = sscale * kexc[i]; + temp = lpi0 * .125f + lpi1 * .75f + lpi2 * .125f; + lpi2 = lpi1; + lpi1 = lpi0; + } + else{ + lpi0 = temp = 0.f; + temp = lpi1 * .75f + lpi2 * .125f; + lpi2 = lpi1; + lpi1 = lpi0; + } + hpi0 = (float)(random16() >> 6); + exc[10 + i] = temp + hpi0 * -.125f + hpi1 * .25f + hpi2 * -.125f; + hpi2 = hpi1; + hpi1 = hpi0; + } + } + /* Synthesis filters: */ + /* Modify the excitation with all-zero filter 1 + G*SUM */ + xssq = 0.f; + for (i = 0; i < ip; ++i) { + k = 10 + i; + sum = 0.f; + for (j = 1; j <= 10; ++j) { + sum += coef[j] * exc[k - j]; + } + sum *= *g2pass; + exc2[k] = sum + exc[k]; + } + /* Synthesize using the all pole filter 1 / (1 - SUM) */ + for (i = 0; i < ip; ++i) { + k = 10 + i; + sum = 0.f; + for (j = 1; j <= 10; ++j) { + sum += coef[j] * exc2[k - j]; + } + exc2[k] += sum; + xssq += exc2[k] * exc2[k]; + } + /* Save filter history for next epoch */ + for (i = 0; i < 10; ++i) { + exc[i] = exc[ip + i]; + exc2[i] = exc2[ip + i]; + } + /* Apply gain to match RMS */ + ssq = *rms * *rms * ip; + gain = (float)sqrt(ssq / xssq); + for (i = 0; i < ip; ++i) { + sout[i] = gain * exc2[10 + i]; + } + st->lpi1 = lpi1; + st->lpi2 = lpi2; + st->hpi1 = hpi1; + st->hpi2 = hpi2; +} /* bsynz_ */ + +static void irc2pc(float *rc, float *pc, float gprime, float *g2pass) +{ + /* System generated locals */ + long i2; + + /* Local variables */ + float temp[10]; + long i, j; + + /* Parameter adjustments */ + --pc; + --rc; + + /* Function Body */ + *g2pass = 1.f; + for (i = 1; i <= 10; ++i) { + *g2pass *= 1.f - rc[i] * rc[i]; + } + *g2pass = gprime * (float)sqrt(*g2pass); + pc[1] = rc[1]; + for (i = 2; i <= 10; ++i) { + i2 = i - 1; + for (j = 1; j <= i2; ++j) { + temp[j - 1] = pc[j] - rc[i] * pc[i - j]; + } + i2 = i - 1; + for (j = 1; j <= i2; ++j) { + pc[j] = temp[j - 1]; + } + pc[i] = rc[i]; + } +} /* irc2pc_ */ + +static void deemp(float *x, long n, lpc10_decoder_state *st) +{ + /* Initialized data */ + + float dei1; + float dei2; + float deo1; + float deo2; + float deo3; + + /* Local variables */ + long k; + float dei0; + + /* Function Body */ + + dei1 = st->dei1; + dei2 = st->dei2; + deo1 = st->deo1; + deo2 = st->deo2; + deo3 = st->deo3; + + for (k = 0; k < n; ++k) { + dei0 = x[k]; + x[k] = dei0 - dei1 * 1.9998f + dei2 + deo1 * 2.5f - deo2 * 2.0925f + deo3 * .585f; + dei2 = dei1; + dei1 = dei0; + deo3 = deo2; + deo2 = deo1; + deo1 = x[k]; + } + st->dei1 = dei1; + st->dei2 = dei2; + st->deo1 = deo1; + st->deo2 = deo2; + st->deo3 = deo3; +} /* deemp_ */ + +static void synths(long *voice, long pitch, float rms, float *rc, short *speech, lpc10_decoder_state *st) +{ + /* Initialized data */ + + float *buf; + long *buflen; + + /* Local variables */ + float rmsi[16]; + long nout, ivuv[16], i, j; + float ratio; + long ipiti[16]; + float g2pass; + float pc[10]; + float rci[160] /* was [10][16] */; + + /* Function Body */ + buf = &(st->buf[0]); + buflen = &(st->buflen); + + pitch = max(min(pitch,156), 20); + for (i = 0; i < 10; ++i) { + rc[i] = max(min(rc[i],.99f), -.99f); + } + pitsyn(voice, &pitch, &rms, rc, ivuv, ipiti, rmsi, rci, &nout, &ratio, st); + if (nout > 0) { + for (j = 0; j < nout; ++j) { + + irc2pc(&rci[j * 10], pc, 0.7f, &g2pass); + bsynz(pc, ipiti[j], &ivuv[j], &buf[*buflen], &rmsi[j], &ratio, &g2pass, st); + deemp(&buf[*buflen], ipiti[j], st); + *buflen += ipiti[j]; + } + + for (i = 0; i < LPC10_SAMPLES_PER_FRAME; ++i) { + speech[i] = (short) max(-32768, min(lrintf(8.0f * buf[i]), 32767)); + } + *buflen -= LPC10_SAMPLES_PER_FRAME; + for (i = 0; i < *buflen; ++i) { + buf[i] = buf[i + LPC10_SAMPLES_PER_FRAME]; + } + } +} /* synths_ */ + +static void decode(long ipitv, long irms, long *irc, long *voice, long *pitch, + float *rms, float *rc, lpc10_decoder_state *st) +{ + + /* Local variables */ + long i, i1, i2, i4; + long ishift; + + /* Function Body */ + + i4 = detau[ipitv]; + voice[0] = 1; + voice[1] = 1; + if (ipitv <= 1) { + voice[0] = 0; + } + if (ipitv == 0 || ipitv == 2) { + voice[1] = 0; + } + *pitch = i4; + if (*pitch <= 4) { + *pitch = st->iptold; + } + if (voice[0] == 1 && voice[1] == 1) { + st->iptold = *pitch; + } + if (voice[0] != voice[1]) { + *pitch = st->iptold; + } + /* Decode RMS */ + irms = rmst[(31 - irms) * 2]; + /* Decode RC(1) and RC(2) from log-area-ratios */ + /* Protect from illegal coded value (-16) caused by bit errors */ + for (i = 0; i < 2; ++i) { + i2 = irc[i]; + i1 = 0; + if (i2 < 0) { + i1 = 1; + i2 = -i2; + if (i2 > 15) { + i2 = 0; + } + } + i2 = detab7[i2 * 2]; + if (i1 == 1) { + i2 = -i2; + } + ishift = 15 - nbit[i]; + irc[i] = i2 * (2 << (ishift-1)); + } + /* Decode RC(3)-RC(10) to sign plus 14 bits */ + for (i = 2; i < 10; ++i) { + i2 = irc[i]; + ishift = 15 - nbit[i]; + i2 *= (2 << (ishift-1)); + i2 += qb[i - 2]; + irc[i] = (int)(i2 * descl[i - 2] + deadd[i - 2]); + } + /* Scale RMS and RC's to floats */ + *rms = (float) (irms); + for (i = 0; i < 10; ++i) { + rc[i] = irc[i] / 16384.f; + } +} /* decode_ */ + +static void unpack(long *array, long bits, long *value, long *pointer) +{ + int i; + + for (i = 0, *value = 0; i < bits; i++, (*pointer)++) + *value |= array[*pointer] << i; +} + +static void chanrd(long *ipitv, long *irms, long *irc, long *ibits, int *p, int vbr) +{ + static long bit[] = {0, 1, 2, 4, 8, 16, 32, 64, 128}; + long pointer, i; + + pointer = 0; + + unpack(ibits, 7, ipitv, &pointer); + if(vbr == TRUE) + { + /* check for silence packet */ + if (*ipitv == 127) { + *ipitv = 0; + *irms = 0; + *p = 1; + return; + } + } + unpack(ibits, 5, irms, &pointer); + *p = 4; + + for (i = 0; i < 4; ++i) { + unpack(ibits, lpcbits[i], &irc[i], &pointer); + } + if ((*ipitv != 0 && *ipitv != 126) || vbr == FALSE) { + *p = 7; + for (i = 4; i < 10; ++i) { + unpack(ibits, lpcbits[i], &irc[i], &pointer); + } + } + + /* Sign extend RC's */ + for (i = 0; i < 10; ++i) { + if ((irc[i] & bit[lpcbits[i]]) != 0) { + irc[i] -= bit[lpcbits[i]] << 1; + } + } +} + +static int lpc10_decode_int(unsigned char *in, int inLenMax, short *speech, + lpc10_decoder_state *st, int *p, int vbr) +{ + long bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + int i; + long irms, voice[2], pitch, ipitv; + float rc[10]; + long irc[10]; + float rms; + + /* unpack bits into array */ + int maxBits = inLenMax << 3; + if(maxBits > LPC10_BITS_IN_COMPRESSED_FRAME) + maxBits = LPC10_BITS_IN_COMPRESSED_FRAME; + + for (i = 0; i < maxBits; i++) + { + bits[i] = (in[i >> 3] & (1 << (i & 7))) != 0 ? 1 : 0; + } + for (; i < LPC10_BITS_IN_COMPRESSED_FRAME; i++) + bits[i] = 0; + + /* decode speech */ + memset(irc, 0, sizeof(irc)); + chanrd(&ipitv, &irms, irc, bits, p, vbr); + decode(ipitv, irms, irc, voice, &pitch, &rms, rc, st); + synths(voice, pitch, rms, rc, speech, st); + + return LPC10_SAMPLES_PER_FRAME; +} + +int lpc10_decode(unsigned char *in, int inLenMax, short *speech, lpc10_decoder_state *st) +{ + int p = 0; + + return lpc10_decode_int(in, inLenMax, speech, st, &p, FALSE); +} + +int vbr_lpc10_decode(unsigned char *in, int inLenMax, short *speech, lpc10_decoder_state *st, int *p) +{ + return lpc10_decode_int(in, inLenMax, speech, st, p, TRUE); +} + +/* Allocate memory for, and initialize, the state that needs to be +kept from decoding one frame to the next for a single +LPC-10-compressed audio stream. Return 0 if malloc fails, +otherwise return pointer to new structure. */ + +lpc10_decoder_state *create_lpc10_decoder_state(void) +{ + lpc10_decoder_state *st; + + st = (lpc10_decoder_state *)malloc((unsigned) sizeof (lpc10_decoder_state)); + return (st); +} + +void init_lpc10_decoder_state(lpc10_decoder_state *st) +{ + int i; + + /* State used by function decode */ + st->iptold = 60; + + /* State used by function synths */ + for (i = 0; i < 360; i++) { + st->buf[i] = 0.0f; + } + st->buflen = 180; + + /* State used by function pitsyn */ + st->rmso = 1.0f; + st->first_pitsyn = TRUE; + + /* State used by function bsynz */ + st->ipo = 0; + for (i = 0; i < 166; i++) { + st->exc[i] = 0.0f; + st->exc2[i] = 0.0f; + } + st->lpi1 = 0.0f; + st->lpi2 = 0.0f; + st->lpi3 = 0.0f; + st->hpi1 = 0.0f; + st->hpi2 = 0.0f; + st->hpi3 = 0.0f; + st->rmso_bsynz = 0.0f; + + /* State used by function deemp */ + st->dei1 = 0.0f; + st->dei2 = 0.0f; + st->deo1 = 0.0f; + st->deo2 = 0.0f; + st->deo3 = 0.0f; +} + +void destroy_lpc10_decoder_state (lpc10_decoder_state *st) +{ + if(st != NULL) + { + free(st); + st = NULL; + } +} diff --git a/tnl-1.5.0/tnl/zap/lpc10enc.c b/tnl-1.5.0/tnl/zap/lpc10enc.c new file mode 100644 index 0000000000000000000000000000000000000000..8fdd3ad3931ff781632d62026e8a8aa189544a81 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/lpc10enc.c @@ -0,0 +1,1476 @@ +/* + LPC-10 voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com) + + The VBR algorithm was contributed by + Ben Appleton + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +#if !defined( MACOSX ) && !defined (__APPLE__) +#include +#endif +#include +#ifdef __MWERKS__ +#include +#else +#include +#endif +#ifdef _MSC_VER + +#pragma warning (disable:4711) /* to disable automatic inline warning */ +#endif +#include +#include "ftol.h" +#include "lpc10.h" + +#if __GNUC__ == 2 +#define lrintf(d) ((int)(d)) +#endif + +#define LPC10_BITS_IN_COMPRESSED_FRAME 54 + +#ifndef TRUE +#define TRUE (1) +#define FALSE (0) +#endif + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +typedef struct lpc10_e_state { + /* State used only by function hp100 */ + float z11; + float z21; + float z12; + float z22; + + /* State used by function analys */ + float inbuf[540], pebuf[540]; + float lpbuf[696], ivbuf[312]; + float bias; + long osbuf[10]; /* no initial value necessary */ + long osptr; /* initial value 1 */ + long obound[3]; + long vwin[6] /* was [2][3] */; /* initial value vwin[4] = 307; vwin[5] = 462; */ + long awin[6] /* was [2][3] */; /* initial value awin[4] = 307; awin[5] = 462; */ + long voibuf[8] /* was [2][4] */; + float rmsbuf[3]; + float rcbuf[30] /* was [10][3] */; + float zpre; + + + /* State used by function onset */ + float n; + float d; /* initial value 1.f */ + float fpc; /* no initial value necessary */ + float l2buf[16]; + float l2sum1; + long l2ptr1; /* initial value 1 */ + long l2ptr2; /* initial value 9 */ + long lasti; /* no initial value necessary */ + int hyst; /* initial value FALSE_ */ + + /* State used by function voicin */ + float dither; /* initial value 20.f */ + float snr; + float maxmin; + float voice[6] /* was [2][3] */; /* initial value is probably unnecessary */ + long lbve, lbue, fbve, fbue; + long ofbue, sfbue; + long olbue, slbue; + + /* State used by function dyptrk */ + float s[60]; + long p[120] /* was [60][2] */; + long ipoint; + float alphax; + + /* State used by function chanwr */ + long isync; + +} lpc10_e_state_t; + +/* Table of constant values */ +long lpcbits[10] = { 5,5,5,5,4,4,4,4,3,3 }; + +static long entau[60] = { 19,11,27,25,29,21,23,22,30,14,15,7,39,38,46, + 42,43,41,45,37,53,49,51,50,54,52,60,56,58,26,90,88,92,84,86,82,83, + 81,85,69,77,73,75,74,78,70,71,67,99,97,113,112,114,98,106,104,108, + 100,101,76 }; +static long enadd[8] = { 1920,-768,2432,1280,3584,1536,2816,-1152 }; +static float enscl[8] = { .0204f,.0167f,.0145f,.0147f,.0143f,.0135f,.0125f,.0112f }; +static long enbits[8] = { 6,5,4,4,4,4,3,3 }; +static long entab6[64] = { 0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3, + 3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,9,9, + 9,10,10,11,11,12,13,14,15 }; +static long rmst[64] = { 1024,936,856,784,718,656,600,550,502,460,420, + 384,352,328,294,270,246,226,206,188,172,158,144,132,120,110,102, + 92,84,78,70,64,60,54,50,46,42,38,34,32,30,26,24,22,20,18,17,16,15, + 14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 }; + +static void vparms(long *vwin, float *inbuf, float *lpbuf, long half, + float *dither, long *mintau, long *zc, long *lbe, + long *fbe, float *qs, float *rc1, float *ar_b, float *ar_f) +{ + /* Local variables */ + float temp; + long vlen, stop, i; + float e_pre; + long start; + float ap_rms, e_0, oldsgn, lp_rms, e_b, e_f, r_b, r_f, e0ap; + + /* Parameter adjustments */ + lpbuf -= 25; + inbuf -= 181; + + /* Function Body */ + lp_rms = 0.f; + ap_rms = 0.f; + e_pre = 0.f; + e0ap = 0.f; + *rc1 = 0.f; + e_0 = 0.f; + e_b = 0.f; + e_f = 0.f; + r_f = 0.f; + r_b = 0.f; + *zc = 0; + vlen = vwin[1] - vwin[0] + 1; + start = vwin[0] + (half - 1) * vlen / 2 + 1; + stop = start + vlen / 2 - 1; + + oldsgn = ((inbuf[start - 1] - *dither)<0.0f)?-1.0f:1.0f; + for (i = start; i <= stop; ++i) { + if(lpbuf[i] < 0.0f) + lp_rms -= lpbuf[i]; + else + lp_rms += lpbuf[i]; + if(inbuf[i] < 0.0f) + ap_rms -= inbuf[i]; + else + ap_rms += inbuf[i]; + temp = inbuf[i] - inbuf[i - 1]; + if(temp < 0.0f) + e_pre -= temp; + else + e_pre += temp; + e0ap += inbuf[i] * inbuf[i]; + *rc1 += inbuf[i] * inbuf[i - 1]; + e_0 += lpbuf[i] * lpbuf[i]; + e_b += lpbuf[i - *mintau] * lpbuf[i - *mintau]; + e_f += lpbuf[i + *mintau] * lpbuf[i + *mintau]; + r_f += lpbuf[i] * lpbuf[i + *mintau]; + r_b += lpbuf[i] * lpbuf[i - *mintau]; + if ((((inbuf[i] + *dither)<0.0f)?-1.0f:1.0f) != oldsgn) { + ++(*zc); + oldsgn = -oldsgn; + } + *dither = -(*dither); + } + *rc1 /= max(e0ap,1.f); + *qs = e_pre / max(ap_rms * 2.f, 1.f); + *ar_b = r_b / max(e_b,1.f) * (r_b / max(e_0,1.f)); + *ar_f = r_f / max(e_f,1.f) * (r_f / max(e_0,1.f)); + *zc = lrintf((float) (*zc << 1) * (90.f / vlen)); + /* Computing MIN */ + *lbe = min(lrintf(lp_rms * 0.25f * (90.f / vlen)),32767); + /* Computing MIN */ + *fbe = min(lrintf(ap_rms * 0.25f * (90.f / vlen)),32767); +} /* vparms_ */ + +static void voicin(long *vwin, float *inbuf, float *lpbuf, long half, + float *minamd, float *maxamd, long *mintau, float *ivrc, long *obound, + long *voibuf, lpc10_encoder_state *st) +{ + /* Initialized data */ + + float *dither; + static float vdc[100] /* was [10][10] */ = { 0.f,1714.f,-110.f, + 334.f,-4096.f,-654.f,3752.f,3769.f,0.f,1181.f,0.f,874.f,-97.f, + 300.f,-4096.f,-1021.f,2451.f,2527.f,0.f,-500.f,0.f,510.f,-70.f, + 250.f,-4096.f,-1270.f,2194.f,2491.f,0.f,-1500.f,0.f,500.f,-10.f, + 200.f,-4096.f,-1300.f,2e3f,2e3f,0.f,-2e3f,0.f,500.f,0.f,0.f, + -4096.f,-1300.f,2e3f,2e3f,0.f,-2500.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, + 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, + 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, + 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f }; + static float vdcl[10] = { 600.f,450.f,300.f,200.f,0.f,0.f,0.f,0.f,0.f,0.f }; + + /* Local variables */ + float ar_b, ar_f; + long snrl, i; + float *voice; + float value[9]; + long zc; + int ot; + float qs; + long vstate; + float rc1; + long fbe, lbe; + float snr2; + + + /* Declare and initialize filters: */ + + dither = (&st->dither); + voice = (&st->voice[0]); + + /* Function Body */ + + /* Update linear discriminant function history each frame: */ + if (half == 1) { + voice[0] = voice[2]; + voice[1] = voice[3]; + voice[2] = voice[4]; + voice[3] = voice[5]; + st->maxmin = *maxamd / max(*minamd, 1.f); + } + /* Calculate voicing parameters twice per frame: */ + vparms(vwin, inbuf, lpbuf, half, dither, mintau, + &zc, &lbe, &fbe, &qs, &rc1, &ar_b, &ar_f); + /* Estimate signal-to-noise ratio to select the appropriate VDC vector. */ + st->snr = (float) lrintf((st->snr + st->fbve / (float) max(st->fbue, 1)) * 63 / 64.f); + snr2 = st->snr * st->fbue / max(st->lbue, 1); + /* Quantize SNR to SNRL according to VDCL thresholds. */ + for (snrl = 1; snrl <= 4; ++snrl) { + if (snr2 > vdcl[snrl - 1]) { + break; + } + } + /* Linear discriminant voicing parameters: */ + value[0] = st->maxmin; + value[1] = (float) lbe / max(st->lbve, 1); + value[2] = (float) zc; + value[3] = rc1; + value[4] = qs; + value[5] = ivrc[1]; + value[6] = ar_b; + value[7] = ar_f; + /* Evaluation of linear discriminant function: */ + voice[half + 3] = vdc[snrl * 10 - 1]; + for (i = 1; i <= 8; ++i) { + voice[half + 3] += vdc[i + snrl * 10 - 11] * value[i - 1]; + } + /* Classify as voiced if discriminant > 0, otherwise unvoiced */ + /* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */ + if (voice[half + 3] > 0.f) { + voibuf[half + 5] = 1; + } else { + voibuf[half + 5] = 0; + } + /* Skip voicing decision smoothing in first half-frame: */ + vstate = -1; + if (half != 1) { + /* Determine if there is an onset transition between P and 1F. */ + /* OT (Onset Transition) is true if there is an onset between */ + /* P and 1F but not after 1F. */ + ot = ((obound[0] & 2) != 0 || obound[1] == 1) && (obound[2] & 1) == 0; + /* Multi-way dispatch on voicing decision history: */ + vstate = (voibuf[2] << 3) + (voibuf[3] << 2) + (voibuf[4] << 1) + voibuf[5]; + + switch (vstate + 1) { + case 1: + break; + case 2: + if (ot && voibuf[6] == 1) { + voibuf[4] = 1; + } + break; + case 3: + if (voibuf[6] == 0 || voice[2] < -voice[3]) { + voibuf[4] = 0; + } else { + voibuf[5] = 1; + } + break; + case 4: + break; + case 5: + voibuf[3] = 0; + break; + case 6: + if (voice[1] < -voice[2]) { + voibuf[3] = 0; + } else { + voibuf[4] = 1; + } + break; + case 7: + if (voibuf[0] == 1 || voibuf[6] == 1 || voice[3] > voice[0]) { + voibuf[5] = 1; + } else { + voibuf[2] = 1; + } + break; + case 8: + if (ot) { + voibuf[3] = 0; + } + break; + case 9: + if (ot) { + voibuf[3] = 1; + } + break; + case 10: + break; + case 11: + if (voice[2] < -voice[1]) { + voibuf[4] = 0; + } else { + voibuf[3] = 1; + } + break; + case 12: + voibuf[3] = 1; + break; + case 13: + break; + case 14: + if (voibuf[6] == 0 && voice[3] < -voice[2]) { + voibuf[5] = 0; + } else { + voibuf[4] = 1; + } + break; + case 15: + if (ot && voibuf[6] == 0) { + voibuf[4] = 0; + } + break; + case 16: + break; + } + } + /* Now update parameters: */ + if (voibuf[half + 5] == 0) { + /* Computing MIN */ + st->sfbue = lrintf((st->sfbue * 63 + (min(fbe, st->ofbue * 3) << 3)) / 64.f); + st->fbue = st->sfbue / 8; + st->ofbue = fbe; + /* Computing MIN */ + st->slbue = lrintf((st->slbue * 63 + (min(lbe, st->olbue * 3) << 3)) / 64.f); + st->lbue = st->slbue / 8; + st->olbue = lbe; + } else { + st->lbve = lrintf((st->lbve * 63 + lbe) / 64.f); + st->fbve = lrintf((st->fbve * 63 + fbe) / 64.f); + } + /* Set dither threshold to yield proper zero crossing rates in the */ + /* presence of low frequency noise and low level signal input. */ + *dither = min(max(((float)sqrt((float) (st->lbue * st->lbve)) * 64 / 3000), 1.f),20.f); +} /* voicin_ */ + +static void difmag(float *speech, long *tau, + long ltau, long maxlag, float *amdf, + long *minptr, long *maxptr) +{ + /* Local variables */ + long i, j, n1, n2; + long lmin, lmax; + float sum; + + /* Function Body */ + lmin = 0; + lmax = 0; + + for (i = 0; i < ltau; ++i) { + long t = tau[i]; + + n1 = (maxlag - t) / 2; + n2 = n1 + 156; + sum = 0.f; + t += n1; + for (j = n1; j < n2; j += 4, t += 4) { + float temp = speech[j] - speech[t]; + + if(temp < 0.0f) + { + sum -= temp; + } + else + { + sum += temp; + } + } + if (sum < amdf[lmin]) { + lmin = i; + } else if (sum > amdf[lmax]) { + lmax = i; + } + amdf[i] = sum; + } + *minptr = lmin + 1; + *maxptr = lmax + 1; +} /* difmag_ */ + +static void tbdm(float *speech, long *tau, float *amdf, long *minptr, long *maxptr, long *mintau) +{ + /* Local variables */ + float amdf2[6]; + long minp2, ltau2, maxp2, i, j; + long minamd, ptr, tau2[6]; + + /* Compute full AMDF using log spaced lags, find coarse minimum */ + /* Parameter adjustments */ + --amdf; + --tau; + + /* Function Body */ + difmag(speech, &tau[1], 60, tau[60], &amdf[1], minptr, maxptr); + *mintau = tau[*minptr]; + minamd = (long)amdf[*minptr]; + /* Build table containing all lags within +/- 3 of the AMDF minimum */ + /* excluding all that have already been computed */ + ltau2 = 0; + ptr = *minptr - 2; + /* Computing MIN */ + j = min(*mintau + 3, tau[60] - 1); + /* Computing MAX */ + i = max(*mintau - 3, 41); + for (; i <= j; ++i) { + while(tau[ptr] < i) { + ++ptr; + } + if (tau[ptr] != i) { + ++ltau2; + tau2[ltau2 - 1] = i; + } + } + /* Compute AMDF of the new lags, if there are any, and choose one */ + /* if it is better than the coarse minimum */ + if (ltau2 > 0) { + difmag(speech, tau2, ltau2, tau[60], amdf2, &minp2, &maxp2); + if (amdf2[minp2 - 1] < (float) minamd) { + *mintau = tau2[minp2 - 1]; + minamd = (long)amdf2[minp2 - 1]; + } + } + /* Check one octave up, if there are any lags not yet computed */ + if (*mintau >= 80) { + i = *mintau / 2; + if ((i & 1) == 0) { + ltau2 = 2; + tau2[0] = i - 1; + tau2[1] = i + 1; + } else { + ltau2 = 1; + tau2[0] = i; + } + difmag(speech, tau2, ltau2, tau[60], amdf2, &minp2, &maxp2); + if (amdf2[minp2 - 1] < (float) minamd) { + *mintau = tau2[minp2 - 1]; + minamd = (long)amdf2[minp2 - 1]; + *minptr += -20; + } + } + /* Force minimum of the AMDF array to the high resolution minimum */ + amdf[*minptr] = (float) minamd; + /* Find maximum of AMDF within 1/2 octave of minimum */ + /* Computing MAX */ + *maxptr = max(*minptr - 5,1); + /* Computing MIN */ + j = min(*minptr + 5, 60); + for (i = *maxptr + 1; i <= j; ++i) { + if (amdf[i] > amdf[*maxptr]) { + *maxptr = i; + } + } +} /* tbdm_ */ + +static void placev(long *osbuf, long osptr, long *obound, long *vwin) +{ + /* Local variables */ + int crit; + long i, q, osptr1, hrange, lrange; + + /* Compute the placement range */ + /* Parameter adjustments */ + --osbuf; + + /* Function Body */ + /* Computing MAX */ + lrange = max(vwin[3] + 1, LPC10_SAMPLES_PER_FRAME + 1); + hrange = 3 * LPC10_SAMPLES_PER_FRAME; + /* Compute OSPTR1, so the following code only looks at relevant onsets. */ + for (osptr1 = osptr; osptr1 >= 1; --osptr1) { + if (osbuf[osptr1] <= hrange) { + break; + } + } + ++osptr1; + /* Check for case 1 first (fast case): */ + if (osptr1 <= 1 || osbuf[osptr1 - 1] < lrange) { + /* Computing MAX */ + vwin[4] = max(vwin[3] + 1,307); + vwin[5] = vwin[4] + 156 - 1; + *obound = 0; + } else { + /* Search backward in OSBUF for first onset in range. */ + /* This code relies on the above check being performed first. */ + for (q = osptr1 - 1; q >= 1; --q) { + if (osbuf[q] < lrange) { + break; + } + } + ++q; + /* Check for case 2 (placement before onset): */ + /* Check for critical region exception: */ + crit = FALSE; + for (i = q + 1; i <= (osptr1 - 1); ++i) { + if (osbuf[i] - osbuf[q] >= 90) { + crit = TRUE; + break; + } + } + /* Computing MAX */ + if (! crit && osbuf[q] > max(2 * LPC10_SAMPLES_PER_FRAME, lrange + 90 - 1)) { + vwin[5] = osbuf[q] - 1; + /* Computing MAX */ + vwin[4] = max(lrange, vwin[5] - 156 + 1); + *obound = 2; + /* Case 3 (placement after onset) */ + } else { + vwin[4] = osbuf[q]; +L110: + ++q; + if (q >= osptr1) { + goto L120; + } + if (osbuf[q] > vwin[4] + 156) { + goto L120; + } + if (osbuf[q] < vwin[4] + 90) { + goto L110; + } + vwin[5] = osbuf[q] - 1; + *obound = 3; + return; +L120: + /* Computing MIN */ + vwin[5] = min(vwin[4] + 156 - 1,hrange); + *obound = 1; + } + } +} /* placev_ */ + +static void placea(long ipitch, long *voibuf, long obound, + long *vwin, long *awin, long *ewin) +{ + /* Local variables */ + int allv, winv; + long i, j, k, l, hrange; + int ephase; + long lrange; + + /* Function Body */ + lrange = (3 - 2) * LPC10_SAMPLES_PER_FRAME + 1; + hrange = 3 * LPC10_SAMPLES_PER_FRAME; + allv = voibuf[3] == 1; + allv = allv && voibuf[4] == 1; + allv = allv && voibuf[5] == 1; + allv = allv && voibuf[6] == 1; + allv = allv && voibuf[7] == 1; + winv = voibuf[6] == 1 || voibuf[7] == 1; + if ((allv || winv) && (obound == 0)) { +/* APHASE: Phase synchronous window placement. */ +/* Get minimum lower index of the window. */ + i = (lrange + ipitch - 1 - awin[2]) / ipitch; + i *= ipitch; + i += awin[2]; +/* L = the actual length of this frame's analysis window. */ + l = 156; +/* Calculate the location where a perfectly centered window would star +t. */ + k = (vwin[4] + vwin[5] + 1 - l) / 2; +/* Choose the actual location to be the pitch multiple closest to this +. */ + awin[4] = i + lrintf((float) (k - i) / ipitch) * ipitch; + awin[5] = awin[4] + l - 1; + if (obound >= 2 && awin[5] > vwin[5]) { + awin[4] -= ipitch; + awin[5] -= ipitch; + } +/* Similarly for the left of the voicing window. */ + if ((obound == 1 || obound == 3) && awin[4] < vwin[4]) { + awin[4] += ipitch; + awin[5] += ipitch; + } +/* If this placement puts the analysis window above HRANGE, then */ +/* move it backward an integer number of pitch periods. */ + while(awin[5] > hrange) { + awin[4] -= ipitch; + awin[5] -= ipitch; + } +/* Similarly if the placement puts the analysis window below LRANGE. +*/ + while(awin[4] < lrange) { + awin[4] += ipitch; + awin[5] += ipitch; + } +/* Make Energy window be phase-synchronous. */ + ephase = TRUE; +/* Case 3 */ + } else { + awin[4] = vwin[4]; + awin[5] = vwin[5]; + ephase = FALSE; + } + + j = (awin[5] - awin[4] + 1) / ipitch * ipitch; + if (j == 0 || ! winv) { + ewin[4] = vwin[4]; + ewin[5] = vwin[5]; + } else if (! ephase && obound == 2) { + ewin[4] = awin[5] - j + 1; + ewin[5] = awin[5]; + } else { + ewin[4] = awin[4]; + ewin[5] = awin[4] + j - 1; + } +} /* placea_ */ + +static void mload(long awinf, float *speech, float *phi, float *psi) +{ + long c, i, r; + + /* Function Body */ + for (r = 0; r < 10; ++r) { + phi[r] = 0.f; + for (i = 10; i < awinf; ++i) { + phi[r] += speech[i - 1] * speech[i - r - 1]; + } + } + /* Load last element of vector PSI */ + psi[9] = 0.f; + for (i = 10; i < awinf; ++i) { + psi[9] += speech[i] * speech[i - 10]; + } + /* End correct to get additional columns of PHI */ + for (r = 1; r < 10; ++r) { + for (c = 1; c <= r; ++c) { + phi[r + (c) * 10] = phi[r + (c - 1) * 10 - 1] - + speech[awinf - r - 1] * speech[awinf - c - 1] + + speech[10 - r - 1] * speech[10 - c - 1]; + } + } + /* End correct to get additional elements of PSI */ + for (c = 0; c < 9; ++c) { + psi[c] = phi[c + 1] - speech[10] * speech[10 - 2 - c] + + speech[awinf - 1] * speech[awinf - c - 2]; + } +} /* mload_ */ + +static void rcchk(float *rc1f, float *rc2f) +{ + /* Local variables */ + long i; + + /* Function Body */ + for (i = 0; i < 10; ++i) { + if ((fabs(rc2f[i])) > .99f) { + goto L10; + } + } + return; +L10: + for (i = 0; i < 10; ++i) { + rc2f[i] = rc1f[i]; + } +} /* rcchk_ */ + +static void dcbias(long len, float *speech, float *sigout) +{ + /* Local variables */ + float bias; + long i; + + /* Function Body */ + bias = 0.f; + for (i = 0; i < len; ++i) { + bias += speech[i]; + } + bias /= len; + for (i = 0; i < len; ++i) { + *sigout++ = *speech++ - bias; + } +} /* dcbias_ */ + +static void preemp(float *inbuf, float *pebuf, long nsamp, float *z) +{ + /* Local variables */ + float temp; + long i; + + /* Function Body */ + for (i = 0; i< nsamp; ++i) { + temp = *inbuf - .9375f * *z; + *z = *inbuf++; + *pebuf++ = temp; + } +} /* preemp_ */ + +static void lpfilt(float *inbuf, float *lpbuf, long nsamp) +{ + /* Local variables */ + long j; + + /* Function Body */ + lpbuf = &lpbuf[312 - nsamp]; + for (j = 312 - nsamp; j < 312; ++j) { + *lpbuf++ = (inbuf[j] + inbuf[j - 30]) * -.0097201988f + + (inbuf[j - 1] + inbuf[j - 29]) * -.0105179986f + + (inbuf[j - 2] + inbuf[j - 28]) * -.0083479648f + + (inbuf[j - 3] + inbuf[j - 27]) * 5.860774e-4f + + (inbuf[j - 4] + inbuf[j - 26]) * .0130892089f + + (inbuf[j - 5] + inbuf[j - 25]) * .0217052232f + + (inbuf[j - 6] + inbuf[j - 24]) * .0184161253f + + (inbuf[j - 7] + inbuf[j - 23]) * 3.39723e-4f + + (inbuf[j - 8] + inbuf[j - 22]) * -.0260797087f + + (inbuf[j - 9] + inbuf[j - 21]) * -.0455563702f + + (inbuf[j - 10] + inbuf[j - 20]) * -.040306855f + + (inbuf[j - 11] + inbuf[j - 19]) * 5.029835e-4f + + (inbuf[j - 12] + inbuf[j - 18]) * .0729262903f + + (inbuf[j - 13] + inbuf[j - 17]) * .1572008878f + + (inbuf[j - 14] + inbuf[j - 16]) * .2247288674f + + inbuf[j - 15] * .250535965f; + } +} /* lpfilt_ */ + +static void ivfilt(float *lpbuf, float *ivbuf, long nsamp, float *ivrc) +{ + /* Local variables */ + long i, j, k; + float r[3], pc1, pc2; + + /* Function Body */ + for (i = 0; i < 3; ++i) { + r[i] = 0.f; + k = (i) << 2; + for (j = ((i + 1) << 2) + 312 - nsamp - 1; j < 312; j += 2) { + r[i] += lpbuf[j] * lpbuf[j - k]; + } + } + /* Calculate predictor coefficients */ + pc1 = 0.f; + pc2 = 0.f; + ivrc[0] = 0.f; + ivrc[1] = 0.f; + if (r[0] > 1e-10f) { + ivrc[0] = r[1] / r[0]; + ivrc[1] = (r[2] - ivrc[0] * r[1]) / (r[0] - ivrc[0] * r[1]); + pc1 = ivrc[0] - ivrc[0] * ivrc[1]; + pc2 = ivrc[1]; + } + /* Inverse filter LPBUF into IVBUF */ + for (i = 312 - nsamp; i < 312; ++i) { + ivbuf[i] = lpbuf[i] - pc1 * lpbuf[i - 4] - pc2 * lpbuf[i - 8]; + } +} /* ivfilt_ */ + +static void invert(float *phi, float *psi, float *rc) +{ + /* Local variables */ + float save; + long i, j, k; + float v[100] /* was [10][10] */; + + + /* Function Body */ + for (j = 0; j < 10; ++j) { + for (i = j; i < 10; ++i) { + v[i + j * 10] = phi[i + j * 10]; + } + for (k = 0; k < j; ++k) { + save = v[j + k * 10] * v[k + k * 10]; + for (i = j; i < 10; ++i) { + v[i + j * 10] -= v[i + k * 10] * save; + } + } + /* Compute intermediate results, which are similar to RC's */ + if ((fabs(v[j + j * 10])) < 1e-10f) { + goto L100; + } + rc[j] = psi[j]; + for (k = 0; k < j; ++k) { + rc[j] -= rc[k] * v[j + k * 10]; + } + v[j + j * 10] = 1.f / v[j + j * 10]; + rc[j] *= v[j + j * 10]; + + rc[j] = max(min(rc[j],.999f),-.999f); + } + return; + /* Zero out higher order RC's if algorithm terminated early */ +L100: + for (i = j; i < 10; ++i) { + rc[i] = 0.f; + } +} /* invert_ */ + +static void energy(long len, float *speech, float *rms) +{ + /* Local variables */ + long i; + + /* Function Body */ + *rms = 0.f; + for (i = 0; i < len; ++i) { + *rms += speech[i] * speech[i]; + } + *rms = (float)sqrt(*rms / len); +} /* energy_ */ + +static void dyptrk(float *amdf, long *minptr, long *voice, long *pitch, + long *midx, lpc10_encoder_state *st) +{ + /* Initialized data */ + + float *s; + long *p; + long *ipoint; + float *alphax; + + + /* Local variables */ + long pbar; + float sbar; + long path[2], iptr, i, j; + float alpha, minsc, maxsc; + + s = &(st->s[0]); + p = &(st->p[0]); + ipoint = &(st->ipoint); + alphax = &(st->alphax); + + + /* Parameter adjustments */ + if (amdf) { + --amdf; + } + + /* Function Body */ + + if (*voice == 1) { + *alphax = *alphax * .75f + amdf[*minptr] / 2.f; + } else { + *alphax *= .984375f; + } + alpha = *alphax / 16; + if (*voice == 0 && *alphax < 128.f) { + alpha = 8.f; + } + /* SEESAW: Construct a pitch pointer array and intermediate winner function*/ + /* Left to right pass: */ + iptr = *ipoint + 1; + p[iptr * 60 - 60] = 1; + i = 1; + pbar = 1; + sbar = s[0]; + for (i = 1; i <= 60; ++i) { + sbar += alpha; + if (sbar < s[i - 1]) { + s[i - 1] = sbar; + p[i + iptr * 60 - 61] = pbar; + } else { + sbar = s[i - 1]; + p[i + iptr * 60 - 61] = i; + pbar = i; + } + } + /* Right to left pass: */ + i = pbar - 1; + sbar = s[i]; + while(i >= 1) { + sbar += alpha; + if (sbar < s[i - 1]) { + s[i - 1] = sbar; + p[i + iptr * 60 - 61] = pbar; + } else { + pbar = p[i + iptr * 60 - 61]; + i = pbar; + sbar = s[i - 1]; + } + --i; + } + /* Update S using AMDF */ + /* Find maximum, minimum, and location of minimum */ + s[0] += amdf[1] / 2; + minsc = s[0]; + maxsc = minsc; + *midx = 1; + for (i = 2; i <= 60; ++i) { + s[i - 1] += amdf[i] / 2; + if (s[i - 1] > maxsc) { + maxsc = s[i - 1]; + } + if (s[i - 1] < minsc) { + *midx = i; + minsc = s[i - 1]; + } + } + /* Subtract MINSC from S to prevent overflow */ + for (i = 1; i <= 60; ++i) { + s[i - 1] -= minsc; + } + maxsc -= minsc; + /* Use higher octave pitch if significant null there */ + j = 0; + for (i = 20; i <= 40; i += 10) { + if (*midx > i) { + if (s[*midx - i - 1] < maxsc / 4) { + j = i; + } + } + } + *midx -= j; + /* TRACE: look back two frames to find minimum cost pitch estimate */ + j = *ipoint; + *pitch = *midx; + for (i = 1; i <= 2; ++i) { + j = j % 2 + 1; + *pitch = p[*pitch + j * 60 - 61]; + path[i - 1] = *pitch; + } + + *ipoint = (*ipoint + 1) % 2; +} /* dyptrk_ */ + +static void onset(float *pebuf, long *osbuf, long *osptr, lpc10_encoder_state *st) +{ + /* Initialized data */ + + float n; + float d; + float *l2buf; + float *l2sum1; + long *l2ptr1; + long *l2ptr2; + int *hyst; + + /* System generated locals */ + float temp; + + /* Local variables */ + long i; + long *lasti; + float l2sum2; + float *fpc; + + + n = st->n; + d = st->d; + fpc = &(st->fpc); + l2buf = &(st->l2buf[0]); + l2sum1 = &(st->l2sum1); + l2ptr1 = &(st->l2ptr1); + l2ptr2 = &(st->l2ptr2); + lasti = &(st->lasti); + hyst = &(st->hyst); + + /* Parameter adjustments */ + if (pebuf) { + pebuf -= 181; + } + + /* Function Body */ + + if (*hyst) { + *lasti -= LPC10_SAMPLES_PER_FRAME; + } + for (i = 720 - LPC10_SAMPLES_PER_FRAME + 1; i <= 720; ++i) { + /* Compute FPC; Use old FPC on divide by zero; Clamp FPC to +/- 1. */ + n = (pebuf[i] * pebuf[i - 1] + n * 63.f) * 0.015625f; + /* Computing 2nd power */ + temp = pebuf[i - 1]; + d = (temp * temp + d * 63.f) * 0.015625f; + if (d != 0.f) { + if(n > d || n < -(d)){ + *fpc = (n<0.0f)?-1.0f:1.0f; + } else { + *fpc = n / d; + } + } + + l2sum2 = l2buf[*l2ptr1 - 1]; + *l2sum1 = *l2sum1 - l2buf[*l2ptr2 - 1] + *fpc; + l2buf[*l2ptr2 - 1] = *l2sum1; + l2buf[*l2ptr1 - 1] = *fpc; + *l2ptr1 = *l2ptr1 % 16 + 1; + *l2ptr2 = *l2ptr2 % 16 + 1; + temp = *l2sum1 - l2sum2; + if (temp > 1.7f || temp < -1.7f) { + if (! (*hyst)) { + /* Ignore if buffer full */ + if (*osptr < 10) { + osbuf[*osptr] = i - 9; + ++(*osptr); + } + *hyst = TRUE; + } + *lasti = i; + /* After one onset detection, at least OSHYST sample times must go */ + /* by before another is allowed to occur. */ + } else if ((*hyst) && i - *lasti >= 10) { + *hyst = FALSE; + } + } + st->n = n; + st->d = d; +} /* onset_ */ + +static void analys(float *speech, long *voice, long + *pitch, float *rms, float *rc, lpc10_encoder_state *st) +{ + /* Initialized data */ + + static long tau[60] = { 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34, + 35,36,37,38,39,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72, + 74,76,78,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136, + 140,144,148,152,156 }; + + /* System generated locals */ + long i1; + + /* Local variables */ + float amdf[60]; + long half; + float abuf[156]; + float bias; + long *awin; + long midx, ewin[6] /* was [2][3] */; + float ivrc[2], temp; + long *vwin; + long i, j, lanal; + float *inbuf, *pebuf; + float *lpbuf, *ivbuf; + float *rcbuf; + long *osptr; + long *osbuf; + long ipitch; + long *obound; + long *voibuf; + long mintau; + float *rmsbuf; + long minptr, maxptr; + float phi[100] /* was [10][10] */, psi[10]; + + inbuf = &(st->inbuf[0]); + pebuf = &(st->pebuf[0]); + lpbuf = &(st->lpbuf[0]); + ivbuf = &(st->ivbuf[0]); + bias = st->bias; + osbuf = &(st->osbuf[0]); + osptr = &(st->osptr); + obound = &(st->obound[0]); + vwin = &(st->vwin[0]); + awin = &(st->awin[0]); + voibuf = &(st->voibuf[0]); + rmsbuf = &(st->rmsbuf[0]); + rcbuf = &(st->rcbuf[0]); + + i1 = 720 - LPC10_SAMPLES_PER_FRAME; + for (i = LPC10_SAMPLES_PER_FRAME; i < i1; ++i) { + inbuf[i - LPC10_SAMPLES_PER_FRAME] = inbuf[i]; + pebuf[i - LPC10_SAMPLES_PER_FRAME] = pebuf[i]; + } + i1 = 540 - LPC10_SAMPLES_PER_FRAME - 229; + for (i = 0; i <= i1; ++i) { + ivbuf[i] = ivbuf[LPC10_SAMPLES_PER_FRAME + i]; + } + i1 = 720 - LPC10_SAMPLES_PER_FRAME - 25; + for (i = 0; i <= i1; ++i) { + lpbuf[i] = lpbuf[LPC10_SAMPLES_PER_FRAME + i]; + } + j = 0; + for (i = 0; i < *osptr; ++i) { + if (osbuf[i] > LPC10_SAMPLES_PER_FRAME) { + osbuf[j] = osbuf[i] - LPC10_SAMPLES_PER_FRAME; + ++j; + } + } + *osptr = j; + voibuf[0] = voibuf[2]; + voibuf[1] = voibuf[3]; + for (i = 1; i <= 2; ++i) { + vwin[(i << 1) - 2] = vwin[((i + 1) << 1) - 2] - LPC10_SAMPLES_PER_FRAME; + vwin[(i << 1) - 1] = vwin[((i + 1) << 1) - 1] - LPC10_SAMPLES_PER_FRAME; + awin[(i << 1) - 2] = awin[((i + 1) << 1) - 2] - LPC10_SAMPLES_PER_FRAME; + awin[(i << 1) - 1] = awin[((i + 1) << 1) - 1] - LPC10_SAMPLES_PER_FRAME; + obound[i - 1] = obound[i]; + voibuf[i << 1] = voibuf[(i + 1) << 1]; + voibuf[(i << 1) + 1] = voibuf[((i + 1) << 1) + 1]; + rmsbuf[i - 1] = rmsbuf[i]; + for (j = 1; j <= 10; ++j) { + rcbuf[j + i * 10 - 11] = rcbuf[j + (i + 1) * 10 - 11]; + } + } + temp = 0.f; + for (i = 0; i < LPC10_SAMPLES_PER_FRAME; ++i) { + inbuf[720 - LPC10_SAMPLES_PER_FRAME + i - 180] = speech[i] * 4096.f - bias; + temp += inbuf[720 - LPC10_SAMPLES_PER_FRAME + i - 180]; + } + if (temp > (float) LPC10_SAMPLES_PER_FRAME) { + st->bias += 1; + } + if (temp < (float) (-LPC10_SAMPLES_PER_FRAME)) { + st->bias += -1; + } + /* Place Voicing Window */ + i = 720 - LPC10_SAMPLES_PER_FRAME; + preemp(&inbuf[i - 180], &pebuf[i - 180], LPC10_SAMPLES_PER_FRAME, &(st->zpre)); + onset(pebuf, osbuf, osptr, st); + + placev(osbuf, *osptr, &obound[2], vwin); + lpfilt(&inbuf[228], &lpbuf[384], LPC10_SAMPLES_PER_FRAME); + ivfilt(&lpbuf[204], ivbuf, LPC10_SAMPLES_PER_FRAME, ivrc); + tbdm(ivbuf, tau, amdf, &minptr, &maxptr, &mintau); + /* voicing decisions. */ + for (half = 1; half <= 2; ++half) { + voicin(&vwin[4], inbuf, lpbuf, half, &amdf[minptr - 1], + &amdf[maxptr - 1], &mintau, ivrc, obound, voibuf, st); + } + dyptrk(amdf, &minptr, &voibuf[7], pitch, &midx, st); + ipitch = tau[midx - 1]; + placea(ipitch, voibuf, obound[2], vwin, awin, ewin); + lanal = awin[5] + 1 - awin[4]; + dcbias(lanal, &pebuf[awin[4] - 181], abuf); + i1 = ewin[5] - ewin[4] + 1; + energy(i1, &abuf[ewin[4] - awin[4]], &rmsbuf[2]); + /* Matrix load and invert, check RC's for stability */ + mload(lanal, abuf, phi, psi); + invert(phi, psi, &rcbuf[20]); + rcchk(&rcbuf[10], &rcbuf[20]); + /* Set return parameters */ + voice[0] = voibuf[2]; + voice[1] = voibuf[3]; + *rms = rmsbuf[0]; + for (i = 0; i < 10; ++i) { + rc[i] = rcbuf[i]; + } +} /* analys_ */ + +static void encode(long *voice, long pitch, float rms, float *rc, long *ipitch, + long *irms, long *irc) +{ + /* Local variables */ + long idel, nbit, i, j, i2, i3, mrk; + + /* Function Body */ + /* Scale RMS and RC's to integers */ + *irms = lrintf(rms); + for (i = 0; i < 10; ++i) { + irc[i] = lrintf(rc[i] * 32768.f); + } + /* Encode pitch and voicing */ + if (voice[0] != 0 && voice[1] != 0) { + *ipitch = entau[pitch - 1]; + } else { + *ipitch = (voice[0] << 1) + voice[1]; + } + /* Encode RMS by binary table search */ + j = 32; + idel = 16; + *irms = min(*irms,1023); + while(idel > 0) { + if (*irms > rmst[j - 1]) { + j -= idel; + } + if (*irms < rmst[j - 1]) { + j += idel; + } + idel /= 2; + } + if (*irms > rmst[j - 1]) { + --j; + } + *irms = 31 - j / 2; + /* Encode RC(1) and (2) as log-area-ratios */ + for (i = 0; i < 2; ++i) { + i2 = irc[i]; + mrk = 0; + if (i2 < 0) { + i2 = -i2; + mrk = 1; + } + i2 /= 512; + i2 = min(i2,63); + i2 = entab6[i2]; + if (mrk != 0) { + i2 = -i2; + } + irc[i] = i2; + } + /* Encode RC(3) - (10) linearly, remove bias then scale */ + for (i = 2; i < 10; ++i) { + i2 = irc[i] / 2; + i2 = lrintf((i2 + enadd[10 + 1 - i - 2]) * enscl[10 + 1 - i - 2]); + /* Computing MIN */ + i2 = min(max(i2,-127),127); + nbit = enbits[10 + 1 - i - 2]; + i3 = 0; + if (i2 < 0) { + i3 = -1; + } + i2 = i2 / (2 << (nbit-1)); + if (i3 == -1) { + --i2; + } + irc[i] = i2; + } +/* printf("%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d\n",irc[0],irc[1],irc[2],irc[3],irc[4],irc[5] + ,irc[6],irc[7],irc[8],irc[9], *ipitch, *irms); +*/ +} /* encode_ */ + +static void hp100(float *speech, long end, lpc10_encoder_state *st) +{ + float z11; + float z21; + float z12; + float z22; + + /* Local variables */ + long i; + float si, err; + + /* Function Body */ + + z11 = st->z11; + z21 = st->z21; + z12 = st->z12; + z22 = st->z22; + + for (i = 0; iz11 = z11; + st->z21 = z21; + st->z12 = z12; + st->z22 = z22; + +} /* hp100_ */ + +static void pack(long value, long bits, long *array, long *pointer) +{ + int i; + + for (i = 0; i < bits; (*pointer)++, i++) + array[*pointer] = (long)((value & 1 << i) >> i); +} + +static long chanwr(long ipitv, long irms, long *irc, long *ibits, int vbr) +{ + long i; + long pointer; + + pointer = 0; + + if(vbr == TRUE) + { + /* test for silence */ + if(irms < 10) { + pack(127, 7, ibits, &pointer); + return 1; + } + } + + pack(ipitv, 7, ibits, &pointer); + pack(irms, 5, ibits, &pointer); + + for (i = 0; i < 4; ++i) { + pack(irc[i], lpcbits[i], ibits, &pointer); + } + /* test for unvoiced */ + if((ipitv != 0 && ipitv != 126) || vbr == FALSE) { + for (i = 4; i < 10; ++i) { + pack(irc[i], lpcbits[i], ibits, &pointer); + } + return 7; + } + return 4; +} + +int lpc10_encode_int(short *in, unsigned char *out, lpc10_encoder_state *st, int vbr) +{ + float speech[LPC10_SAMPLES_PER_FRAME]; + float *sp = speech; + long bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + int i; + long irms, voice[2], pitch, ipitv; + float rc[10]; + long irc[10]; + float rms; + long framesize; + + /* convert sound from short to float */ + for(i=LPC10_SAMPLES_PER_FRAME;i--;) + { + *sp++ = (float)(*in++ / 32768.0f); + } + + /* encode it */ + memset(bits, 0, sizeof(bits)); + hp100(speech, LPC10_SAMPLES_PER_FRAME, st); + analys(speech, voice, &pitch, &rms, rc, st); + encode(voice, pitch, rms, rc, &ipitv, &irms, irc); + framesize = chanwr(ipitv, irms, irc, bits, vbr); + + /* pack the bits */ + memset(out, 0, 7); + for (i = 0; i < 54; i++) + { + out[i >> 3] |= ((bits[i] != 0)? 1 : 0) << (i & 7); + } + + /* return number of bytes encoded*/ + return framesize; +} + +int lpc10_encode(short *in, unsigned char *out, lpc10_encoder_state *st) +{ + return lpc10_encode_int(in, out, st, FALSE); + +} + +int vbr_lpc10_encode(short *in, unsigned char *out, lpc10_encoder_state *st) +{ + return lpc10_encode_int(in, out, st, TRUE); + +} + +/* Allocate memory for, and initialize, the state that needs to be + kept from encoding one frame to the next for a single + LPC-10-compressed audio stream. Return 0 if malloc fails, + otherwise return pointer to new structure. */ + +lpc10_encoder_state *create_lpc10_encoder_state(void) +{ + lpc10_encoder_state *st; + + st = (lpc10_encoder_state *)malloc((unsigned) sizeof (lpc10_encoder_state)); + return (st); +} + +void init_lpc10_encoder_state(lpc10_encoder_state *st) +{ + int i; + + /* State used only by function hp100 */ + st->z11 = 0.0f; + st->z21 = 0.0f; + st->z12 = 0.0f; + st->z22 = 0.0f; + + /* State used by function analys */ + for (i = 0; i < 540; i++) { + st->inbuf[i] = 0.0f; + st->pebuf[i] = 0.0f; + } + for (i = 0; i < 696; i++) { + st->lpbuf[i] = 0.0f; + } + for (i = 0; i < 312; i++) { + st->ivbuf[i] = 0.0f; + } + st->bias = 0.0f; + st->osptr = 0; + for (i = 0; i < 3; i++) { + st->obound[i] = 0; + } + st->vwin[4] = 307; + st->vwin[5] = 462; + st->awin[4] = 307; + st->awin[5] = 462; + for (i = 0; i < 8; i++) { + st->voibuf[i] = 0; + } + for (i = 0; i < 3; i++) { + st->rmsbuf[i] = 0.0f; + } + for (i = 0; i < 30; i++) { + st->rcbuf[i] = 0.0f; + } + st->zpre = 0.0f; + + + /* State used by function onset */ + st->n = 0.0f; + st->d = 1.0f; + for (i = 0; i < 16; i++) { + st->l2buf[i] = 0.0f; + } + st->l2sum1 = 0.0f; + st->l2ptr1 = 1; + st->l2ptr2 = 9; + st->hyst = FALSE; + + /* State used by function voicin */ + st->dither = 20.0f; + st->maxmin = 0.0f; + for (i = 0; i < 6; i++) { + st->voice[i] = 0.0f; + } + st->lbve = 3000; + st->fbve = 3000; + st->fbue = 187; + st->ofbue = 187; + st->sfbue = 187; + st->lbue = 93; + st->olbue = 93; + st->slbue = 93; + st->snr = (float) (st->fbve / st->fbue << 6); + + /* State used by function dyptrk */ + for (i = 0; i < 60; i++) { + st->s[i] = 0.0f; + } + for (i = 0; i < 120; i++) { + st->p[i] = 0; + } + st->ipoint = 0; + st->alphax = 0.0f; + + /* State used by function chanwr */ + st->isync = 0; +} + +/* free the memory */ +void destroy_lpc10_encoder_state (lpc10_encoder_state *st) +{ + if(st != NULL) + { + free(st); + st = NULL; + } +} + diff --git a/tnl-1.5.0/tnl/zap/main.cpp b/tnl-1.5.0/tnl/zap/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32848c6929b8802ac7c62068a6bcc72bee06a402 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/main.cpp @@ -0,0 +1,751 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "tnl.h" +#include "tnlRandom.h" +#include "tnlGhostConnection.h" +#include "tnlNetInterface.h" +#include "tnlJournal.h" + +#include "glutInclude.h" +#include + +using namespace TNL; +#include "UI.h" +#include "UIGame.h" +#include "UINameEntry.h" +#include "UIMenus.h" +#include "UIEditor.h" +#include "game.h" +#include "gameNetInterface.h" +#include "masterConnection.h" +#include "sfx.h" +#include "sparkManager.h" +#include "input.h" + +#ifdef TNL_OS_MAC_OSX +#include +#endif + +namespace Zap +{ + +bool gIsCrazyBot = false; +bool gQuit = false; +bool gIsServer = false; +const char *gHostName = "ZAP Game"; +const char *gWindowTitle = "ZAP II - The Return"; +U32 gMaxPlayers = 128; +U32 gSimulatedPing = 0; +F32 gSimulatedPacketLoss = 0; +bool gDedicatedServer = false; + +const char *gMasterAddressString = "IP:master.opentnl.org:29005"; +const char *gServerPassword = NULL; +const char *gAdminPassword = NULL; + +Address gMasterAddress; +Address gConnectAddress; +Address gBindAddress(IPProtocol, Address::Any, 28000); + +const char *gLevelList = "retrieve1.txt " + "retrieve2.txt " + "retrieve3.txt " + "football1.txt " + "football2.txt " + "football3.txt " + "football4.txt " + "football5.txt " + "rabbit1.txt " + "soccer1.txt " + "ctf1.txt " + "ctf2.txt " + "ctf3.txt " + "ctf4.txt " + "hunters1.txt " + "hunters2.txt " + "zm1.txt " + ; + +class ZapJournal : public Journal +{ +public: + TNL_DECLARE_JOURNAL_ENTRYPOINT(reshape, (S32 newWidth, S32 newHeight)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(motion, (S32 x, S32 y)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(passivemotion, (S32 x, S32 y)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(key, (U8 key)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(keyup, (U8 key)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(modifierkey, (U32 modkey)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(modifierkeyup, (U32 modkey)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(mouse, (S32 button, S32 state, S32 x, S32 y)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(specialkey, (S32 key)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(specialkeyup, (S32 key)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(idle, (U32 timeDelta)); + TNL_DECLARE_JOURNAL_ENTRYPOINT(display, ()); + TNL_DECLARE_JOURNAL_ENTRYPOINT(startup, (Vector theArgv)); +}; + +ZapJournal gZapJournal; + +void reshape(int nw, int nh) +{ + gZapJournal.reshape(nw, nh); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, reshape, + (S32 newWidth, S32 newHeight), (newWidth, newHeight)) +{ + UserInterface::windowWidth = newWidth; + UserInterface::windowHeight = newHeight; +} + +void motion(int x, int y) +{ + gZapJournal.motion(x, y); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, motion, + (S32 x, S32 y), (x, y)) +{ + if(gIsCrazyBot) + return; + + if(UserInterface::current) + UserInterface::current->onMouseDragged(x, y); +} + +void passivemotion(int x, int y) +{ + gZapJournal.passivemotion(x, y); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, passivemotion, + (S32 x, S32 y), (x, y)) +{ + if(gIsCrazyBot) + return; + + if(UserInterface::current) + UserInterface::current->onMouseMoved(x, y); +} + +void key(unsigned char key, int x, int y) +{ + gZapJournal.key(key); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, key, (U8 key), (key)) +{ + // check for ALT-ENTER + if(key == '\r' && (glutGetModifiers() & GLUT_ACTIVE_ALT)) + gOptionsMenuUserInterface.toggleFullscreen(); + else if(UserInterface::current) + UserInterface::current->onKeyDown(key); +} + +void keyup(unsigned char key, int x, int y) +{ + gZapJournal.keyup(key); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, keyup, (U8 key), (key)) +{ + if(UserInterface::current) + UserInterface::current->onKeyUp(key); +} + +void mouse(int button, int state, int x, int y) +{ + gZapJournal.mouse(button, state, x, y); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, mouse, + (S32 button, S32 state, S32 x, S32 y), (button, state, x, y)) +{ + static int mouseState[2] = { 0, }; + if(!UserInterface::current) + return; + + if(gIsCrazyBot) + return; + + if(button == GLUT_LEFT_BUTTON) + { + if(state == 1 && !mouseState[0]) + { + UserInterface::current->onMouseUp(x, y); + mouseState[0] = 0; + } + else + { + mouseState[0] = state; + UserInterface::current->onMouseDown(x, y); + } + } + else if(button == GLUT_RIGHT_BUTTON) + { + if(state == 1 && !mouseState[1]) + { + UserInterface::current->onRightMouseUp(x, y); + mouseState[1] = 0; + } + else + { + mouseState[1] = state; + UserInterface::current->onRightMouseDown(x, y); + } + } +} + +void specialkey(int key, int x, int y) +{ + gZapJournal.specialkey(key); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, specialkey, (S32 key), (key)) +{ + if(UserInterface::current) + UserInterface::current->onSpecialKeyDown(key); +} + +void specialkeyup(int key, int x, int y) +{ + gZapJournal.specialkeyup(key); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, specialkeyup, (S32 key), (key)) +{ + if(UserInterface::current) + UserInterface::current->onSpecialKeyUp(key); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, modifierkey, (U32 key), (key)) +{ + if(UserInterface::current) + UserInterface::current->onModifierKeyDown(key); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, modifierkeyup, (U32 key), (key)) +{ + if(UserInterface::current) + UserInterface::current->onModifierKeyUp(key); +} + +inline U32 RandomInt(U32 range) +{ + return U32((U32(rand()) / (F32(RAND_MAX) + 1)) * range); +} + +inline U32 RandomBool() +{ + return (U32(rand()) / (F32(RAND_MAX) + 1)) > 0.5f; +} + +extern void getModifierState( bool &shiftDown, bool &controlDown, bool &altDown ); + +void idle() +{ + // ok, since GLUT is L4m3 as far as modifier keys, we're going + // to have to do this ourselves on each platform: + static bool gShiftDown = false; + static bool gControlDown = false; + static bool gAltDown = false; + + bool sd, cd, ad; + getModifierState(sd, cd, ad); + if(sd != gShiftDown) + { + if(sd) + gZapJournal.modifierkey(0); + else + gZapJournal.modifierkeyup(0); + gShiftDown = sd; + } + if(cd != gControlDown) + { + if(cd) + gZapJournal.modifierkey(1); + else + gZapJournal.modifierkeyup(1); + } + if(ad != gAltDown) + { + if(ad) + gZapJournal.modifierkey(2); + else + gZapJournal.modifierkeyup(2); + } + static S64 lastTimer = Platform::getHighPrecisionTimerValue(); + static F64 unusedFraction = 0; + + S64 currentTimer = Platform::getHighPrecisionTimerValue(); + + F64 timeElapsed = Platform::getHighPrecisionMilliseconds(currentTimer - lastTimer) + unusedFraction; + U32 integerTime = U32(timeElapsed); + + if(integerTime >= 10) + { + lastTimer = currentTimer; + unusedFraction = timeElapsed - integerTime; + + gZapJournal.idle(integerTime); + } + + // Make us move all crazy like... + if(gIsCrazyBot) + { + gIsCrazyBot = false; // Reenable input events + static S64 lastMove = Platform::getHighPrecisionTimerValue(); + static const char keyBuffer[] = "wasdwasdwasdwasdwasdwasdwasdwasdwasd\r\r\r\r\r\r\rabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 \r\t\n?{}_+-=[]\\"; + + static Vector keyDownVector; + + F64 delta = Platform::getHighPrecisionMilliseconds(currentTimer - lastMove); + if(delta > 5) + { + U32 rklen = (U32) strlen(keyBuffer); + // generate some random keys: + for(S32 i = 0; i < 32; i++) + { + bool found = false; + S8 key = keyBuffer[RandomInt(rklen)]; + for(S32 i = 0; i < keyDownVector.size(); i++) + { + if(keyDownVector[i] == key) + { + keyDownVector.erase_fast(i); + gZapJournal.keyup(key); + found = true; + break; + } + } + if(!found) + { + keyDownVector.push_back(key); + gZapJournal.key(key); + } + } + + // Do mouse craziness + S32 x = RandomInt(800); + S32 y = RandomInt(600); + gZapJournal.passivemotion(x,y); + gZapJournal.mouse(0, RandomBool(), x, y); + gZapJournal.mouse(1, RandomBool(), x, y); + gZapJournal.mouse(2, RandomBool(), x, y); + lastMove = currentTimer; + } + gIsCrazyBot = true; // Reenable input events + } + + + + // Sleep a bit so we don't saturate the system. For a non-dedicated server, + // sleep(0) helps reduce the impact of OpenGL on windows. + U32 sleepTime = 1; + + if(gClientGame) sleepTime = 0; + if(gIsCrazyBot) sleepTime = 10; + + Platform::sleep(sleepTime); + gZapJournal.processNextJournalEntry(); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, idle, (U32 integerTime), (integerTime)) +{ + if(UserInterface::current) + UserInterface::current->idle(integerTime); + if(gClientGame) + gClientGame->idle(integerTime); + if(gServerGame) + gServerGame->idle(integerTime); + if(gClientGame) + glutPostRedisplay(); +} + +void dedicatedServerLoop() +{ + for(;;) + idle(); +} + +void display(void) +{ + gZapJournal.display(); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, display, (), ()) +{ + glFlush(); + UserInterface::renderCurrent(); + + // Render master connection state... + if(gClientGame && gClientGame->getConnectionToMaster() + && gClientGame->getConnectionToMaster()->getConnectionState() != NetConnection::Connected) + { + glColor3f(1,1,1); + UserInterface::drawStringf(10, 550, 15, "Master Server - %s", + gConnectStatesTable[gClientGame->getConnectionToMaster()->getConnectionState()]); + + } + glutSwapBuffers(); +} + +#include +class StdoutLogConsumer : public LogConsumer +{ +public: + void logString(const char *string) + { + printf("%s\n", string); + } +} gStdoutLogConsumer; + +class FileLogConsumer : public LogConsumer +{ +private: + FILE *f; +public: + FileLogConsumer(const char* logFile="zap.log") + { + f = fopen(logFile, "w"); + logString("------ Zap Log File ------"); + } + + ~FileLogConsumer() + { + if(f) + fclose(f); + } + + void logString(const char *string) + { + if(f) + { + fprintf(f, "%s\n", string); + fflush(f); + } + } +} gFileLogConsumer; + +void hostGame(bool dedicated, Address bindAddress) +{ + gServerGame = new ServerGame(bindAddress, gMaxPlayers, gHostName); + gServerGame->setLevelList(gLevelList); + + if(!dedicated) + joinGame(Address(), false, true); + +} + + +void joinGame(Address remoteAddress, bool isFromMaster, bool local) +{ + if(isFromMaster && gClientGame->getConnectionToMaster()) + { + gClientGame->getConnectionToMaster()->requestArrangedConnection(remoteAddress); + gGameUserInterface.activate(); + } + else + { + GameConnection *theConnection = new GameConnection(); + gClientGame->setConnectionToServer(theConnection); + + const char *name = gNameEntryUserInterface.getText(); + if(!name[0]) + name = "Playa"; + + theConnection->setClientName(name); + theConnection->setSimulatedNetParams(gSimulatedPacketLoss, gSimulatedPing); + + if(local) + { + theConnection->connectLocal(gClientGame->getNetInterface(), gServerGame->getNetInterface()); + // set the local connection to be an admin + theConnection->setIsAdmin(true); + GameConnection *gc = (GameConnection *) theConnection->getRemoteConnectionObject(); + gc->setIsAdmin(true); + } + else + theConnection->connect(gClientGame->getNetInterface(), remoteAddress); + gGameUserInterface.activate(); + } +} + +void endGame() +{ + if(gClientGame && gClientGame->getConnectionToMaster()) + gClientGame->getConnectionToMaster()->cancelArrangedConnectionAttempt(); + + if(gClientGame && gClientGame->getConnectionToServer()) + gClientGame->getConnectionToServer()->disconnect(""); + delete gServerGame; + gServerGame = NULL; +} + +void onExit() +{ + endGame(); + SFXObject::shutdown(); + ShutdownJoystick(); + NetClassRep::logBitUsage(); +} + +TNL_IMPLEMENT_JOURNAL_ENTRYPOINT(ZapJournal, startup, (Vector argv), (argv)) +{ + bool hasClient = true; + bool hasServer = false; + bool connectLocal = false; + bool connectRemote = false; + bool nameSet = false; + bool hasEditor = false; + + S32 argc = argv.size(); + + for(S32 i = 0; i < argc;i+=2) + { + bool hasAdditionalArg = (i != argc - 1); + + if(!stricmp(argv[i], "-server")) + { + hasServer = true; + connectLocal = true; + if(hasAdditionalArg) + gBindAddress.set(argv[i+1]); + } + else if(!stricmp(argv[i], "-connect")) + { + connectRemote = true; + if(hasAdditionalArg) + gConnectAddress.set(argv[i+1]); + } + else if(!stricmp(argv[i], "-master")) + { + if(hasAdditionalArg) + gMasterAddressString = argv[i+1]; + } + else if(!stricmp(argv[i], "-joystick")) + { + if(hasAdditionalArg) + OptionsMenuUserInterface::joystickType = atoi(argv[i+1]); + } + else if(!stricmp(argv[i], "-loss")) + { + if(hasAdditionalArg) + gSimulatedPacketLoss = atof(argv[i+1]); + } + else if(!stricmp(argv[i], "-lag")) + { + if(hasAdditionalArg) + gSimulatedPing = atoi(argv[i+1]); + } + else if(!stricmp(argv[i], "-dedicated")) + { + hasClient = false; + hasServer = true; + gDedicatedServer = true; + if(hasAdditionalArg) + gBindAddress.set(argv[i+1]); + } + else if(!stricmp(argv[i], "-name")) + { + if(hasAdditionalArg) + { + nameSet = true; + gNameEntryUserInterface.setText(argv[i+1]); + } + } + else if(!stricmp(argv[i], "-password")) + { + if(hasAdditionalArg) + gServerPassword = strdup(argv[i+1]); + } + else if(!stricmp(argv[i], "-adminpassword")) + { + if(hasAdditionalArg) + gAdminPassword = strdup(argv[i+1]); + } + else if(!stricmp(argv[i], "-levels")) + { + if(hasAdditionalArg) + gLevelList = strdup(argv[i+1]); + } + else if(!stricmp(argv[i], "-hostname")) + { + if(hasAdditionalArg) + gHostName = strdup(argv[i+1]); + } + else if(!stricmp(argv[i], "-maxplayers")) + { + if(hasAdditionalArg) + gMaxPlayers = atoi(argv[i+1]); + } + else if(!stricmp(argv[i], "-window")) + { + i--; + OptionsMenuUserInterface::fullscreen = false; + } + else if(!stricmp(argv[i], "-edit")) + { + if(hasAdditionalArg) + { + hasEditor = true; + gEditorUserInterface.setEditName(argv[i+1]); + } + } + } + gMasterAddress.set(gMasterAddressString); +#ifdef ZAP_DEDICATED + hasClient = false; + hasServer = true; + connectRemote = false; + connectLocal = false; +#endif + + if(hasClient) + gClientGame = new ClientGame(Address()); + + if(hasEditor) + gEditorUserInterface.activate(); + else + { + if(hasServer) + hostGame(hasClient == false, gBindAddress); + else if(connectRemote) + joinGame(gConnectAddress, false); + + if(!connectLocal && !connectRemote) + { + if(!nameSet) + gNameEntryUserInterface.activate(); + else + gMainMenuUserInterface.activate(); + } + } +} + +}; + +using namespace Zap; +#ifdef TNL_OS_XBOX +int zapmain(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ +#ifdef TNL_OS_MAC_OSX + char path[1024]; + strcpy(path, argv[0]); + char *pos = strrchr(path, '/'); + *pos = 0; + logprintf("Path = %s", path); + chdir(path); +#endif + + //TNLLogEnable(LogConnectionProtocol, true); + //TNLLogEnable(LogNetConnection, true); + TNLLogEnable(LogNetInterface, true); + TNLLogEnable(LogPlatform, true); + TNLLogEnable(LogNetBase, true); + + for(S32 i = 0; i < argc;i++) + logprintf(argv[i]); + + Vector theArgv; + + for(S32 i = 1; i < argc; i++) + { + if(!stricmp(argv[i], "-crazybot")) + { + srand(Platform::getRealMilliseconds()); + gIsCrazyBot = true; + } + else if(!stricmp(argv[i], "-jsave")) + { + if(i != argc - 1) + { + gZapJournal.record(argv[i+1]); + i++; + } + } + else if(!stricmp(argv[i], "-jplay")) + { + if(i != argc - 1) + { + gZapJournal.load(argv[i+1]); + i++; + } + } + else + theArgv.push_back(argv[i]); + } + + gZapJournal.startup(theArgv); + + // we need to process the startup code if this is playing back + // a journal. + gZapJournal.processNextJournalEntry(); + + if(gClientGame) + { + SFXObject::init(); + InitJoystick(); + OptionsMenuUserInterface::joystickType = autodetectJoystickType(); + + glutInitWindowSize(800, 600); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB); + glutCreateWindow(gWindowTitle); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutPassiveMotionFunc(passivemotion); + glutMotionFunc(motion); + glutKeyboardFunc(key); + glutKeyboardUpFunc(keyup); + glutSpecialFunc(specialkey); + glutSpecialUpFunc(specialkeyup); + glutMouseFunc(mouse); + glutIdleFunc(idle); + + glutSetCursor(GLUT_CURSOR_NONE); + glMatrixMode(GL_PROJECTION); + glOrtho(0, 800, 600, 0, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(400, 300, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glLineWidth(DefaultLineWidth); + + atexit(onExit); + if(OptionsMenuUserInterface::fullscreen) + glutFullScreen(); + + glutMainLoop(); + } + else + dedicatedServerLoop(); + return 0; +} diff --git a/tnl-1.5.0/tnl/zap/masterConnection.cpp b/tnl-1.5.0/tnl/zap/masterConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6446ccf75b26e1910dba1d6dfa79ca35a62bed9 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/masterConnection.cpp @@ -0,0 +1,220 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "../tnl/tnl.h" +#include "masterConnection.h" +#include "../tnl/tnlNetInterface.h" +#include "gameConnection.h" +#include "gameNetInterface.h" +#include "UIQueryServers.h" +#include "UIMenus.h" +#include "UINameEntry.h" +#include "gameObject.h" + +namespace Zap +{ + +extern U32 gSimulatedPing; +extern F32 gSimulatedPacketLoss; +extern bool gQuit; + +TNL_IMPLEMENT_NETCONNECTION(MasterServerConnection, NetClassGroupMaster, false); + +void MasterServerConnection::startGameTypesQuery() +{ + // Kick off a game types query. + mCurrentQueryId++; + c2mQueryGameTypes(mCurrentQueryId); +} + +TNL_IMPLEMENT_RPC_OVERRIDE(MasterServerConnection, m2cQueryGameTypesResponse, (U32 queryId, Vector gameTypes, Vector missionTypes)) +{ + // Ignore old queries... + if(queryId != mCurrentQueryId) + return; + + // Inform the user of the results... + logprintf("Got game types response - %d game types, %d mission types", gameTypes.size(), missionTypes.size()); + for(S32 i = 0; i < gameTypes.size(); i++) + logprintf("G(%d): %s", i, gameTypes[i].getString()); + for(S32 i = 0; i < missionTypes.size(); i++) + logprintf("M(%d): %s", i, missionTypes[i].getString()); + + // when we receive the final list of mission and game types, + // query for servers: + if(gameTypes.size() == 0 && missionTypes.size() == 0) + { + // Invalidate old queries + mCurrentQueryId++; + + // And automatically do a server query as well - you may not want to do things + // in this order in your own clients. + c2mQueryServers(mCurrentQueryId, 0xFFFFFFFF, 0, 128, 0, 128, 0, "", ""); + } +} + +TNL_IMPLEMENT_RPC_OVERRIDE(MasterServerConnection, m2cQueryServersResponse, (U32 queryId, Vector ipList)) +{ + // Only process results from current query... + if(queryId != mCurrentQueryId) + return; + + // Display the results... + logprintf("got a list of servers from the master: %d servers", ipList.size()); + for(S32 i = 0; i < ipList.size(); i++) + logprintf(" %s", Address(ipList[i]).toString()); + + gQueryServersUserInterface.addPingServers(ipList); +} + +void MasterServerConnection::requestArrangedConnection(const Address &remoteAddress) +{ + mCurrentQueryId++; + + c2mRequestArrangedConnection(mCurrentQueryId, remoteAddress.toIPAddress(), + getInterface()->getFirstBoundInterfaceAddress().toIPAddress(), + new ByteBuffer((U8 *) "ZAP!", 5)); +} + +TNL_IMPLEMENT_RPC_OVERRIDE(MasterServerConnection, m2cClientRequestedArrangedConnection, (U32 requestId, Vector possibleAddresses, + ByteBufferPtr connectionParameters)) +{ + if(!mIsGameServer) + { + logprintf("Rejecting arranged connection from %s", Address(possibleAddresses[0]).toString()); + c2mRejectArrangedConnection(requestId, connectionParameters); + return; + } + + Vector
fullPossibleAddresses; + for(S32 i = 0; i < possibleAddresses.size(); i++) + fullPossibleAddresses.push_back(Address(possibleAddresses[i])); + + // First check if the specified host is banned on this server + if(gServerGame->getNetInterface()->isHostBanned(fullPossibleAddresses[0])) + { + logprintf("Blocking connection from banned host %s", fullPossibleAddresses[0].toString()); + c2mRejectArrangedConnection(requestId, connectionParameters); + return; + } + // Ok, let's do the arranged connection! + U8 data[Nonce::NonceSize * 2 + SymmetricCipher::KeySize * 2]; + Random::read(data, sizeof(data)); + IPAddress localAddress = getInterface()->getFirstBoundInterfaceAddress().toIPAddress(); + ByteBufferPtr b = new ByteBuffer(data, sizeof(data)); + b->takeOwnership(); + + c2mAcceptArrangedConnection(requestId, localAddress, b); + GameConnection *conn = new GameConnection(); + + conn->setNetAddress(fullPossibleAddresses[0]); + + logprintf("Accepting arranged connection from %s", Address(fullPossibleAddresses[0]).toString()); + logprintf(" Generated shared secret data: %s", b->encodeBase64()->getBuffer()); + + ByteBufferPtr theSharedData = new ByteBuffer(data + 2 * Nonce::NonceSize, sizeof(data) - 2 * Nonce::NonceSize); + Nonce nonce(data); + Nonce serverNonce(data + Nonce::NonceSize); + theSharedData->takeOwnership(); + + conn->connectArranged(getInterface(), fullPossibleAddresses, + nonce, serverNonce, theSharedData,false); +} + +TNL_IMPLEMENT_RPC_OVERRIDE(MasterServerConnection, m2cArrangedConnectionAccepted, (U32 requestId, Vector possibleAddresses, ByteBufferPtr connectionData)) +{ + if(!mIsGameServer && requestId == mCurrentQueryId && connectionData->getBufferSize() >= Nonce::NonceSize * 2 + SymmetricCipher::KeySize * 2) + { + logprintf("Remote host accepted arranged connection."); + logprintf(" Shared secret data: %s", connectionData->encodeBase64()->getBuffer()); + + Vector
fullPossibleAddresses; + for(S32 i = 0; i < possibleAddresses.size(); i++) + fullPossibleAddresses.push_back(Address(possibleAddresses[i])); + + ByteBufferPtr theSharedData = + new ByteBuffer( + (U8 *) connectionData->getBuffer() + Nonce::NonceSize * 2, + connectionData->getBufferSize() - Nonce::NonceSize * 2 + ); + + Nonce nonce(connectionData->getBuffer()); + Nonce serverNonce(connectionData->getBuffer() + Nonce::NonceSize); + + GameConnection *conn = new GameConnection(); + const char *name = gNameEntryUserInterface.getText(); + if(!name[0]) + name = "Playa"; + + conn->setSimulatedNetParams(gSimulatedPacketLoss, gSimulatedPing); + conn->setClientName(name); + gClientGame->setConnectionToServer(conn); + + conn->connectArranged(getInterface(), fullPossibleAddresses, + nonce, serverNonce, theSharedData,true); + } +} + +TNL_IMPLEMENT_RPC_OVERRIDE(MasterServerConnection, m2cArrangedConnectionRejected, (U32 requestId, ByteBufferPtr rejectData)) +{ + if(!mIsGameServer && requestId == mCurrentQueryId) + { + logprintf("Remote host rejected arranged connection..."); + endGame(); + gMainMenuUserInterface.activate(); + } +} + +TNL_IMPLEMENT_RPC_OVERRIDE(MasterServerConnection, m2cSetMOTD, (StringPtr motdString)) +{ + gMainMenuUserInterface.setMOTD(motdString); +} + +void MasterServerConnection::writeConnectRequest(BitStream *bstream) +{ + Parent::writeConnectRequest(bstream); + + bstream->writeString(ZAP_GAME_STRING); // Game Name + if(bstream->writeFlag(mIsGameServer)) + { + bstream->write((U32) 1000); // CPU speed + bstream->write((U32) 0xFFFFFFFF); // region code + bstream->write((U32) 5); // num bots + bstream->write((U32) 10); // num players + bstream->write((U32) 32); // max players + bstream->write((U32) 0); // info flags + + bstream->writeString("ZAP Game Type"); // Game type + bstream->writeString("ZAP Mission Type"); // Mission type + } +} + +void MasterServerConnection::onConnectionEstablished() +{ +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/masterConnection.h b/tnl-1.5.0/tnl/zap/masterConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..3dfe20d14a9da4842374b4d5ca7afdf56aa38e0a --- /dev/null +++ b/tnl-1.5.0/tnl/zap/masterConnection.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _MASTERCONNECTION_H_ +#define _MASTERCONNECTION_H_ + +#include "../master/masterInterface.h" + +namespace Zap +{ + +class MasterServerConnection : public MasterServerInterface +{ + typedef MasterServerInterface Parent; + + // ID of our current query. + U32 mCurrentQueryId; + + bool mIsGameServer; + +public: + MasterServerConnection(bool isGameServer = false) + { + mIsGameServer = isGameServer; + mCurrentQueryId = 0; + setIsConnectionToServer(); + setIsAdaptive(); + } + + void startGameTypesQuery(); + void cancelArrangedConnectionAttempt() { mCurrentQueryId++; } + void requestArrangedConnection(const Address &remoteAddress); + + TNL_DECLARE_RPC_OVERRIDE(m2cQueryGameTypesResponse, (U32 queryId, Vector gameTypes, Vector missionTypes)); + TNL_DECLARE_RPC_OVERRIDE(m2cQueryServersResponse, (U32 queryId, Vector ipList)); + TNL_DECLARE_RPC_OVERRIDE(m2cClientRequestedArrangedConnection, (U32 requestId, Vector possibleAddresses, + ByteBufferPtr connectionParameters)); + TNL_DECLARE_RPC_OVERRIDE(m2cArrangedConnectionAccepted, (U32 requestId, Vector possibleAddresses, ByteBufferPtr connectionData)); + TNL_DECLARE_RPC_OVERRIDE(m2cArrangedConnectionRejected, (U32 requestId, ByteBufferPtr rejectData)); + TNL_DECLARE_RPC_OVERRIDE(m2cSetMOTD, (StringPtr motdString)); + + void writeConnectRequest(BitStream *bstream); + void onConnectionEstablished(); + + TNL_DECLARE_NETCONNECTION(MasterServerConnection); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/move.h b/tnl-1.5.0/tnl/zap/move.h new file mode 100644 index 0000000000000000000000000000000000000000..65846edb39b430de7f6793edd69bb731b430b1e1 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/move.h @@ -0,0 +1,131 @@ +//---------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _MOVE_H_ +#define _MOVE_H_ + +#include "tnlTypes.h" +#include "tnlBitStream.h" + +using namespace TNL; + +namespace Zap +{ + +// some angle conversion functions: +const F32 radiansToDegreesConversion = 360.0f * FloatInverse2Pi; + +inline F32 radiansToDegrees(F32 angle) +{ + return angle * radiansToDegreesConversion; +} + +inline F32 radiansToUnit(F32 angle) +{ + return angle * FloatInverse2Pi; +} + +inline F32 unitToRadians(F32 angle) +{ + return angle * Float2Pi; +} + +struct Move +{ + float left; + float right; + float up; + float down; + float angle; + bool fire; + bool module[2]; + U32 time; + + enum { + MaxMoveTime = 127, + }; + + Move() { left = right = up = down = angle = 0; module[0] = module[1] = fire = false; time = 32; } + + bool isEqualMove(Move *prev) + { + return prev->left == left && + prev->right == right && + prev->up == up && + prev->down == down && + prev->angle == angle && + prev->fire == fire && + prev->module[0] == module[0] && + prev->module[1] == module[1]; + } + + void pack(BitStream *stream, Move *prev, bool packTime) + { + if(!stream->writeFlag(prev && isEqualMove(prev))) + { + stream->writeFloat(left, 4); + stream->writeFloat(right, 4); + stream->writeFloat(up, 4); + stream->writeFloat(down, 4); + U32 writeAngle = U32(radiansToUnit(angle) * 0xFFF); + + stream->writeInt(writeAngle, 12); + stream->writeFlag(fire); + stream->writeFlag(module[0]); + stream->writeFlag(module[1]); + } + if(packTime) + stream->writeRangedU32(time, 0, MaxMoveTime); + } + void unpack(BitStream *stream, bool unpackTime) + { + if(!stream->readFlag()) + { + left = stream->readFloat(4); + right = stream->readFloat(4); + up = stream->readFloat(4); + down = stream->readFloat(4); + angle = unitToRadians(stream->readInt(12) / F32(0xFFF)); + fire = stream->readFlag(); + module[0] = stream->readFlag(); + module[1] = stream->readFlag(); + } + if(unpackTime) + time = stream->readRangedU32(0, MaxMoveTime); + } + void prepare() + { + PacketStream stream; + pack(&stream, NULL, false); + stream.setBytePosition(0); + unpack(&stream, false); + } +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/moveObject.cpp b/tnl-1.5.0/tnl/zap/moveObject.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cab900aa0041803f70a29e0ad86569daf75fc9cf --- /dev/null +++ b/tnl-1.5.0/tnl/zap/moveObject.cpp @@ -0,0 +1,425 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "moveObject.h" +#include "SweptEllipsoid.h" +#include "sparkManager.h" +#include "sfx.h" + +namespace Zap +{ + +MoveObject::MoveObject(Point pos, float radius, float mass) +{ + for(U32 i = 0; i < MoveStateCount; i++) + { + mMoveState[i].pos = pos; + mMoveState[i].angle = 0; + } + mRadius = radius; + mMass = mass; + mInterpolating = false; +} + +static const float MoveObjectCollisionElasticity = 1.7f; + +void MoveObject::updateExtent() +{ + Rect r(mMoveState[ActualState].pos, mMoveState[RenderState].pos); + r.expand(Point(mRadius + 10, mRadius + 10)); + setExtent(r); +} + +// Ship movement system +// Identify the several cases in which a ship may be moving: +// if this is a client: +// Ship controlled by this client. Pos may have been set to something else by server, leaving renderPos elsewhere +// all movement updates affect pos + +// collision process for ships: +// + +// +// ship *theShip; +// F32 time; +// while(time > 0) +// { +// ObjHit = findFirstCollision(theShip); +// advanceToCollision(); +// if(velocitiesColliding) +// { +// doCollisionResponse(); +// } +// else +// { +// computeMinimumSeperationTime(ObjHit); +// displaceObject(ObjHit, seperationTime); +// } +// } +// +// displaceObject(Object, time) +// { +// while(time > 0) +// { +// ObjHit = findFirstCollision(); +// advanceToCollision(); +// if(velocitiesColliding) +// { +// doCollisionResponse(); +// return; +// } +// else +// { +// computeMinimumSeperationTime(ObjHit); +// displaceObject(ObjHit, seperationTime); +// } +// } +// } + +extern bool FindLowestRootInInterval(Point::member_type inA, Point::member_type inB, Point::member_type inC, Point::member_type inUpperBound, Point::member_type &outX); +static Vector fillVector; + +F32 MoveObject::computeMinSeperationTime(U32 stateIndex, MoveObject *contactShip, Point intendedPos) +{ + // ok, this ship wants to move to intendedPos + // so we need to figure out how far contactShip has to move so it won't be in the way + + F32 myRadius; + F32 contactShipRadius; + + Point myPos; + Point contactShipPos; + + getCollisionCircle(stateIndex, myPos, myRadius); + contactShip->getCollisionCircle(stateIndex, contactShipPos, contactShipRadius); + + Point v = contactShip->mMoveState[stateIndex].vel; + Point posDelta = contactShipPos - intendedPos; + + F32 R = myRadius + contactShipRadius; + + F32 a = v.dot(v); + F32 b = 2 * v.dot(posDelta); + F32 c = posDelta.dot(posDelta) - R * R; + + F32 t; + + bool result = FindLowestRootInInterval(a, b, c, 100000, t); + if(!result) + return 0; + return t; +} + +const F32 moveTimeEpsilon = 0.000001f; +const F32 velocityEpsilon = 0.00001f; + +void MoveObject::move(F32 moveTime, U32 stateIndex, bool displacing) +{ + U32 tryCount = 0; + while(moveTime > moveTimeEpsilon && tryCount < 8) + { + tryCount++; + if(!displacing && mMoveState[stateIndex].vel.len() < velocityEpsilon) + return; + + F32 collisionTime = moveTime; + Point collisionPoint; + + GameObject *objectHit = findFirstCollision(stateIndex, collisionTime, collisionPoint); + if(!objectHit) + { + mMoveState[stateIndex].pos += mMoveState[stateIndex].vel * moveTime; + return; + } + // advance to the point of collision + mMoveState[stateIndex].pos += mMoveState[stateIndex].vel * collisionTime; + + if(objectHit->getObjectTypeMask() & MoveableType) + { + MoveObject *shipHit = (MoveObject *) objectHit; + Point velDelta = shipHit->mMoveState[stateIndex].vel - + mMoveState[stateIndex].vel; + Point posDelta = shipHit->mMoveState[stateIndex].pos - + mMoveState[stateIndex].pos; + + if(posDelta.dot(velDelta) < 0) // there is a collision + { + computeCollisionResponseMoveObject(stateIndex, shipHit); + if(displacing) + return; + } + else + { + Point intendedPos = mMoveState[stateIndex].pos + + mMoveState[stateIndex].vel * moveTime; + + F32 displaceEpsilon = 0.002f; + F32 t = computeMinSeperationTime(stateIndex, shipHit, intendedPos); + if(t <= 0) + return; // some kind of math error - just stop simulating this ship + shipHit->move(t + displaceEpsilon, stateIndex, true); + } + } + else if(objectHit->getObjectTypeMask() & (BarrierType | EngineeredType | ForceFieldType)) + { + computeCollisionResponseBarrier(stateIndex, collisionPoint); + } + moveTime -= collisionTime; + } +} + +bool MoveObject::collide(GameObject *otherObject) +{ + return true; +} + +GameObject *MoveObject::findFirstCollision(U32 stateIndex, F32 &collisionTime, Point &collisionPoint) +{ + // check for collisions against other objects + Point delta = mMoveState[stateIndex].vel * collisionTime; + + Rect queryRect(mMoveState[stateIndex].pos, mMoveState[stateIndex].pos + delta); + queryRect.expand(Point(mRadius, mRadius)); + + fillVector.clear(); + findObjects(AllObjectTypes, fillVector, queryRect); + + float collisionFraction; + + GameObject *collisionObject = NULL; + + for(S32 i = 0; i < fillVector.size(); i++) + { + if(!fillVector[i]->isCollisionEnabled()) + continue; + + static Vector poly; + poly.clear(); + if(fillVector[i]->getCollisionPoly(poly)) + { + Point cp; + if(PolygonSweptCircleIntersect(&poly[0], poly.size(), mMoveState[stateIndex].pos, + delta, mRadius, cp, collisionFraction)) + { + if((cp - mMoveState[stateIndex].pos).dot(mMoveState[stateIndex].vel) > velocityEpsilon) + { + bool collide1 = collide(fillVector[i]); + bool collide2 = fillVector[i]->collide(this); + + if(!(collide1 && collide2)) + continue; + collisionPoint = cp; + delta *= collisionFraction; + collisionTime *= collisionFraction; + collisionObject = fillVector[i]; + if(!collisionTime) + break; + } + } + } + else if(fillVector[i]->getObjectTypeMask() & MoveableType) + { + MoveObject *otherShip = (MoveObject *) fillVector[i]; + + F32 myRadius; + F32 otherRadius; + Point myPos; + Point shipPos; + + getCollisionCircle(stateIndex, myPos, myRadius); + otherShip->getCollisionCircle(stateIndex, shipPos, otherRadius); + + Point v = mMoveState[stateIndex].vel; + Point p = myPos - shipPos; + + if(v.dot(p) < 0) + { + F32 R = myRadius + otherRadius; + if(p.len() <= R) + { + bool collide1 = collide(otherShip); + bool collide2 = otherShip->collide(this); + + if(!(collide1 && collide2)) + continue; + + collisionTime = 0; + collisionObject = fillVector[i]; + delta.set(0,0); + } + else + { + F32 a = v.dot(v); + F32 b = 2 * p.dot(v); + F32 c = p.dot(p) - R * R; + F32 t; + if(FindLowestRootInInterval(a, b, c, collisionTime, t)) + { + bool collide1 = collide(otherShip); + bool collide2 = otherShip->collide(this); + + if(!(collide1 && collide2)) + continue; + + collisionTime = t; + collisionObject = fillVector[i]; + delta = mMoveState[stateIndex].vel * collisionTime; + } + } + } + } + } + return collisionObject; +} + +void MoveObject::computeCollisionResponseBarrier(U32 stateIndex, Point &collisionPoint) +{ + // reflect the velocity along the collision point + Point normal = mMoveState[stateIndex].pos - collisionPoint; + normal.normalize(); + + mMoveState[stateIndex].vel -= normal * MoveObjectCollisionElasticity * normal.dot(mMoveState[stateIndex].vel); + + // Emit some bump particles (try not to if we're running server side) + if(isGhost()) + { + F32 scale = normal.dot(mMoveState[stateIndex].vel) * 0.01f; + if(scale > 0.5f) + { + // Make a noise... + SFXObject::play(SFXBounceWall, collisionPoint, Point(), getMin(1.0f, scale - 0.25f)); + + Color bumpC(scale/3, scale/3, scale); + + for(S32 i=0; i<4*pow((F32)scale, 0.5f); i++) + { + Point chaos(Random::readF(), Random::readF()); + chaos *= scale + 1; + + if(Random::readF() > 0.5) + FXManager::emitSpark(collisionPoint, normal * chaos.len() + Point(normal.y, -normal.x)*scale*5 + chaos + mMoveState[stateIndex].vel*0.05f, bumpC); + + if(Random::readF() > 0.5) + FXManager::emitSpark(collisionPoint, normal * chaos.len() + Point(normal.y, -normal.x)*scale*-5 + chaos + mMoveState[stateIndex].vel*0.05f, bumpC); + } + } + } +} + +void MoveObject::computeCollisionResponseMoveObject(U32 stateIndex, MoveObject *shipHit) +{ + Point collisionVector = shipHit->mMoveState[stateIndex].pos - + mMoveState[stateIndex].pos; + + collisionVector.normalize(); + F32 m1 = getMass(); + F32 m2 = shipHit->getMass(); + + F32 v1i = mMoveState[stateIndex].vel.dot(collisionVector); + F32 v2i = shipHit->mMoveState[stateIndex].vel.dot(collisionVector); + + F32 v1f, v2f; + + F32 e = 0.9f; + v2f = ( e * (v1i - v2i) + v1i + v2i) / (2); + v1f = ( v1i + v2i - v2f); + + mMoveState[stateIndex].vel += collisionVector * (v1f - v1i); + shipHit->mMoveState[stateIndex].vel += collisionVector * (v2f - v2i); + + if(v1i > 0.25) + SFXObject::play(SFXBounceObject, shipHit->mMoveState[stateIndex].pos, Point()); +} + +void MoveObject::updateInterpolation() +{ + U32 deltaT = mCurrentMove.time; + { + mMoveState[RenderState].angle = mMoveState[ActualState].angle; + + if(mInterpolating) + { + // first step is to constrain the render velocity to + // the vector of difference between the current position and + // the actual position. + // we can also clamp to zero, the actual velocity, or the + // render velocity, depending on which one is best. + + Point deltaP = mMoveState[ActualState].pos - mMoveState[RenderState].pos; + F32 distance = deltaP.len(); + + if(!distance) + goto interpDone; + + deltaP.normalize(); + F32 vel = deltaP.dot(mMoveState[RenderState].vel); + F32 avel = deltaP.dot(mMoveState[ActualState].vel); + + if(avel > vel) + vel = avel; + if(vel < 0) + vel = 0; + + bool hit = true; + float time = deltaT * 0.001f; + if(vel * time > distance) + goto interpDone; + + float requestVel = distance / time; + float interpMaxVel = InterpMaxVelocity; + float currentActualVelocity = mMoveState[ActualState].vel.len(); + if(interpMaxVel < currentActualVelocity) + interpMaxVel = currentActualVelocity; + if(requestVel > interpMaxVel) + { + hit = false; + requestVel = interpMaxVel; + } + F32 a = (requestVel - vel) / time; + if(a > InterpAcceleration) + { + a = InterpAcceleration; + hit = false; + } + + if(hit) + goto interpDone; + + vel += a * time; + mMoveState[RenderState].vel = deltaP * vel; + mMoveState[RenderState].pos += mMoveState[RenderState].vel * time; + } + else + { + interpDone: + mInterpolating = false; + mMoveState[RenderState] = mMoveState[ActualState]; + } + } +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/moveObject.h b/tnl-1.5.0/tnl/zap/moveObject.h new file mode 100644 index 0000000000000000000000000000000000000000..e2105c0ff2454d70ad9571d0a8c455b3a0939ceb --- /dev/null +++ b/tnl-1.5.0/tnl/zap/moveObject.h @@ -0,0 +1,95 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _MOVEOBJECT_H_ +#define _MOVEOBJECT_H_ + +#include "gameObject.h" + +namespace Zap +{ + +class MoveObject : public GameObject +{ +protected: + + float mRadius; + float mMass; + +public: + enum { + ActualState = 0, + RenderState, + LastProcessState, + MoveStateCount, + }; +protected: + struct MoveState + { + Point pos; // actual position of the ship + float angle; // actual angle of the ship + Point vel; // actual velocity of the ship + }; + enum { + InterpMaxVelocity = 900, // velocity to use to interpolate to proper position + InterpAcceleration = 1800, + }; + + MoveState mMoveState[MoveStateCount]; + bool mInterpolating; +public: + MoveObject(Point pos = Point(0,0), float radius = 1, float mass = 1); + + void updateInterpolation(); + void updateExtent(); + + Point getRenderPos() { return mMoveState[RenderState].pos; } + Point getActualPos() { return mMoveState[ActualState].pos; } + float getMass() { return mMass; } + Point getRenderVel() { return mMoveState[RenderState].vel; } + Point getActualVel() { return mMoveState[ActualState].vel; } + + void move(F32 time, U32 stateIndex, bool displacing); + bool collide(GameObject *otherObject); + + GameObject *findFirstCollision(U32 stateIndex, F32 &collisionTime, Point &collisionPoint); + void computeCollisionResponseMoveObject(U32 stateIndex, MoveObject *objHit); + void computeCollisionResponseBarrier(U32 stateIndex, Point &collisionPoint); + F32 computeMinSeperationTime(U32 stateIndex, MoveObject *contactObject, Point intendedPos); + + bool getCollisionCircle(U32 stateIndex, Point &point, float &radius) + { + point = mMoveState[stateIndex].pos; + radius = mRadius; + return true; + } + F32 getRadius() { return mRadius; } +}; + + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/osxInput.cpp b/tnl-1.5.0/tnl/zap/osxInput.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3a381c555a8356751650dd94f3f02aacce981a5 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/osxInput.cpp @@ -0,0 +1,348 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef MACOS_10_0_4 +#include +#else +/* The header was moved here in MacOS X 10.1 */ +#include +#endif +#include +#include +#include +#include +#include "TNLAssert.h" +#include "tnlVector.h" +#include "input.h" +#include "tnlLog.h" + +namespace Zap +{ + +bool gJoystickInit = false; + +void getModifierState(bool &shiftDown, bool &controlDown, bool &altDown) +{ + UInt32 modKeys = GetCurrentEventKeyModifiers(); + shiftDown = (modKeys & shiftKey) != 0; + controlDown = (modKeys & controlKey) != 0; + altDown = (modKeys & optionKey) != 0; +} + +enum AxisIndex +{ + AxisX, + AxisY, + AxisZ, + AxisRx, + AxisRy, + AxisRz, + AxisSlider0, + AxisSlider1, +}; + +struct ControllerElement +{ + IOHIDElementCookie cookie; + long minValue; + long maxValue; + ControllerElement() { cookie = 0; minValue = 0; maxValue = 1; } +}; + +struct Controller +{ + IOHIDDeviceInterface **device; + ControllerElement axes[MaxJoystickAxes]; + Vector buttons; +}; + +Controller gController; + +static S32 getElementValue(ControllerElement *theElement) +{ + if(!theElement->cookie) + return 0; + + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + + IOReturn result = (*(gController.device))->getElementValue(gController.device, theElement->cookie, &hidEvent); + if(result == kIOReturnSuccess) + { + if(hidEvent.value < theElement->minValue) + theElement->minValue = hidEvent.value; + if(hidEvent.value > theElement->maxValue) + theElement->maxValue = hidEvent.value; + } + return hidEvent.value; +} + +static void HIDGetElementsCFArrayHandler (const void * value, void * parameter) +{ + if (CFGetTypeID (value) != CFDictionaryGetTypeID ()) + return; + + CFTypeRef refElement = CFTypeRef(value); + long elementType, usagePage, usage; + CFTypeRef refElementType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementTypeKey)); + CFTypeRef refUsagePage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsagePageKey)); + CFTypeRef refUsage = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementUsageKey)); + bool isButton = false, isAxis = false; + + ControllerElement *theElement = NULL; + if ((refElementType) && (CFNumberGetValue (refElementType, kCFNumberLongType, &elementType))) + { + /* look at types of interest */ + if ((elementType == kIOHIDElementTypeInput_Misc) || (elementType == kIOHIDElementTypeInput_Button) || + (elementType == kIOHIDElementTypeInput_Axis)) + { + if (refUsagePage && CFNumberGetValue (refUsagePage, kCFNumberLongType, &usagePage) && + refUsage && CFNumberGetValue (refUsage, kCFNumberLongType, &usage)) + { + switch (usagePage) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ + { + case kHIDPage_GenericDesktop: + { + switch (usage) /* look at usage to determine function */ + { + case kHIDUsage_GD_X: + theElement = gController.axes + AxisX; + break; + case kHIDUsage_GD_Y: + theElement = gController.axes + AxisY; + break; + case kHIDUsage_GD_Z: + theElement = gController.axes + AxisZ; + break; + case kHIDUsage_GD_Rx: + theElement = gController.axes + AxisRx; + break; + case kHIDUsage_GD_Ry: + theElement = gController.axes + AxisRy; + break; + case kHIDUsage_GD_Rz: + theElement = gController.axes + AxisRz; + break; + case kHIDUsage_GD_Slider: + theElement = gController.axes + AxisSlider0; + break; + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + break; + } + } + break; + case kHIDPage_Button: + { + ControllerElement e; + gController.buttons.push_back(e); + theElement = &gController.buttons.last(); + } + break; + default: + break; + } + } + } + else if (kIOHIDElementTypeCollection == elementType) + { + CFTypeRef refElementTop = CFDictionaryGetValue ((CFMutableDictionaryRef) refElement, CFSTR(kIOHIDElementKey)); + if (refElementTop) + { + CFTypeID type = CFGetTypeID (refElementTop); + if (type == CFArrayGetTypeID()) /* if element is an array */ + { + CFRange range = {0, CFArrayGetCount (refElementTop)}; + /* CountElementsCFArrayHandler called for each array member */ + CFArrayApplyFunction (refElementTop, range, HIDGetElementsCFArrayHandler, NULL); + } + } + } + } + if (theElement) /* add to list */ + { + long number; + CFTypeRef refType; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementCookieKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + theElement->cookie = (IOHIDElementCookie) number; + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMinKey)); + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + theElement->minValue = number; + + refType = CFDictionaryGetValue (refElement, CFSTR(kIOHIDElementMaxKey)); + + if (refType && CFNumberGetValue (refType, kCFNumberLongType, &number)) + theElement->maxValue = number; + logprintf("Cookie = %d min = %d max = %d", theElement->cookie, theElement->minValue, theElement->maxValue); + } +} + +enum { +MaxJoystickNameLen = 256, +}; +char gJoystickName[MaxJoystickNameLen + 1] = { 0, }; +const char *GetJoystickName() { return gJoystickName; } +void InitJoystick() +{ + mach_port_t masterPort = NULL; + io_iterator_t hidObjectIterator = NULL; + + IOReturn result = IOMasterPort (bootstrap_port, &masterPort); + if(result != kIOReturnSuccess) + return; + + CFMutableDictionaryRef hidMatchDictionary = IOServiceMatching (kIOHIDDeviceKey); + if(!hidMatchDictionary) + return; + result = IOServiceGetMatchingServices (masterPort, hidMatchDictionary, &hidObjectIterator); + if(result != kIOReturnSuccess) + return; + + // find the first joystick/gamepad on the USB + for(;;) + { + IOHIDDeviceInterface **device; + io_object_t ioHIDDeviceObject = IOIteratorNext(hidObjectIterator); + if(!ioHIDDeviceObject) + break; + + CFMutableDictionaryRef hidProperties = 0; + long kresult = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, &hidProperties, kCFAllocatorDefault, kNilOptions); + if(kresult == KERN_SUCCESS && hidProperties) + { + CFTypeRef refCF = 0; + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDProductKey)); + + if(CFGetTypeID(refCF) == CFStringGetTypeID()) + { + CFIndex bufferSize = CFStringGetLength (refCF) + 1; + char * buffer = (char *)malloc (bufferSize); + if (buffer) + { + if (CFStringGetCString (refCF, buffer, bufferSize, CFStringGetSystemEncoding ())) + strncpy(gJoystickName, buffer, MaxJoystickNameLen); + free(buffer); + } + } + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); + long usage, usagePage; + CFNumberGetValue (refCF, kCFNumberLongType, &usagePage); + refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); + CFNumberGetValue (refCF, kCFNumberLongType, &usage); + + if ( (usagePage == kHIDPage_GenericDesktop) && + ((usage == kHIDUsage_GD_Joystick || + usage == kHIDUsage_GD_GamePad)) ) + { + CFTypeRef refElementTop = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDElementKey)); + if (refElementTop) + { + CFTypeID type = CFGetTypeID (refElementTop); + if (type == CFArrayGetTypeID()) /* if element is an array */ + { + CFRange range = {0, CFArrayGetCount (refElementTop)}; + /* CountElementsCFArrayHandler called for each array member */ + CFArrayApplyFunction (refElementTop, range, HIDGetElementsCFArrayHandler, NULL); + + IOCFPlugInInterface ** ppPlugInInterface = NULL; + S32 score; + IOReturn result = IOCreatePlugInInterfaceForService (ioHIDDeviceObject, kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); + if (result == kIOReturnSuccess) + { + // Call a method of the intermediate plug-in to create the device interface + (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, + CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &device); + if(device) + { + result = (*device)->open(device, 0); + gController.device = device; + gJoystickInit = true; + } + (*ppPlugInInterface)->Release (ppPlugInInterface); + } + } + } + } + CFRelease(hidProperties); + } + IOObjectRelease(ioHIDDeviceObject); + if(gJoystickInit) + break; + } + IOObjectRelease (hidObjectIterator); /* release the iterator */ +} + +bool ReadJoystick(F32 axes[MaxJoystickAxes], U32 &buttonMask, U32 &hatMask) +{ + if(!gJoystickInit) + return false; + + S32 i; + for(i = 0; i < MaxJoystickAxes; i++) + { + ControllerElement *e = &gController.axes[i]; + S32 elementValue = getElementValue(e); + S32 diff = e->maxValue - e->minValue; + if(diff != 0) + { + axes[i] = (elementValue - e->minValue) * 2 / F32(diff); + axes[i] -= 1; + } + else + axes[i] = 0; + } + + buttonMask = 0; + for(i = 0; i < gController.buttons.size(); i++) + { + ControllerElement *e = &gController.buttons[i]; + S32 value = getElementValue(e); + if(value) + buttonMask |= (1 << i); + } + return true; +} + +void ShutdownJoystick() +{ + if(gController.device) + (*(gController.device))->close(gController.device); +} + +}; diff --git a/tnl-1.5.0/tnl/zap/point.h b/tnl-1.5.0/tnl/zap/point.h new file mode 100644 index 0000000000000000000000000000000000000000..9ceb97fe48086487a8fc5fccb380ea152f9693ac --- /dev/null +++ b/tnl-1.5.0/tnl/zap/point.h @@ -0,0 +1,177 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _POINT_H_ +#define _POINT_H_ +#include +#include + +namespace Zap +{ + +struct Point +{ + typedef float member_type; + member_type x; + member_type y; + + Point() { x = 0; y = 0; } + Point(const Point& pt) { x = pt.x; y = pt.y; } + Point(member_type in_x, member_type in_y) { x = in_x; y = in_y; } + void set(member_type ix, member_type iy) { x = ix; y = iy; } + void set(const Point &pt) { x = pt.x; y = pt.y; } + + Point operator+(const Point &pt) const { return Point (x + pt.x, y + pt.y); } + Point operator-(const Point &pt) const { return Point (x - pt.x, y - pt.y); } + Point operator-() const { return Point(-x, -y); } + Point &operator+=(const Point &pt) { x += pt.x; y += pt.y; return *this; } + Point &operator-=(const Point &pt) { x -= pt.x; y -= pt.y; return *this; } + + Point operator*(const member_type f) { return Point (x * f, y * f); } + Point &operator*=(const member_type f) { x *= f; y *= f; return *this; } + + Point operator*(const Point &pt) { return Point(x * pt.x, y * pt.y); } + + Point &operator=(const Point &pt) { x = pt.x; y = pt.y; return *this; } + bool operator==(const Point &pt) const { return x == pt.x && y == pt.y; } + + member_type len() const { return (member_type) sqrt(x * x + y * y); } + member_type lenSquared() const { return x * x + y * y; } + void normalize() { member_type l = len(); if(l == 0) { x = 1; y = 0; } else { l = 1 / l; x *= l; y *= l; } } + void normalize(float newLen) { member_type l = len(); if(l == 0) { x = newLen; y = 0; } else { l = newLen / l; x *= l; y *= l; } } + + void scaleFloorDiv(float scaleFactor, float divFactor) + { + x = (member_type) floor(x * scaleFactor + 0.5) * divFactor; + y = (member_type) floor(y * scaleFactor + 0.5) * divFactor; + } + member_type dot(const Point &p) const { return x * p.x + y * p.y; } + void read(const char **argv) { x = (member_type) atof(argv[0]); y = (member_type) atof(argv[1]); } +}; + +struct Color +{ + float r, g, b; + + Color(const Color &c) { r = c.r; g = c.g; b = c.b; } + Color(float red = 1, float green = 1, float blue = 1) { r = red; g = green; b = blue; } + void read(const char **argv) { r = (float) atof(argv[0]); g = (float) atof(argv[1]); b = (float) atof(argv[2]); } + + void interp(float t, const Color &c1, const Color &c2) + { + float oneMinusT = 1.0f - t; + r = c1.r * t + c2.r * oneMinusT; + g = c1.g * t + c2.g * oneMinusT; + b = c1.b * t + c2.b * oneMinusT; + } + void set(float _r, float _g, float _b) { r = _r; g = _g; b = _b; } + void set(const Color &c) { r = c.r; g = c.g; b = c.b; } + + Color operator+(const Color &c) const { return Color (r + c.r, g + c.g, b + c.b); } + Color operator-(const Color &c) const { return Color (r - c.r, g - c.g, b - c.b); } + Color operator-() const { return Color(-r, -g, -b); } + Color &operator+=(const Color &c) { r += c.r; g += c.g; b += c.b; return *this; } + Color &operator-=(const Color &c) { r -= c.r; g -= c.g; b -= c.b; return *this; } + + Color operator*(const float f) { return Color (r * f, g * f, b * f); } + Color &operator*=(const float f) { r *= f; g *= f; b *= f; return *this; } +}; + +struct Rect +{ + Point min, max; + + Rect() {} + Rect(Point p1, Point p2) { set(p1, p2); } + Point getCenter() { return (max + min) * 0.5; } + void set(Point p1, Point p2) + { + if(p1.x < p2.x) + { + min.x = p1.x; + max.x = p2.x; + } + else + { + min.x = p2.x; + max.x = p1.x; + } + if(p1.y < p2.y) + { + min.y = p1.y; + max.y = p2.y; + } + else + { + min.y = p2.y; + max.y = p1.y; + } + } + bool contains(const Point &p) + { + return p.x >= min.x && p.x <= max.x && p.y >= min.y && p.y <= max.y; + } + + void unionPoint(const Point &p) + { + if(p.x < min.x) + min.x = p.x; + else if(p.x > max.x) + max.x = p.x; + if(p.y < min.y) + min.y = p.y; + else if(p.y > max.y) + max.y = p.y; + } + + void unionRect(const Rect &r) + { + if(r.min.x < min.x) + min.x = r.min.x; + if(r.max.x > max.x) + max.x = r.max.x; + if(r.min.y < min.y) + min.y = r.min.y; + if(r.max.y > max.y) + max.y = r.max.y; + } + + bool intersects(const Rect &r) + { + return min.x < r.max.x && min.y < r.max.y && + max.x > r.min.x && max.y > r.min.y; + } + void expand(Point delta) { min -= delta; max += delta; } + + Point getExtents() + { + return max - min; + } +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/private.h b/tnl-1.5.0/tnl/zap/private.h new file mode 100644 index 0000000000000000000000000000000000000000..365f41a69527a8803dfec699c2ace84432eaab39 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/private.h @@ -0,0 +1,106 @@ +/* + GSM voice codec, part of the HawkVoice Direct Interface (HVDI) + cross platform network voice library + Copyright (C) 2001-2003 Phil Frisbie, Jr. (phil@hawksoft.com) + + 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., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Or go to http://www.gnu.org/copyleft/lgpl.html +*/ + +/* + * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische + * Universitaet Berlin. See the accompanying file "COPYRIGHT" for + * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. + */ + + +#ifndef PRIVATE_H +#define PRIVATE_H + +#ifdef __GNUC__ + #define INLINE extern __inline__ +#elif defined(__MWERKS__) + #define INLINE __inline +#else + #ifdef _MSC_VER + #define INLINE __inline + #pragma warning (disable:4514) + #pragma warning (disable:4711) + #else + #define INLINE + #endif +#endif + +#if defined(__MWERKS__) + #include +#else + #include +#endif +#include "gsm.h" +#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ + +typedef long gsmword; /* 16 or 32 bit signed int */ +typedef long longword; /* 32 bit signed int */ + +struct gsm_state { + + gsmword dp0[ 280 ]; + + gsmword z1; /* preprocessing.c, Offset_com. */ + longword L_z2; /* Offset_com. */ + int mp; /* Preemphasis */ + + gsmword u[8]; /* short_term_aly_filter.c */ + gsmword LARpp[2][8];/* */ + gsmword j; /* */ + + gsmword ltp_cut; /* long_term.c, LTP crosscorr. */ + gsmword nrp; /* 40 */ /* long_term.c, synthesis */ + gsmword v[9]; /* short_term.c, synthesis */ + gsmword msr; /* decoder.c, Postprocessing */ + + char fast; /* only used if FAST */ +}; + + +#define MIN_WORD (-32767 - 1) +#define MAX_WORD 32767 + +#define SASR(x, by) ((x) >> (by)) +#define SASL(x, by) ((x) << (by)) + +# define GSM_MULT_R(a, b) (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_MULT(a, b) (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_ADD(a, b) (gsmword)((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_SUB(a, b) (gsmword)((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) (gsmword)((a) < 0 ? -(a) : (a)) + +INLINE gsmword gsm_div (gsmword num, gsmword denum) +{ + longword L_num = SASL( num, 15 ); + longword L_denum = denum; + + if (L_num == 0) + return 0; + return (gsmword)(L_num/L_denum); +} + +#endif /* PRIVATE_H */ diff --git a/tnl-1.5.0/tnl/zap/projectile.cpp b/tnl-1.5.0/tnl/zap/projectile.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ef581a5019885d3af9249dd8353529ec2d8fd10 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/projectile.cpp @@ -0,0 +1,504 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "gameWeapons.h" +#include "projectile.h" +#include "ship.h" +#include "sparkManager.h" +#include "sfx.h" +#include "gameObject.h" +#include "gameObjectRender.h" +#include "glutInclude.h" + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(Projectile); + +Projectile::Projectile(U32 type, Point p, Point v, U32 t, GameObject *shooter) +{ + mObjectTypeMask = BIT(4); //ProjectileType + + mNetFlags.set(Ghostable); + pos = p; + velocity = v; + mTimeRemaining = t; + collided = false; + alive = true; + mShooter = shooter; + if(shooter) + { + setOwner(shooter->getOwner()); + mTeam = shooter->getTeam(); + } + mType = type; +} + +U32 Projectile::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + if(stream->writeFlag(updateMask & InitialMask)) + { + ((GameConnection *) connection)->writeCompressedPoint(pos, stream); + writeCompressedVelocity(velocity, CompressedVelocityMax, stream); + + stream->writeEnum(mType, ProjectileTypeCount); + + S32 index = -1; + if(mShooter.isValid()) + index = connection->getGhostIndex(mShooter); + if(stream->writeFlag(index != -1)) + stream->writeInt(index, GhostConnection::GhostIdBitSize); + } + stream->writeFlag(collided); + stream->writeFlag(alive); + return 0; +} + +void Projectile::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + bool initial = false; + + if(stream->readFlag()) + { + ((GameConnection *) connection)->readCompressedPoint(pos, stream); + readCompressedVelocity(velocity, CompressedVelocityMax, stream); + + mType = stream->readEnum(ProjectileTypeCount); + + if(stream->readFlag()) + mShooter = (Ship *) connection->resolveGhost(stream->readInt(GhostConnection::GhostIdBitSize)); + pos += velocity * -0.020f; + Rect newExtent(pos,pos); + setExtent(newExtent); + initial = true; + SFXObject::play(gProjInfo[mType].projectileSound, pos, velocity); + } + bool preCollided = collided; + collided = stream->readFlag(); + alive = stream->readFlag(); + + if(!preCollided && collided) + explode(NULL, pos); + + if(!collided && initial) + { + mCurrentMove.time = U32(connection->getOneWayTime()); + // idle(GameObject::ClientIdleMainRemote); + } +} + +void Projectile::handleCollision(GameObject *hitObject, Point collisionPoint) +{ + collided = true; + + if(!isGhost()) + { + DamageInfo theInfo; + theInfo.collisionPoint = collisionPoint; + theInfo.damageAmount = gProjInfo[mType].damageAmount; + theInfo.damageType = 0; + theInfo.damagingObject = this; + theInfo.impulseVector = velocity; + + hitObject->damageObject(&theInfo); + } + + mTimeRemaining = 0; + explode(hitObject, collisionPoint); +} + +void Projectile::idle(GameObject::IdleCallPath path) +{ + U32 deltaT = mCurrentMove.time; + if(!collided && alive) + { + Point endPos = pos + velocity * deltaT * 0.001; + static Vector disableVector; + + Rect queryRect(pos, endPos); + + float collisionTime; + disableVector.clear(); + + U32 aliveTime = getGame()->getCurrentTime() - getCreationTime(); + if(mShooter.isValid() && aliveTime < 500) + { + disableVector.push_back(mShooter); + mShooter->disableCollision(); + } + + GameObject *hitObject; + Point surfNormal; + for(;;) + { + hitObject = findObjectLOS(MoveableType | BarrierType | EngineeredType | ForceFieldType, MoveObject::RenderState, pos, endPos, collisionTime, surfNormal); + if(!hitObject || hitObject->collide(this)) + break; + disableVector.push_back(hitObject); + hitObject->disableCollision(); + } + + for(S32 i = 0; i < disableVector.size(); i++) + disableVector[i]->enableCollision(); + + if(hitObject) + { + bool bounce = false; + U32 typeMask = hitObject->getObjectTypeMask(); + + if(mType == ProjectileBounce && (typeMask & BarrierType)) + bounce = true; + else if(typeMask & ShipType) + { + Ship *s = (Ship *) hitObject; + if(s->isShieldActive()) + bounce = true; + } + + if(bounce) + { + // We hit something that we should bounce from, so bounce! + velocity -= surfNormal * surfNormal.dot(velocity) * 2; + Point collisionPoint = pos + (endPos - pos) * collisionTime; + pos = collisionPoint + surfNormal; + + SFXObject::play(SFXBounceShield, collisionPoint, surfNormal * surfNormal.dot(velocity) * 2); + } + else + { + Point collisionPoint = pos + (endPos - pos) * collisionTime; + handleCollision(hitObject, collisionPoint); + } + } + else + pos = endPos; + + Rect newExtent(pos,pos); + setExtent(newExtent); + } + + if(alive && path == GameObject::ServerIdleMainLoop) + { + if(mTimeRemaining <= deltaT) + { + deleteObject(500); + mTimeRemaining = 0; + alive = false; + setMaskBits(ExplodedMask); + } + else + mTimeRemaining -= deltaT; + } +} + +void Projectile::explode(GameObject *hitObject, Point thePos) +{ + // Do some particle spew... + if(isGhost()) + { + FXManager::emitExplosion(thePos, 0.3, gProjInfo[mType].sparkColors, NumSparkColors); + + Ship *s = dynamic_cast(hitObject); + if(s && s->isShieldActive()) + SFXObject::play(SFXBounceShield, thePos, velocity); + else + SFXObject::play(gProjInfo[mType].impactSound, thePos, velocity); + } +} + +void Projectile::render() +{ + if(collided || !alive) + return; + renderProjectile(pos, mType, getGame()->getCurrentTime() - getCreationTime()); +} + +//----------------------------------------------------------------------------- +TNL_IMPLEMENT_NETOBJECT(Mine); + +Mine::Mine(Point pos, Ship *planter) + : GrenadeProjectile(pos, Point()) +{ + mObjectTypeMask |= MineType; + + if(planter) + { + setOwner(planter->getOwner()); + mTeam = planter->getTeam(); + } + else + { + mTeam = -1; + } + mArmed = false; +} + +static Vector fillVector; + +void Mine::idle(IdleCallPath path) +{ + // Skip the grenade timing goofiness... + Item::idle(path); + + if(exploded || path != GameObject::ServerIdleMainLoop) + return; + + // And check for enemies in the area... + Point pos = getActualPos(); + Rect queryRect(pos, pos); + queryRect.expand(Point(SensorRadius, SensorRadius)); + + fillVector.clear(); + findObjects(MotionTriggerTypes | MineType, fillVector, queryRect); + + // Found something! + bool foundItem = false; + for(S32 i = 0; i < fillVector.size(); i++) + { + F32 radius; + Point ipos; + if(fillVector[i]->getCollisionCircle(MoveObject::RenderState, ipos, radius)) + { + if((ipos - pos).len() < (radius + SensorRadius)) + { + bool isMine = fillVector[i]->getObjectTypeMask() & MineType; + if(!isMine) + { + foundItem = true; + break; + } + else if(mArmed && fillVector[i] != this) + { + foundItem = true; + break; + } + } + } + } + if(foundItem) + { + if(mArmed) + explode(getActualPos()); + } + else + { + if(!mArmed) + { + setMaskBits(ArmedMask); + mArmed = true; + } + } +} + +bool Mine::collide(GameObject *otherObj) +{ + if(otherObj->getObjectTypeMask() & (ProjectileType)) + explode(getActualPos()); + return false; +} + +void Mine::damageObject(DamageInfo *info) +{ + if(info->damageAmount > 0.f && !exploded) + explode(getActualPos()); +} + +U32 Mine::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + U32 ret = Parent::packUpdate(connection, updateMask, stream); + if(stream->writeFlag(updateMask & InitialMask)) + stream->write(mTeam); + stream->writeFlag(mArmed); + return ret; +} + +void Mine::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + bool initial = false; + Parent::unpackUpdate(connection, stream); + + if(stream->readFlag()) + { + initial = true; + stream->read(&mTeam); + } + bool wasArmed = mArmed; + mArmed = stream->readFlag(); + if(initial && !mArmed) + SFXObject::play(SFXMineDeploy, getActualPos(), Point()); + else if(!initial && !wasArmed && mArmed) + SFXObject::play(SFXMineArm, getActualPos(), Point()); +} + +void Mine::renderItem(Point pos) +{ + if(exploded) + return; + + Ship *co = (Ship *) gClientGame->getConnectionToServer()->getControlObject(); + + if(!co) + return; + bool visible = co->getTeam() == getTeam() || co->isSensorActive(); + renderMine(pos, mArmed, visible); +} + +//----------------------------------------------------------------------------- +TNL_IMPLEMENT_NETOBJECT(GrenadeProjectile); + +GrenadeProjectile::GrenadeProjectile(Point pos, Point vel, U32 liveTime, GameObject *shooter) + : Item(pos, true, 7.f, 1.f) +{ + mObjectTypeMask = MoveableType | ProjectileType; + + mNetFlags.set(Ghostable); + + mMoveState[0].pos = pos; + mMoveState[0].vel = vel; + setMaskBits(PositionMask); + + updateExtent(); + + ttl = liveTime; + exploded = false; + if(shooter) + { + setOwner(shooter->getOwner()); + mTeam = shooter->getTeam(); + } +} + +void GrenadeProjectile::idle(IdleCallPath path) +{ + Parent::idle(path); + + // Do some drag... + mMoveState[0].vel -= mMoveState[0].vel * (F32(mCurrentMove.time) / 1000.f); + + if(!exploded) + { + if(getActualVel().len() < 4.0) + explode(getActualPos()); + } + + if(isGhost()) return; + + // Update TTL + U32 deltaT = mCurrentMove.time; + if(path == GameObject::ClientIdleMainRemote) + ttl += deltaT; + else if(!exploded) + { + if(ttl <= deltaT) + explode(getActualPos()); + else + ttl -= deltaT; + } + +} + +U32 GrenadeProjectile::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + U32 ret = Parent::packUpdate(connection, updateMask, stream); + stream->writeFlag(exploded); + stream->writeFlag(updateMask & InitialMask); + return ret; +} + +void GrenadeProjectile::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + Parent::unpackUpdate(connection, stream); + + if(stream->readFlag()) + { + explode(getActualPos()); + } + + if(stream->readFlag()) + { + SFXObject::play(SFXGrenadeProjectile, getActualPos(), getActualVel()); + } +} + +void GrenadeProjectile::damageObject(DamageInfo *theInfo) +{ + // If we're being damaged by another grenade, explode... + if(theInfo->damageType == 1) + { + explode(getActualPos()); + return; + } + + // Bounce off of stuff. + Point dv = theInfo->impulseVector - mMoveState[ActualState].vel; + Point iv = mMoveState[ActualState].pos - theInfo->collisionPoint; + iv.normalize(); + mMoveState[ActualState].vel += iv * dv.dot(iv) * 0.3; + + setMaskBits(PositionMask); +} + +void GrenadeProjectile::explode(Point pos) +{ + if(exploded) return; + + if(isGhost()) + { + // Make us go boom! + Color b(1,1,1); + + FXManager::emitExplosion(getRenderPos(), 0.5, gProjInfo[ProjectilePhaser].sparkColors, NumSparkColors); + SFXObject::play(SFXMineExplode, getActualPos(), Point()); + } + + disableCollision(); + + if(!isGhost()) + { + setMaskBits(PositionMask); + deleteObject(100); + + DamageInfo info; + info.collisionPoint = pos; + info.damagingObject = this; + info.damageAmount = 0.5; + info.damageType = 1; + + radiusDamage(pos, 100.f, 250.f, DamagableTypes, info); + } + + exploded = true; + +} + +void GrenadeProjectile::renderItem(Point pos) +{ + if(exploded) + return; + renderGrenade(pos); +} + +}; diff --git a/tnl-1.5.0/tnl/zap/projectile.h b/tnl-1.5.0/tnl/zap/projectile.h new file mode 100644 index 0000000000000000000000000000000000000000..90ab501e2828dd82f84bb3be7695a4210c1d0a33 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/projectile.h @@ -0,0 +1,132 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _PROJECTILE_H_ +#define _PROJECTILE_H_ + +#include "gameType.h" +#include "gameObject.h" +#include "item.h" +#include "gameWeapons.h" +namespace Zap +{ + +class Ship; + +class Projectile : public GameObject +{ +public: + enum { + CompressedVelocityMax = 2047, + InitialMask = BIT(0), + ExplodedMask = BIT(1), + }; + + Point pos; + Point velocity; + U32 mTimeRemaining; + U32 mType; + bool collided; + bool alive; + SafePtr mShooter; + + Projectile(U32 type = ProjectilePhaser, Point pos = Point(), Point vel = Point(), U32 liveTime = 0, GameObject *shooter = NULL); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + void handleCollision(GameObject *theObject, Point collisionPoint); + + void idle(GameObject::IdleCallPath path); + void explode(GameObject *hitObject, Point p); + + virtual Point getRenderVel() { return velocity; } + virtual Point getActualVel() { return velocity; } + + void render(); + TNL_DECLARE_CLASS(Projectile); +}; + +class GrenadeProjectile : public Item +{ + typedef Item Parent; +public: + GrenadeProjectile(Point pos = Point(), Point vel = Point(), U32 liveTime = 0, GameObject *shooter = NULL); + + enum Constants + { + ExplodeMask = Item::FirstFreeMask, + FirstFreeMask = ExplodeMask << 1, + }; + + S32 ttl; + bool exploded; + + bool collide(GameObject *otherObj) { return true; }; + + void renderItem(Point p); + void idle(IdleCallPath path); + void damageObject(DamageInfo *damageInfo); + void explode(Point p); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + TNL_DECLARE_CLASS(GrenadeProjectile); +}; + +class Mine : public GrenadeProjectile +{ + typedef GrenadeProjectile Parent; + +public: + enum Constants + { + ArmedMask = GrenadeProjectile::FirstFreeMask, + + SensorRadius = 50, + InnerBlastRadius = 75, + OuterBlastRadius = 100 , + }; + + Mine(Point pos = Point(), Ship *owner=NULL); + bool mArmed; + Timer mScanTimer; + SafePtr mOwnerConnection; + bool collide(GameObject *otherObj); + void idle(IdleCallPath path); + + void damageObject(DamageInfo *damageInfo); + void renderItem(Point p); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + TNL_DECLARE_CLASS(Mine); +}; + +}; +#endif diff --git a/tnl-1.5.0/tnl/zap/quickChat.cpp b/tnl-1.5.0/tnl/zap/quickChat.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3823c41716f440d8e102d7c6e954e66bdf92dfca --- /dev/null +++ b/tnl-1.5.0/tnl/zap/quickChat.cpp @@ -0,0 +1,212 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "quickChat.h" +#include "UIGame.h" +#include "glutInclude.h" +#include "gameType.h" +#include "UIMenus.h" +#include "gameObjectRender.h" +#include "input.h" +#include +namespace Zap +{ +void renderControllerButton(F32 x, F32 y, U32 buttonIndex, U32 keyIndex); + +VChatHelper::VChatNode VChatHelper::mChatTree[] = +{ + // Root node + {0, ' ', -1, true, "", ""}, + {1, 'G', 5, true, "Global", ""}, + {2, 'Z', 5, false, "Doh", "Doh!"}, + {2, 'S', 4, false, "Shazbot", "Shazbot!"}, + {2, 'D', 3, false, "Damnit", "Dammit!"}, + {2, 'C', -1, false, "Crap", "Ah Crap!"}, + {2, 'E', 2, false, "Duh", "Duh."}, + {2, 'X', -1, false, "You idiot!", "You idiot!"}, + {2, 'T', 1, false, "Thanks", "Thanks."}, + {2, 'A', 0, false, "No Problem", "No Problemo."}, + {1, 'D', 4, true, "Defense", ""}, + {2, 'A', -1, true, "Attacked", "We are being attacked."}, + {2, 'E', 5, true, "Enemy Attacking Base", "The enemy is attacking our base."}, + {2, 'N', 4, true, "Need More Defense", "We need more defense."}, + {2, 'T', 3, true, "Base Taken", "Base is taken."}, + {2, 'C', 2, true, "Base Clear", "Base is secured."}, + {2, 'Q', 1, true, "Is Base Clear?", "Is our base clear?"}, + {2, 'D', 0, true, "Defending Base", "Defending our base."}, + {2, 'G', -1, true, "Defend Our Base", "Defend our base."}, + {1, 'F', 3, true, "Flag", ""}, + {2, 'G', 5, true, "Flag gone", "Our flag is not in the base!"}, + {2, 'E', 4, true, "Enemy has flag", "The enemy has our flag!"}, + {2, 'H', 3, true, "Have enemy flag", "I have the enemy flag."}, + {2, 'S', 2, true, "Flag secure", "Our flag is secure."}, + {2, 'R', 1, true, "Return our flag", "Return our flag to base."}, + {2, 'F', 0, true, "Get enemy flag", "Get the enemy flag."}, + {1, 'S', -1, true, "Incoming Enemies - Direction", ""}, + {2, 'V', -1, true, "Incoming Enemies", "Incoming enemies!"}, + {2, 'W', -1, true, "Incoming North", "*** INCOMING NORTH ***"}, + {2, 'D', -1, true, "Incoming West", "*** INCOMING WEST ***"}, + {2, 'A', -1, true, "Incoming East", "*** INCOMING EAST ***"}, + {2, 'S', -1, true, "Incoming South", "*** INCOMING SOUTH ***"}, + {1, 'V', 2, true, "Quick", ""}, + {2, 'Z', 5, true, "Move out", "Move out."}, + {2, 'G', 4, true, "Going offense", "Going offense."}, + {2, 'E', 3, true, "Regroup", "Regroup."}, + {2, 'V', 2, true, "Help!", "Help!" }, + {2, 'W', 1, true, "Wait for signal", "Wait for my signal to attack."}, + {2, 'A', 0, true, "Attack!", "Attack!"}, + {2, 'O', -1, true, "Go on the offensive", "Go on the offensive."}, + {2, 'J', -1, true, "Capture the objective", "Capture the objective."}, + {1, 'R', 1, true, "Reponses", ""}, + {2, 'D', 5, true, "Dont know", "I don't know."}, + {2, 'T', 4, true, "Thanks", "Thanks."}, + {2, 'S', 3, true, "Sorry", "Sorry."}, + {2, 'Y', 2, true, "Yes", "Yes."}, + {2, 'N', 1, true, "No", "No."}, + {2, 'A', 0, true, "Acknowledge", "Acknowledged."}, + {1, 'T', 0, true, "Taunts", ""}, + {2, 'E', 5, false, "Yoohoo!", "Yoohoo!"}, + {2, 'Q', 4, false, "How'd THAT feel?", "How'd THAT feel?"}, + {2, 'W', 3, false, "I've had worse...", "I've had worse..."}, + {2, 'X', 2, false, "Missed me!", "Missed me!"}, + {2, 'D', 1, false, "Dance!", "Dance!"}, + {2, 'C', 0, false, "Come get some!", "Come get some!"}, + {2, 'R', -1, false, "Rawr", "RAWR!"}, + + // Terminate + {0, ' ', false, "", ""} +}; + +VChatHelper::VChatHelper() +{ + mCurNode = &mChatTree[0]; +} + +void VChatHelper::render() +{ + Vector renderNodes; + + VChatNode *walk = mCurNode; + U32 matchLevel = walk->depth + 1; + walk++; + + // First get to the end... + while(walk->depth >= matchLevel) + walk++; + + // Then draw bottom up... + while(walk != mCurNode) + { + if(walk->depth == matchLevel && (!mFromController || (mFromController && walk->buttonIndex != -1))) + renderNodes.push_back(walk); + walk--; + } + + S32 curPos = 300; + const int fontSize = 15; + + for(S32 i = 0; i < renderNodes.size(); i++) + { + glColor3f(0.3, 1.0, 0.3); + renderControllerButton(UserInterface::horizMargin, curPos, renderNodes[i]->buttonIndex, renderNodes[i]->trigger); + + glColor3f(0.3, 1.0, 0.3); + UserInterface::drawStringf(UserInterface::horizMargin + 20, curPos, fontSize, "- %s", + renderNodes[i]->caption); + curPos += fontSize + 4; + } +} + +void VChatHelper::show(bool fromController) +{ + mCurNode = &mChatTree[0]; + mFromController = OptionsMenuUserInterface::joystickType != -1; + mIdleTimer.reset(MenuTimeout); +} + +void VChatHelper::idle(U32 delta) +{ + if(mIdleTimer.update(delta)) + gGameUserInterface.setPlayMode(); +} + +void VChatHelper::processKey(U32 key) +{ + // Escape... + if(key == 8 || key == 27) + { + UserInterface::playBoop(); + gGameUserInterface.setPlayMode(); + return; + } + + // Try to find a match if we can... + + // work in upper case... + key = toupper(key); + + // Set up walk... + VChatNode *walk = mCurNode; + U32 matchLevel = walk->depth+1; + walk++; + + // Iterate over anything at our desired depth or lower... + while(walk->depth >= matchLevel) + { + + // If it has the same key and depth... + bool match = (!mFromController && toupper(walk->trigger) == key) || + (mFromController && key == walk->buttonIndex); + if(match && walk->depth == matchLevel) + { + mIdleTimer.reset(MenuTimeout); + // select it... + mCurNode = walk; + + UserInterface::playBoop(); + + // If we're at a leaf (ie, next child down is higher or equal to us), then issue the chat and call it good... + walk++; + if(mCurNode->depth >= walk->depth) + { + GameType *gt = gClientGame->getGameType(); + gGameUserInterface.setPlayMode(); + + StringTableEntry entry(mCurNode->msg); + if(gt) + gt->c2sSendChatSTE(!mCurNode->teamOnly, entry); + + return; + } + } + + walk++; + } + +} + + +}; diff --git a/tnl-1.5.0/tnl/zap/quickChat.h b/tnl-1.5.0/tnl/zap/quickChat.h new file mode 100644 index 0000000000000000000000000000000000000000..d29af1abc0d6e65e296e5dc2d991c377e2cee683 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/quickChat.h @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _UIVCHAT_H_ +#define _UIVCHAT_H_ + +#include "tnlNetBase.h" +#include "UI.h" +#include "tnlNetStringTable.h" +#include "timer.h" + +namespace Zap +{ + +class VChatHelper +{ +private: + struct VChatNode + { + U32 depth; + U8 trigger; + S32 buttonIndex; + bool teamOnly; + const char *caption; + const char *msg; + }; + + static VChatNode mChatTree[]; + + bool mFromController; + VChatNode *mCurNode; + Timer mIdleTimer; + enum { + MenuTimeout = 3500, + }; + +public: + VChatHelper(); + + void idle(U32 delta); + void render(); + void show(bool fromController); + void processKey(U32 key); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/rabbitGame.cpp b/tnl-1.5.0/tnl/zap/rabbitGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..808f1e18fefea22d02b4fa2e88b38a3200ed6a0f --- /dev/null +++ b/tnl-1.5.0/tnl/zap/rabbitGame.cpp @@ -0,0 +1,263 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "rabbitGame.h" +#include "ship.h" +#include "UIGame.h" +#include "sfx.h" +#include "flagItem.h" + +#include "glutInclude.h" +#include + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT_RPC(RabbitGameType, s2cRabbitMessage, (U32 msgIndex, StringTableEntry clientName), (msgIndex, clientName), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0) +{ + switch (msgIndex) + { + case RabbitMsgGrab: + SFXObject::play(SFXFlagCapture); + gGameUserInterface.displayMessage(Color(1.0f, 0.0f, 0.0f), + "%s GRABBED the Carrot!", + clientName.getString()); + break; + case RabbitMsgRabbitKill: + SFXObject::play(SFXShipHeal); + gGameUserInterface.displayMessage(Color(1.0f, 0.0f, 0.0f), + "%s is a rabbid rabbit!", + clientName.getString()); + break; + case RabbitMsgDrop: + SFXObject::play(SFXFlagDrop); + gGameUserInterface.displayMessage(Color(0.0f, 1.0f, 0.0f), + "%s DROPPED the Carrot!", + clientName.getString()); + break; + case RabbitMsgRabbitDead: + SFXObject::play(SFXShipExplode); + gGameUserInterface.displayMessage(Color(1.0f, 0.0f, 0.0f), + "%s killed the rabbit!", + clientName.getString()); + break; + case RabbitMsgReturn: + SFXObject::play(SFXFlagReturn); + gGameUserInterface.displayMessage(Color(1.0f, 0.0f, 1.0f), + "The Carrot has been returned!"); + break; + case RabbitMsgGameOverWin: + gGameUserInterface.displayMessage(Color(1.0f, 1.0f, 0.0f), + "%s is the top rabbit!", + clientName.getString()); + break; + case RabbitMsgGameOverTie: + gGameUserInterface.displayMessage(Color(1.0f, 1.0f, 0.0f), + "No top rabbit - Carrot wins by default!"); + break; + } +} + +//----------------------------------------------------- +// RabbitGameType +//----------------------------------------------------- +TNL_IMPLEMENT_NETOBJECT(RabbitGameType); + +void RabbitGameType::processArguments(S32 argc, const char **argv) +{ + if (argc != 4) + return; + + Parent::processArguments(argc, argv); + + mFlagReturnTimer = Timer(atoi(argv[2]) * 1000); + mFlagScoreTimer = Timer(1.0f / atoi(argv[3]) * 60 * 1000); //secs per point +} + +void RabbitGameType::spawnShip(GameConnection *theClient) +{ + Parent::spawnShip(theClient); + ClientRef *cl = theClient->getClientRef(); + setClientShipLoadout(cl, theClient->getLoadout()); +} + +bool RabbitGameType::objectCanDamageObject(GameObject *damager, GameObject *victim) +{ + if(!damager) + return true; + + GameConnection *c1 = damager->getOwner(); + GameConnection *c2 = victim->getOwner(); + + if( (!c1 || !c2) || (c1 == c2)) + return true; + + Ship *damnShip = (Ship *) c1->getControlObject(); + Ship *victimShip = (Ship *) c2->getControlObject(); + + if(!damnShip || !victimShip) + return true; + + //only hunters can hurt rabbits and only rabbits can hurt hunters + return shipHasFlag(damnShip) != shipHasFlag(victimShip); +} + +Color RabbitGameType::getShipColor(Ship *s) +{ + GameConnection *gc = gClientGame->getConnectionToServer(); + if(!gc) + return Color(); + Ship *co = (Ship *) gc->getControlObject(); + + if(s == co || shipHasFlag(s) == shipHasFlag(co)) + return Color(0,1,0); + return Color(1,0,0); +} + +bool RabbitGameType::shipHasFlag(Ship *ship) +{ + if (!ship) + return false; + + for (S32 k = 0; k < ship->mMountedItems.size(); k++) + { + if (dynamic_cast(ship->mMountedItems[k].getPointer())) + return true; + } + return false; +} + +void RabbitGameType::onClientScore(Ship *ship, S32 howMuch) +{ + GameConnection *controlConnection = ship->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + + if(!cl) + return; + + cl->score += howMuch; + if (cl->score >= mTeamScoreLimit) + gameOverManGameOver(); +} + +void RabbitGameType::idle(GameObject::IdleCallPath path) +{ + Parent::idle(path); + if(path != GameObject::ServerIdleMainLoop || !mRabbitFlag) + return; + + U32 deltaT = mCurrentMove.time; + + if (mRabbitFlag->isMounted()) + { + if (mFlagScoreTimer.update(deltaT)) + { + onFlagHeld(mRabbitFlag->getMount()); + mFlagScoreTimer.reset(); + } + } + else + { + if (!mRabbitFlag->isAtHome() && mFlagReturnTimer.update(deltaT)) + { + mFlagReturnTimer.reset(); + mRabbitFlag->sendHome(); + static StringTableEntry returnString("The carrot has been returned!"); + for (S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagReturn, returnString, NULL); + } + } + Parent::idle(path); +} + +void RabbitGameType::controlObjectForClientKilled(GameConnection *theClient, GameObject *clientObject, GameObject *killerObject) +{ + Parent::controlObjectForClientKilled(theClient, clientObject, killerObject); + + Ship *killerShip = NULL; + GameConnection *ko = killerObject->getOwner(); + if(ko) + killerShip = (Ship *) ko->getControlObject(); + + Ship *victimShip = dynamic_cast(clientObject); + + if (killerShip) + { + if (shipHasFlag(killerShip)) + { + //rabbit killed another person + onFlaggerKill(killerShip); + } + else if (shipHasFlag(victimShip)) + { + //someone killed the rabbit! Poor rabbit! + onFlaggerDead(killerShip); + } + } +} + +void RabbitGameType::shipTouchFlag(Ship *ship, FlagItem *flag) +{ + s2cRabbitMessage(RabbitMsgGrab, ship->mPlayerName); + + flag->mountToShip(ship); +} + +void RabbitGameType::flagDropped(Ship *theShip, FlagItem *theFlag) +{ + mFlagScoreTimer.reset(); + mFlagReturnTimer.reset(); + s2cRabbitMessage(RabbitMsgDrop, theShip->mPlayerName); + Point vel = theShip->getActualVel(); + theFlag->setActualVel(vel); +} + +void RabbitGameType::onFlagHeld(Ship *ship) +{ + onClientScore(ship, 1); +} + +void RabbitGameType::addFlag(FlagItem *theFlag) +{ + mRabbitFlag = theFlag; + theFlag->setScopeAlways(); +} + +void RabbitGameType::onFlaggerKill(Ship *rabbitShip) +{ + s2cRabbitMessage(RabbitMsgRabbitKill, rabbitShip->mPlayerName); + onClientScore(rabbitShip, RabbidRabbitBonus); +} + +void RabbitGameType::onFlaggerDead(Ship *killerShip) +{ + s2cRabbitMessage(RabbitMsgRabbitDead, killerShip->mPlayerName); + onClientScore(killerShip, RabbitKillBonus); +} + +}; //namespace Zap + diff --git a/tnl-1.5.0/tnl/zap/rabbitGame.h b/tnl-1.5.0/tnl/zap/rabbitGame.h new file mode 100644 index 0000000000000000000000000000000000000000..364c2fab1ddb939002bec98f0d954faf1800d061 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/rabbitGame.h @@ -0,0 +1,106 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _RABBITGAME_H_ +#define _RABBITGAME_H_ + +#include "gameType.h" +#include "item.h" +#include "gameWeapons.h" +#include "shipItems.h" + +namespace Zap +{ +class Ship; +class RabbitFlagItem; + +class RabbitGameType : public GameType +{ + typedef GameType Parent; + + FlagItem *mRabbitFlag; + Timer mFlagReturnTimer; + Timer mFlagScoreTimer; + +public: + + enum + { + RabbitMsgGrab, + RabbitMsgRabbitKill, + RabbitMsgRabbitDead, + RabbitMsgDrop, + RabbitMsgReturn, + RabbitMsgGameOverWin, + RabbitMsgGameOverTie + }; + + enum + { + RabbitKillBonus = 4, //one for the kill and 4 more = 5 point bonus + RabbidRabbitBonus = 4 + }; + + RabbitGameType() + { + mTeamScoreLimit = 100; + mRabbitFlag = NULL; + } + + void processArguments(S32 argc, const char **argv); + void spawnShip(GameConnection *theClient); + + void idle(GameObject::IdleCallPath path); + + void addFlag(FlagItem *theFlag); + void flagDropped(Ship *theShip, FlagItem *theFlag); + void shipTouchFlag(Ship *theShip, FlagItem *theFlag); + + bool objectCanDamageObject(GameObject *damager, GameObject *victim); + void controlObjectForClientKilled(GameConnection *theClient, GameObject *clientObject, GameObject *killerObject); + bool shipHasFlag(Ship *ship); + Color getShipColor(Ship *s); + + void onFlagGrabbed(Ship *ship, RabbitFlagItem *flag); + void onFlagHeld(Ship *ship); + void onFlagDropped(Ship *victimShip); + void onFlaggerDead(Ship *killerShip); + void onFlaggerKill(Ship *rabbitShip); + void onFlagReturned(); + + void onClientScore(Ship *ship, S32 howMuch); + const char *getGameTypeString() { return "Rabbit"; } + const char *getInstructionString() { return "Grab the flag and hold it for as long as you can!"; } + + TNL_DECLARE_RPC(s2cRabbitMessage, (U32 msgIndex, StringTableEntry clientName)); + TNL_DECLARE_CLASS(RabbitGameType); +}; + +}; + + +#endif + diff --git a/tnl-1.5.0/tnl/zap/resource.h b/tnl-1.5.0/tnl/zap/resource.h new file mode 100644 index 0000000000000000000000000000000000000000..c8599fab26a02be037e4c0ffbefddc6957b44056 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ZAP.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/tnl-1.5.0/tnl/zap/retrieveGame.cpp b/tnl-1.5.0/tnl/zap/retrieveGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b2c38f2c87118a635357dbd194d66c1053ddf73 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/retrieveGame.cpp @@ -0,0 +1,285 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "goalZone.h" +#include "gameType.h" +#include "ship.h" +#include "flagItem.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +class RetrieveGameType : public GameType +{ + typedef GameType Parent; + Vector mZones; + Vector > mFlags; + enum { + CapScore = 2, + }; +public: + void addFlag(FlagItem *theFlag) + { + S32 i; + for(i = 0; i < mFlags.size(); i++) + { + if(mFlags[i] == NULL) + { + mFlags[i] = theFlag; + break; + } + } + if(i == mFlags.size()) + mFlags.push_back(theFlag); + + if(!isGhost()) + addItemOfInterest(theFlag); + } + + void addZone(GoalZone *zone) + { + mZones.push_back(zone); + } + + void shipTouchFlag(Ship *theShip, FlagItem *theFlag) + { + // see if the ship is already carrying a flag - can only carry one at a time + for(S32 i = 0; i < theShip->mMountedItems.size(); i++) + if(theShip->mMountedItems[i].isValid() && (theShip->mMountedItems[i]->getObjectTypeMask() & FlagType)) + return; + + S32 flagIndex; + + for(flagIndex = 0; flagIndex < mFlags.size(); flagIndex++) + if(mFlags[flagIndex] == theFlag) + break; + + GameConnection *controlConnection = theShip->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + if(!cl) + return; + + // see if this flag is already in a flag zone owned by the ship's team + if(theFlag->getZone() != NULL && theFlag->getZone()->getTeam() == theShip->getTeam()) + return; + + static StringTableEntry stealString("%e0 stole a flag from team %e1!"); + static StringTableEntry takeString("%e0 of team %e1 took a flag!"); + static StringTableEntry oneFlagTakeString("%e0 of team %e1 took the flag!"); + StringTableEntry r = takeString; + if(mFlags.size() == 1) + r = oneFlagTakeString; + S32 teamIndex; + + if(theFlag->getZone() == NULL) + teamIndex = cl->teamId; + else + { + r = stealString; + teamIndex = theFlag->getZone()->getTeam(); + setTeamScore(teamIndex, mTeams[teamIndex].score - 1); + } + Vector e; + e.push_back(cl->name); + e.push_back(mTeams[teamIndex].name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE( + GameConnection::ColorNuclearGreen, SFXFlagSnatch, r, e); + theFlag->mountToShip(theShip); + theFlag->setZone(NULL); + } + + void flagDropped(Ship *theShip, FlagItem *theFlag) + { + static StringTableEntry dropString("%e0 dropped a flag!"); + Vector e; + e.push_back(theShip->mPlayerName); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagDrop, dropString, e); + } + + void shipTouchZone(Ship *s, GoalZone *z) + { + GameConnection *controlConnection = s->getControllingClient(); + ClientRef *cl = controlConnection->getClientRef(); + + if(!cl) + return; + + // see if this is an opposing team's zone + if(s->getTeam() != z->getTeam()) + return; + + // see if this zone already has a flag in it... + for(S32 i = 0; i < mFlags.size(); i++) + if(mFlags[i]->getZone() == z) + return; + + // ok, it's an empty zone on our team: + // see if this ship is carrying a flag + S32 i; + for(i = 0; i < s->mMountedItems.size(); i++) + if(s->mMountedItems[i].isValid() && (s->mMountedItems[i]->getObjectTypeMask() & FlagType)) + break; + if(i == s->mMountedItems.size()) + return; + + // ok, the ship has a flag and it's on the ship... + Item *theItem = s->mMountedItems[i]; + FlagItem *mountedFlag = dynamic_cast(theItem); + if(mountedFlag) + { + setTeamScore(cl->teamId, mTeams[cl->teamId].score + 1); + + static StringTableEntry capString("%e0 retrieved a flag!"); + static StringTableEntry oneFlagCapString("%e0 retrieved the flag!"); + + Vector e; + e.push_back(cl->name); + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, + SFXFlagCapture, (mFlags.size() == 1) ? oneFlagCapString : capString, e); + + // score the flag for the client's team... + mountedFlag->dismount(); + + S32 flagIndex; + for(flagIndex = 0; flagIndex < mFlags.size(); flagIndex++) + if(mFlags[flagIndex] == mountedFlag) + break; + + mFlags[flagIndex]->setZone(z); + + mountedFlag->setActualPos(z->getExtent().getCenter()); + cl->score += CapScore; + // see if all the flags are owned by one team + for(S32 i = 0; i < mFlags.size(); i++) + { + if(!mFlags[i]->getZone() || mFlags[i]->getZone()->getTeam() != cl->teamId) + return; + } + + if(mFlags.size() != 1) + { + static StringTableEntry capAllString("Team %e0 retrieved all the flags!"); + e[0] = mTeams[cl->teamId].name; + for(S32 i = 0; i < mClientList.size(); i++) + mClientList[i]->clientConnection->s2cDisplayMessageE(GameConnection::ColorNuclearGreen, SFXFlagCapture, capAllString, e); + } + for(S32 i = 0; i < mFlags.size(); i++) + { + mFlags[i]->setZone(NULL); + mFlags[i]->sendHome(); + } + } + } + + void performProxyScopeQuery(GameObject *scopeObject, GameConnection *connection) + { + Parent::performProxyScopeQuery(scopeObject, connection); + S32 uTeam = scopeObject->getTeam(); + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(mFlags[i]->isAtHome() || mFlags[i]->getZone()) + connection->objectInScope(mFlags[i]); + else + { + Ship *mount = mFlags[i]->getMount(); + if(mount && mount->getTeam() == uTeam) + { + connection->objectInScope(mount); + connection->objectInScope(mFlags[i]); + } + } + } + } + + void renderInterfaceOverlay(bool scoreboardVisible) + { + Parent::renderInterfaceOverlay(scoreboardVisible); + Ship *u = (Ship *) gClientGame->getConnectionToServer()->getControlObject(); + if(!u) + return; + bool uFlag = false; + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(mFlags[i].isValid() && mFlags[i]->getMount() == u) + { + for(S32 j = 0; j < mZones.size(); j++) + { + // see if this is one of our zones and that it doesn't have a flag in it. + if(mZones[j]->getTeam() != u->getTeam()) + continue; + S32 k; + for(k = 0; k < mFlags.size(); k++) + { + if(!mFlags[k].isValid()) + continue; + if(mFlags[k]->getZone() == mZones[j]) + break; + } + if(k == mFlags.size()) + renderObjectiveArrow(mZones[j], getTeamColor(u->getTeam())); + } + uFlag = true; + break; + } + } + + for(S32 i = 0; i < mFlags.size(); i++) + { + if(!mFlags[i].isValid()) + continue; + + if(!mFlags[i]->isMounted() && !uFlag) + { + GoalZone *gz = mFlags[i]->getZone(); + if(gz && gz->getTeam() != u->getTeam()) + renderObjectiveArrow(mFlags[i], getTeamColor(gz->getTeam())); + else if(!gz) + renderObjectiveArrow(mFlags[i], getTeamColor(-1)); + } + else + { + Ship *mount = mFlags[i]->getMount(); + if(mount && mount != u) + renderObjectiveArrow(mount, getTeamColor(mount->getTeam())); + } + } + } + + const char *getGameTypeString() { return "Retrieve"; } + const char *getInstructionString() { return "Bring all the flags to your capture zones!"; } + TNL_DECLARE_CLASS(RetrieveGameType); +}; + +TNL_IMPLEMENT_NETOBJECT(RetrieveGameType); + + +}; \ No newline at end of file diff --git a/tnl-1.5.0/tnl/zap/sfx.cpp b/tnl-1.5.0/tnl/zap/sfx.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d4d7561101f8e39a59b743ca87c034c95ee1277f --- /dev/null +++ b/tnl-1.5.0/tnl/zap/sfx.cpp @@ -0,0 +1,822 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "sfx.h" +#include "tnl.h" +#include "tnlLog.h" +#include "tnlRandom.h" + +#if !defined (ZAP_DEDICATED) && !defined (TNL_OS_XBOX) + +#include "alInclude.h" + +using namespace TNL; + +namespace Zap +{ + +static SFXProfile gSFXProfiles[] = { + // Utility sounds + { "phaser.wav", true, 1.0f, false, 0, 0 }, + { "phaser.wav", false, 0.45f, false, 150, 600 }, + + // Weapon noises + { "phaser.wav", false, 0.45f, false, 150, 600 }, + { "phaser_impact.wav", false, 0.7f, false, 150, 600 }, + { "bounce.wav", false, 0.45f, false, 150, 600 }, + { "bounce_impact.wav", false, 0.7f, false, 150, 600 }, + { "triple.wav", false, 0.45f, false, 150, 600 }, + { "triple_impact.wav", false, 0.7f, false, 150, 600 }, + { "turret.wav", false, 0.45f, false, 150, 600 }, + { "turret_impact.wav", false, 0.7f, false, 150, 600 }, + + { "grenade.wav", false, 0.9f, false, 300, 600 }, + + { "mine_deploy.wav", false, 0.4f, false, 150, 600 }, + { "mine_arm.wav", false, 0.7f, false, 400, 600 }, + { "mine_explode.wav", false, 0.8f, false, 300, 800 }, + + // Ship noises + { "ship_explode.wav", false, 1.0, false, 300, 1000 }, + { "ship_heal.wav", false, 1.0, false, 300, 1000 }, + { "ship_turbo.wav", false, 0.15f, true, 150, 500 }, + + { "bounce_wall.wav", false, 0.7f, false, 150, 600 }, + { "bounce_obj.wav", false, 0.7f, false, 150, 600 }, + { "bounce_shield.wav", false, 0.7f, false, 150, 600 }, + + { "ship_shield.wav", false, 0.15f, true, 150, 500 }, + { "ship_sensor.wav", false, 0.15f, true, 150, 500 }, + { "ship_repair.wav", false, 0.15f, true, 150, 500 }, + { "ship_cloak.wav", false, 0.15f, true, 150, 500 }, + + // Flag noises + { "flag_capture.wav", true, 0.45f, false, 0, 0 }, + { "flag_drop.wav", true, 0.45f, false, 0, 0 }, + { "flag_return.wav", true, 0.45f, false, 0, 0 }, + { "flag_snatch.wav", true, 0.45f, false, 0, 0 }, + + // Teleport noises + { "teleport_in.wav", false, 1.0, false, 200, 500 }, + { "teleport_out.wav", false, 1.0, false, 200, 500 }, + + // Forcefield noises + { "forcefield_up.wav", false, 0.7f, false, 150, 600 }, + { "forcefield_down.wav", false, 0.7f, false, 150, 600 }, + + // UI noises + { "boop.wav", true, 0.4f, false, 150, 600 }, + { "comm_up.wav", true, 0.4f, false, 150, 600 }, + { "comm_down.wav", true, 0.4f, false, 150, 600 }, + { "boop.wav", true, 0.25f, false, 150, 600 }, + + { NULL, false, 0, false, 0, 0 }, +}; + +static ALCdevice *gDevice = NULL; +static ALCcontext *gContext = NULL; +static bool gSFXValid = false; + +enum { + NumSources = 16, +}; + +static ALuint gSources[NumSources]; +Point SFXObject::mListenerPosition; +Point SFXObject::mListenerVelocity; +F32 SFXObject::mMaxDistance = 500; + +static ALuint gBuffers[NumSFXBuffers]; +static Vector gVoiceFreeBuffers; + +static Vector gPlayList; + +SFXObject::SFXObject(U32 profileIndex, ByteBufferPtr ib, F32 gain, Point position, Point velocity) +{ + mSFXIndex = profileIndex; + mProfile = gSFXProfiles + profileIndex; + mGain = gain; + mPosition = position; + mVelocity = velocity; + mSourceIndex = -1; + mPriority = 0; + mInitialBuffer = ib; +} + +RefPtr SFXObject::play(U32 profileIndex, F32 gain) +{ + RefPtr ret = new SFXObject(profileIndex, NULL, gain, Point(), Point()); + ret->play(); + return ret; +} + +RefPtr SFXObject::play(U32 profileIndex, Point position, Point velocity, F32 gain) +{ + RefPtr ret = new SFXObject(profileIndex, NULL, gain, position, velocity); + ret->play(); + return ret; +} + +RefPtr SFXObject::playRecordedBuffer(ByteBufferPtr p, F32 gain) +{ + RefPtr ret = new SFXObject(0, p, gain, Point(), Point()); + ret->play(); + return ret; +} + +SFXObject::~SFXObject() +{ + +} + +void SFXObject::updateGain() +{ + ALuint source = gSources[mSourceIndex]; + F32 gain = mGain; + + if(!mProfile->isRelative) + { + F32 distance = (mListenerPosition - mPosition).len(); + if(distance > mProfile->fullGainDistance) + { + if(distance < mProfile->zeroGainDistance) + gain *= 1 - (distance - mProfile->fullGainDistance) / + (mProfile->zeroGainDistance - mProfile->fullGainDistance); + else + gain = 0.0f; + } + else + gain = 1.0f; + } + else + gain = 1.0f; + + alSourcef(source, AL_GAIN, gain * mProfile->gainScale); +} + +void SFXObject::updateMovementParams() +{ + ALuint source = gSources[mSourceIndex]; + if(mProfile->isRelative) + { + alSourcei(source, AL_SOURCE_RELATIVE, true); + alSource3f(source, AL_POSITION, 0, 0, 0); + //alSource3f(source, AL_VELOCITY, 0, 0, 0); + } + else + { + alSourcei(source, AL_SOURCE_RELATIVE, false); + alSource3f(source, AL_POSITION, mPosition.x, mPosition.y, 0); + //alSource3f(source, AL_VELOCITY, mVelocity.x, mVelocity.y, 0); + } +} + + +static void unqueueBuffers(S32 sourceIndex) +{ + // free up any played buffers from this source. + if(sourceIndex != -1) + { + ALint processed; + alGetError(); + + alGetSourcei(gSources[sourceIndex], AL_BUFFERS_PROCESSED, &processed); + + while(processed) + { + ALuint buffer; + alSourceUnqueueBuffers(gSources[sourceIndex], 1, &buffer); + if(alGetError() != AL_NO_ERROR) + return; + + //logprintf("unqueued buffer %d\n", buffer); + processed--; + + // ok, this is a lame solution - but the way OpenAL should work is... + // you should only be able to unqueue buffers that you queued - duh! + // otherwise it's a bitch to manage sources that can either be streamed + // or already loaded. + U32 i; + for(i = 0 ; i < NumSFXBuffers; i++) + if(buffer == gBuffers[i]) + break; + if(i == NumSFXBuffers) + gVoiceFreeBuffers.push_back(buffer); + } + } +} + +void SFXObject::queueBuffer(ByteBufferPtr p) +{ + if(!gSFXValid) + return; + + if(!p->getBufferSize()) + return; + + mInitialBuffer = p; + if(mSourceIndex != -1) + { + if(!gVoiceFreeBuffers.size()) + return; + + ALuint source = gSources[mSourceIndex]; + ALuint buffer = gVoiceFreeBuffers.first(); + gVoiceFreeBuffers.pop_front(); + + S16 max = 0; + S16 *ptr = (S16 *) p->getBuffer(); + U32 count = p->getBufferSize() / 2; + while(count--) + { + if(max < *ptr) + max = *ptr; + ptr++; + } + + //logprintf("queued buffer %d - %d max %d len\n", buffer, max, mInitialBuffer->getBufferSize()); + alBufferData(buffer, AL_FORMAT_MONO16, mInitialBuffer->getBuffer(), + mInitialBuffer->getBufferSize(), 8000); + alSourceQueueBuffers(source, 1, &buffer); + + ALint state; + alGetSourcei(mSourceIndex, AL_SOURCE_STATE, &state); + if(state == AL_STOPPED) + alSourcePlay(mSourceIndex); + } + else + play(); +} + +void SFXObject::playOnSource() +{ + ALuint source = gSources[mSourceIndex]; + alSourceStop(source); + unqueueBuffers(mSourceIndex); + + if(mInitialBuffer.isValid()) + { + if(!gVoiceFreeBuffers.size()) + return; + + ALuint buffer = gVoiceFreeBuffers.first(); + gVoiceFreeBuffers.pop_front(); + + alBufferData(buffer, AL_FORMAT_MONO16, mInitialBuffer->getBuffer(), + mInitialBuffer->getBufferSize(), 8000); + alSourceQueueBuffers(source, 1, &buffer); + } + else + alSourcei(source, AL_BUFFER, gBuffers[mSFXIndex]); + + alSourcei(source, AL_LOOPING, mProfile->isLooping); +#ifdef TNL_OS_MAC_OSX + // This is a workaround for the broken OS X implementation of AL_NONE distance model. + alSourcef(source, AL_REFERENCE_DISTANCE,9000); + alSourcef(source, AL_ROLLOFF_FACTOR,1); + alSourcef(source, AL_MAX_DISTANCE, 10000); +#endif + updateMovementParams(); + + updateGain(); + alSourcePlay(source); +} + +void SFXObject::setGain(F32 gain) +{ + if(!gSFXValid) + return; + + mGain = gain; + if(mSourceIndex != -1) + updateGain(); +} + +void SFXObject::setMovementParams(Point position, Point velocity) +{ + if(!gSFXValid) + return; + + mPosition = position; + mVelocity = velocity; + if(mSourceIndex != -1) + updateMovementParams(); +} + +void SFXObject::play() +{ + if(!gSFXValid) + return; + + if(mSourceIndex != -1) + return; + else + { + // see if it's on the play list: + for(S32 i = 0; i < gPlayList.size(); i++) + if(this == gPlayList[i].getPointer()) + return; + gPlayList.push_back(this); + } +} + +void SFXObject::stop() +{ + if(!gSFXValid) + return; + + // remove from the play list, if this sound is playing: + if(mSourceIndex != -1) + { + alSourceStop(gSources[mSourceIndex]); + mSourceIndex = -1; + } + for(S32 i = 0; i < gPlayList.size(); i++) + { + if(gPlayList[i].getPointer() == this) + { + gPlayList.erase(i); + return; + } + } +} + +void SFXObject::init() +{ + ALint error; + gDevice = alcOpenDevice((ALubyte *) "DirectSound3D"); + if(!gDevice) + { + logprintf("Failed to intitialize OpenAL."); + return; + } + + static int contextData[][2] = + { + {ALC_FREQUENCY, 11025}, + {0,0} // Indicate end of list... + }; + + gContext = alcCreateContext(gDevice, (ALCint*)contextData); + alcMakeContextCurrent(gContext); + + error = alGetError(); + + alGenBuffers(NumSFXBuffers, gBuffers); + gVoiceFreeBuffers.setSize(32); + alGenBuffers(32, gVoiceFreeBuffers.address()); + + error = alGetError(); + + alDistanceModel(AL_NONE); + error = alGetError(); + + // load up all the sound buffers + //if(error != AL_NO_ERROR) + // return; + + alGenSources(NumSources, gSources); + + for(U32 i = 0; i < NumSFXBuffers; i++) + { + if(!gSFXProfiles[i].fileName) + break; + + ALsizei size,freq; + ALenum format; + ALvoid *data; + ALboolean loop; + + char fileBuffer[256]; + dSprintf(fileBuffer, sizeof(fileBuffer), "sfx/%s", gSFXProfiles[i].fileName); +#ifdef TNL_OS_MAC_OSX + alutLoadWAVFile((ALbyte *) fileBuffer, &format, &data, &size, &freq); +#else + alutLoadWAVFile((ALbyte *) fileBuffer, &format, &data, &size, &freq, &loop); +#endif + if(alGetError() != AL_NO_ERROR) + { + logprintf("Failure (1) loading sound file '%s'", gSFXProfiles[i].fileName); + return; + } + alBufferData(gBuffers[i], format, data, size, freq); + alutUnloadWAV(format, data, size, freq); + if(alGetError() != AL_NO_ERROR) + { + logprintf("Failure (2) loading sound file '%s'", gSFXProfiles[i].fileName); + return; + } + } + gSFXValid = true; +} + +void SFXObject::process() +{ + if(!gSFXValid) + return; + + // ok, so we have a list of currently "playing" sounds, which is + // unbounded in length, but only the top NumSources actually have sources + // associtated with them. Sounds are prioritized on a 0-1 scale + // based on type and distance. + // Each time through the main loop, newly played sounds are placed + // on the process list. When SFXProcess is called, any finished sounds + // are retired from the list, and then it prioritizes and sorts all + // the remaining sounds. For any sounds from 0 to NumSources that don't + // have a current source, they grab one of the sources not used by the other + // top sounds. At this point, any sound that is not looping, and is + // not in the active top list is retired. + + // ok, look through all the currently playing sources and see which + // ones need to be retired: + + bool sourceActive[NumSources]; + for(S32 i = 0; i < NumSources; i++) + { + ALint state; + unqueueBuffers(i); + alGetSourcei(gSources[i], AL_SOURCE_STATE, &state); + sourceActive[i] = state != AL_STOPPED && state != AL_INITIAL; + } + for(S32 i = 0; i < gPlayList.size(); ) + { + SFXHandle &s = gPlayList[i]; + + if(s->mSourceIndex != -1 && !sourceActive[s->mSourceIndex]) + { + // this sound was playing; now it is stopped, + // so remove it from the list. + s->mSourceIndex = -1; + gPlayList.erase_fast(i); + } + else + { + // compute a priority for this sound. + if(!s->mProfile->isRelative) + s->mPriority = (500 - (s->mPosition - mListenerPosition).len()) / 500.0f; + else + s->mPriority = 1.0; + i++; + } + } + // now, bubble sort all the sounds up the list: + // we choose bubble sort, because the list should + // have a lot of frame-to-frame coherency, making the + // sort most often O(n) + for(S32 i = 1; i < gPlayList.size(); i++) + { + F32 priority = gPlayList[i]->mPriority; + for(S32 j = i - 1; j >= 0; j--) + { + if(priority > gPlayList[j]->mPriority) + { + SFXHandle temp = gPlayList[j]; + gPlayList[j] = gPlayList[j+1]; + gPlayList[j+1] = temp; + } + } + } + // last, release any sources and get rid of non-looping sounds + // outside our max sound limit + for(S32 i = NumSources; i < gPlayList.size(); ) + { + SFXHandle &s = gPlayList[i]; + if(s->mSourceIndex != -1) + { + sourceActive[s->mSourceIndex] = false; + s->mSourceIndex = -1; + } + if(!s->mProfile->isLooping) + gPlayList.erase_fast(i); + else + i++; + } + // now assign sources to all our sounds that need them: + S32 firstFree = 0; + S32 max = NumSources; + if(max > gPlayList.size()) + max = gPlayList.size(); + + for(S32 i = 0; i < max; i++) + { + SFXHandle &s = gPlayList[i]; + if(s->mSourceIndex == -1) + { + while(sourceActive[firstFree]) + firstFree++; + s->mSourceIndex = firstFree; + sourceActive[firstFree] = true; + s->playOnSource(); + } + else + { + // for other sources, just attenuate the gain. + s->updateGain(); + } + } +} + +void SFXObject::setListenerParams(Point pos, Point velocity) +{ + if(!gSFXValid) + return; + + mListenerPosition = pos; + mListenerVelocity = velocity; + alListener3f(AL_POSITION, pos.x, pos.y, -mMaxDistance/2); +} + +void SFXObject::shutdown() +{ + if(!gSFXValid) + return; + + alDeleteBuffers(NumSFXBuffers, gBuffers); + alcMakeContextCurrent(NULL); + alcDestroyContext(gContext); + alcCloseDevice(gDevice); +} + +}; + +#elif defined (ZAP_DEDICATED) + +using namespace TNL; + +namespace Zap +{ + +Point SFXObject::mListenerPosition; +Point SFXObject::mListenerVelocity; +F32 SFXObject::mMaxDistance = 500; + +SFXObject::SFXObject(U32 profileIndex, ByteBufferPtr ib, F32 gain, Point position, Point velocity) +{ +} + +RefPtr SFXObject::play(U32 profileIndex, F32 gain) +{ + return new SFXObject(0,NULL,0,Point(0,0), Point(0,0)); +} + +RefPtr SFXObject::play(U32 profileIndex, Point position, Point velocity, F32 gain) +{ + return new SFXObject(0,NULL,0,Point(0,0), Point(0,0)); +} + +RefPtr SFXObject::playRecordedBuffer(ByteBufferPtr p, F32 gain) +{ + return new SFXObject(0,NULL,0,Point(0,0), Point(0,0)); +} + +void SFXObject::queueBuffer(ByteBufferPtr p) +{ +} + +SFXObject::~SFXObject() +{ + +} + +void SFXObject::updateGain() +{ +} + +void SFXObject::updateMovementParams() +{ +} + +void SFXObject::playOnSource() +{ +} + +void SFXObject::setGain(F32 gain) +{ +} + +void SFXObject::setMovementParams(Point position, Point velocity) +{ +} + +void SFXObject::play() +{ +} + +void SFXObject::stop() +{ +} + +void SFXObject::init() +{ + logprintf("No OpenAL support on this platform."); +} + +void SFXObject::process() +{ + } + +void SFXObject::setListenerParams(Point pos, Point velocity) +{ +} + +void SFXObject::shutdown() +{ +}; + +}; + +#endif + +#ifdef TNL_OS_WIN32 + +#include +#include + +namespace Zap +{ + +extern bool gIsCrazyBot; + +static LPDIRECTSOUNDCAPTURE8 capture = NULL; +static LPDIRECTSOUNDCAPTUREBUFFER captureBuffer = NULL; +static bool recording = false; +static bool captureInit = false; + +enum { + BufferBytes = 16000, +}; + +static U32 lastReadOffset = 0; + +bool SFXObject::startRecording() +{ + if(recording) + return true; + + if(!captureInit) + { + captureInit = true; + DirectSoundCaptureCreate8(NULL, &capture, NULL); + } + if(!capture) + return false; + + if(!captureBuffer) + { + HRESULT hr; + DSCBUFFERDESC dscbd; + + // wFormatTag, nChannels, nSamplesPerSec, mAvgBytesPerSec, + // nBlockAlign, wBitsPerSample, cbSize + WAVEFORMATEX wfx = { WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16, 0}; + + dscbd.dwSize = sizeof(DSCBUFFERDESC); + dscbd.dwFlags = 0; + dscbd.dwBufferBytes = BufferBytes; + dscbd.dwReserved = 0; + dscbd.lpwfxFormat = &wfx; + dscbd.dwFXCount = 0; + dscbd.lpDSCFXDesc = NULL; + + if (FAILED(hr = capture->CreateCaptureBuffer(&dscbd, &captureBuffer, NULL))) + { + captureBuffer = NULL; + return false; + } + } + recording = true; + lastReadOffset = 0; + captureBuffer->Start(DSCBSTART_LOOPING); + return true; +} + +void SFXObject::captureSamples(ByteBufferPtr buffer) +{ + if(!recording) + { + return; + } + else + { + DWORD capturePosition; + DWORD readPosition; + + captureBuffer->GetCurrentPosition(&capturePosition, &readPosition); + S32 byteCount = readPosition - lastReadOffset; + if(byteCount < 0) + byteCount += BufferBytes; + + void *buf1; + void *buf2; + DWORD count1; + DWORD count2; + + //printf("Capturing samples... %d ... %d\n", lastReadOffset, readPosition); + + if(!byteCount) + return; + + captureBuffer->Lock(lastReadOffset, byteCount, &buf1, &count1, &buf2, &count2, 0); + + U32 sizeAdd = count1 + count2; + U32 start = buffer->getBufferSize(); + + buffer->resize(start + sizeAdd); + + memcpy(buffer->getBuffer() + start, buf1, count1); + if(count2) + memcpy(buffer->getBuffer() + start + count1, buf2, count2); + + captureBuffer->Unlock(buf1, count1, buf2, count2); + + // Write our own random noise in... + if(gIsCrazyBot) + { + S16 *buff = (S16*)buffer->getBuffer() + start/2; + static U32 synthCount = 0; + static U16 synthGoal = 100; + static U16 curSynth = 0; + for(U32 i=0; iStop(); + if(captureBuffer) + captureBuffer->Release(); + captureBuffer = NULL; + } +} + +}; + +#else + +namespace Zap +{ + +bool SFXObject::startRecording() +{ + return false; +} + +void SFXObject::captureSamples(ByteBufferPtr buffer) +{ +} + +void SFXObject::stopRecording() +{ +} + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/sfx.h b/tnl-1.5.0/tnl/zap/sfx.h new file mode 100644 index 0000000000000000000000000000000000000000..472bff19d7e184bb6d3d08cbfadaac101e631065 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/sfx.h @@ -0,0 +1,162 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _SFX_H_ +#define _SFX_H_ + +#include "tnl.h" +#include "tnlNetBase.h" +#include "point.h" +#include "tnlByteBuffer.h" + +using namespace TNL; + +namespace Zap +{ + +enum SFXProfiles +{ + // Utility sounds. + SFXVoice, + SFXNone, + + // Weapon noises + SFXPhaserProjectile, + SFXPhaserImpact, + SFXBounceProjectile, + SFXBounceImpact, + SFXTripleProjectile, + SFXTripleImpact, + SFXTurretProjectile, + SFXTurretImpact, + + SFXGrenadeProjectile, + + SFXMineDeploy, + SFXMineArm, + SFXMineExplode, + + // Ship noises + SFXShipExplode, + SFXShipHeal, + SFXShipBoost, + + SFXBounceWall, + SFXBounceObject, + SFXBounceShield, + + SFXShieldActive, + SFXSensorActive, + SFXRepairActive, + SFXCloakActive, + + // Flag noises + SFXFlagCapture, + SFXFlagDrop, + SFXFlagReturn, + SFXFlagSnatch, + + // Teleport noises + SFXTeleportIn, + SFXTeleportOut, + + // Forcefield noises + SFXForceFieldUp, + SFXForceFieldDown, + + // UI noises + SFXUIBoop, + SFXUICommUp, + SFXUICommDown, + SFXIncomingMessage, + + NumSFXBuffers +}; + +struct SFXProfile +{ + const char *fileName; + bool isRelative; + F32 gainScale; + bool isLooping; + F32 fullGainDistance; + F32 zeroGainDistance; +}; + +class SFXObject : public Object +{ + static Point mListenerPosition; + static Point mListenerVelocity; + static F32 mMaxDistance; + static S32 mCaptureGain; + + U32 mSFXIndex; + Point mPosition; + Point mVelocity; + ByteBufferPtr mInitialBuffer; + SFXProfile *mProfile; + F32 mGain; + S32 mSourceIndex; + F32 mPriority; + void playOnSource(); + void updateGain(); + void updateMovementParams(); +public: + SFXObject(U32 profileIndex, ByteBufferPtr samples, F32 gain, Point position, Point velocity); + ~SFXObject(); + + void setGain(F32 gain); + void play(); + void stop(); + void setMovementParams(Point position, Point velocity); + void queueBuffer(ByteBufferPtr b); + bool isPlaying() { return mSourceIndex != -1; } + + static bool startRecording(); + static void captureSamples(ByteBufferPtr sampleBuffer); + static void stopRecording(); + + static void setMaxDistance(F32 maxDistance); + static void init(); + static void shutdown(); + static void process(); + static void setListenerParams(Point position, Point velocity); + static RefPtr play(U32 profileIndex, F32 gain = 1.0f); + static RefPtr play(U32 profileIndex, Point position, Point velocity, F32 gain = 1.0f); + static RefPtr playRecordedBuffer(ByteBufferPtr b, F32 gain = 1.0f); +}; + +typedef RefPtr SFXHandle; + +extern void SFXInit(); +extern void SFXShutdown(); +extern void SFXProcess(); +extern void SFXSetListenerParams(Point position, Point velocity); + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/ship.cpp b/tnl-1.5.0/tnl/zap/ship.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5eb04ae0856ad7625d399f19e403189430f48e48 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/ship.cpp @@ -0,0 +1,1183 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "ship.h" +#include "item.h" + +#include "glutInclude.h" +#include "sparkManager.h" +#include "projectile.h" +#include "gameLoader.h" +#include "sfx.h" +#include "UI.h" +#include "UIMenus.h" +#include "UIGame.h" +#include "gameType.h" +#include "gameConnection.h" +#include "shipItems.h" +#include "gameWeapons.h" +#include "gameObjectRender.h" + +#include + +namespace Zap +{ + +static Vector fillVector; + +//------------------------------------------------------------------------ +TNL_IMPLEMENT_NETOBJECT(Ship); + +Ship::Ship(StringTableEntry playerName, S32 team, Point p, F32 m) : MoveObject(p, CollisionRadius) +{ + mObjectTypeMask = ShipType | MoveableType | CommandMapVisType | TurretTargetType; + + mNetFlags.set(Ghostable); + + for(U32 i = 0; i < MoveStateCount; i++) + { + mMoveState[i].pos = p; + mMoveState[i].angle = 0; + } + mTeam = team; + mHealth = 1.0; + mass = m; + hasExploded = false; + updateExtent(); + + mPlayerName = playerName; + + for(S32 i=0; igetGridSize(); + for(U32 i = 0; i < MoveStateCount; i++) + { + mMoveState[i].pos = pos; + mMoveState[i].angle = 0; + } + + updateExtent(); +} + +void Ship::setActualPos(Point p) +{ + mMoveState[ActualState].pos = p; + mMoveState[RenderState].pos = p; + setMaskBits(PositionMask | WarpPositionMask); +} + +// process a move. This will advance the position of the ship, as well as adjust the velocity and angle. +void Ship::processMove(U32 stateIndex) +{ + U32 msTime = mCurrentMove.time; + + mMoveState[LastProcessState] = mMoveState[stateIndex]; + + F32 maxVel = isBoostActive() ? BoostMaxVelocity : MaxVelocity; + + F32 time = mCurrentMove.time * 0.001; + Point requestVel(mCurrentMove.right - mCurrentMove.left, mCurrentMove.down - mCurrentMove.up); + + requestVel *= maxVel; + F32 len = requestVel.len(); + + if(len > maxVel) + requestVel *= maxVel / len; + + Point velDelta = requestVel - mMoveState[stateIndex].vel; + F32 accRequested = velDelta.len(); + + F32 maxAccel = (isBoostActive() ? BoostAcceleration : Acceleration) * time; + if(accRequested > maxAccel) + { + velDelta *= maxAccel / accRequested; + mMoveState[stateIndex].vel += velDelta; + } + else + mMoveState[stateIndex].vel = requestVel; + + mMoveState[stateIndex].angle = mCurrentMove.angle; + move(time, stateIndex, false); +} + +Point Ship::getAimVector() +{ + return Point(cos(mMoveState[ActualState].angle), sin(mMoveState[ActualState].angle) ); +} + +void Ship::selectWeapon() +{ + selectWeapon(mActiveWeapon + 1); +} + +void Ship::selectWeapon(U32 weaponIdx) +{ + mActiveWeapon = weaponIdx % ShipWeaponCount; + GameConnection *cc = getControllingClient(); + if(cc) + { + Vector e; + e.push_back(gWeapons[mWeapon[mActiveWeapon]].name); + static StringTableEntry msg("%e0 selected."); + cc->s2cDisplayMessageE(GameConnection::ColorAqua, SFXUIBoop, msg, e); + } +} + +void Ship::processWeaponFire() +{ + mFireTimer.update(mCurrentMove.time); + mWeaponFireDecloakTimer.update(mCurrentMove.time); + + U32 curWeapon = mWeapon[mActiveWeapon]; + + if(mCurrentMove.fire && mFireTimer.getCurrent() == 0) + { + if(mEnergy >= gWeapons[curWeapon].minEnergy) + { + mEnergy -= gWeapons[curWeapon].drainEnergy; + mFireTimer.reset(gWeapons[curWeapon].fireDelay); + mWeaponFireDecloakTimer.reset(WeaponFireDecloakTime); + + if(!isGhost()) + { + Point dir = getAimVector(); + createWeaponProjectiles(curWeapon, dir, mMoveState[ActualState].pos, mMoveState[ActualState].vel, CollisionRadius - 2, this); + } + } + } +} + +void Ship::controlMoveReplayComplete() +{ + // compute the delta between our current render position + // and the server position after client-side prediction has + // been run. + Point delta = mMoveState[ActualState].pos - mMoveState[RenderState].pos; + F32 deltaLen = delta.len(); + + // if the delta is either very small, or greater than the + // max interpolation threshold, just warp to the new position + if(deltaLen <= 0.5 || deltaLen > MaxControlObjectInterpDistance) + { + // if it's a large delta, get rid of the movement trails. + if(deltaLen > MaxControlObjectInterpDistance) + for(S32 i=0; i hitObjects; + Point pos = getRenderPos(); + Point extend(RepairRadius, RepairRadius); + Rect r(pos - extend, pos + extend); + findObjects(ShipType | EngineeredType, hitObjects, r); + + mRepairTargets.clear(); + for(S32 i = 0; i < hitObjects.size(); i++) + { + GameObject *s = hitObjects[i]; + if(s->isDestroyed() || s->getHealth() >= 1) + continue; + if((s->getRenderPos() - pos).len() > (RepairRadius + CollisionRadius)) + continue; + if(s->getTeam() != -1 && s->getTeam() != getTeam()) + continue; + mRepairTargets.push_back(s); + } + return mRepairTargets.size() != 0; +} + +void Ship::repairTargets() +{ + F32 totalRepair = RepairHundredthsPerSecond * 0.01 * mCurrentMove.time * 0.001f; + +// totalRepair /= mRepairTargets.size(); + + DamageInfo di; + di.damageAmount = -totalRepair; + di.damagingObject = this; + di.damageType = 0; + + for(S32 i = 0; i < mRepairTargets.size(); i++) + mRepairTargets[i]->damageObject(&di); +} + +void Ship::processEnergy() +{ + static U32 gEnergyDrain[ModuleCount] = + { + Ship::EnergyShieldDrain, + Ship::EnergyBoostDrain, + Ship::EnergySensorDrain, + Ship::EnergyRepairDrain, + 0, + Ship::EnergyCloakDrain, + }; + + bool modActive[ModuleCount]; + for(S32 i = 0; i < ModuleCount; i++) + { + modActive[i] = mModuleActive[i]; + mModuleActive[i] = false; + } + + if(mEnergy > EnergyCooldownThreshold) + mCooldown = false; + + for(S32 i = 0; i < ShipModuleCount; i++) + if(mCurrentMove.module[i] && !mCooldown) + mModuleActive[mModule[i]] = true; + + // No boost if we're not moving. + if(mModuleActive[ModuleBoost] && + mCurrentMove.up == 0 && + mCurrentMove.down == 0 && + mCurrentMove.left == 0 && + mCurrentMove.right == 0) + { + mModuleActive[ModuleBoost] = false; + } + + // No repair with no targets. + if(mModuleActive[ModuleRepair] && !findRepairTargets()) + mModuleActive[ModuleRepair] = false; + + // No cloak with nearby sensored people. + if(mModuleActive[ModuleCloak]) + { + if(mWeaponFireDecloakTimer.getCurrent() != 0) + mModuleActive[ModuleCloak] = false; + else + { + Rect cloakCheck(getActualPos(), getActualPos()); + cloakCheck.expand(Point(CloakCheckRadius, CloakCheckRadius)); + + fillVector.clear(); + findObjects(ShipType, fillVector, cloakCheck); + + if(fillVector.size() > 0) + { + for(S32 i=0; i(fillVector[i]); + + if(!s) continue; + + if(s->getTeam() != getTeam() && s->isSensorActive()) + { + mModuleActive[ModuleCloak] = false; + break; + } + } + } + } + } + + F32 scaleFactor = mCurrentMove.time * 0.001; + + // Update things based on available energy... + bool anyActive = false; + for(S32 i = 0; i < ModuleCount; i++) + { + if(mModuleActive[i]) + { + mEnergy -= S32(gEnergyDrain[i] * scaleFactor); + anyActive = true; + } + } + + if(!anyActive && mEnergy <= EnergyCooldownThreshold) + mCooldown = true; + + if(mEnergy < EnergyMax) + { + // If we're not doing anything, recharge. + if(!anyActive) + mEnergy += S32(EnergyRechargeRate * scaleFactor); + + if(mEnergy <= 0) + { + mEnergy = 0; + for(S32 i = 0; i < ModuleCount; i++) + mModuleActive[i] = false; + mCooldown = true; + } + } + + if(mEnergy >= EnergyMax) + mEnergy = EnergyMax; + + for(S32 i = 0; i < ModuleCount;i++) + { + if(mModuleActive[i] != modActive[i]) + { + if(i == ModuleSensor) + { + mSensorZoomTimer.reset(SensorZoomTime - mSensorZoomTimer.getCurrent(), SensorZoomTime); + mSensorStartTime = getGame()->getCurrentTime(); + } + else if(i == ModuleCloak) + mCloakTimer.reset(CloakFadeTime - mCloakTimer.getCurrent(), CloakFadeTime); + setMaskBits(PowersMask); + } + } +} + +void Ship::damageObject(DamageInfo *theInfo) +{ + if(theInfo->damageAmount > 0) + { + if(!getGame()->getGameType()->objectCanDamageObject(theInfo->damagingObject, this)) + return; + + // Factor in shields + if(isShieldActive())// && mEnergy >= EnergyShieldHitDrain) + { + //mEnergy -= EnergyShieldHitDrain; + return; + } + } + mHealth -= theInfo->damageAmount; + setMaskBits(HealthMask); + if(mHealth <= 0) + { + mHealth = 0; + kill(theInfo); + } + else if(mHealth > 1) + mHealth = 1; + + // Deal with grenades + if(theInfo->damageType == 1) + { + mMoveState[0].vel += theInfo->impulseVector; + } +} + + +void Ship::updateModuleSounds() +{ + static S32 moduleSFXs[ModuleCount] = + { + SFXShieldActive, + SFXShipBoost, + SFXSensorActive, + SFXRepairActive, + -1, // No engineer pack, yo! + SFXCloakActive, + }; + + for(U32 i = 0; i < ModuleCount; i++) + { + if(mModuleActive[i]) + { + if(mModuleSound[i].isValid()) + mModuleSound[i]->setMovementParams(mMoveState[RenderState].pos, mMoveState[RenderState].vel); + else if(moduleSFXs[i] != -1) + mModuleSound[i] = SFXObject::play(moduleSFXs[i], mMoveState[RenderState].pos, mMoveState[RenderState].vel); + } + else + { + if(mModuleSound[i].isValid()) + { + mModuleSound[i]->stop(); + mModuleSound[i] = 0; + } + } + } +} + + +void Ship::writeControlState(BitStream *stream) +{ + stream->write(mMoveState[ActualState].pos.x); + stream->write(mMoveState[ActualState].pos.y); + stream->write(mMoveState[ActualState].vel.x); + stream->write(mMoveState[ActualState].vel.y); + stream->writeRangedU32(mEnergy, 0, EnergyMax); + stream->writeFlag(mCooldown); + stream->writeRangedU32(mFireTimer.getCurrent(), 0, MaxFireDelay); + stream->writeRangedU32(mWeapon[mActiveWeapon], 0, WeaponCount); +} + +void Ship::readControlState(BitStream *stream) +{ + stream->read(&mMoveState[ActualState].pos.x); + stream->read(&mMoveState[ActualState].pos.y); + stream->read(&mMoveState[ActualState].vel.x); + stream->read(&mMoveState[ActualState].vel.y); + mEnergy = stream->readRangedU32(0, EnergyMax); + mCooldown = stream->readFlag(); + U32 fireTimer = stream->readRangedU32(0, MaxFireDelay); + mFireTimer.reset(fireTimer); + mActiveWeapon = 0; + mWeapon[mActiveWeapon] = stream->readRangedU32(0, WeaponCount); +} + +U32 Ship::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + GameConnection *gameConnection = (GameConnection *) connection; + + if(isInitialUpdate()) + { + stream->writeFlag(getGame()->getCurrentTime() - getCreationTime() < 300); + stream->writeStringTableEntry(mPlayerName); + stream->write(mass); + stream->writeRangedU32(mTeam + 1, 0, getGame()->getTeamCount()); + + // now write all the mounts: + for(S32 i = 0; i < mMountedItems.size(); i++) + { + if(mMountedItems[i].isValid()) + { + S32 index = connection->getGhostIndex(mMountedItems[i]); + if(index != -1) + { + stream->writeFlag(true); + stream->writeInt(index, GhostConnection::GhostIdBitSize); + } + } + } + stream->writeFlag(false); + } + if(stream->writeFlag(updateMask & HealthMask)) + stream->writeFloat(mHealth, 6); + + if(stream->writeFlag(updateMask & LoadoutMask)) + { + stream->writeRangedU32(mModule[0], 0, ModuleCount); + stream->writeRangedU32(mModule[1], 0, ModuleCount); + } + + stream->writeFlag(hasExploded); + + bool shouldWritePosition = (updateMask & InitialMask) || + gameConnection->getControlObject() != this; + + stream->writeFlag(updateMask & WarpPositionMask); + if(!shouldWritePosition) + { + stream->writeFlag(false); + stream->writeFlag(false); + stream->writeFlag(false); + } + else + { + if(stream->writeFlag(updateMask & PositionMask)) + { + gameConnection->writeCompressedPoint(mMoveState[RenderState].pos, stream); + writeCompressedVelocity(mMoveState[RenderState].vel, BoostMaxVelocity + 1, stream); + } + if(stream->writeFlag(updateMask & MoveMask)) + { + mCurrentMove.pack(stream, NULL, false); + } + if(stream->writeFlag(updateMask & PowersMask)) + { + for(S32 i = 0; i < ModuleCount; i++) + stream->writeFlag(mModuleActive[i]); + } + } + return 0; +} + +void Ship::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + bool positionChanged = false; + bool wasInitialUpdate = false; + bool playSpawnEffect = false; + + if(isInitialUpdate()) + { + wasInitialUpdate = true; + playSpawnEffect = stream->readFlag(); + + stream->readStringTableEntry(&mPlayerName); + stream->read(&mass); + mTeam = stream->readRangedU32(0, gClientGame->getTeamCount()) - 1; + + // read mounted items: + while(stream->readFlag()) + { + S32 index = stream->readInt(GhostConnection::GhostIdBitSize); + Item *theItem = (Item *) connection->resolveGhost(index); + theItem->mountToShip(this); + } + } + + if(stream->readFlag()) + mHealth = stream->readFloat(6); + + if(stream->readFlag()) + { + mModule[0] = stream->readRangedU32(0, ModuleCount); + mModule[1] = stream->readRangedU32(0, ModuleCount); + } + + bool explode = stream->readFlag(); + bool warp = stream->readFlag(); + if(warp) + mWarpInTimer.reset(WarpFadeInTime); + + if(stream->readFlag()) + { + ((GameConnection *) connection)->readCompressedPoint(mMoveState[ActualState].pos, stream); + readCompressedVelocity(mMoveState[ActualState].vel, BoostMaxVelocity + 1, stream); + positionChanged = true; + } + if(stream->readFlag()) + { + mCurrentMove = Move(); + mCurrentMove.unpack(stream, false); + } + if(stream->readFlag()) + { + bool wasActive[ModuleCount]; + for(S32 i = 0; i < ModuleCount; i++) + { + wasActive[i] = mModuleActive[i]; + mModuleActive[i] = stream->readFlag(); + if(i == ModuleSensor && wasActive[i] != mModuleActive[i]) + { + mSensorZoomTimer.reset(SensorZoomTime - mSensorZoomTimer.getCurrent(), SensorZoomTime); + mSensorStartTime = gClientGame->getCurrentTime(); + } + if(i == ModuleCloak && wasActive[i] != mModuleActive[i]) + mCloakTimer.reset(CloakFadeTime - mCloakTimer.getCurrent(), CloakFadeTime); + } + } + + mMoveState[ActualState].angle = mCurrentMove.angle; + + if(positionChanged) + { + mCurrentMove.time = (U32) connection->getOneWayTime(); + processMove(ActualState); + + if(!warp) + { + mInterpolating = true; + // if the actual velocity is in the direction of the actual position + // then we'll set it into the render velocity + } + else + { + mInterpolating = false; + mMoveState[RenderState] = mMoveState[ActualState]; + + for(S32 i=0; i360) a-=360; + + while(b<0) b+=360; + while(b>360) b-=360; + + if(fabs(b-a) > 180) + { + // Go the other way + return 360-(b-a); + } + else + { + return b-a; + } +} + +bool Ship::carryingResource() +{ + for(S32 i = mMountedItems.size() - 1; i >= 0; i--) + if(mMountedItems[i].isValid() && mMountedItems[i]->getObjectTypeMask() & ResourceItemType) + return true; + return false; +} + +Item *Ship::unmountResource() +{ + for(S32 i = mMountedItems.size() - 1; i >= 0; i--) + { + if(mMountedItems[i]->getObjectTypeMask() & ResourceItemType) + { + Item *ret = mMountedItems[i]; + ret->dismount(); + return ret; + } + } + return NULL; +} + +void Ship::setLoadout(U32 module1, U32 module2, U32 weapon1, U32 weapon2, U32 weapon3) +{ + if(module1 == mModule[0] && module2 == mModule[1] + && weapon1 == mWeapon[0] && weapon2 == mWeapon[1] && weapon3 == mWeapon[2]) + return; + + U32 currentWeapon = mWeapon[mActiveWeapon]; + + mModule[0] = module1; + mModule[1] = module2; + mWeapon[0] = weapon1; + mWeapon[1] = weapon2; + mWeapon[2] = weapon3; + + setMaskBits(LoadoutMask); + + GameConnection *cc = getControllingClient(); + + if(cc) + { + static StringTableEntry msg("Ship loadout configuration updated."); + cc->s2cDisplayMessage(GameConnection::ColorAqua, SFXUIBoop, msg); + } + + // Try to see if we can maintain the same weapon we had before. + U32 i; + for(i = 0; i < 3; i++) + { + if(mWeapon[i] == currentWeapon) + { + mActiveWeapon = i; + break; + } + } + if(i == 3) + selectWeapon(0); + + if(mModule[0] != ModuleEngineer && mModule[1] != ModuleEngineer) + { + // drop any resources we may be carrying + for(S32 i = mMountedItems.size() - 1; i >= 0; i--) + if(mMountedItems[i]->getObjectTypeMask() & ResourceItemType) + mMountedItems[i]->dismount(); + } +} + +void Ship::kill() +{ + deleteObject(KillDeleteDelay); + hasExploded = true; + setMaskBits(ExplosionMask); + disableCollision(); + for(S32 i = mMountedItems.size() - 1; i >= 0; i--) + mMountedItems[i]->onMountDestroyed(); +} + +void Ship::kill(DamageInfo *theInfo) +{ + if(isGhost()) + return; + + GameConnection *controllingClient = getControllingClient(); + if(controllingClient) + { + GameType *gt = getGame()->getGameType(); + if(gt) + gt->controlObjectForClientKilled(controllingClient, this, theInfo->damagingObject); + } + kill(); +} + +enum { + NumShipExplosionColors = 12, +}; + +Color ShipExplosionColors[NumShipExplosionColors] = { +Color(1, 0, 0), +Color(0.9, 0.5, 0), +Color(1, 1, 1), +Color(1, 1, 0), +Color(1, 0, 0), +Color(0.8, 1.0, 0), +Color(1, 0.5, 0), +Color(1, 1, 1), +Color(1, 0, 0), +Color(0.9, 0.5, 0), +Color(1, 1, 1), +Color(1, 1, 0), +}; + +void Ship::emitShipExplosion(Point pos) +{ + SFXObject::play(SFXShipExplode, pos, Point()); + + F32 a, b; + a = Random::readF() * 0.4 + 0.5; + b = Random::readF() * 0.2 + 0.9; + + F32 c, d; + c = Random::readF() * 0.15 + 0.125; + d = Random::readF() * 0.2 + 0.9; + + FXManager::emitExplosion(mMoveState[ActualState].pos, 0.9, ShipExplosionColors, NumShipExplosionColors); + FXManager::emitBurst(pos, Point(a,c), Color(1,1,0.25), Color(1,0,0)); + FXManager::emitBurst(pos, Point(b,d), Color(1,1,0), Color(0,0.75,0)); +} + +void Ship::emitMovementSparks() +{ + U32 deltaT = mCurrentMove.time; + + // Do nothing if we're under 0.1 vel + if(hasExploded || mMoveState[ActualState].vel.len() < 0.1) + return; + + mSparkElapsed += deltaT; + + if(mSparkElapsed <= 32) + return; + + bool boostActive = isBoostActive(); + bool cloakActive = isCloakActive(); + + Point corners[3]; + Point shipDirs[3]; + + corners[0].set(-20, -15); + corners[1].set( 0, 25); + corners[2].set( 20, -15); + + F32 th = FloatHalfPi - mMoveState[RenderState].angle; + + F32 sinTh = sin(th); + F32 cosTh = cos(th); + F32 warpInScale = (WarpFadeInTime - mWarpInTimer.getCurrent()) / F32(WarpFadeInTime); + + for(S32 i=0; i<3; i++) + { + shipDirs[i].x = corners[i].x * cosTh + corners[i].y * sinTh; + shipDirs[i].y = corners[i].y * cosTh - corners[i].x * sinTh; + shipDirs[i] *= warpInScale; + } + + Point leftVec ( mMoveState[ActualState].vel.y, -mMoveState[ActualState].vel.x); + Point rightVec(-mMoveState[ActualState].vel.y, mMoveState[ActualState].vel.x); + + leftVec.normalize(); + rightVec.normalize(); + + S32 bestId = -1, leftId, rightId; + F32 bestDot = -1; + + // Find the left-wards match + for(S32 i = 0; i < 3; i++) + { + F32 d = leftVec.dot(shipDirs[i]); + if(d >= bestDot) + { + bestDot = d; + bestId = i; + } + } + + leftId = bestId; + Point leftPt = mMoveState[RenderState].pos + shipDirs[bestId]; + + // Find the right-wards match + bestId = -1; + bestDot = -1; + + for(S32 i = 0; i < 3; i++) + { + F32 d = rightVec.dot(shipDirs[i]); + if(d >= bestDot) + { + bestDot = d; + bestId = i; + } + } + + rightId = bestId; + Point rightPt = mMoveState[RenderState].pos + shipDirs[bestId]; + + // Stitch things up if we must... + if(leftId == mLastTrailPoint[0] && rightId == mLastTrailPoint[1]) + { + mTrail[0].update(leftPt, boostActive, cloakActive); + mTrail[1].update(rightPt, boostActive, cloakActive); + mLastTrailPoint[0] = leftId; + mLastTrailPoint[1] = rightId; + } + else if(leftId == mLastTrailPoint[1] && rightId == mLastTrailPoint[0]) + { + mTrail[1].update(leftPt, boostActive, cloakActive); + mTrail[0].update(rightPt, boostActive, cloakActive); + mLastTrailPoint[1] = leftId; + mLastTrailPoint[0] = rightId; + } + else + { + mTrail[0].update(leftPt, boostActive, cloakActive); + mTrail[1].update(rightPt, boostActive, cloakActive); + mLastTrailPoint[0] = leftId; + mLastTrailPoint[1] = rightId; + } + + if(isCloakActive()) + return; + + // Finally, do some particles + Point velDir(mCurrentMove.right - mCurrentMove.left, mCurrentMove.down - mCurrentMove.up); + F32 len = velDir.len(); + + if(len > 0) + { + if(len > 1) + velDir *= 1 / len; + + Point shipDirs[4]; + shipDirs[0].set(cos(mMoveState[RenderState].angle), sin(mMoveState[RenderState].angle) ); + shipDirs[1].set(-shipDirs[0]); + shipDirs[2].set(shipDirs[0].y, -shipDirs[0].x); + shipDirs[3].set(-shipDirs[0].y, shipDirs[0].x); + + for(U32 i = 0; i < 4; i++) + { + F32 th = shipDirs[i].dot(velDir); + + if(th > 0.1) + { + // shoot some sparks... + if(th >= 0.2*velDir.len()) + { + Point chaos(TNL::Random::readF(),TNL::Random::readF()); + chaos *= 5; + + //interp give us some nice enginey colors... + Color dim(1, 0, 0); + Color light(1, 1, boostActive ? 1.f : 0.f); + Color thrust; + + F32 t = TNL::Random::readF(); + thrust.interp(t, dim, light); + + FXManager::emitSpark(mMoveState[RenderState].pos - shipDirs[i] * 13, + -shipDirs[i] * 100 + chaos, thrust, 1.5 * Random::readF()); + } + } + } + } +} + +void Ship::render() +{ + if(hasExploded) + return; + + GameType *g = gClientGame->getGameType(); + Color color; + if(g) + color = g->getShipColor(this); + + F32 alpha = 1.0; + if(isCloakActive()) + alpha = 1 - mCloakTimer.getFraction(); + else + alpha = mCloakTimer.getFraction(); + + Point velDir(mCurrentMove.right - mCurrentMove.left, mCurrentMove.down - mCurrentMove.up); + F32 len = velDir.len(); + F32 thrusts[4]; + for(U32 i = 0; i < 4; i++) + thrusts[i] = 0; + + if(len > 0) + { + if(len > 1) + velDir *= 1 / len; + + Point shipDirs[4]; + shipDirs[0].set(cos(mMoveState[RenderState].angle), sin(mMoveState[RenderState].angle) ); + shipDirs[1].set(-shipDirs[0]); + shipDirs[2].set(shipDirs[0].y, -shipDirs[0].x); + shipDirs[3].set(-shipDirs[0].y, shipDirs[0].x); + + for(U32 i = 0; i < 4; i++) + thrusts[i] = shipDirs[i].dot(velDir); + } + + // Tweak side thrusters to show rotational force + F32 rotVel = getAngleDiff(mMoveState[LastProcessState].angle, mMoveState[RenderState].angle); + + if(rotVel > 0.001) + thrusts[2] += 0.25; + else if(rotVel < -0.001) + thrusts[3] += 0.25; + + if(isBoostActive()) + { + for(U32 i = 0; i < 4; i++) + thrusts[i] *= 1.3; + } + // an angle of 0 means the ship is heading down the +X axis + // since we draw the ship pointing up the Y axis, we should rotate + // by the ship's angle, - 90 degrees + glPushMatrix(); + glTranslatef(mMoveState[RenderState].pos.x, mMoveState[RenderState].pos.y, 0); + GameConnection *conn = gClientGame->getConnectionToServer(); + if(conn && conn->getControlObject() != this) + { + const char *string = mPlayerName.getString(); + glEnable(GL_BLEND); + F32 textAlpha = 0.5 * alpha; + F32 textSize = 14; +#ifdef TNL_OS_XBOX + textAlpha *= 1 - gClientGame->getCommanderZoomFraction(); + textSize = 23; +#else + glLineWidth(1); +#endif + glColor4f(1,1,1,textAlpha); + UserInterface::drawString( U32( UserInterface::getStringWidth(textSize, string) * -0.5), 30, textSize, string ); + glDisable(GL_BLEND); + glLineWidth(DefaultLineWidth); + } + else + { + if(alpha < 0.25) + alpha = 0.25; + } + F32 warpInScale = (WarpFadeInTime - mWarpInTimer.getCurrent()) / F32(WarpFadeInTime); + + F32 rotAmount = 0; + if(warpInScale < 0.8) + rotAmount = (0.8 - warpInScale) * 540; + + glRotatef(radiansToDegrees(mMoveState[RenderState].angle) - 90 + rotAmount, 0, 0, 1.0); + glScalef(warpInScale, warpInScale, 1); + renderShip(color, alpha, thrusts, mHealth, mRadius, isCloakActive(), isShieldActive()); + glColor3f(1,1,1); + if(isSensorActive()) + { + U32 delta = getGame()->getCurrentTime() - mSensorStartTime; + F32 radius = (delta & 0x1FF) * 0.002; + drawCircle(Point(), radius * Ship::CollisionRadius + 4); + } + glPopMatrix(); + + for(S32 i = 0; i < mMountedItems.size(); i++) + if(mMountedItems[i].isValid()) + mMountedItems[i]->renderItem(mMoveState[RenderState].pos); + + if(isRepairActive()) + { + glLineWidth(3); + glColor3f(1,0,0); + // render repair rays to all the repairing objects + Point pos = mMoveState[RenderState].pos; + + for(S32 i = 0; i < mRepairTargets.size(); i++) + { + if(mRepairTargets[i].getPointer() == this) + drawCircle(pos, RepairDisplayRadius); + else if(mRepairTargets[i]) + { + glBegin(GL_LINES); + glVertex2f(pos.x, pos.y); + Point shipPos = mRepairTargets[i]->getRenderPos(); + glVertex2f(shipPos.x, shipPos.y); + glEnd(); + } + } + glLineWidth(DefaultLineWidth); + } +} + +}; diff --git a/tnl-1.5.0/tnl/zap/ship.h b/tnl-1.5.0/tnl/zap/ship.h new file mode 100644 index 0000000000000000000000000000000000000000..9a05d5da68f8355dcdf7295b945545ede1355fc9 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/ship.h @@ -0,0 +1,188 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _SHIP_H_ +#define _SHIP_H_ + +#include "moveObject.h" +#include "sparkManager.h" +#include "sfx.h" +#include "timer.h" +#include "shipItems.h" + +namespace Zap +{ + +class Item; + +class Ship : public MoveObject +{ + typedef MoveObject Parent; +public: + enum { + MaxVelocity = 450, // points per second + Acceleration = 2500, // points per second per second + BoostMaxVelocity = 700, // points per second + BoostAcceleration = 5000, // points per second per second + + RepairRadius = 65, + RepairDisplayRadius = 18, + CollisionRadius = 24, + VisibilityRadius = 30, + KillDeleteDelay = 1500, + ExplosionFadeTime = 300, + MaxControlObjectInterpDistance = 200, + TrailCount = 2, + EnergyMax = 100000, + EnergyRechargeRate = 6000, // How many percent/second + EnergyBoostDrain = 15000, + EnergyShieldDrain = 27000, + EnergyRepairDrain = 15000, + EnergySensorDrain = 8000, + EnergyCloakDrain = 8000, + EnergyEngineerCost = 75000, + EnergyShieldHitDrain = 20000, + EnergyCooldownThreshold = 15000, + WeaponFireDecloakTime = 350, + ShipModuleCount = 2, + ShipWeaponCount = 3, + SensorZoomTime = 300, + CloakFadeTime = 300, + CloakCheckRadius = 200, + RepairHundredthsPerSecond = 16, + MaxEngineerDistance = 100, + WarpFadeInTime = 500, + }; + + enum MaskBits { + InitialMask = BIT(0), + PositionMask = BIT(1), + MoveMask = BIT(2), + WarpPositionMask = BIT(3), + ExplosionMask = BIT(4), + HealthMask = BIT(5), + PowersMask = BIT(6), + LoadoutMask = BIT(7), + }; + + Timer mFireTimer; + Timer mWarpInTimer; + F32 mHealth; + S32 mEnergy; + StringTableEntry mPlayerName; + bool mCooldown; + U32 mSensorStartTime; + + U32 mModule[ShipModuleCount]; + bool mModuleActive[ModuleCount]; + SFXHandle mModuleSound[ModuleCount]; + + U32 mWeapon[ShipWeaponCount]; + U32 mActiveWeapon; + + void selectWeapon(); + void selectWeapon(U32 weaponIndex); + + Timer mSensorZoomTimer; + Timer mWeaponFireDecloakTimer; + Timer mCloakTimer; + + U32 mSparkElapsed; + S32 mLastTrailPoint[TrailCount]; + FXTrail mTrail[TrailCount]; + + F32 mass; // mass of ship + bool hasExploded; + + Vector > mMountedItems; + Vector > mRepairTargets; + + void render(); + Ship(StringTableEntry playerName="", S32 team = -1, Point p = Point(0,0), F32 m = 1.0); + + F32 getHealth() { return mHealth; } + + void onGhostRemove(); + + bool isShieldActive() { return mModuleActive[ModuleShield]; } + bool isBoostActive() { return mModuleActive[ModuleBoost]; } + bool isCloakActive() { return mModuleActive[ModuleCloak]; } + bool isSensorActive() { return mModuleActive[ModuleSensor]; } + bool isRepairActive() { return mModuleActive[ModuleRepair]; } + bool isEngineerActive() { return mModuleActive[ModuleEngineer]; } + bool engineerBuildObject() + { + if(mEnergy < EnergyEngineerCost) + return false; + mEnergy -= EnergyEngineerCost; + return true; + } + + bool hasEngineeringModule() { return mModule[0] == ModuleEngineer || + mModule[1] == ModuleEngineer; } + + bool isDestroyed() { return hasExploded; } + bool areItemsMounted() { return mMountedItems.size() != 0; } + bool carryingResource(); + Item *unmountResource(); + + F32 getSensorZoomFraction() { return mSensorZoomTimer.getFraction(); } + Point getAimVector(); + + void setLoadout(U32 module1, U32 module2, U32 weapon1, U32 weapon2, U32 weapon3); + void idle(IdleCallPath path); + + void processMove(U32 stateIndex); + void processWeaponFire(); + void processEnergy(); + void updateModuleSounds(); + void emitMovementSparks(); + bool findRepairTargets(); + void repairTargets(); + + void controlMoveReplayComplete(); + + void emitShipExplosion(Point pos); + void setActualPos(Point p); + + virtual void damageObject(DamageInfo *theInfo); + void kill(DamageInfo *theInfo); + void kill(); + + void writeControlState(BitStream *stream); + void readControlState(BitStream *stream); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + void processArguments(S32 argc, const char **argv); + + TNL_DECLARE_CLASS(Ship); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/shipItems.h b/tnl-1.5.0/tnl/zap/shipItems.h new file mode 100644 index 0000000000000000000000000000000000000000..c02b3e214842f160bdc07330d09e5eeb7ca2f61a --- /dev/null +++ b/tnl-1.5.0/tnl/zap/shipItems.h @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _SHIPITEMS_H_ +#define _SHIPITEMS_H_ + +namespace Zap +{ + +enum ShipModule +{ + ModuleShield, + ModuleBoost, + ModuleSensor, + ModuleRepair, + ModuleEngineer, + ModuleCloak, + ModuleCount, +}; + + +enum EngineerBuildObjects +{ + EngineeredTurret, + EngineeredForceField, +}; + +}; +#endif + diff --git a/tnl-1.5.0/tnl/zap/soccerGame.cpp b/tnl-1.5.0/tnl/zap/soccerGame.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c49a385f504d410d3521c7a4a71fe9c545151d67 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/soccerGame.cpp @@ -0,0 +1,208 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "soccerGame.h" +#include "glutInclude.h" +#include "UIGame.h" +#include "sfx.h" +#include "gameNetInterface.h" +#include "ship.h" +#include "gameObjectRender.h" +#include "goalZone.h" + +namespace Zap +{ + +class Ship; +class SoccerBallItem; + +TNL_IMPLEMENT_NETOBJECT(SoccerGameType); + +TNL_IMPLEMENT_NETOBJECT_RPC(SoccerGameType, s2cSoccerScoreMessage, + (U32 msgIndex, StringTableEntry clientName, U32 teamIndex), (msgIndex, clientName, teamIndex), + NetClassGroupGameMask, RPCGuaranteedOrdered, RPCToGhost, 0) +{ + if(msgIndex == SoccerMsgScoreGoal) + { + SFXObject::play(SFXFlagCapture); + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "%s scored a goal on team %s!", + clientName.getString(), + mTeams[teamIndex].name.getString()); + } + else if(msgIndex == SoccerMsgScoreOwnGoal) + { + SFXObject::play(SFXFlagCapture); + if(clientName.isNull()) + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "A goal was scored on team %s!", + mTeams[teamIndex].name.getString()); + else + gGameUserInterface.displayMessage(Color(0.6f, 1.0f, 0.8f), + "%s scored a goal for the other team%s!", + clientName.getString(), + mTeams.size() > 2 ? "s" : ""); + } +} + +void SoccerGameType::addZone(GoalZone *theZone) +{ + mGoals.push_back(theZone); +} + +void SoccerGameType::setBall(SoccerBallItem *theBall) +{ + mBall = theBall; +} + +void SoccerGameType::scoreGoal(StringTableEntry playerName, U32 goalTeamIndex) +{ + ClientRef *cl = findClientRef(playerName); + S32 scoringTeam = -1; + if(cl) + scoringTeam = cl->teamId; + + if(scoringTeam == -1 || scoringTeam == goalTeamIndex) + { + // give all the other teams a point. + for(S32 i = 0; i < mTeams.size(); i++) + { + if(i != goalTeamIndex) + setTeamScore(i, mTeams[i].score + 1); + } + s2cSoccerScoreMessage(SoccerMsgScoreOwnGoal, playerName, goalTeamIndex); + } + else + { + cl->score += GoalScore; + setTeamScore(scoringTeam, mTeams[scoringTeam].score + 1); + s2cSoccerScoreMessage(SoccerMsgScoreGoal, playerName, goalTeamIndex); + } +} + +void SoccerGameType::renderInterfaceOverlay(bool scoreboardVisible) +{ + Parent::renderInterfaceOverlay(scoreboardVisible); + Ship *u = (Ship *) gClientGame->getConnectionToServer()->getControlObject(); + if(!u) + return; + + for(S32 i = 0; i < mGoals.size(); i++) + { + if(mGoals[i]->getTeam() != u->getTeam()) + renderObjectiveArrow(mGoals[i], getTeamColor(mGoals[i]->getTeam())); + } + if(mBall.isValid()) + renderObjectiveArrow(mBall, getTeamColor(-1)); +} + +TNL_IMPLEMENT_NETOBJECT(SoccerBallItem); + +SoccerBallItem::SoccerBallItem(Point pos) : Item(pos, true, 30, 4) +{ + mObjectTypeMask |= CommandMapVisType | TurretTargetType; + mNetFlags.set(Ghostable); + initialPos = pos; +} + +void SoccerBallItem::processArguments(S32 argc, const char **argv) +{ + Parent::processArguments(argc, argv); + initialPos = mMoveState[ActualState].pos; +} + +void SoccerBallItem::onAddedToGame(Game *theGame) +{ + if(!isGhost()) + theGame->getGameType()->addItemOfInterest(this); + ((SoccerGameType *) theGame->getGameType())->setBall(this); +} + +void SoccerBallItem::renderItem(Point pos) +{ + glColor3f(1, 1, 1); + drawCircle(pos, mRadius); +} + +void SoccerBallItem::idle(GameObject::IdleCallPath path) +{ + if(mSendHomeTimer.update(mCurrentMove.time)) + sendHome(); + else if(mSendHomeTimer.getCurrent()) + { + F32 accelFraction = 1 - (0.98 * mCurrentMove.time * 0.001f); + + mMoveState[ActualState].vel *= accelFraction; + mMoveState[RenderState].vel *= accelFraction; + } + Parent::idle(path); +} + +void SoccerBallItem::damageObject(DamageInfo *theInfo) +{ + // compute impulse direction + Point dv = theInfo->impulseVector - mMoveState[ActualState].vel; + Point iv = mMoveState[ActualState].pos - theInfo->collisionPoint; + iv.normalize(); + mMoveState[ActualState].vel += iv * dv.dot(iv) * 0.3; + if(theInfo->damagingObject && (theInfo->damagingObject->getObjectTypeMask() & ShipType)) + { + lastPlayerTouch = ((Ship *) theInfo->damagingObject)->mPlayerName; + } +} + +void SoccerBallItem::sendHome() +{ + mMoveState[ActualState].vel = mMoveState[RenderState].vel = Point(); + mMoveState[ActualState].pos = mMoveState[RenderState].pos = initialPos; + setMaskBits(PositionMask); + updateExtent(); +} + +bool SoccerBallItem::collide(GameObject *hitObject) +{ + if(isGhost()) + return true; + + if(hitObject->getObjectTypeMask() & ShipType) + { + lastPlayerTouch = ((Ship *) hitObject)->mPlayerName; + } + else + { + GoalZone *goal = dynamic_cast(hitObject); + + if(goal && !mSendHomeTimer.getCurrent()) + { + SoccerGameType *g = (SoccerGameType *) getGame()->getGameType(); + g->scoreGoal(lastPlayerTouch, goal->getTeam()); + mSendHomeTimer.reset(1500); + } + } + return true; +} + +}; diff --git a/tnl-1.5.0/tnl/zap/soccerGame.h b/tnl-1.5.0/tnl/zap/soccerGame.h new file mode 100644 index 0000000000000000000000000000000000000000..b6943d9d39d04ded74aa1a503971a93731944568 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/soccerGame.h @@ -0,0 +1,93 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _SOCCERGAME_H_ +#define _SOCCERGAME_H_ + +#include "gameType.h" +#include "item.h" + +namespace Zap +{ + +class Ship; +class SoccerBallItem; + +class SoccerGameType : public GameType +{ + typedef GameType Parent; + enum Scores + { + KillScore = 1, + GoalScore = 5, + }; + Vector mGoals; + SafePtr mBall; + +public: + void scoreGoal(StringTableEntry playerName, U32 goalTeamIndex); + void addZone(GoalZone *theZone); + void setBall(SoccerBallItem *theBall); + void renderInterfaceOverlay(bool scoreboardVisible); + + enum { + SoccerMsgScoreGoal, + SoccerMsgScoreOwnGoal, + SoccerMsgGameOverTeamWin, + SoccerMsgGameOverTie, + }; + const char *getGameTypeString() { return "Soccer"; } + virtual const char *getInstructionString() { return "Push the ball into the opposing team's goal."; } + + TNL_DECLARE_RPC(s2cSoccerScoreMessage, (U32 msgIndex, StringTableEntry clientName, U32 teamIndex)); + TNL_DECLARE_CLASS(SoccerGameType); +}; + +class SoccerBallItem : public Item +{ + typedef Item Parent; + Point initialPos; + Timer mSendHomeTimer; + StringTableEntry lastPlayerTouch; +public: + SoccerBallItem(Point pos = Point()); + void renderItem(Point pos); + void sendHome(); + void damageObject(DamageInfo *theInfo); + void idle(GameObject::IdleCallPath path); + void processArguments(S32 argc, const char **argv); + void onAddedToGame(Game *theGame); + + bool collide(GameObject *hitObject); + + TNL_DECLARE_CLASS(SoccerBallItem); +}; + +}; + + +#endif + diff --git a/tnl-1.5.0/tnl/zap/sparkManager.cpp b/tnl-1.5.0/tnl/zap/sparkManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01e3be814e3670aa062e29aacd8efafb46f5e9fd --- /dev/null +++ b/tnl-1.5.0/tnl/zap/sparkManager.cpp @@ -0,0 +1,340 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "sparkManager.h" +#include "glutInclude.h" +#include "teleporter.h" +#include "gameObjectRender.h" + +using namespace TNL; + +namespace Zap +{ + +namespace FXManager +{ + +struct Spark +{ + Point pos; + Color color; + F32 alpha; + F32 ttl; + Point vel; +}; + +enum { + MaxSparks = 8192, +}; + +U32 firstFreeIndex = 0; +U32 grabIndex = MaxSparks/2; +Spark gSparks[MaxSparks]; + +void emitSpark(Point pos, Point vel, Color color, F32 ttl) +{ + Spark *s; + + if(firstFreeIndex >= MaxSparks) + { + s = gSparks + grabIndex; + + // Bump an arbitrary amount ahead to avoid noticable artifacts. + grabIndex = (grabIndex + 100) % MaxSparks; + } + else + { + s = gSparks + firstFreeIndex; + firstFreeIndex++; + } + + s->pos = pos; + s->vel = vel; + s->color = color; + + if(!ttl) + s->ttl = 15 * Random::readF() * Random::readF(); + else + s->ttl = ttl; +} + +struct TeleporterEffect +{ + Point pos; + S32 time; + U32 type; + TeleporterEffect *nextEffect; +}; + +TeleporterEffect *teleporterEffects = NULL; + +void emitTeleportInEffect(Point pos, U32 type) +{ + TeleporterEffect *e = new TeleporterEffect; + e->pos = pos; + e->time = 0; + e->type = type; + e->nextEffect = teleporterEffects; + teleporterEffects = e; +} + +void tick( F32 dT ) +{ + for(U32 i = 0; i < firstFreeIndex; ) + { + Spark *theSpark = gSparks + i; + if(theSpark->ttl <= dT) + { + firstFreeIndex--; + *theSpark = gSparks[firstFreeIndex]; + } + else + { + theSpark->ttl -= dT; + theSpark->pos += theSpark->vel * dT; + if(theSpark->ttl > 1) + theSpark->alpha = 1; + else + theSpark->alpha = theSpark->ttl; + i++; + } + } + for(TeleporterEffect **walk = &teleporterEffects; *walk; ) + { + TeleporterEffect *temp = *walk; + temp->time += dT * 1000; + if(temp->time > Teleporter::TeleportInExpandTime) + { + *walk = temp->nextEffect; + delete temp; + } + else + walk = &(temp->nextEffect); + } +} + +void render(U32 renderPass) +{ + // the teleporter effects should render under the ships and such + if(renderPass == 0) + { + for(TeleporterEffect *walk = teleporterEffects; walk; walk = walk->nextEffect) + { + F32 radius = walk->time / F32(Teleporter::TeleportInExpandTime); + F32 alpha = 1.0; + if(radius > 0.5) + alpha = (1 - radius) / 0.5; + renderTeleporter(walk->pos, walk->type, false, Teleporter::TeleportInExpandTime - walk->time, radius, Teleporter::TeleportInRadius, alpha); + } + } + else if(renderPass == 1) + { + glPointSize( 2.0f ); + glEnable(GL_BLEND); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(Spark), &gSparks[0].pos); + glColorPointer(4, GL_FLOAT , sizeof(Spark), &gSparks[0].color); + + glDrawArrays(GL_POINTS, 0, firstFreeIndex); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); + } +} + +void emitExplosion(Point pos, F32 size, Color *colorArray, U32 numColors) +{ + for(U32 i = 0; i < (250.0 * size); i++) + { + + F32 th = Random::readF() * 2 * 3.14; + F32 f = (Random::readF() * 2 - 1) * 400 * size; + U32 colorIndex = Random::readI() % numColors; + + emitSpark(pos, Point(cos(th)*f, sin(th)*f), colorArray[colorIndex], Random::readF()*size + 2*size); + } +} + +void emitBurst(Point pos, Point scale, Color color1, Color color2) +{ + F32 size = 1; + + for(U32 i = 0; i < (250.0 * size); i++) + { + + F32 th = Random::readF() * 2 * 3.14; + F32 f = (Random::readF() * 0.1 + 0.9) * 200 * size; + F32 t = Random::readF(); + + Color r; + + r.interp(t, color1, color2); + + emitSpark( + pos + Point(cos(th)*scale.x, sin(th)*scale.y), + Point(cos(th)*scale.x*f, sin(th)*scale.y*f), + r, + Random::readF() * scale.len() * 3 + scale.len() + ); + } +} + +}; + +//----------------------------------------------------------------------------- + +FXTrail::FXTrail(U32 dropFrequency, U32 len) +{ + mDropFreq = dropFrequency; + mLength = len; + registerTrail(); +} + +FXTrail::~FXTrail() +{ + unregisterTrail(); +} + +void FXTrail::update(Point pos, bool boosted, bool invisible) +{ + if(mNodes.size() < mLength) + { + TrailNode t; + t.pos = pos; + t.ttl = mDropFreq; + t.boosted = boosted; + t.invisible = invisible; + + mNodes.push_front(t); + } + else + { + mNodes[0].pos = pos; + if(invisible) + mNodes[0].invisible = true; + else if(boosted) + mNodes[0].boosted = true; + } +} + +void FXTrail::tick(U32 dT) +{ + if(mNodes.size() == 0) + return; + + mNodes.last().ttl -= dT; + if(mNodes.last().ttl <= 0) + mNodes.pop_back(); +} + +void FXTrail::render() +{ + glBegin(GL_LINE_STRIP); + + for(S32 i=0; imNext = w->mNext; + } + else + { + mHead = w->mNext; + } + } + p = w; + w = w->mNext; + } +} + +void FXTrail::renderTrails() +{ + glEnable(GL_BLEND); + + FXTrail *w = mHead; + while(w) + { + w->render(); + w = w->mNext; + } + + glDisable(GL_BLEND); +} + +}; + diff --git a/tnl-1.5.0/tnl/zap/sparkManager.h b/tnl-1.5.0/tnl/zap/sparkManager.h new file mode 100644 index 0000000000000000000000000000000000000000..01cce0ad45d399629cdfca547800562101405f1a --- /dev/null +++ b/tnl-1.5.0/tnl/zap/sparkManager.h @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _FXMANAGER_H_ +#define _FXMANAGER_H_ + +#include "point.h" +#include "gameObject.h" + +namespace Zap +{ + +namespace FXManager +{ + void emitSpark(Point pos, Point vel, Color color, F32 ttl=0); + void emitExplosion(Point pos, F32 size, Color *colorArray, U32 numColors); + void emitBurst(Point pos, Point scale, Color color1, Color color2); + void emitTeleportInEffect(Point pos, U32 type); + void tick( F32 dT); + void render(U32 renderPass); +}; + +class FXTrail +{ +private: + struct TrailNode + { + Point pos; + S32 ttl; + bool boosted; + bool invisible; + }; + + Vector mNodes; + + U32 mDropFreq; + S32 mLength; + + FXTrail *mNext; + + + static FXTrail *mHead; + void registerTrail(); + void unregisterTrail(); + + +public: + FXTrail(U32 dropFrequency = 32, U32 len = 15); + ~FXTrail(); + + /// Update the point this trail is attached to. + void update(Point pos, bool boosted = false, bool invisible = false); + + void tick(U32 dT); + + void render(); + + void reset(); + + Point getLastPos(); + + static void renderTrails(); +}; + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/teleporter.cpp b/tnl-1.5.0/tnl/zap/teleporter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9b2be9a44c4041ba070c88466d1107f1dc206aa --- /dev/null +++ b/tnl-1.5.0/tnl/zap/teleporter.cpp @@ -0,0 +1,194 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "teleporter.h" +#include "glutInclude.h" + +using namespace TNL; +#include "ship.h" +#include "sparkManager.h" +#include "gameLoader.h" +#include "sfx.h" +#include "gameObjectRender.h" + +namespace Zap +{ + +TNL_IMPLEMENT_NETOBJECT(Teleporter); + +Teleporter::Teleporter(Point start, Point end) +{ + mNetFlags.set(Ghostable); + pos = start; + dest = end; + timeout = 0; + + Rect r(pos, pos); + r.expand(Point(TeleporterRadius, TeleporterRadius)); + setExtent(r); + mObjectTypeMask |= CommandMapVisType; + + mTime = 0; +} + +void Teleporter::onAddedToGame(Game *theGame) +{ + if(!isGhost()) + setScopeAlways(); +} + +void Teleporter::processArguments(S32 argc, const char **argv) +{ + if(argc != 4) + return; + + pos.read(argv); + pos *= getGame()->getGridSize(); + + dest.read(argv + 2); + dest *= getGame()->getGridSize(); + + Rect r(pos, pos); + r.expand(Point(TeleporterRadius, TeleporterRadius)); + setExtent(r); +} + +U32 Teleporter::packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream) +{ + bool isInitial = (updateMask & BIT(3)); + + if(stream->writeFlag(updateMask & InitMask)) + { + stream->write(pos.x); + stream->write(pos.y); + stream->write(dest.x); + stream->write(dest.y); + } + + stream->writeFlag((updateMask & TeleportMask) && !isInitial); + + return 0; +} + +void Teleporter::unpackUpdate(GhostConnection *connection, BitStream *stream) +{ + if(stream->readFlag()) + { + stream->read(&pos.x); + stream->read(&pos.y); + stream->read(&dest.x); + stream->read(&dest.y); + + Rect r(pos, pos); + r.expand(Point(TeleporterRadius, TeleporterRadius)); + setExtent(r); + } + if(stream->readFlag() && isGhost()) + { + FXManager::emitTeleportInEffect(dest, 0); + SFXObject::play(SFXTeleportIn, dest, Point()); + SFXObject::play(SFXTeleportOut, pos, Point()); + timeout = TeleporterDelay; + } +} + +static Vector fillVector2; + +void Teleporter::idle(GameObject::IdleCallPath path) +{ + U32 deltaT = mCurrentMove.time; + mTime += deltaT; + // Deal with our timeout... + if(timeout > deltaT) + { + timeout -= deltaT; + return; + } + else + timeout = 0; + + if(path != GameObject::ServerIdleMainLoop) + return; + + // Check for players within range + // if so, blast them to dest + Rect queryRect(pos, pos); + queryRect.expand(Point(TeleporterRadius, TeleporterRadius)); + + fillVector2.clear(); + findObjects(ShipType, fillVector2, queryRect); + + // First see if we're triggered... + bool isTriggered = false; + + for(S32 i=0; igetActualPos()).len() < TeleporterTriggerRadius) + { + isTriggered = true; + setMaskBits(TeleportMask); + timeout = TeleporterDelay; + } + } + + if(!isTriggered) + return; + + for(S32 i=0; igetRenderPos()).len() < TeleporterRadius + s->getRadius()) + { + Point newPos = s->getActualPos() - pos + dest; + s->setActualPos(newPos); + } + } +} + +inline Point polarToRect(Point p) +{ + F32 &r = p.x; + F32 &th = p.y; + + return Point( + cos(th) * r, + sin(th) * r + ); + +} + +void Teleporter::render() +{ + F32 r; + if(timeout > TeleporterExpandTime) + r = (timeout - TeleporterExpandTime) / F32(TeleporterDelay - TeleporterExpandTime); + else + r = F32(TeleporterExpandTime - timeout) / F32(TeleporterExpandTime); + renderTeleporter(pos, 0, true, mTime, r, TeleporterRadius, 1.0); +} + +}; diff --git a/tnl-1.5.0/tnl/zap/teleporter.h b/tnl-1.5.0/tnl/zap/teleporter.h new file mode 100644 index 0000000000000000000000000000000000000000..23541acf423d0e39be2f1fc54e45d4e77373a0cc --- /dev/null +++ b/tnl-1.5.0/tnl/zap/teleporter.h @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "point.h" +#include "gameConnection.h" +#include "gameObject.h" +#include "../tnl/tnlNetObject.h" + +namespace Zap +{ + +class Teleporter : public GameObject +{ +public: + Point pos; + Point dest; + bool doSplash; + U32 timeout; + U32 mTime; + + enum { + InitMask = BIT(0), + TeleportMask = BIT(1), + + TeleporterRadius = 75, + TeleporterTriggerRadius = 50, + TeleporterDelay = 1500, + TeleporterExpandTime = 1350, + TeleportInExpandTime = 750, + TeleportInRadius = 120, + }; + + Teleporter(Point center = Point(), Point exit = Point()); + + U32 packUpdate(GhostConnection *connection, U32 updateMask, BitStream *stream); + void unpackUpdate(GhostConnection *connection, BitStream *stream); + + void idle(GameObject::IdleCallPath path); + void render(); + + void onAddedToGame(Game *theGame); + + void processArguments(S32 argc, const char **argv); + + TNL_DECLARE_CLASS(Teleporter); +}; + +}; diff --git a/tnl-1.5.0/tnl/zap/timer.h b/tnl-1.5.0/tnl/zap/timer.h new file mode 100644 index 0000000000000000000000000000000000000000..295fb7871cd7cfe82b586c7e35b5c32a555b4e03 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/timer.h @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _TIMER_H_ +#define _TIMER_H_ + +#include "tnlTypes.h" +using namespace TNL; + +namespace Zap +{ + +class Timer +{ + U32 mPeriod; + U32 mCurrentCounter; +public: + Timer(U32 period = 0) + { + mCurrentCounter = mPeriod = period; + } + + bool update(U32 timeDelta) + { + if(!mCurrentCounter) + return false; + + if(timeDelta >= mCurrentCounter) + { + mCurrentCounter = 0; + return true; + } + mCurrentCounter -= timeDelta; + return false; + } + + U32 getCurrent() + { + return mCurrentCounter; + } + + F32 getFraction() + { + if(!mPeriod) + return 1; + return 1 - (mCurrentCounter / F32(mPeriod)); + } + + void reset() + { + mCurrentCounter = mPeriod; + } + + void reset(U32 newCounter, U32 newPeriod = 0) + { + if(!newPeriod) + newPeriod = newCounter; + mCurrentCounter = newCounter; + mPeriod = newPeriod; + } +}; + + +}; + +#endif diff --git a/tnl-1.5.0/tnl/zap/voiceCodec.cpp b/tnl-1.5.0/tnl/zap/voiceCodec.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a03e87f5e4a9330eac3fc20410de4244e5a1062 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/voiceCodec.cpp @@ -0,0 +1,205 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include "voiceCodec.h" +#include "lpc10.h" +#include "gsm.h" + +namespace Zap +{ + +ByteBufferPtr VoiceEncoder::compressBuffer(ByteBufferPtr sampleBuffer) +{ + U32 sampleCount = sampleBuffer->getBufferSize() >> 1; + U32 spf = getSamplesPerFrame(); + + U32 framesUsed = U32(sampleCount / spf); + if(framesUsed) + { + U32 samplesUsed = framesUsed * spf; + U32 maxSize = getMaxCompressedFrameSize() * framesUsed; + ByteBufferPtr ret = new ByteBuffer(maxSize); + + U8 *compressedPtr = ret->getBuffer(); + S16 *samplePtr = (S16 *) sampleBuffer->getBuffer(); + + U32 len = 0; + + for(U32 i = 0; i < samplesUsed; i += spf) + len += compressFrame(samplePtr + i, compressedPtr + len); + + ret->resize(len); + + U32 newSize = (sampleCount - samplesUsed) * sizeof(U16); + memcpy(samplePtr, samplePtr + samplesUsed, newSize); + + sampleBuffer->resize(newSize); + return ret; + } + return NULL; +} + +ByteBufferPtr VoiceDecoder::decompressBuffer(ByteBufferRef compressedBuffer) +{ + U32 spf = getSamplesPerFrame(); + U32 avgCompressedSize = getAvgCompressedFrameSize(); + U32 compressedSize = compressedBuffer.getBufferSize(); + + // guess the total number of frames: + U32 guessFrameCount = (compressedSize / avgCompressedSize) + 1; + + ByteBufferPtr ret = new ByteBuffer(spf * sizeof(S16) * guessFrameCount); + + U32 p = 0; + U8 *inputPtr = (U8 *) compressedBuffer.getBuffer(); + U32 frameCount = 0; + S16 *samplePtr = (S16 *) ret->getBuffer(); + + for(U32 i = 0; i < compressedSize; i += p) + { + if(frameCount == guessFrameCount) + { + guessFrameCount = frameCount + ( (compressedSize - i) / avgCompressedSize ) + 1; + ret->resize(spf * sizeof(S16) * guessFrameCount); + + samplePtr = (S16 *) ret->getBuffer(); + } + p = decompressFrame(samplePtr + frameCount * spf, inputPtr + i, compressedSize - i); + frameCount++; + } + ret->resize(frameCount * spf * sizeof(S16)); + return ret; +} + + +LPC10VoiceEncoder::LPC10VoiceEncoder() +{ + encoderState = create_lpc10_encoder_state(); + init_lpc10_encoder_state((lpc10_encoder_state *) encoderState); +} + +LPC10VoiceEncoder::~LPC10VoiceEncoder() +{ + destroy_lpc10_encoder_state((lpc10_encoder_state *) encoderState); +} + +U32 LPC10VoiceEncoder::getSamplesPerFrame() +{ + return LPC10_SAMPLES_PER_FRAME; +} + +U32 LPC10VoiceEncoder::getMaxCompressedFrameSize() +{ + return LPC10_ENCODED_FRAME_SIZE; +} + +U32 LPC10VoiceEncoder::compressFrame(S16 *samplePtr, U8 *outputPtr) +{ + return vbr_lpc10_encode(samplePtr, outputPtr, (lpc10_encoder_state *) encoderState); +} + +LPC10VoiceDecoder::LPC10VoiceDecoder() +{ + decoderState = create_lpc10_decoder_state(); + init_lpc10_decoder_state((lpc10_decoder_state *) decoderState); +} + +LPC10VoiceDecoder::~LPC10VoiceDecoder() +{ + destroy_lpc10_decoder_state((lpc10_decoder_state *) decoderState); +} + +U32 LPC10VoiceDecoder::getSamplesPerFrame() +{ + return LPC10_SAMPLES_PER_FRAME; +} + +U32 LPC10VoiceDecoder::getAvgCompressedFrameSize() +{ + return (LPC10_ENCODED_FRAME_SIZE + 1) >> 1; +} + +U32 LPC10VoiceDecoder::decompressFrame(S16 *framePtr, U8 *inputPtr, U32 inSize) +{ + int p; + vbr_lpc10_decode(inputPtr, inSize, framePtr, (lpc10_decoder_state *) decoderState, &p); + return (U32) p; +} + +GSMVoiceEncoder::GSMVoiceEncoder() +{ + encoderState = gsm_create(); +} + +GSMVoiceEncoder::~GSMVoiceEncoder() +{ + gsm_destroy((struct gsm_state *) encoderState); +} + +U32 GSMVoiceEncoder::getSamplesPerFrame() +{ + return GSM_SAMPLES_PER_FRAME; +} + +U32 GSMVoiceEncoder::getMaxCompressedFrameSize() +{ + return GSM_ENCODED_FRAME_SIZE; +} + +U32 GSMVoiceEncoder::compressFrame(S16 *samplePtr, U8 *outputPtr) +{ + return gsm_encode((struct gsm_state *) encoderState, samplePtr, outputPtr); +} + +GSMVoiceDecoder::GSMVoiceDecoder() +{ + decoderState = gsm_create(); +} + +GSMVoiceDecoder::~GSMVoiceDecoder() +{ + gsm_destroy((struct gsm_state *) decoderState); +} + +U32 GSMVoiceDecoder::getSamplesPerFrame() +{ + return GSM_SAMPLES_PER_FRAME; +} + +U32 GSMVoiceDecoder::getAvgCompressedFrameSize() +{ + return GSM_ENCODED_FRAME_SIZE; +} + +U32 GSMVoiceDecoder::decompressFrame(S16 *framePtr, U8 *inputPtr, U32 inSize) +{ + gsm_decode((struct gsm_state *) decoderState, inputPtr, framePtr); + return GSM_ENCODED_FRAME_SIZE; +} + + +}; + diff --git a/tnl-1.5.0/tnl/zap/voiceCodec.h b/tnl-1.5.0/tnl/zap/voiceCodec.h new file mode 100644 index 0000000000000000000000000000000000000000..930a4a0f9f3daafe9d5bc0a89955e52f352fb9c9 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/voiceCodec.h @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#ifndef _VOICECODEC_H_ +#define _VOICECODEC_H_ + +#ifndef _TNL_BYTEBUFFER_H_ +#include "tnlByteBuffer.h" +#endif + +using namespace TNL; + +namespace Zap +{ + +/// The VoiceEncoder class is an abstract base class for the various +/// voice compression algorithms supported by Zap - initially just the +/// HawkVoice variable bitrate LPC10 codec. It takes an arbitrary buffer +/// of 16 bit samples at 8KHz and returns a compressed buffer. The +/// original buffer is modified to contain any samples that were not used +/// due to unfilled frame sizing. +class VoiceEncoder : public Object +{ + virtual U32 getSamplesPerFrame() = 0; + virtual U32 getMaxCompressedFrameSize() = 0; + virtual U32 compressFrame(S16 *samplePtr, U8 *outputPtr) = 0; +public: + ByteBufferPtr compressBuffer(ByteBufferPtr sampleBuffer); +}; + +/// The VoiceDecoder class is an abstract base class for the various +/// voice decompression algorithms supported by Zap - initially just the +/// HawkVoice variable bitrate LPC10 codec. It takes a buffer compressed +/// with the appropriate VoiceEncoder analogue and returns the decompressed +/// 16 bit sample buffer. +class VoiceDecoder : public Object +{ + virtual U32 getSamplesPerFrame() = 0; + virtual U32 getAvgCompressedFrameSize() = 0; + + virtual U32 decompressFrame(S16 *framePtr, U8 *inputPtr, U32 inSize) = 0; +public: + ByteBufferPtr decompressBuffer(ByteBufferRef compressedBuffer); +}; + +/// The LPC10VoiceEncoder class implements the HawkVoice LPC10 codec +/// compressor. +class LPC10VoiceEncoder : public VoiceEncoder +{ + void *encoderState; + U32 getSamplesPerFrame(); + U32 getMaxCompressedFrameSize(); + U32 compressFrame(S16 *samplePtr, U8 *outputPtr); +public: + LPC10VoiceEncoder(); + ~LPC10VoiceEncoder(); +}; + +/// The LPC10VoiceDecoder class implements the HawkVoice LPC10 codec +/// decompressor. +class LPC10VoiceDecoder : public VoiceDecoder +{ + void *decoderState; + U32 getSamplesPerFrame(); + U32 getAvgCompressedFrameSize(); + + U32 decompressFrame(S16 *framePtr, U8 *inputPtr, U32 inSize); +public: + LPC10VoiceDecoder(); + ~LPC10VoiceDecoder(); +}; + +/// The GSMVoiceEncoder class implements the HawkVoice GSM codec +/// compressor. +class GSMVoiceEncoder : public VoiceEncoder +{ + void *encoderState; + U32 getSamplesPerFrame(); + U32 getMaxCompressedFrameSize(); + U32 compressFrame(S16 *samplePtr, U8 *outputPtr); +public: + GSMVoiceEncoder(); + ~GSMVoiceEncoder(); +}; + +/// The GSMVoiceDecoder class implements the HawkVoice GSM codec +/// decompressor. +class GSMVoiceDecoder : public VoiceDecoder +{ + void *decoderState; + U32 getSamplesPerFrame(); + U32 getAvgCompressedFrameSize(); + + U32 decompressFrame(S16 *framePtr, U8 *inputPtr, U32 inSize); +public: + GSMVoiceDecoder(); + ~GSMVoiceDecoder(); +}; + +}; + +#endif + diff --git a/tnl-1.5.0/tnl/zap/winJoystick.cpp b/tnl-1.5.0/tnl/zap/winJoystick.cpp new file mode 100644 index 0000000000000000000000000000000000000000..08f9b23a5be2574e429012fe837fec759abb7206 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/winJoystick.cpp @@ -0,0 +1,222 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#define STRICT +#define DIRECTINPUT_VERSION 0x0800 +#include +#include + +#include "gameConnection.h" +#include "point.h" +#include "UI.h" +#include "input.h" + +namespace Zap +{ + +extern const char *gWindowTitle; + +void getModifierState( bool &shiftDown, bool &controlDown, bool &altDown ) +{ + shiftDown = ( GetKeyState( VK_SHIFT ) & 0xFF00 ) != 0; + controlDown = ( GetKeyState( VK_CONTROL ) & 0xFF00 ) != 0; + altDown = ( GetKeyState( VK_MENU ) & 0xFF00 ) != 0; +} + +void checkMousePos(S32 maxdx, S32 maxdy) +{ + char windowName[256]; + + HWND theWindow = GetForegroundWindow(); + GetWindowText(theWindow, windowName, sizeof(windowName)); + + if(strcmp(windowName, gWindowTitle)) + return; + + RECT r; + + GetWindowRect(theWindow, &r); + POINT cp; + GetCursorPos(&cp); + + // Check our position in the window; if we're close to the top (within 32px) then ignore + // same if we're within 5px of the edges. That way we can avoid going crazy when + // people try to resize/drag the window. + if(cp.x - r.top < 32) return; + if(cp.y - r.left < 5) return; + if(r.right - cp.y < 5) return; + if(r.bottom - cp.x < 5) return; + + S32 centerX = (r.right + r.left) >> 1; + S32 centerY = (r.bottom + r.top) >> 1; + + cp.x -= centerX; + cp.y -= centerY; + + if(cp.x > maxdx) + cp.x = maxdx; + if(cp.y > maxdy) + cp.y = maxdy; + if(cp.x < -maxdx) + cp.x = -maxdx; + if(cp.y < -maxdy) + cp.y = -maxdy; + + SetCursorPos(int(centerX + cp.x), int(centerY + cp.y)); +} + +BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext ); + +LPDIRECTINPUT8 gDirectInput = NULL; +LPDIRECTINPUTDEVICE8 gJoystick = NULL; +char gJoystickName[MAX_PATH] = ""; + +void InitJoystick() +{ + if(FAILED(DirectInput8Create ( GetModuleHandle(NULL), DIRECTINPUT_VERSION, + IID_IDirectInput8, (VOID**)&gDirectInput, NULL ) ) ) + return; + + if(FAILED(gDirectInput->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, + NULL, DIEDFL_ATTACHEDONLY ) ) ) + return; + + if(!gJoystick) + return; + + if( FAILED(gJoystick->SetDataFormat( &c_dfDIJoystick2 ) ) ) + return; +} + +const char *GetJoystickName() +{ + return gJoystickName; +} + +BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, + VOID* pContext ) +{ + // Obtain an interface to the enumerated joystick. + if(FAILED(gDirectInput->CreateDevice( pdidInstance->guidInstance, &gJoystick, NULL ))) + return DIENUM_CONTINUE; + strcpy(gJoystickName, pdidInstance->tszProductName); + logprintf("Joystick found: %s", gJoystickName); + return DIENUM_STOP; +} + + +bool ReadJoystick(F32 axes[MaxJoystickAxes], U32 &buttonMask, U32 &hatMask) +{ + // mark: it's ok + // mark: it's called "winJoystick" + // mark: it's supposed to be gross. + + DIJOYSTATE2 js; // DInput joystick state + + if(!gJoystick) + return false; + + if(FAILED(gJoystick->Poll() ) ) + { + HRESULT hr; + hr = gJoystick->Acquire(); + + while( hr == DIERR_INPUTLOST ) + hr = gJoystick->Acquire(); + return false; + } + + // Get the input's device state + if(FAILED(gJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js ) ) ) + return false; // The device should have been acquired during the Poll() + + F32 scale = 1 / 32768.0f; + axes[0] = (F32(js.lX) - 32768.0f) * scale; + axes[1] = (F32(js.lY) - 32768.0f) * scale; + axes[2] = (F32(js.lZ) - 32768.0f) * scale; + axes[3] = (F32(js.lRx) - 32768.0f) * scale; + axes[4] = (F32(js.lRy) - 32768.0f) * scale; + axes[5] = (F32(js.lRz) - 32768.0f) * scale; + axes[6] = (F32(js.rglSlider[0]) - 32768.0f) * scale; + axes[7] = (F32(js.rglSlider[1]) - 32768.0f) * scale; + axes[8] = 0; + axes[9] = 0; + axes[10] = 0; + axes[11] = 0; + + // check the state of the buttons: + buttonMask = 0; + U32 pov = js.rgdwPOV[0]; + + for( U32 i = 0; i < 12; i++ ) + if((js.rgbButtons[i] & 0x80) != 0) + buttonMask |= BIT(i); + + switch(pov) + { + case 0: + hatMask |= ControllerButtonDPadUp; + break; + case 4500: + hatMask |= ControllerButtonDPadUp | ControllerButtonDPadRight; + break; + case 9000: + hatMask |= ControllerButtonDPadRight; + break; + case 13500: + hatMask |= ControllerButtonDPadRight | ControllerButtonDPadDown; + break; + case 18000: + hatMask |= ControllerButtonDPadDown; + break; + case 22500: + hatMask |= ControllerButtonDPadDown | ControllerButtonDPadLeft; + break; + case 27000: + hatMask |= ControllerButtonDPadLeft; + break; + case 31500: + hatMask |= ControllerButtonDPadLeft | ControllerButtonDPadUp; + break; + } + return true; +} + +void ShutdownJoystick() +{ + // Unacquire the device one last time just in case + // the app tried to exit while the device is still acquired. + if( gJoystick ) + gJoystick->Unacquire(); + + // Release any DirectInput objects. + if(gJoystick) + gJoystick->Release(); + if(gDirectInput) + gDirectInput->Release(); +} + +}; diff --git a/tnl-1.5.0/tnl/zap/winmain.cpp b/tnl-1.5.0/tnl/zap/winmain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6f650eafa7a5eaa06c8aa517061ac2d61a0e85c8 --- /dev/null +++ b/tnl-1.5.0/tnl/zap/winmain.cpp @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------------------- +// +// Torque Network Library - ZAP example multiplayer vector graphics space game +// Copyright (C) 2004 GarageGames.com, Inc. +// For more information see http://www.opentnl.org +// +// 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. +// +// For use in products that are not compatible with the terms of the GNU +// General Public License, alternative licensing options are available +// from GarageGames.com. +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//------------------------------------------------------------------------------------ + +#include + +extern int main(int argc, char **argv); + +int PASCAL WinMain (HINSTANCE theInstance, HINSTANCE, LPSTR cmdLine, int ) +{ + main(__argc, __argv); +} diff --git a/tnl-1.5.0/tnl/zap/zap_mac_icon.icns b/tnl-1.5.0/tnl/zap/zap_mac_icon.icns new file mode 100644 index 0000000000000000000000000000000000000000..e9f5b81db93bc337eebe65d89fce0597c761dbf1 Binary files /dev/null and b/tnl-1.5.0/tnl/zap/zap_mac_icon.icns differ diff --git a/tnl-1.5.0/tnl/zap/zap_win_icon.ico b/tnl-1.5.0/tnl/zap/zap_win_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..345b7722f243b0b3cdbc743e11048ba609c6ba23 Binary files /dev/null and b/tnl-1.5.0/tnl/zap/zap_win_icon.ico differ