From 0d3da0f09166bba180b9491589dcaccdbe0adb0f Mon Sep 17 00:00:00 2001 From: Mark Frohnmayer Date: Fri, 5 Mar 2010 18:13:12 -0800 Subject: [PATCH] cleanup --- tnl-1.5.0/README | 1 - tnl-1.5.0/tnl/LICENSE.txt | 126 - tnl-1.5.0/tnl/Makefile | 19 - tnl-1.5.0/tnl/ReadMe.html | 115 - tnl-1.5.0/tnl/cwPrefixWin32.h | 11 - tnl-1.5.0/tnl/docs/Makefile | 26 - tnl-1.5.0/tnl/docs/doco.css | 382 - tnl-1.5.0/tnl/docs/docs.plaintext.txt | 519 - tnl-1.5.0/tnl/docs/doxygen.html.cfg | 216 - tnl-1.5.0/tnl/docs/footer.html | 10 - tnl-1.5.0/tnl/docs/header.html | 64 - tnl-1.5.0/tnl/docs/images/gglogo.png | Bin 21895 -> 0 bytes .../docs/images/layout_left_contributors.gif | Bin 1625 -> 0 bytes .../docs/images/layout_left_documentation.gif | Bin 1654 -> 0 bytes .../tnl/docs/images/layout_left_downloads.gif | Bin 1569 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_left_faq.gif | Bin 1381 -> 0 bytes .../tnl/docs/images/layout_left_forums.gif | Bin 1426 -> 0 bytes .../tnl/docs/images/layout_left_mailing.gif | Bin 1588 -> 0 bytes .../tnl/docs/images/layout_left_news.gif | Bin 1430 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_left_sf.gif | Bin 1655 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_left_tnl.gif | Bin 964 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_temp_03.png | Bin 3289 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_temp_05.png | Bin 11306 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_temp_14.png | Bin 5115 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif | Bin 4707 -> 0 bytes tnl-1.5.0/tnl/docs/images/layout_topbar.gif | Bin 16725 -> 0 bytes tnl-1.5.0/tnl/docs/images/opentnl.png | Bin 3139 -> 0 bytes tnl-1.5.0/tnl/docs/images/spacer.gif | Bin 43 -> 0 bytes tnl-1.5.0/tnl/docs/images/testshot.png | Bin 13599 -> 0 bytes tnl-1.5.0/tnl/docs/images/zapshot.png | Bin 12337 -> 0 bytes tnl-1.5.0/tnl/docs/tree_footer.html | 7 - tnl-1.5.0/tnl/docs/tree_header.html | 25 - tnl-1.5.0/tnl/exe/OpenAL32.dll | Bin 60416 -> 0 bytes tnl-1.5.0/tnl/exe/README.txt | 250 - tnl-1.5.0/tnl/exe/bot.sh | 17 - tnl-1.5.0/tnl/exe/build.sh | 69 - tnl-1.5.0/tnl/exe/glut32.dll | Bin 237568 -> 0 bytes tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe | Bin 231424 -> 0 bytes tnl-1.5.0/tnl/exe/installer/nsisconf.nsi | 27 - tnl-1.5.0/tnl/exe/installer/nsisdl.dll | Bin 12800 -> 0 bytes tnl-1.5.0/tnl/exe/installer/upx.exe | Bin 94208 -> 0 bytes tnl-1.5.0/tnl/exe/installer/zap.nsi | 82 - tnl-1.5.0/tnl/exe/levels/ctf1.txt | 70 - tnl-1.5.0/tnl/exe/levels/ctf2.txt | 62 - tnl-1.5.0/tnl/exe/levels/ctf3.txt | 148 - tnl-1.5.0/tnl/exe/levels/ctf4.txt | 95 - tnl-1.5.0/tnl/exe/levels/football1.txt | 71 - tnl-1.5.0/tnl/exe/levels/football2.txt | 107 - tnl-1.5.0/tnl/exe/levels/football3.txt | 124 - tnl-1.5.0/tnl/exe/levels/football4.txt | 124 - tnl-1.5.0/tnl/exe/levels/football5.txt | 116 - tnl-1.5.0/tnl/exe/levels/hunters1.txt | 45 - tnl-1.5.0/tnl/exe/levels/hunters2.txt | 80 - tnl-1.5.0/tnl/exe/levels/level9.txt | 108 - tnl-1.5.0/tnl/exe/levels/rabbit1.txt | 37 - tnl-1.5.0/tnl/exe/levels/rabbit2.txt | 30 - tnl-1.5.0/tnl/exe/levels/retrieve1.txt | 94 - tnl-1.5.0/tnl/exe/levels/retrieve2.txt | 113 - tnl-1.5.0/tnl/exe/levels/retrieve3.txt | 108 - tnl-1.5.0/tnl/exe/levels/soccer1.txt | 64 - tnl-1.5.0/tnl/exe/levels/soccer2.txt | 71 - tnl-1.5.0/tnl/exe/levels/zm1.txt | 33 - tnl-1.5.0/tnl/exe/master.cfg | 4 - tnl-1.5.0/tnl/exe/sfx/boop.wav | Bin 692 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/bounce.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/bounce_shield.wav | Bin 475 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/comm_down.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/comm_up.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/flag_capture.wav | Bin 13405 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/flag_drop.wav | Bin 13405 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/flag_return.wav | Bin 13405 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav | Bin 13405 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/forcefield_up.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/grenade.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/mine_arm.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/mine_explode.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/phaser.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav | Bin 43144 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_explode.wav | Bin 17284 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_heal.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_repair.wav | Bin 21594 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_sensor.wav | Bin 27628 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_shield.wav | Bin 19008 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/ship_turbo.wav | Bin 24180 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/teleport_in.wav | Bin 8234 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/teleport_out.wav | Bin 8233 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/triple.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/triple_impact.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/turret.wav | Bin 1768 -> 0 bytes tnl-1.5.0/tnl/exe/sfx/turret_impact.wav | Bin 3061 -> 0 bytes tnl-1.5.0/tnl/glut/glDedicated.h | 2126 --- tnl-1.5.0/tnl/glut/glut.h | 724 - tnl-1.5.0/tnl/glut/glut32.lib | Bin 28728 -> 0 bytes tnl-1.5.0/tnl/glut/glutInclude.h | 48 - tnl-1.5.0/tnl/libtomcrypt/aes.c | 595 - tnl-1.5.0/tnl/libtomcrypt/aes_tab.c | 977 -- tnl-1.5.0/tnl/libtomcrypt/authors | 55 - tnl-1.5.0/tnl/libtomcrypt/base64.c | 109 - tnl-1.5.0/tnl/libtomcrypt/bits.c | 199 - tnl-1.5.0/tnl/libtomcrypt/blowfish.c | 519 - tnl-1.5.0/tnl/libtomcrypt/cast5.c | 659 - tnl-1.5.0/tnl/libtomcrypt/cbc.c | 111 - tnl-1.5.0/tnl/libtomcrypt/cfb.c | 101 - tnl-1.5.0/tnl/libtomcrypt/crypt.c | 541 - tnl-1.5.0/tnl/libtomcrypt/crypt.pdf | Bin 456096 -> 0 bytes tnl-1.5.0/tnl/libtomcrypt/ctr.c | 83 - tnl-1.5.0/tnl/libtomcrypt/des.c | 1803 --- tnl-1.5.0/tnl/libtomcrypt/dh.c | 491 - tnl-1.5.0/tnl/libtomcrypt/dh_sys.c | 406 - tnl-1.5.0/tnl/libtomcrypt/dsa.c | 498 - tnl-1.5.0/tnl/libtomcrypt/ecb.c | 49 - tnl-1.5.0/tnl/libtomcrypt/ecc.c | 975 -- tnl-1.5.0/tnl/libtomcrypt/ecc_sys.c | 424 - tnl-1.5.0/tnl/libtomcrypt/gf.c | 295 - tnl-1.5.0/tnl/libtomcrypt/hash.c | 92 - tnl-1.5.0/tnl/libtomcrypt/hmac.c | 512 - tnl-1.5.0/tnl/libtomcrypt/keyring.c | 852 -- tnl-1.5.0/tnl/libtomcrypt/libtomcrypt.vcproj | 315 - tnl-1.5.0/tnl/libtomcrypt/makefile | 168 - tnl-1.5.0/tnl/libtomcrypt/md2.c | 204 - tnl-1.5.0/tnl/libtomcrypt/md4.c | 258 - tnl-1.5.0/tnl/libtomcrypt/md5.c | 247 - tnl-1.5.0/tnl/libtomcrypt/mem.c | 19 - tnl-1.5.0/tnl/libtomcrypt/mpi.c | 7942 ----------- tnl-1.5.0/tnl/libtomcrypt/mycrypt.h | 80 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_argchk.h | 24 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_cfg.h | 78 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_cipher.h | 376 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_custom.h | 91 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_gf.h | 32 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_hash.h | 293 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_kr.h | 81 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_macros.h | 241 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_misc.h | 17 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_pk.h | 198 - tnl-1.5.0/tnl/libtomcrypt/mycrypt_prng.h | 66 - tnl-1.5.0/tnl/libtomcrypt/noekeon.c | 280 - tnl-1.5.0/tnl/libtomcrypt/ofb.c | 67 - tnl-1.5.0/tnl/libtomcrypt/omac.c | 244 - tnl-1.5.0/tnl/libtomcrypt/packet.c | 41 - tnl-1.5.0/tnl/libtomcrypt/prime.c | 70 - tnl-1.5.0/tnl/libtomcrypt/rc2.c | 305 - tnl-1.5.0/tnl/libtomcrypt/rc4.c | 97 - tnl-1.5.0/tnl/libtomcrypt/rc5.c | 257 - tnl-1.5.0/tnl/libtomcrypt/rc6.c | 269 - tnl-1.5.0/tnl/libtomcrypt/rmd128.c | 353 - tnl-1.5.0/tnl/libtomcrypt/rmd160.c | 412 - tnl-1.5.0/tnl/libtomcrypt/rsa.c | 477 - tnl-1.5.0/tnl/libtomcrypt/rsa_sys.c | 262 - tnl-1.5.0/tnl/libtomcrypt/safer+.c | 499 - tnl-1.5.0/tnl/libtomcrypt/safer.c | 457 - tnl-1.5.0/tnl/libtomcrypt/safer_tab.c | 48 - tnl-1.5.0/tnl/libtomcrypt/sha1.c | 213 - tnl-1.5.0/tnl/libtomcrypt/sha224.c | 82 - tnl-1.5.0/tnl/libtomcrypt/sha256.c | 293 - tnl-1.5.0/tnl/libtomcrypt/sha384.c | 96 - tnl-1.5.0/tnl/libtomcrypt/sha512.c | 271 - tnl-1.5.0/tnl/libtomcrypt/skipjack.c | 279 - tnl-1.5.0/tnl/libtomcrypt/sprng.c | 42 - tnl-1.5.0/tnl/libtomcrypt/strings.c | 72 - tnl-1.5.0/tnl/libtomcrypt/tiger.c | 762 - tnl-1.5.0/tnl/libtomcrypt/tommath.h | 513 - tnl-1.5.0/tnl/libtomcrypt/twofish.c | 652 - tnl-1.5.0/tnl/libtomcrypt/twofish_tab.c | 477 - tnl-1.5.0/tnl/libtomcrypt/xtea.c | 158 - tnl-1.5.0/tnl/libtomcrypt/yarrow.c | 156 - tnl-1.5.0/tnl/master/Makefile | 27 - tnl-1.5.0/tnl/master/config.cpp | 209 - tnl-1.5.0/tnl/master/main.cpp | 647 - tnl-1.5.0/tnl/master/master.vcproj | 135 - tnl-1.5.0/tnl/master/masterInterface.cpp | 86 - tnl-1.5.0/tnl/master/masterInterface.h | 144 - tnl-1.5.0/tnl/masterclient/Makefile | 26 - tnl-1.5.0/tnl/masterclient/main.cpp | 456 - .../tnl/masterclient/masterclient.vcproj | 129 - tnl-1.5.0/tnl/openal/ALut.lib | Bin 4702 -> 0 bytes tnl-1.5.0/tnl/openal/OpenAL32.lib | Bin 16866 -> 0 bytes tnl-1.5.0/tnl/openal/al.h | 499 - tnl-1.5.0/tnl/openal/alInclude.h | 38 - tnl-1.5.0/tnl/openal/alc.h | 97 - tnl-1.5.0/tnl/openal/alctypes.h | 125 - tnl-1.5.0/tnl/openal/altypes.h | 332 - tnl-1.5.0/tnl/openal/alu.h | 41 - tnl-1.5.0/tnl/openal/alut.h | 31 - tnl-1.5.0/tnl/openal/linux/libopenal.a | Bin 1646150 -> 0 bytes .../tnl/osx/English.lproj/InfoPlist.strings | Bin 508 -> 0 bytes .../English.lproj/MainMenu.nib/classes.nib | 17 - .../osx/English.lproj/MainMenu.nib/info.nib | 22 - .../MainMenu.nib/keyedobjects.nib | Bin 11692 -> 0 bytes tnl-1.5.0/tnl/osx/Info.plist | 26 - tnl-1.5.0/tnl/osx/MyOpenGLView.h | 38 - tnl-1.5.0/tnl/osx/MyOpenGLView.mm | 166 - tnl-1.5.0/tnl/osx/main.mm | 32 - tnl-1.5.0/tnl/osx/tnl.xcode/project.pbxproj | 4879 ------- tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.mode1v3 | 1468 -- tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.pbxuser | 416 - .../tnl/osx/tnl.xcodeproj/project.pbxproj | 2081 --- tnl-1.5.0/tnl/osx/version.plist | 16 - tnl-1.5.0/tnl/test/Makefile | 34 - tnl-1.5.0/tnl/test/TNLTest.def | 9 - tnl-1.5.0/tnl/test/TNLTest.suo | Bin 9728 -> 0 bytes tnl-1.5.0/tnl/test/TNLTest.vcproj | 171 - tnl-1.5.0/tnl/test/client.cpp | 30 - tnl-1.5.0/tnl/test/fractal.suo | Bin 10240 -> 0 bytes tnl-1.5.0/tnl/test/mondrian.ico | Bin 766 -> 0 bytes tnl-1.5.0/tnl/test/server.cpp | 359 - tnl-1.5.0/tnl/test/server.vcproj | 126 - tnl-1.5.0/tnl/test/test.rc | 4 - tnl-1.5.0/tnl/test/test.suo | Bin 13312 -> 0 bytes tnl-1.5.0/tnl/test/testGame.cpp | 636 - tnl-1.5.0/tnl/test/testGame.h | 369 - tnl-1.5.0/tnl/test/testGameRender.cpp | 121 - tnl-1.5.0/tnl/test/testWindow.cpp | 182 - tnl-1.5.0/tnl/tnl.mcp | Bin 330982 -> 0 bytes tnl-1.5.0/tnl/tnl.sln | 134 - tnl-1.5.0/tnl/tnl/Makefile | 49 - tnl-1.5.0/tnl/tnl/assert.cpp | 85 - tnl-1.5.0/tnl/tnl/asymmetricKey.cpp | 200 - tnl-1.5.0/tnl/tnl/bitStream.cpp | 591 - tnl-1.5.0/tnl/tnl/byteBuffer.cpp | 154 - tnl-1.5.0/tnl/tnl/certificate.cpp | 86 - tnl-1.5.0/tnl/tnl/clientPuzzle.cpp | 179 - tnl-1.5.0/tnl/tnl/connectionStringTable.cpp | 152 - tnl-1.5.0/tnl/tnl/dataChunker.cpp | 83 - tnl-1.5.0/tnl/tnl/eventConnection.cpp | 494 - tnl-1.5.0/tnl/tnl/ghostConnection.cpp | 840 -- tnl-1.5.0/tnl/tnl/huffmanStringProcessor.cpp | 524 - tnl-1.5.0/tnl/tnl/journal.cpp | 330 - tnl-1.5.0/tnl/tnl/log.cpp | 110 - tnl-1.5.0/tnl/tnl/netBase.cpp | 173 - tnl-1.5.0/tnl/tnl/netConnection.cpp | 918 -- tnl-1.5.0/tnl/tnl/netInterface.cpp | 1312 -- tnl-1.5.0/tnl/tnl/netObject.cpp | 268 - tnl-1.5.0/tnl/tnl/netStringTable.cpp | 441 - tnl-1.5.0/tnl/tnl/platform.cpp | 488 - tnl-1.5.0/tnl/tnl/random.cpp | 109 - tnl-1.5.0/tnl/tnl/rpc.cpp | 57 - tnl-1.5.0/tnl/tnl/symmetricCipher.cpp | 103 - tnl-1.5.0/tnl/tnl/thread.cpp | 300 - tnl-1.5.0/tnl/tnl/tnl.changelog.txt | 28 - tnl-1.5.0/tnl/tnl/tnl.h | 54 - tnl-1.5.0/tnl/tnl/tnl.overview.txt | 539 - tnl-1.5.0/tnl/tnl/tnl.suo | Bin 7680 -> 0 bytes tnl-1.5.0/tnl/tnl/tnl.vcproj | 395 - tnl-1.5.0/tnl/tnl/tnlAssert.h | 92 - tnl-1.5.0/tnl/tnl/tnlAsymmetricKey.h | 130 - tnl-1.5.0/tnl/tnl/tnlBitSet.h | 110 - tnl-1.5.0/tnl/tnl/tnlBitStream.h | 405 - tnl-1.5.0/tnl/tnl/tnlByteBuffer.h | 208 - tnl-1.5.0/tnl/tnl/tnlCertificate.h | 112 - tnl-1.5.0/tnl/tnl/tnlClientPuzzle.h | 144 - tnl-1.5.0/tnl/tnl/tnlConnectionStringTable.h | 108 - tnl-1.5.0/tnl/tnl/tnlDataChunker.h | 136 - tnl-1.5.0/tnl/tnl/tnlEndian.h | 140 - tnl-1.5.0/tnl/tnl/tnlEventConnection.h | 158 - tnl-1.5.0/tnl/tnl/tnlGhostConnection.h | 331 - tnl-1.5.0/tnl/tnl/tnlHuffmanStringProcessor.h | 55 - tnl-1.5.0/tnl/tnl/tnlJournal.h | 189 - tnl-1.5.0/tnl/tnl/tnlLog.h | 134 - tnl-1.5.0/tnl/tnl/tnlMethodDispatch.cpp | 75 - tnl-1.5.0/tnl/tnl/tnlMethodDispatch.h | 319 - tnl-1.5.0/tnl/tnl/tnlNetBase.h | 657 - tnl-1.5.0/tnl/tnl/tnlNetConnection.h | 599 - tnl-1.5.0/tnl/tnl/tnlNetEvent.h | 281 - tnl-1.5.0/tnl/tnl/tnlNetInterface.h | 386 - tnl-1.5.0/tnl/tnl/tnlNetObject.h | 421 - tnl-1.5.0/tnl/tnl/tnlNetStringTable.h | 186 - tnl-1.5.0/tnl/tnl/tnlNonce.h | 63 - tnl-1.5.0/tnl/tnl/tnlPlatform.h | 128 - tnl-1.5.0/tnl/tnl/tnlRPC.h | 200 - tnl-1.5.0/tnl/tnl/tnlRandom.h | 67 - tnl-1.5.0/tnl/tnl/tnlString.h | 103 - tnl-1.5.0/tnl/tnl/tnlSymmetricCipher.h | 70 - tnl-1.5.0/tnl/tnl/tnlThread.h | 215 - tnl-1.5.0/tnl/tnl/tnlTypes.h | 448 - tnl-1.5.0/tnl/tnl/tnlUDP.h | 194 - tnl-1.5.0/tnl/tnl/tnlVector.h | 403 - tnl-1.5.0/tnl/tnl/udp.cpp | 796 -- tnl-1.5.0/tnl/tnl/vector.cpp | 55 - tnl-1.5.0/tnl/zap/CTFGame.cpp | 176 - tnl-1.5.0/tnl/zap/CTFGame.h | 66 - tnl-1.5.0/tnl/zap/HTFGame.cpp | 305 - tnl-1.5.0/tnl/zap/LoadoutZone.cpp | 140 - tnl-1.5.0/tnl/zap/Makefile | 91 - tnl-1.5.0/tnl/zap/SweptEllipsoid.cpp | 347 - tnl-1.5.0/tnl/zap/SweptEllipsoid.h | 43 - tnl-1.5.0/tnl/zap/UI.cpp | 208 - tnl-1.5.0/tnl/zap/UI.h | 81 - tnl-1.5.0/tnl/zap/UICredits.cpp | 181 - tnl-1.5.0/tnl/zap/UICredits.h | 111 - tnl-1.5.0/tnl/zap/UIEditor.cpp | 1247 -- tnl-1.5.0/tnl/zap/UIEditor.h | 140 - tnl-1.5.0/tnl/zap/UIGame.cpp | 834 -- tnl-1.5.0/tnl/zap/UIGame.h | 159 - tnl-1.5.0/tnl/zap/UIInstructions.cpp | 452 - tnl-1.5.0/tnl/zap/UIInstructions.h | 55 - tnl-1.5.0/tnl/zap/UIMenus.cpp | 548 - tnl-1.5.0/tnl/zap/UIMenus.h | 160 - tnl-1.5.0/tnl/zap/UINameEntry.cpp | 192 - tnl-1.5.0/tnl/zap/UINameEntry.h | 124 - tnl-1.5.0/tnl/zap/UIQueryServers.cpp | 590 - tnl-1.5.0/tnl/zap/UIQueryServers.h | 117 - tnl-1.5.0/tnl/zap/ZAP.rc | 72 - tnl-1.5.0/tnl/zap/ZAP.vcproj | 520 - tnl-1.5.0/tnl/zap/barrier.cpp | 258 - tnl-1.5.0/tnl/zap/barrier.h | 80 - tnl-1.5.0/tnl/zap/controlObjectConnection.cpp | 266 - tnl-1.5.0/tnl/zap/controlObjectConnection.h | 105 - tnl-1.5.0/tnl/zap/engineeredObjects.cpp | 711 - tnl-1.5.0/tnl/zap/engineeredObjects.h | 163 - tnl-1.5.0/tnl/zap/flagItem.cpp | 133 - tnl-1.5.0/tnl/zap/flagItem.h | 60 - tnl-1.5.0/tnl/zap/footballGame.cpp | 242 - tnl-1.5.0/tnl/zap/ftol.h | 35 - tnl-1.5.0/tnl/zap/game.cpp | 773 - tnl-1.5.0/tnl/zap/game.h | 241 - tnl-1.5.0/tnl/zap/gameConnection.cpp | 440 - tnl-1.5.0/tnl/zap/gameConnection.h | 131 - tnl-1.5.0/tnl/zap/gameItems.cpp | 190 - tnl-1.5.0/tnl/zap/gameLoader.cpp | 191 - tnl-1.5.0/tnl/zap/gameLoader.h | 44 - tnl-1.5.0/tnl/zap/gameNetInterface.cpp | 178 - tnl-1.5.0/tnl/zap/gameNetInterface.h | 69 - tnl-1.5.0/tnl/zap/gameObject.cpp | 378 - tnl-1.5.0/tnl/zap/gameObject.h | 191 - tnl-1.5.0/tnl/zap/gameObjectRender.cpp | 635 - tnl-1.5.0/tnl/zap/gameObjectRender.h | 58 - tnl-1.5.0/tnl/zap/gameType.cpp | 1073 -- tnl-1.5.0/tnl/zap/gameType.h | 241 - tnl-1.5.0/tnl/zap/gameWeapons.cpp | 85 - tnl-1.5.0/tnl/zap/gameWeapons.h | 120 - tnl-1.5.0/tnl/zap/goalZone.cpp | 161 - tnl-1.5.0/tnl/zap/goalZone.h | 74 - tnl-1.5.0/tnl/zap/gridDB.cpp | 265 - tnl-1.5.0/tnl/zap/gridDB.h | 71 - tnl-1.5.0/tnl/zap/gsm.h | 58 - tnl-1.5.0/tnl/zap/gsm_decode.c | 446 - tnl-1.5.0/tnl/zap/gsm_encode.c | 1113 -- tnl-1.5.0/tnl/zap/gsm_state.c | 71 - tnl-1.5.0/tnl/zap/huntersGame.cpp | 490 - tnl-1.5.0/tnl/zap/huntersGame.h | 146 - tnl-1.5.0/tnl/zap/input.cpp | 466 - tnl-1.5.0/tnl/zap/input.h | 79 - tnl-1.5.0/tnl/zap/item.cpp | 314 - tnl-1.5.0/tnl/zap/item.h | 111 - tnl-1.5.0/tnl/zap/linuxInput.cpp | 57 - tnl-1.5.0/tnl/zap/loadoutSelect.cpp | 209 - tnl-1.5.0/tnl/zap/loadoutSelect.h | 59 - tnl-1.5.0/tnl/zap/lpc10.h | 72 - tnl-1.5.0/tnl/zap/lpc10dec.c | 776 - tnl-1.5.0/tnl/zap/lpc10enc.c | 1476 -- tnl-1.5.0/tnl/zap/main.cpp | 751 - tnl-1.5.0/tnl/zap/masterConnection.cpp | 220 - tnl-1.5.0/tnl/zap/masterConnection.h | 73 - tnl-1.5.0/tnl/zap/move.h | 131 - tnl-1.5.0/tnl/zap/moveObject.cpp | 425 - tnl-1.5.0/tnl/zap/moveObject.h | 95 - tnl-1.5.0/tnl/zap/osxInput.cpp | 348 - tnl-1.5.0/tnl/zap/point.h | 177 - tnl-1.5.0/tnl/zap/private.h | 106 - tnl-1.5.0/tnl/zap/projectile.cpp | 504 - tnl-1.5.0/tnl/zap/projectile.h | 132 - tnl-1.5.0/tnl/zap/quickChat.cpp | 212 - tnl-1.5.0/tnl/zap/quickChat.h | 71 - tnl-1.5.0/tnl/zap/rabbitGame.cpp | 263 - tnl-1.5.0/tnl/zap/rabbitGame.h | 106 - tnl-1.5.0/tnl/zap/resource.h | 16 - tnl-1.5.0/tnl/zap/retrieveGame.cpp | 285 - tnl-1.5.0/tnl/zap/sfx.cpp | 954 -- tnl-1.5.0/tnl/zap/sfx.h | 162 - tnl-1.5.0/tnl/zap/ship.cpp | 1183 -- tnl-1.5.0/tnl/zap/ship.h | 188 - tnl-1.5.0/tnl/zap/shipItems.h | 53 - tnl-1.5.0/tnl/zap/soccerGame.cpp | 208 - tnl-1.5.0/tnl/zap/soccerGame.h | 93 - tnl-1.5.0/tnl/zap/sparkManager.cpp | 340 - tnl-1.5.0/tnl/zap/sparkManager.h | 90 - tnl-1.5.0/tnl/zap/teleporter.cpp | 194 - tnl-1.5.0/tnl/zap/teleporter.h | 71 - tnl-1.5.0/tnl/zap/timer.h | 89 - tnl-1.5.0/tnl/zap/voiceCodec.cpp | 205 - tnl-1.5.0/tnl/zap/voiceCodec.h | 126 - tnl-1.5.0/tnl/zap/winJoystick.cpp | 222 - tnl-1.5.0/tnl/zap/winmain.cpp | 34 - tnl-1.5.0/tnl/zap/zap_mac_icon.icns | Bin 33927 -> 0 bytes tnl-1.5.0/tnl/zap/zap_win_icon.ico | Bin 7406 -> 0 bytes tnl-_next/core/algorithm_templates.h | 96 - tnl-_next/core/array.h | 356 - tnl-_next/core/assert.h | 10 - tnl-_next/core/base_type_declarations.h | 93 - tnl-_next/core/base_type_io.h | 17 - tnl-_next/core/base_type_traits.h | 291 - tnl-_next/core/base_types.h | 2 - tnl-_next/core/bit_stream.h | 250 - tnl-_next/core/byte_stream_fixed.h | 53 - tnl-_next/core/construct.h | 54 - tnl-_next/core/core.h | 14 - tnl-_next/core/cpu_endian.h | 44 - tnl-_next/core/formatted_string_buffer.h | 111 - tnl-_next/core/memory_functions.h | 22 - tnl-_next/core/string.h | 91 - tnl-_next/core/time.h | 291 - tnl-_next/core/utils.h | 43 - tnl-_next/crypto/asymmetric_key.h | 245 - tnl-_next/crypto/certificate.h | 150 - tnl-_next/crypto/crypto.h | 8 - tnl-_next/crypto/random_generator.h | 63 - tnl-_next/crypto/symmetric_cipher.h | 101 - tnl-_next/libtomcrypt-1.17/Debug/BuildLog.htm | Bin 73034 -> 0 bytes tnl-_next/libtomcrypt-1.17/Debug/vc90.idb | Bin 691200 -> 0 bytes tnl-_next/libtomcrypt-1.17/Debug/vc90.pdb | Bin 118784 -> 0 bytes tnl-_next/libtomcrypt-1.17/Doxyfile | 1155 -- tnl-_next/libtomcrypt-1.17/LICENSE | 5 - tnl-_next/libtomcrypt-1.17/README | 3 - tnl-_next/libtomcrypt-1.17/TODO | 3 - tnl-_next/libtomcrypt-1.17/build.sh | 20 - tnl-_next/libtomcrypt-1.17/changes | 1571 -- tnl-_next/libtomcrypt-1.17/crypt.tex | 6568 --------- tnl-_next/libtomcrypt-1.17/demos/encrypt.c | 241 - tnl-_next/libtomcrypt-1.17/demos/hashsum.c | 119 - tnl-_next/libtomcrypt-1.17/demos/multi.c | 110 - tnl-_next/libtomcrypt-1.17/demos/small.c | 14 - tnl-_next/libtomcrypt-1.17/demos/test.c | 36 - tnl-_next/libtomcrypt-1.17/demos/timing.c | 42 - tnl-_next/libtomcrypt-1.17/demos/tv_gen.c | 786 - tnl-_next/libtomcrypt-1.17/doc/footer.html | 10 - tnl-_next/libtomcrypt-1.17/doc/header.html | 12 - tnl-_next/libtomcrypt-1.17/filter.pl | 30 - tnl-_next/libtomcrypt-1.17/fixupind.pl | 11 - tnl-_next/libtomcrypt-1.17/genlist.sh | 10 - tnl-_next/libtomcrypt-1.17/libtomcrypt.dsp | 1634 --- tnl-_next/libtomcrypt-1.17/libtomcrypt.vcproj | 7182 ---------- tnl-_next/libtomcrypt-1.17/makefile | 395 - tnl-_next/libtomcrypt-1.17/makefile.icc | 295 - tnl-_next/libtomcrypt-1.17/makefile.msvc | 152 - tnl-_next/libtomcrypt-1.17/makefile.shared | 282 - tnl-_next/libtomcrypt-1.17/makefile.unix | 242 - tnl-_next/libtomcrypt-1.17/mess.sh | 4 - .../libtomcrypt-1.17/notes/base64_tv.txt | 35 - tnl-_next/libtomcrypt-1.17/notes/ccm_tv.txt | 214 - .../libtomcrypt-1.17/notes/cipher_tv.txt | 1967 --- tnl-_next/libtomcrypt-1.17/notes/eax_tv.txt | 461 - tnl-_next/libtomcrypt-1.17/notes/ecc_tv.txt | 1261 -- .../notes/etc/saferp_optimizer.c | 177 - .../libtomcrypt-1.17/notes/etc/whirlgen.c | 95 - .../libtomcrypt-1.17/notes/etc/whirltest.c | 19 - tnl-_next/libtomcrypt-1.17/notes/gcm_tv.txt | 214 - tnl-_next/libtomcrypt-1.17/notes/hash_tv.txt | 1771 --- tnl-_next/libtomcrypt-1.17/notes/hmac_tv.txt | 1771 --- tnl-_next/libtomcrypt-1.17/notes/lrw_tv.txt | 126 - tnl-_next/libtomcrypt-1.17/notes/ocb_tv.txt | 461 - tnl-_next/libtomcrypt-1.17/notes/omac_tv.txt | 461 - tnl-_next/libtomcrypt-1.17/notes/pmac_tv.txt | 461 - tnl-_next/libtomcrypt-1.17/notes/tech0001.txt | 73 - tnl-_next/libtomcrypt-1.17/notes/tech0002.txt | 52 - tnl-_next/libtomcrypt-1.17/notes/tech0003.txt | 52 - tnl-_next/libtomcrypt-1.17/notes/tech0004.txt | 91 - tnl-_next/libtomcrypt-1.17/notes/tech0005.txt | 20 - tnl-_next/libtomcrypt-1.17/notes/tech0006.txt | 91 - tnl-_next/libtomcrypt-1.17/notes/tech0007.txt | 5 - tnl-_next/libtomcrypt-1.17/parsenames.pl | 26 - tnl-_next/libtomcrypt-1.17/run.sh | 35 - .../libtomcrypt-1.17/src/ciphers/aes/aes.c | 760 - .../src/ciphers/aes/aes_tab.c | 1028 -- .../libtomcrypt-1.17/src/ciphers/anubis.c | 1558 -- .../libtomcrypt-1.17/src/ciphers/blowfish.c | 594 - .../libtomcrypt-1.17/src/ciphers/cast5.c | 720 - tnl-_next/libtomcrypt-1.17/src/ciphers/des.c | 1902 --- .../libtomcrypt-1.17/src/ciphers/kasumi.c | 318 - .../libtomcrypt-1.17/src/ciphers/khazad.c | 855 -- .../libtomcrypt-1.17/src/ciphers/kseed.c | 376 - .../libtomcrypt-1.17/src/ciphers/multi2.c | 303 - .../libtomcrypt-1.17/src/ciphers/noekeon.c | 303 - tnl-_next/libtomcrypt-1.17/src/ciphers/rc2.c | 362 - tnl-_next/libtomcrypt-1.17/src/ciphers/rc5.c | 322 - tnl-_next/libtomcrypt-1.17/src/ciphers/rc6.c | 348 - .../src/ciphers/safer/safer.c | 491 - .../src/ciphers/safer/safer_tab.c | 68 - .../src/ciphers/safer/saferp.c | 559 - .../libtomcrypt-1.17/src/ciphers/skipjack.c | 343 - .../src/ciphers/twofish/twofish.c | 716 - .../src/ciphers/twofish/twofish_tab.c | 496 - tnl-_next/libtomcrypt-1.17/src/ciphers/xtea.c | 211 - .../src/encauth/ccm/ccm_memory.c | 351 - .../src/encauth/ccm/ccm_test.c | 180 - .../src/encauth/eax/eax_addheader.c | 38 - .../src/encauth/eax/eax_decrypt.c | 50 - .../encauth/eax/eax_decrypt_verify_memory.c | 108 - .../src/encauth/eax/eax_done.c | 94 - .../src/encauth/eax/eax_encrypt.c | 51 - .../eax/eax_encrypt_authenticate_memory.c | 82 - .../src/encauth/eax/eax_init.c | 144 - .../src/encauth/eax/eax_test.c | 282 - .../src/encauth/gcm/gcm_add_aad.c | 124 - .../src/encauth/gcm/gcm_add_iv.c | 94 - .../src/encauth/gcm/gcm_done.c | 83 - .../src/encauth/gcm/gcm_gf_mult.c | 221 - .../src/encauth/gcm/gcm_init.c | 107 - .../src/encauth/gcm/gcm_memory.c | 109 - .../src/encauth/gcm/gcm_mult_h.c | 58 - .../src/encauth/gcm/gcm_process.c | 152 - .../src/encauth/gcm/gcm_reset.c | 44 - .../src/encauth/gcm/gcm_test.c | 413 - .../src/encauth/ocb/ocb_decrypt.c | 79 - .../encauth/ocb/ocb_decrypt_verify_memory.c | 86 - .../src/encauth/ocb/ocb_done_decrypt.c | 80 - .../src/encauth/ocb/ocb_done_encrypt.c | 46 - .../src/encauth/ocb/ocb_encrypt.c | 72 - .../ocb/ocb_encrypt_authenticate_memory.c | 84 - .../src/encauth/ocb/ocb_init.c | 137 - .../src/encauth/ocb/ocb_ntz.c | 42 - .../src/encauth/ocb/ocb_shift_xor.c | 39 - .../src/encauth/ocb/ocb_test.c | 237 - .../src/encauth/ocb/s_ocb_done.c | 148 - .../libtomcrypt-1.17/src/hashes/chc/chc.c | 298 - .../src/hashes/helper/hash_file.c | 57 - .../src/hashes/helper/hash_filehandle.c | 71 - .../src/hashes/helper/hash_memory.c | 69 - .../src/hashes/helper/hash_memory_multi.c | 87 - tnl-_next/libtomcrypt-1.17/src/hashes/md2.c | 251 - tnl-_next/libtomcrypt-1.17/src/hashes/md4.c | 307 - tnl-_next/libtomcrypt-1.17/src/hashes/md5.c | 368 - .../libtomcrypt-1.17/src/hashes/rmd128.c | 410 - .../libtomcrypt-1.17/src/hashes/rmd160.c | 469 - .../libtomcrypt-1.17/src/hashes/rmd256.c | 431 - .../libtomcrypt-1.17/src/hashes/rmd320.c | 495 - tnl-_next/libtomcrypt-1.17/src/hashes/sha1.c | 288 - .../libtomcrypt-1.17/src/hashes/sha2/sha224.c | 125 - .../libtomcrypt-1.17/src/hashes/sha2/sha256.c | 340 - .../libtomcrypt-1.17/src/hashes/sha2/sha384.c | 135 - .../libtomcrypt-1.17/src/hashes/sha2/sha512.c | 319 - tnl-_next/libtomcrypt-1.17/src/hashes/tiger.c | 814 -- .../libtomcrypt-1.17/src/hashes/whirl/whirl.c | 314 - .../src/hashes/whirl/whirltab.c | 583 - .../libtomcrypt-1.17/src/headers/tomcrypt.h | 87 - .../src/headers/tomcrypt_argchk.h | 38 - .../src/headers/tomcrypt_cfg.h | 136 - .../src/headers/tomcrypt_cipher.h | 891 -- .../src/headers/tomcrypt_custom.h | 406 - .../src/headers/tomcrypt_hash.h | 379 - .../src/headers/tomcrypt_mac.h | 384 - .../src/headers/tomcrypt_macros.h | 424 - .../src/headers/tomcrypt_math.h | 500 - .../src/headers/tomcrypt_misc.h | 23 - .../src/headers/tomcrypt_pk.h | 552 - .../src/headers/tomcrypt_pkcs.h | 89 - .../src/headers/tomcrypt_prng.h | 199 - .../libtomcrypt-1.17/src/mac/f9/f9_done.c | 77 - .../libtomcrypt-1.17/src/mac/f9/f9_file.c | 83 - .../libtomcrypt-1.17/src/mac/f9/f9_init.c | 70 - .../libtomcrypt-1.17/src/mac/f9/f9_memory.c | 71 - .../src/mac/f9/f9_memory_multi.c | 90 - .../libtomcrypt-1.17/src/mac/f9/f9_process.c | 78 - .../libtomcrypt-1.17/src/mac/f9/f9_test.c | 78 - .../libtomcrypt-1.17/src/mac/hmac/hmac_done.c | 109 - .../libtomcrypt-1.17/src/mac/hmac/hmac_file.c | 93 - .../libtomcrypt-1.17/src/mac/hmac/hmac_init.c | 112 - .../src/mac/hmac/hmac_memory.c | 88 - .../src/mac/hmac/hmac_memory_multi.c | 92 - .../src/mac/hmac/hmac_process.c | 43 - .../libtomcrypt-1.17/src/mac/hmac/hmac_test.c | 316 - .../libtomcrypt-1.17/src/mac/omac/omac_done.c | 86 - .../libtomcrypt-1.17/src/mac/omac/omac_file.c | 83 - .../libtomcrypt-1.17/src/mac/omac/omac_init.c | 101 - .../src/mac/omac/omac_memory.c | 85 - .../src/mac/omac/omac_memory_multi.c | 90 - .../src/mac/omac/omac_process.c | 89 - .../libtomcrypt-1.17/src/mac/omac/omac_test.c | 110 - .../src/mac/pelican/pelican.c | 165 - .../src/mac/pelican/pelican_memory.c | 59 - .../src/mac/pelican/pelican_test.c | 120 - .../libtomcrypt-1.17/src/mac/pmac/pmac_done.c | 74 - .../libtomcrypt-1.17/src/mac/pmac/pmac_file.c | 84 - .../libtomcrypt-1.17/src/mac/pmac/pmac_init.c | 147 - .../src/mac/pmac/pmac_memory.c | 74 - .../src/mac/pmac/pmac_memory_multi.c | 89 - .../libtomcrypt-1.17/src/mac/pmac/pmac_ntz.c | 39 - .../src/mac/pmac/pmac_process.c | 100 - .../src/mac/pmac/pmac_shift_xor.c | 44 - .../libtomcrypt-1.17/src/mac/pmac/pmac_test.c | 165 - .../libtomcrypt-1.17/src/mac/xcbc/xcbc_done.c | 77 - .../libtomcrypt-1.17/src/mac/xcbc/xcbc_file.c | 83 - .../libtomcrypt-1.17/src/mac/xcbc/xcbc_init.c | 108 - .../src/mac/xcbc/xcbc_memory.c | 71 - .../src/mac/xcbc/xcbc_memory_multi.c | 90 - .../src/mac/xcbc/xcbc_process.c | 75 - .../libtomcrypt-1.17/src/mac/xcbc/xcbc_test.c | 128 - .../src/math/fp/ltc_ecc_fp_mulmod.c | 1587 -- .../libtomcrypt-1.17/src/math/gmp_desc.c | 478 - .../libtomcrypt-1.17/src/math/ltm_desc.c | 483 - tnl-_next/libtomcrypt-1.17/src/math/multi.c | 61 - .../libtomcrypt-1.17/src/math/rand_prime.c | 87 - .../libtomcrypt-1.17/src/math/tfm_desc.c | 777 - .../src/misc/base64/base64_decode.c | 104 - .../src/misc/base64/base64_encode.c | 81 - .../libtomcrypt-1.17/src/misc/burn_stack.c | 34 - .../libtomcrypt-1.17/src/misc/crypt/crypt.c | 373 - .../src/misc/crypt/crypt_argchk.c | 30 - .../src/misc/crypt/crypt_cipher_descriptor.c | 27 - .../src/misc/crypt/crypt_cipher_is_valid.c | 36 - .../src/misc/crypt/crypt_find_cipher.c | 41 - .../src/misc/crypt/crypt_find_cipher_any.c | 50 - .../src/misc/crypt/crypt_find_cipher_id.c | 40 - .../src/misc/crypt/crypt_find_hash.c | 40 - .../src/misc/crypt/crypt_find_hash_any.c | 49 - .../src/misc/crypt/crypt_find_hash_id.c | 40 - .../src/misc/crypt/crypt_find_hash_oid.c | 35 - .../src/misc/crypt/crypt_find_prng.c | 41 - .../src/misc/crypt/crypt_fsa.c | 59 - .../src/misc/crypt/crypt_hash_descriptor.c | 27 - .../src/misc/crypt/crypt_hash_is_valid.c | 36 - .../src/misc/crypt/crypt_ltc_mp_descriptor.c | 13 - .../src/misc/crypt/crypt_prng_descriptor.c | 26 - .../src/misc/crypt/crypt_prng_is_valid.c | 36 - .../src/misc/crypt/crypt_register_cipher.c | 54 - .../src/misc/crypt/crypt_register_hash.c | 54 - .../src/misc/crypt/crypt_register_prng.c | 54 - .../src/misc/crypt/crypt_unregister_cipher.c | 45 - .../src/misc/crypt/crypt_unregister_hash.c | 44 - .../src/misc/crypt/crypt_unregister_prng.c | 44 - .../src/misc/error_to_string.c | 74 - .../src/misc/pkcs5/pkcs_5_1.c | 106 - .../src/misc/pkcs5/pkcs_5_2.c | 129 - tnl-_next/libtomcrypt-1.17/src/misc/zeromem.c | 34 - .../src/modes/cbc/cbc_decrypt.c | 97 - .../libtomcrypt-1.17/src/modes/cbc/cbc_done.c | 42 - .../src/modes/cbc/cbc_encrypt.c | 98 - .../src/modes/cbc/cbc_getiv.c | 46 - .../src/modes/cbc/cbc_setiv.c | 44 - .../src/modes/cbc/cbc_start.c | 62 - .../src/modes/cfb/cfb_decrypt.c | 67 - .../libtomcrypt-1.17/src/modes/cfb/cfb_done.c | 42 - .../src/modes/cfb/cfb_encrypt.c | 65 - .../src/modes/cfb/cfb_getiv.c | 46 - .../src/modes/cfb/cfb_setiv.c | 52 - .../src/modes/cfb/cfb_start.c | 65 - .../src/modes/ctr/ctr_decrypt.c | 42 - .../libtomcrypt-1.17/src/modes/ctr/ctr_done.c | 42 - .../src/modes/ctr/ctr_encrypt.c | 112 - .../src/modes/ctr/ctr_getiv.c | 46 - .../src/modes/ctr/ctr_setiv.c | 56 - .../src/modes/ctr/ctr_start.c | 101 - .../libtomcrypt-1.17/src/modes/ctr/ctr_test.c | 85 - .../src/modes/ecb/ecb_decrypt.c | 61 - .../libtomcrypt-1.17/src/modes/ecb/ecb_done.c | 42 - .../src/modes/ecb/ecb_encrypt.c | 61 - .../src/modes/ecb/ecb_start.c | 48 - .../src/modes/f8/f8_decrypt.c | 43 - .../libtomcrypt-1.17/src/modes/f8/f8_done.c | 42 - .../src/modes/f8/f8_encrypt.c | 103 - .../libtomcrypt-1.17/src/modes/f8/f8_getiv.c | 46 - .../libtomcrypt-1.17/src/modes/f8/f8_setiv.c | 52 - .../libtomcrypt-1.17/src/modes/f8/f8_start.c | 98 - .../src/modes/f8/f8_test_mode.c | 76 - .../src/modes/lrw/lrw_decrypt.c | 51 - .../libtomcrypt-1.17/src/modes/lrw/lrw_done.c | 42 - .../src/modes/lrw/lrw_encrypt.c | 50 - .../src/modes/lrw/lrw_getiv.c | 45 - .../src/modes/lrw/lrw_process.c | 120 - .../src/modes/lrw/lrw_setiv.c | 79 - .../src/modes/lrw/lrw_start.c | 103 - .../libtomcrypt-1.17/src/modes/lrw/lrw_test.c | 136 - .../src/modes/ofb/ofb_decrypt.c | 43 - .../libtomcrypt-1.17/src/modes/ofb/ofb_done.c | 42 - .../src/modes/ofb/ofb_encrypt.c | 60 - .../src/modes/ofb/ofb_getiv.c | 46 - .../src/modes/ofb/ofb_setiv.c | 52 - .../src/modes/ofb/ofb_start.c | 60 - .../src/modes/xts/xts_decrypt.c | 141 - .../libtomcrypt-1.17/src/modes/xts/xts_done.c | 34 - .../src/modes/xts/xts_encrypt.c | 142 - .../libtomcrypt-1.17/src/modes/xts/xts_init.c | 69 - .../src/modes/xts/xts_mult_x.c | 42 - .../libtomcrypt-1.17/src/modes/xts/xts_test.c | 199 - .../pk/asn1/der/bit/der_decode_bit_string.c | 102 - .../pk/asn1/der/bit/der_encode_bit_string.c | 89 - .../pk/asn1/der/bit/der_length_bit_string.c | 54 - .../pk/asn1/der/boolean/der_decode_boolean.c | 47 - .../pk/asn1/der/boolean/der_encode_boolean.c | 51 - .../pk/asn1/der/boolean/der_length_boolean.c | 35 - .../pk/asn1/der/choice/der_decode_choice.c | 182 - .../pk/asn1/der/ia5/der_decode_ia5_string.c | 96 - .../pk/asn1/der/ia5/der_encode_ia5_string.c | 85 - .../pk/asn1/der/ia5/der_length_ia5_string.c | 194 - .../pk/asn1/der/integer/der_decode_integer.c | 110 - .../pk/asn1/der/integer/der_encode_integer.c | 130 - .../pk/asn1/der/integer/der_length_integer.c | 82 - .../der_decode_object_identifier.c | 99 - .../der_encode_object_identifier.c | 111 - .../der_length_object_identifier.c | 89 - .../asn1/der/octet/der_decode_octet_string.c | 91 - .../asn1/der/octet/der_encode_octet_string.c | 86 - .../asn1/der/octet/der_length_octet_string.c | 53 - .../der_decode_printable_string.c | 96 - .../der_encode_printable_string.c | 85 - .../der_length_printable_string.c | 166 - .../der/sequence/der_decode_sequence_ex.c | 287 - .../der/sequence/der_decode_sequence_flexi.c | 386 - .../der/sequence/der_decode_sequence_multi.c | 139 - .../der/sequence/der_encode_sequence_ex.c | 335 - .../der/sequence/der_encode_sequence_multi.c | 138 - .../asn1/der/sequence/der_length_sequence.c | 169 - .../pk/asn1/der/sequence/der_sequence_free.c | 65 - .../src/pk/asn1/der/set/der_encode_set.c | 103 - .../src/pk/asn1/der/set/der_encode_setof.c | 162 - .../short_integer/der_decode_short_integer.c | 68 - .../short_integer/der_encode_short_integer.c | 97 - .../short_integer/der_length_short_integer.c | 70 - .../pk/asn1/der/utctime/der_decode_utctime.c | 127 - .../pk/asn1/der/utctime/der_encode_utctime.c | 83 - .../pk/asn1/der/utctime/der_length_utctime.c | 46 - .../pk/asn1/der/utf8/der_decode_utf8_string.c | 111 - .../pk/asn1/der/utf8/der_encode_utf8_string.c | 105 - .../pk/asn1/der/utf8/der_length_utf8_string.c | 83 - .../src/pk/dsa/dsa_decrypt_key.c | 139 - .../src/pk/dsa/dsa_encrypt_key.c | 135 - .../libtomcrypt-1.17/src/pk/dsa/dsa_export.c | 72 - .../libtomcrypt-1.17/src/pk/dsa/dsa_free.c | 34 - .../libtomcrypt-1.17/src/pk/dsa/dsa_import.c | 90 - .../src/pk/dsa/dsa_make_key.c | 137 - .../src/pk/dsa/dsa_shared_secret.c | 72 - .../src/pk/dsa/dsa_sign_hash.c | 156 - .../src/pk/dsa/dsa_verify_hash.c | 126 - .../src/pk/dsa/dsa_verify_key.c | 100 - tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc.c | 127 - .../src/pk/ecc/ecc_ansi_x963_export.c | 72 - .../src/pk/ecc/ecc_ansi_x963_import.c | 104 - .../src/pk/ecc/ecc_decrypt_key.c | 150 - .../src/pk/ecc/ecc_encrypt_key.c | 136 - .../libtomcrypt-1.17/src/pk/ecc/ecc_export.c | 82 - .../libtomcrypt-1.17/src/pk/ecc/ecc_free.c | 40 - .../src/pk/ecc/ecc_get_size.c | 44 - .../libtomcrypt-1.17/src/pk/ecc/ecc_import.c | 172 - .../src/pk/ecc/ecc_make_key.c | 130 - .../src/pk/ecc/ecc_shared_secret.c | 95 - .../src/pk/ecc/ecc_sign_hash.c | 114 - .../libtomcrypt-1.17/src/pk/ecc/ecc_sizes.c | 48 - .../libtomcrypt-1.17/src/pk/ecc/ecc_test.c | 95 - .../src/pk/ecc/ecc_verify_hash.c | 165 - .../src/pk/ecc/ltc_ecc_is_valid_idx.c | 46 - .../libtomcrypt-1.17/src/pk/ecc/ltc_ecc_map.c | 76 - .../src/pk/ecc/ltc_ecc_mul2add.c | 207 - .../src/pk/ecc/ltc_ecc_mulmod.c | 222 - .../src/pk/ecc/ltc_ecc_mulmod_timing.c | 167 - .../src/pk/ecc/ltc_ecc_points.c | 60 - .../src/pk/ecc/ltc_ecc_projective_add_point.c | 196 - .../src/pk/ecc/ltc_ecc_projective_dbl_point.c | 147 - .../src/pk/katja/katja_decrypt_key.c | 105 - .../src/pk/katja/katja_encrypt_key.c | 87 - .../src/pk/katja/katja_export.c | 75 - .../src/pk/katja/katja_exptmod.c | 115 - .../src/pk/katja/katja_free.c | 35 - .../src/pk/katja/katja_import.c | 81 - .../src/pk/katja/katja_make_key.c | 101 - .../src/pk/pkcs1/pkcs_1_i2osp.c | 51 - .../src/pk/pkcs1/pkcs_1_mgf1.c | 108 - .../src/pk/pkcs1/pkcs_1_oaep_decode.c | 189 - .../src/pk/pkcs1/pkcs_1_oaep_encode.c | 173 - .../src/pk/pkcs1/pkcs_1_os2ip.c | 36 - .../src/pk/pkcs1/pkcs_1_pss_decode.c | 177 - .../src/pk/pkcs1/pkcs_1_pss_encode.c | 175 - .../src/pk/pkcs1/pkcs_1_v1_5_decode.c | 110 - .../src/pk/pkcs1/pkcs_1_v1_5_encode.c | 111 - .../src/pk/rsa/rsa_decrypt_key.c | 105 - .../src/pk/rsa/rsa_encrypt_key.c | 102 - .../libtomcrypt-1.17/src/pk/rsa/rsa_export.c | 69 - .../libtomcrypt-1.17/src/pk/rsa/rsa_exptmod.c | 113 - .../libtomcrypt-1.17/src/pk/rsa/rsa_free.c | 34 - .../libtomcrypt-1.17/src/pk/rsa/rsa_import.c | 143 - .../src/pk/rsa/rsa_make_key.c | 112 - .../src/pk/rsa/rsa_sign_hash.c | 134 - .../src/pk/rsa/rsa_verify_hash.c | 167 - .../libtomcrypt-1.17/src/prngs/fortuna.c | 427 - tnl-_next/libtomcrypt-1.17/src/prngs/rc4.c | 269 - .../src/prngs/rng_get_bytes.c | 148 - .../src/prngs/rng_make_prng.c | 69 - .../libtomcrypt-1.17/src/prngs/sober128.c | 500 - .../libtomcrypt-1.17/src/prngs/sober128tab.c | 162 - tnl-_next/libtomcrypt-1.17/src/prngs/sprng.c | 136 - tnl-_next/libtomcrypt-1.17/src/prngs/yarrow.c | 362 - tnl-_next/libtomcrypt-1.17/testbuild.sh | 11 - tnl-_next/libtomcrypt-1.17/testme.sh | 58 - .../libtomcrypt-1.17/testprof/base64_test.c | 24 - .../testprof/cipher_hash_test.c | 45 - .../libtomcrypt-1.17/testprof/der_tests.c | 853 -- .../libtomcrypt-1.17/testprof/dsa_test.c | 82 - .../libtomcrypt-1.17/testprof/ecc_test.c | 252 - .../libtomcrypt-1.17/testprof/katja_test.c | 231 - .../libtomcrypt-1.17/testprof/mac_test.c | 41 - tnl-_next/libtomcrypt-1.17/testprof/makefile | 24 - .../libtomcrypt-1.17/testprof/makefile.icc | 20 - .../libtomcrypt-1.17/testprof/makefile.msvc | 10 - .../libtomcrypt-1.17/testprof/makefile.shared | 24 - .../libtomcrypt-1.17/testprof/modes_test.c | 119 - .../libtomcrypt-1.17/testprof/pkcs_1_test.c | 93 - .../libtomcrypt-1.17/testprof/rsa_test.c | 387 - .../libtomcrypt-1.17/testprof/store_test.c | 78 - tnl-_next/libtomcrypt-1.17/testprof/test.der | Bin 162 -> 0 bytes tnl-_next/libtomcrypt-1.17/testprof/test.key | 15 - .../libtomcrypt-1.17/testprof/test_driver.c | 15 - .../libtomcrypt-1.17/testprof/tomcrypt_test.h | 83 - .../libtomcrypt-1.17/testprof/x86_prof.c | 1439 -- tnl-_next/libtomcrypt-1.17/updatemakes.sh | 21 - tnl-_next/libtommath-0.41/CVS/Entries | 150 - tnl-_next/libtommath-0.41/CVS/Repository | 1 - tnl-_next/libtommath-0.41/CVS/Root | 1 - tnl-_next/libtommath-0.41/LICENSE | 4 - tnl-_next/libtommath-0.41/bn.tex | 1835 --- tnl-_next/libtommath-0.41/bn_error.c | 47 - tnl-_next/libtommath-0.41/bn_fast_mp_invmod.c | 148 - .../bn_fast_mp_montgomery_reduce.c | 172 - .../libtommath-0.41/bn_fast_s_mp_mul_digs.c | 107 - .../bn_fast_s_mp_mul_high_digs.c | 98 - tnl-_next/libtommath-0.41/bn_fast_s_mp_sqr.c | 114 - tnl-_next/libtommath-0.41/bn_mp_2expt.c | 48 - tnl-_next/libtommath-0.41/bn_mp_abs.c | 43 - tnl-_next/libtommath-0.41/bn_mp_add.c | 53 - tnl-_next/libtommath-0.41/bn_mp_add_d.c | 112 - tnl-_next/libtommath-0.41/bn_mp_addmod.c | 41 - tnl-_next/libtommath-0.41/bn_mp_and.c | 57 - tnl-_next/libtommath-0.41/bn_mp_clamp.c | 44 - tnl-_next/libtommath-0.41/bn_mp_clear.c | 44 - tnl-_next/libtommath-0.41/bn_mp_clear_multi.c | 34 - tnl-_next/libtommath-0.41/bn_mp_cmp.c | 43 - tnl-_next/libtommath-0.41/bn_mp_cmp_d.c | 44 - tnl-_next/libtommath-0.41/bn_mp_cmp_mag.c | 55 - tnl-_next/libtommath-0.41/bn_mp_cnt_lsb.c | 53 - tnl-_next/libtommath-0.41/bn_mp_copy.c | 68 - tnl-_next/libtommath-0.41/bn_mp_count_bits.c | 45 - tnl-_next/libtommath-0.41/bn_mp_div.c | 292 - tnl-_next/libtommath-0.41/bn_mp_div_2.c | 68 - tnl-_next/libtommath-0.41/bn_mp_div_2d.c | 97 - tnl-_next/libtommath-0.41/bn_mp_div_3.c | 79 - tnl-_next/libtommath-0.41/bn_mp_div_d.c | 115 - .../libtommath-0.41/bn_mp_dr_is_modulus.c | 43 - tnl-_next/libtommath-0.41/bn_mp_dr_reduce.c | 94 - tnl-_next/libtommath-0.41/bn_mp_dr_setup.c | 32 - tnl-_next/libtommath-0.41/bn_mp_exch.c | 34 - tnl-_next/libtommath-0.41/bn_mp_expt_d.c | 57 - tnl-_next/libtommath-0.41/bn_mp_exptmod.c | 112 - .../libtommath-0.41/bn_mp_exptmod_fast.c | 321 - tnl-_next/libtommath-0.41/bn_mp_exteuclid.c | 82 - tnl-_next/libtommath-0.41/bn_mp_fread.c | 67 - tnl-_next/libtommath-0.41/bn_mp_fwrite.c | 52 - tnl-_next/libtommath-0.41/bn_mp_gcd.c | 105 - tnl-_next/libtommath-0.41/bn_mp_get_int.c | 45 - tnl-_next/libtommath-0.41/bn_mp_grow.c | 57 - tnl-_next/libtommath-0.41/bn_mp_init.c | 46 - tnl-_next/libtommath-0.41/bn_mp_init_copy.c | 32 - tnl-_next/libtommath-0.41/bn_mp_init_multi.c | 59 - tnl-_next/libtommath-0.41/bn_mp_init_set.c | 32 - .../libtommath-0.41/bn_mp_init_set_int.c | 31 - tnl-_next/libtommath-0.41/bn_mp_init_size.c | 48 - tnl-_next/libtommath-0.41/bn_mp_invmod.c | 43 - tnl-_next/libtommath-0.41/bn_mp_invmod_slow.c | 175 - tnl-_next/libtommath-0.41/bn_mp_is_square.c | 109 - tnl-_next/libtommath-0.41/bn_mp_jacobi.c | 105 - .../libtommath-0.41/bn_mp_karatsuba_mul.c | 167 - .../libtommath-0.41/bn_mp_karatsuba_sqr.c | 121 - tnl-_next/libtommath-0.41/bn_mp_lcm.c | 60 - tnl-_next/libtommath-0.41/bn_mp_lshd.c | 67 - tnl-_next/libtommath-0.41/bn_mp_mod.c | 48 - tnl-_next/libtommath-0.41/bn_mp_mod_2d.c | 55 - tnl-_next/libtommath-0.41/bn_mp_mod_d.c | 27 - .../bn_mp_montgomery_calc_normalization.c | 59 - .../libtommath-0.41/bn_mp_montgomery_reduce.c | 118 - .../libtommath-0.41/bn_mp_montgomery_setup.c | 59 - tnl-_next/libtommath-0.41/bn_mp_mul.c | 66 - tnl-_next/libtommath-0.41/bn_mp_mul_2.c | 82 - tnl-_next/libtommath-0.41/bn_mp_mul_2d.c | 85 - tnl-_next/libtommath-0.41/bn_mp_mul_d.c | 79 - tnl-_next/libtommath-0.41/bn_mp_mulmod.c | 40 - tnl-_next/libtommath-0.41/bn_mp_n_root.c | 132 - tnl-_next/libtommath-0.41/bn_mp_neg.c | 40 - tnl-_next/libtommath-0.41/bn_mp_or.c | 50 - .../libtommath-0.41/bn_mp_prime_fermat.c | 62 - .../bn_mp_prime_is_divisible.c | 50 - .../libtommath-0.41/bn_mp_prime_is_prime.c | 83 - .../bn_mp_prime_miller_rabin.c | 103 - .../libtommath-0.41/bn_mp_prime_next_prime.c | 170 - .../bn_mp_prime_rabin_miller_trials.c | 52 - .../libtommath-0.41/bn_mp_prime_random_ex.c | 125 - tnl-_next/libtommath-0.41/bn_mp_radix_size.c | 78 - tnl-_next/libtommath-0.41/bn_mp_radix_smap.c | 24 - tnl-_next/libtommath-0.41/bn_mp_rand.c | 55 - tnl-_next/libtommath-0.41/bn_mp_read_radix.c | 85 - .../libtommath-0.41/bn_mp_read_signed_bin.c | 41 - .../libtommath-0.41/bn_mp_read_unsigned_bin.c | 55 - tnl-_next/libtommath-0.41/bn_mp_reduce.c | 100 - tnl-_next/libtommath-0.41/bn_mp_reduce_2k.c | 61 - tnl-_next/libtommath-0.41/bn_mp_reduce_2k_l.c | 62 - .../libtommath-0.41/bn_mp_reduce_2k_setup.c | 47 - .../libtommath-0.41/bn_mp_reduce_2k_setup_l.c | 44 - .../libtommath-0.41/bn_mp_reduce_is_2k.c | 52 - .../libtommath-0.41/bn_mp_reduce_is_2k_l.c | 44 - .../libtommath-0.41/bn_mp_reduce_setup.c | 34 - tnl-_next/libtommath-0.41/bn_mp_rshd.c | 72 - tnl-_next/libtommath-0.41/bn_mp_set.c | 29 - tnl-_next/libtommath-0.41/bn_mp_set_int.c | 48 - tnl-_next/libtommath-0.41/bn_mp_shrink.c | 35 - .../libtommath-0.41/bn_mp_signed_bin_size.c | 27 - tnl-_next/libtommath-0.41/bn_mp_sqr.c | 58 - tnl-_next/libtommath-0.41/bn_mp_sqrmod.c | 41 - tnl-_next/libtommath-0.41/bn_mp_sqrt.c | 81 - tnl-_next/libtommath-0.41/bn_mp_sub.c | 59 - tnl-_next/libtommath-0.41/bn_mp_sub_d.c | 93 - tnl-_next/libtommath-0.41/bn_mp_submod.c | 42 - .../libtommath-0.41/bn_mp_to_signed_bin.c | 33 - .../libtommath-0.41/bn_mp_to_signed_bin_n.c | 31 - .../libtommath-0.41/bn_mp_to_unsigned_bin.c | 48 - .../libtommath-0.41/bn_mp_to_unsigned_bin_n.c | 31 - tnl-_next/libtommath-0.41/bn_mp_toom_mul.c | 284 - tnl-_next/libtommath-0.41/bn_mp_toom_sqr.c | 226 - tnl-_next/libtommath-0.41/bn_mp_toradix.c | 75 - tnl-_next/libtommath-0.41/bn_mp_toradix_n.c | 88 - .../libtommath-0.41/bn_mp_unsigned_bin_size.c | 28 - tnl-_next/libtommath-0.41/bn_mp_xor.c | 51 - tnl-_next/libtommath-0.41/bn_mp_zero.c | 36 - tnl-_next/libtommath-0.41/bn_prime_tab.c | 61 - tnl-_next/libtommath-0.41/bn_reverse.c | 39 - tnl-_next/libtommath-0.41/bn_s_mp_add.c | 109 - tnl-_next/libtommath-0.41/bn_s_mp_exptmod.c | 252 - tnl-_next/libtommath-0.41/bn_s_mp_mul_digs.c | 90 - .../libtommath-0.41/bn_s_mp_mul_high_digs.c | 81 - tnl-_next/libtommath-0.41/bn_s_mp_sqr.c | 84 - tnl-_next/libtommath-0.41/bn_s_mp_sub.c | 89 - tnl-_next/libtommath-0.41/bncore.c | 36 - tnl-_next/libtommath-0.41/booker.pl | 265 - tnl-_next/libtommath-0.41/callgraph.txt | 11913 ---------------- tnl-_next/libtommath-0.41/changes.txt | 397 - tnl-_next/libtommath-0.41/demo/CVS/Entries | 3 - tnl-_next/libtommath-0.41/demo/CVS/Repository | 1 - tnl-_next/libtommath-0.41/demo/CVS/Root | 1 - tnl-_next/libtommath-0.41/demo/demo.c | 740 - tnl-_next/libtommath-0.41/demo/timing.c | 319 - tnl-_next/libtommath-0.41/dep.pl | 123 - tnl-_next/libtommath-0.41/etc/2kprime.1 | 2 - tnl-_next/libtommath-0.41/etc/2kprime.c | 84 - tnl-_next/libtommath-0.41/etc/CVS/Entries | 16 - tnl-_next/libtommath-0.41/etc/CVS/Repository | 1 - tnl-_next/libtommath-0.41/etc/CVS/Root | 1 - tnl-_next/libtommath-0.41/etc/drprime.c | 64 - tnl-_next/libtommath-0.41/etc/drprimes.28 | 25 - tnl-_next/libtommath-0.41/etc/drprimes.txt | 9 - tnl-_next/libtommath-0.41/etc/makefile | 50 - tnl-_next/libtommath-0.41/etc/makefile.icc | 67 - tnl-_next/libtommath-0.41/etc/makefile.msvc | 23 - tnl-_next/libtommath-0.41/etc/mersenne.c | 144 - tnl-_next/libtommath-0.41/etc/mont.c | 50 - tnl-_next/libtommath-0.41/etc/pprime.c | 400 - tnl-_next/libtommath-0.41/etc/prime.1024 | 414 - tnl-_next/libtommath-0.41/etc/prime.512 | 205 - tnl-_next/libtommath-0.41/etc/timer.asm | 37 - tnl-_next/libtommath-0.41/etc/tune.c | 142 - tnl-_next/libtommath-0.41/gen.pl | 17 - tnl-_next/libtommath-0.41/libtommath.dsp | 572 - tnl-_next/libtommath-0.41/libtommath.vcproj | 2804 ---- tnl-_next/libtommath-0.41/logs/CVS/Entries | 19 - tnl-_next/libtommath-0.41/logs/CVS/Repository | 1 - tnl-_next/libtommath-0.41/logs/CVS/Root | 1 - tnl-_next/libtommath-0.41/logs/README | 13 - tnl-_next/libtommath-0.41/logs/add.log | 16 - tnl-_next/libtommath-0.41/logs/addsub.png | Bin 6254 -> 0 bytes tnl-_next/libtommath-0.41/logs/expt.log | 7 - tnl-_next/libtommath-0.41/logs/expt.png | Bin 6605 -> 0 bytes tnl-_next/libtommath-0.41/logs/expt_2k.log | 5 - tnl-_next/libtommath-0.41/logs/expt_2kl.log | 4 - tnl-_next/libtommath-0.41/logs/expt_dr.log | 7 - tnl-_next/libtommath-0.41/logs/graphs.dem | 17 - tnl-_next/libtommath-0.41/logs/index.html | 27 - tnl-_next/libtommath-0.41/logs/invmod.log | 0 tnl-_next/libtommath-0.41/logs/invmod.png | Bin 4918 -> 0 bytes tnl-_next/libtommath-0.41/logs/mult.log | 84 - tnl-_next/libtommath-0.41/logs/mult.png | Bin 6770 -> 0 bytes tnl-_next/libtommath-0.41/logs/mult_kara.log | 84 - tnl-_next/libtommath-0.41/logs/sqr.log | 84 - tnl-_next/libtommath-0.41/logs/sqr_kara.log | 84 - tnl-_next/libtommath-0.41/logs/sub.log | 16 - tnl-_next/libtommath-0.41/makefile | 186 - tnl-_next/libtommath-0.41/makefile.bcc | 44 - tnl-_next/libtommath-0.41/makefile.cygwin_dll | 55 - tnl-_next/libtommath-0.41/makefile.icc | 116 - tnl-_next/libtommath-0.41/makefile.msvc | 40 - tnl-_next/libtommath-0.41/makefile.shared | 102 - tnl-_next/libtommath-0.41/mess.sh | 4 - tnl-_next/libtommath-0.41/mtest/CVS/Entries | 7 - .../libtommath-0.41/mtest/CVS/Repository | 1 - tnl-_next/libtommath-0.41/mtest/CVS/Root | 1 - tnl-_next/libtommath-0.41/mtest/logtab.h | 24 - tnl-_next/libtommath-0.41/mtest/mpi-config.h | 90 - tnl-_next/libtommath-0.41/mtest/mpi-types.h | 20 - tnl-_next/libtommath-0.41/mtest/mpi.c | 3985 ------ tnl-_next/libtommath-0.41/mtest/mpi.h | 231 - tnl-_next/libtommath-0.41/mtest/mtest.c | 308 - tnl-_next/libtommath-0.41/pics/CVS/Entries | 10 - tnl-_next/libtommath-0.41/pics/CVS/Repository | 1 - tnl-_next/libtommath-0.41/pics/CVS/Root | 1 - .../libtommath-0.41/pics/design_process.sxd | Bin 6950 -> 0 bytes .../libtommath-0.41/pics/design_process.tif | Bin 79042 -> 0 bytes tnl-_next/libtommath-0.41/pics/expt_state.sxd | Bin 6869 -> 0 bytes tnl-_next/libtommath-0.41/pics/expt_state.tif | Bin 87542 -> 0 bytes tnl-_next/libtommath-0.41/pics/makefile | 35 - tnl-_next/libtommath-0.41/pics/primality.tif | Bin 85514 -> 0 bytes tnl-_next/libtommath-0.41/pics/radix.sxd | Bin 6181 -> 0 bytes .../libtommath-0.41/pics/sliding_window.sxd | Bin 6787 -> 0 bytes .../libtommath-0.41/pics/sliding_window.tif | Bin 53880 -> 0 bytes tnl-_next/libtommath-0.41/poster.out | 0 tnl-_next/libtommath-0.41/poster.tex | 35 - tnl-_next/libtommath-0.41/pre_gen/CVS/Entries | 2 - .../libtommath-0.41/pre_gen/CVS/Repository | 1 - tnl-_next/libtommath-0.41/pre_gen/CVS/Root | 1 - tnl-_next/libtommath-0.41/pre_gen/mpi.c | 9519 ------------ tnl-_next/libtommath-0.41/pretty.build | 66 - tnl-_next/libtommath-0.41/tombc/CVS/Entries | 2 - .../libtommath-0.41/tombc/CVS/Repository | 1 - tnl-_next/libtommath-0.41/tombc/CVS/Root | 1 - tnl-_next/libtommath-0.41/tombc/grammar.txt | 35 - tnl-_next/libtommath-0.41/tommath.h | 584 - tnl-_next/libtommath-0.41/tommath.out | 139 - tnl-_next/libtommath-0.41/tommath.src | 6350 -------- tnl-_next/libtommath-0.41/tommath_class.h | 999 -- .../libtommath-0.41/tommath_superclass.h | 76 - tnl-_next/main.cpp | 18 - tnl-_next/nat_discovery.h | 457 - tnl-_next/net/buffer_utils.h | 129 - tnl-_next/net/class.h | 320 - tnl-_next/net/client_puzzle.h | 232 - tnl-_next/net/connection.h | 1304 -- tnl-_next/net/connection_string_table.h | 176 - tnl-_next/net/event.h | 238 - tnl-_next/net/event_connection.h | 558 - tnl-_next/net/ghost_connection.h | 1017 -- tnl-_next/net/interface.h | 1495 -- tnl-_next/net/nonce.h | 27 - tnl-_next/net/object.h | 556 - tnl-_next/net/packet_stream.h | 75 - tnl-_next/net/rpc.h | 172 - tnl-_next/net/test/client.cpp | 26 - tnl-_next/net/test/server.cpp | 361 - tnl-_next/net/test/testGame.cpp | 620 - tnl-_next/net/test/testGame.h | 345 - tnl-_next/net/test/testGameRender.cpp | 97 - tnl-_next/net/test/testWindow.cpp | 162 - tnl-_next/platform/platform.h | 63 - tnl-_next/platform/system_includes_linux.h | 0 tnl-_next/platform/system_includes_mac_osx.h | 0 tnl-_next/platform/system_includes_win32.h | 9 - tnl-_next/sockets/address.h | 254 - tnl-_next/sockets/sockets.h | 26 - tnl-_next/sockets/udp_socket.h | 161 - 1056 files changed, 248292 deletions(-) delete mode 100644 tnl-1.5.0/README delete mode 100644 tnl-1.5.0/tnl/LICENSE.txt delete mode 100644 tnl-1.5.0/tnl/Makefile delete mode 100644 tnl-1.5.0/tnl/ReadMe.html delete mode 100644 tnl-1.5.0/tnl/cwPrefixWin32.h delete mode 100644 tnl-1.5.0/tnl/docs/Makefile delete mode 100644 tnl-1.5.0/tnl/docs/doco.css delete mode 100644 tnl-1.5.0/tnl/docs/docs.plaintext.txt delete mode 100644 tnl-1.5.0/tnl/docs/doxygen.html.cfg delete mode 100644 tnl-1.5.0/tnl/docs/footer.html delete mode 100644 tnl-1.5.0/tnl/docs/header.html delete mode 100644 tnl-1.5.0/tnl/docs/images/gglogo.png delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_contributors.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_documentation.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_downloads.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_faq.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_forums.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_mailing.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_news.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_sf.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_left_tnl.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_temp_03.png delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_temp_05.png delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_temp_14.png delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/layout_topbar.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/opentnl.png delete mode 100644 tnl-1.5.0/tnl/docs/images/spacer.gif delete mode 100644 tnl-1.5.0/tnl/docs/images/testshot.png delete mode 100644 tnl-1.5.0/tnl/docs/images/zapshot.png delete mode 100644 tnl-1.5.0/tnl/docs/tree_footer.html delete mode 100644 tnl-1.5.0/tnl/docs/tree_header.html delete mode 100644 tnl-1.5.0/tnl/exe/OpenAL32.dll delete mode 100644 tnl-1.5.0/tnl/exe/README.txt delete mode 100644 tnl-1.5.0/tnl/exe/bot.sh delete mode 100644 tnl-1.5.0/tnl/exe/build.sh delete mode 100644 tnl-1.5.0/tnl/exe/glut32.dll delete mode 100644 tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe delete mode 100644 tnl-1.5.0/tnl/exe/installer/nsisconf.nsi delete mode 100644 tnl-1.5.0/tnl/exe/installer/nsisdl.dll delete mode 100644 tnl-1.5.0/tnl/exe/installer/upx.exe delete mode 100644 tnl-1.5.0/tnl/exe/installer/zap.nsi delete mode 100644 tnl-1.5.0/tnl/exe/levels/ctf1.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/ctf2.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/ctf3.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/ctf4.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/football1.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/football2.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/football3.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/football4.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/football5.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/hunters1.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/hunters2.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/level9.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/rabbit1.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/rabbit2.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/retrieve1.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/retrieve2.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/retrieve3.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/soccer1.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/soccer2.txt delete mode 100644 tnl-1.5.0/tnl/exe/levels/zm1.txt delete mode 100644 tnl-1.5.0/tnl/exe/master.cfg delete mode 100644 tnl-1.5.0/tnl/exe/sfx/boop.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/bounce.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/bounce_shield.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/comm_down.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/comm_up.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/flag_capture.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/flag_drop.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/flag_return.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/forcefield_up.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/grenade.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/mine_arm.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/mine_explode.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/phaser.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_explode.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_heal.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_repair.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_sensor.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_shield.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/ship_turbo.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/teleport_in.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/teleport_out.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/triple.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/triple_impact.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/turret.wav delete mode 100644 tnl-1.5.0/tnl/exe/sfx/turret_impact.wav delete mode 100644 tnl-1.5.0/tnl/glut/glDedicated.h delete mode 100644 tnl-1.5.0/tnl/glut/glut.h delete mode 100644 tnl-1.5.0/tnl/glut/glut32.lib delete mode 100644 tnl-1.5.0/tnl/glut/glutInclude.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/aes.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/aes_tab.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/authors delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/base64.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/bits.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/blowfish.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/cast5.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/cbc.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/cfb.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/crypt.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/crypt.pdf delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/ctr.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/des.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/dh.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/dh_sys.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/dsa.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/ecb.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/ecc.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/ecc_sys.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/gf.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/hash.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/hmac.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/keyring.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/libtomcrypt.vcproj delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/makefile delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/md2.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/md4.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/md5.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mem.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mpi.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_argchk.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_cfg.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_cipher.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_custom.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_gf.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_hash.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_kr.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_macros.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_misc.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_pk.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/mycrypt_prng.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/noekeon.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/ofb.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/omac.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/packet.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/prime.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rc2.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rc4.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rc5.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rc6.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rmd128.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rmd160.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rsa.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/rsa_sys.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/safer+.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/safer.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/safer_tab.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/sha1.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/sha224.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/sha256.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/sha384.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/sha512.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/skipjack.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/sprng.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/strings.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/tiger.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/tommath.h delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/twofish.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/twofish_tab.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/xtea.c delete mode 100644 tnl-1.5.0/tnl/libtomcrypt/yarrow.c delete mode 100644 tnl-1.5.0/tnl/master/Makefile delete mode 100644 tnl-1.5.0/tnl/master/config.cpp delete mode 100644 tnl-1.5.0/tnl/master/main.cpp delete mode 100644 tnl-1.5.0/tnl/master/master.vcproj delete mode 100644 tnl-1.5.0/tnl/master/masterInterface.cpp delete mode 100644 tnl-1.5.0/tnl/master/masterInterface.h delete mode 100644 tnl-1.5.0/tnl/masterclient/Makefile delete mode 100644 tnl-1.5.0/tnl/masterclient/main.cpp delete mode 100644 tnl-1.5.0/tnl/masterclient/masterclient.vcproj delete mode 100644 tnl-1.5.0/tnl/openal/ALut.lib delete mode 100644 tnl-1.5.0/tnl/openal/OpenAL32.lib delete mode 100644 tnl-1.5.0/tnl/openal/al.h delete mode 100644 tnl-1.5.0/tnl/openal/alInclude.h delete mode 100644 tnl-1.5.0/tnl/openal/alc.h delete mode 100644 tnl-1.5.0/tnl/openal/alctypes.h delete mode 100644 tnl-1.5.0/tnl/openal/altypes.h delete mode 100644 tnl-1.5.0/tnl/openal/alu.h delete mode 100644 tnl-1.5.0/tnl/openal/alut.h delete mode 100644 tnl-1.5.0/tnl/openal/linux/libopenal.a delete mode 100644 tnl-1.5.0/tnl/osx/English.lproj/InfoPlist.strings delete mode 100644 tnl-1.5.0/tnl/osx/English.lproj/MainMenu.nib/classes.nib delete mode 100644 tnl-1.5.0/tnl/osx/English.lproj/MainMenu.nib/info.nib delete mode 100644 tnl-1.5.0/tnl/osx/English.lproj/MainMenu.nib/keyedobjects.nib delete mode 100644 tnl-1.5.0/tnl/osx/Info.plist delete mode 100644 tnl-1.5.0/tnl/osx/MyOpenGLView.h delete mode 100644 tnl-1.5.0/tnl/osx/MyOpenGLView.mm delete mode 100644 tnl-1.5.0/tnl/osx/main.mm delete mode 100644 tnl-1.5.0/tnl/osx/tnl.xcode/project.pbxproj delete mode 100644 tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.mode1v3 delete mode 100644 tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.pbxuser delete mode 100644 tnl-1.5.0/tnl/osx/tnl.xcodeproj/project.pbxproj delete mode 100644 tnl-1.5.0/tnl/osx/version.plist delete mode 100644 tnl-1.5.0/tnl/test/Makefile delete mode 100644 tnl-1.5.0/tnl/test/TNLTest.def delete mode 100644 tnl-1.5.0/tnl/test/TNLTest.suo delete mode 100644 tnl-1.5.0/tnl/test/TNLTest.vcproj delete mode 100644 tnl-1.5.0/tnl/test/client.cpp delete mode 100644 tnl-1.5.0/tnl/test/fractal.suo delete mode 100644 tnl-1.5.0/tnl/test/mondrian.ico delete mode 100644 tnl-1.5.0/tnl/test/server.cpp delete mode 100644 tnl-1.5.0/tnl/test/server.vcproj delete mode 100644 tnl-1.5.0/tnl/test/test.rc delete mode 100644 tnl-1.5.0/tnl/test/test.suo delete mode 100644 tnl-1.5.0/tnl/test/testGame.cpp delete mode 100644 tnl-1.5.0/tnl/test/testGame.h delete mode 100644 tnl-1.5.0/tnl/test/testGameRender.cpp delete mode 100644 tnl-1.5.0/tnl/test/testWindow.cpp delete mode 100644 tnl-1.5.0/tnl/tnl.mcp delete mode 100644 tnl-1.5.0/tnl/tnl.sln delete mode 100644 tnl-1.5.0/tnl/tnl/Makefile delete mode 100644 tnl-1.5.0/tnl/tnl/assert.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/asymmetricKey.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/bitStream.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/byteBuffer.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/certificate.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/clientPuzzle.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/connectionStringTable.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/dataChunker.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/eventConnection.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/ghostConnection.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/huffmanStringProcessor.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/journal.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/log.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/netBase.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/netConnection.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/netInterface.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/netObject.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/netStringTable.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/platform.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/random.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/rpc.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/symmetricCipher.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/thread.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/tnl.changelog.txt delete mode 100644 tnl-1.5.0/tnl/tnl/tnl.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnl.overview.txt delete mode 100644 tnl-1.5.0/tnl/tnl/tnl.suo delete mode 100644 tnl-1.5.0/tnl/tnl/tnl.vcproj delete mode 100644 tnl-1.5.0/tnl/tnl/tnlAssert.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlAsymmetricKey.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlBitSet.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlBitStream.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlByteBuffer.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlCertificate.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlClientPuzzle.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlConnectionStringTable.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlDataChunker.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlEndian.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlEventConnection.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlGhostConnection.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlHuffmanStringProcessor.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlJournal.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlLog.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlMethodDispatch.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/tnlMethodDispatch.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNetBase.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNetConnection.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNetEvent.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNetInterface.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNetObject.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNetStringTable.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlNonce.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlPlatform.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlRPC.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlRandom.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlString.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlSymmetricCipher.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlThread.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlTypes.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlUDP.h delete mode 100644 tnl-1.5.0/tnl/tnl/tnlVector.h delete mode 100644 tnl-1.5.0/tnl/tnl/udp.cpp delete mode 100644 tnl-1.5.0/tnl/tnl/vector.cpp delete mode 100644 tnl-1.5.0/tnl/zap/CTFGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/CTFGame.h delete mode 100644 tnl-1.5.0/tnl/zap/HTFGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/LoadoutZone.cpp delete mode 100644 tnl-1.5.0/tnl/zap/Makefile delete mode 100644 tnl-1.5.0/tnl/zap/SweptEllipsoid.cpp delete mode 100644 tnl-1.5.0/tnl/zap/SweptEllipsoid.h delete mode 100644 tnl-1.5.0/tnl/zap/UI.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UI.h delete mode 100644 tnl-1.5.0/tnl/zap/UICredits.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UICredits.h delete mode 100644 tnl-1.5.0/tnl/zap/UIEditor.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UIEditor.h delete mode 100644 tnl-1.5.0/tnl/zap/UIGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UIGame.h delete mode 100644 tnl-1.5.0/tnl/zap/UIInstructions.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UIInstructions.h delete mode 100644 tnl-1.5.0/tnl/zap/UIMenus.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UIMenus.h delete mode 100644 tnl-1.5.0/tnl/zap/UINameEntry.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UINameEntry.h delete mode 100644 tnl-1.5.0/tnl/zap/UIQueryServers.cpp delete mode 100644 tnl-1.5.0/tnl/zap/UIQueryServers.h delete mode 100644 tnl-1.5.0/tnl/zap/ZAP.rc delete mode 100644 tnl-1.5.0/tnl/zap/ZAP.vcproj delete mode 100644 tnl-1.5.0/tnl/zap/barrier.cpp delete mode 100644 tnl-1.5.0/tnl/zap/barrier.h delete mode 100644 tnl-1.5.0/tnl/zap/controlObjectConnection.cpp delete mode 100644 tnl-1.5.0/tnl/zap/controlObjectConnection.h delete mode 100644 tnl-1.5.0/tnl/zap/engineeredObjects.cpp delete mode 100644 tnl-1.5.0/tnl/zap/engineeredObjects.h delete mode 100644 tnl-1.5.0/tnl/zap/flagItem.cpp delete mode 100644 tnl-1.5.0/tnl/zap/flagItem.h delete mode 100644 tnl-1.5.0/tnl/zap/footballGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/ftol.h delete mode 100644 tnl-1.5.0/tnl/zap/game.cpp delete mode 100644 tnl-1.5.0/tnl/zap/game.h delete mode 100644 tnl-1.5.0/tnl/zap/gameConnection.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameConnection.h delete mode 100644 tnl-1.5.0/tnl/zap/gameItems.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameLoader.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameLoader.h delete mode 100644 tnl-1.5.0/tnl/zap/gameNetInterface.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameNetInterface.h delete mode 100644 tnl-1.5.0/tnl/zap/gameObject.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameObject.h delete mode 100644 tnl-1.5.0/tnl/zap/gameObjectRender.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameObjectRender.h delete mode 100644 tnl-1.5.0/tnl/zap/gameType.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameType.h delete mode 100644 tnl-1.5.0/tnl/zap/gameWeapons.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gameWeapons.h delete mode 100644 tnl-1.5.0/tnl/zap/goalZone.cpp delete mode 100644 tnl-1.5.0/tnl/zap/goalZone.h delete mode 100644 tnl-1.5.0/tnl/zap/gridDB.cpp delete mode 100644 tnl-1.5.0/tnl/zap/gridDB.h delete mode 100644 tnl-1.5.0/tnl/zap/gsm.h delete mode 100644 tnl-1.5.0/tnl/zap/gsm_decode.c delete mode 100644 tnl-1.5.0/tnl/zap/gsm_encode.c delete mode 100644 tnl-1.5.0/tnl/zap/gsm_state.c delete mode 100644 tnl-1.5.0/tnl/zap/huntersGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/huntersGame.h delete mode 100644 tnl-1.5.0/tnl/zap/input.cpp delete mode 100644 tnl-1.5.0/tnl/zap/input.h delete mode 100644 tnl-1.5.0/tnl/zap/item.cpp delete mode 100644 tnl-1.5.0/tnl/zap/item.h delete mode 100644 tnl-1.5.0/tnl/zap/linuxInput.cpp delete mode 100644 tnl-1.5.0/tnl/zap/loadoutSelect.cpp delete mode 100644 tnl-1.5.0/tnl/zap/loadoutSelect.h delete mode 100644 tnl-1.5.0/tnl/zap/lpc10.h delete mode 100644 tnl-1.5.0/tnl/zap/lpc10dec.c delete mode 100644 tnl-1.5.0/tnl/zap/lpc10enc.c delete mode 100644 tnl-1.5.0/tnl/zap/main.cpp delete mode 100644 tnl-1.5.0/tnl/zap/masterConnection.cpp delete mode 100644 tnl-1.5.0/tnl/zap/masterConnection.h delete mode 100644 tnl-1.5.0/tnl/zap/move.h delete mode 100644 tnl-1.5.0/tnl/zap/moveObject.cpp delete mode 100644 tnl-1.5.0/tnl/zap/moveObject.h delete mode 100644 tnl-1.5.0/tnl/zap/osxInput.cpp delete mode 100644 tnl-1.5.0/tnl/zap/point.h delete mode 100644 tnl-1.5.0/tnl/zap/private.h delete mode 100644 tnl-1.5.0/tnl/zap/projectile.cpp delete mode 100644 tnl-1.5.0/tnl/zap/projectile.h delete mode 100644 tnl-1.5.0/tnl/zap/quickChat.cpp delete mode 100644 tnl-1.5.0/tnl/zap/quickChat.h delete mode 100644 tnl-1.5.0/tnl/zap/rabbitGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/rabbitGame.h delete mode 100644 tnl-1.5.0/tnl/zap/resource.h delete mode 100644 tnl-1.5.0/tnl/zap/retrieveGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/sfx.cpp delete mode 100644 tnl-1.5.0/tnl/zap/sfx.h delete mode 100644 tnl-1.5.0/tnl/zap/ship.cpp delete mode 100644 tnl-1.5.0/tnl/zap/ship.h delete mode 100644 tnl-1.5.0/tnl/zap/shipItems.h delete mode 100644 tnl-1.5.0/tnl/zap/soccerGame.cpp delete mode 100644 tnl-1.5.0/tnl/zap/soccerGame.h delete mode 100644 tnl-1.5.0/tnl/zap/sparkManager.cpp delete mode 100644 tnl-1.5.0/tnl/zap/sparkManager.h delete mode 100644 tnl-1.5.0/tnl/zap/teleporter.cpp delete mode 100644 tnl-1.5.0/tnl/zap/teleporter.h delete mode 100644 tnl-1.5.0/tnl/zap/timer.h delete mode 100644 tnl-1.5.0/tnl/zap/voiceCodec.cpp delete mode 100644 tnl-1.5.0/tnl/zap/voiceCodec.h delete mode 100644 tnl-1.5.0/tnl/zap/winJoystick.cpp delete mode 100644 tnl-1.5.0/tnl/zap/winmain.cpp delete mode 100644 tnl-1.5.0/tnl/zap/zap_mac_icon.icns delete mode 100644 tnl-1.5.0/tnl/zap/zap_win_icon.ico delete mode 100755 tnl-_next/core/algorithm_templates.h delete mode 100755 tnl-_next/core/array.h delete mode 100755 tnl-_next/core/assert.h delete mode 100755 tnl-_next/core/base_type_declarations.h delete mode 100755 tnl-_next/core/base_type_io.h delete mode 100755 tnl-_next/core/base_type_traits.h delete mode 100755 tnl-_next/core/base_types.h delete mode 100755 tnl-_next/core/bit_stream.h delete mode 100755 tnl-_next/core/byte_stream_fixed.h delete mode 100755 tnl-_next/core/construct.h delete mode 100755 tnl-_next/core/core.h delete mode 100755 tnl-_next/core/cpu_endian.h delete mode 100755 tnl-_next/core/formatted_string_buffer.h delete mode 100755 tnl-_next/core/memory_functions.h delete mode 100755 tnl-_next/core/string.h delete mode 100755 tnl-_next/core/time.h delete mode 100755 tnl-_next/core/utils.h delete mode 100755 tnl-_next/crypto/asymmetric_key.h delete mode 100755 tnl-_next/crypto/certificate.h delete mode 100755 tnl-_next/crypto/crypto.h delete mode 100755 tnl-_next/crypto/random_generator.h delete mode 100755 tnl-_next/crypto/symmetric_cipher.h delete mode 100755 tnl-_next/libtomcrypt-1.17/Debug/BuildLog.htm delete mode 100755 tnl-_next/libtomcrypt-1.17/Debug/vc90.idb delete mode 100755 tnl-_next/libtomcrypt-1.17/Debug/vc90.pdb delete mode 100755 tnl-_next/libtomcrypt-1.17/Doxyfile delete mode 100755 tnl-_next/libtomcrypt-1.17/LICENSE delete mode 100755 tnl-_next/libtomcrypt-1.17/README delete mode 100755 tnl-_next/libtomcrypt-1.17/TODO delete mode 100755 tnl-_next/libtomcrypt-1.17/build.sh delete mode 100755 tnl-_next/libtomcrypt-1.17/changes delete mode 100755 tnl-_next/libtomcrypt-1.17/crypt.tex delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/hashsum.c delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/small.c delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/timing.c delete mode 100755 tnl-_next/libtomcrypt-1.17/demos/tv_gen.c delete mode 100755 tnl-_next/libtomcrypt-1.17/doc/footer.html delete mode 100755 tnl-_next/libtomcrypt-1.17/doc/header.html delete mode 100755 tnl-_next/libtomcrypt-1.17/filter.pl delete mode 100755 tnl-_next/libtomcrypt-1.17/fixupind.pl delete mode 100755 tnl-_next/libtomcrypt-1.17/genlist.sh delete mode 100755 tnl-_next/libtomcrypt-1.17/libtomcrypt.dsp delete mode 100755 tnl-_next/libtomcrypt-1.17/libtomcrypt.vcproj delete mode 100755 tnl-_next/libtomcrypt-1.17/makefile delete mode 100755 tnl-_next/libtomcrypt-1.17/makefile.icc delete mode 100755 tnl-_next/libtomcrypt-1.17/makefile.msvc delete mode 100755 tnl-_next/libtomcrypt-1.17/makefile.shared delete mode 100755 tnl-_next/libtomcrypt-1.17/makefile.unix delete mode 100755 tnl-_next/libtomcrypt-1.17/mess.sh delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/base64_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/ccm_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/cipher_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/eax_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/ecc_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/etc/saferp_optimizer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/etc/whirlgen.c delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/etc/whirltest.c delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/gcm_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/hash_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/hmac_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/lrw_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/ocb_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/omac_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/pmac_tv.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0001.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0002.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0003.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0004.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0005.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0006.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/notes/tech0007.txt delete mode 100755 tnl-_next/libtomcrypt-1.17/parsenames.pl delete mode 100755 tnl-_next/libtomcrypt-1.17/run.sh delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/aes/aes.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/aes/aes_tab.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/anubis.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/blowfish.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/cast5.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/des.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/kasumi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/khazad.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/kseed.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/multi2.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/noekeon.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/rc2.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/rc5.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/rc6.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/safer/safer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/safer/safer_tab.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/safer/saferp.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/skipjack.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/twofish/twofish.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/twofish/twofish_tab.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/ciphers/xtea.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ccm/ccm_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ccm/ccm_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_addheader.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_decrypt_verify_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_encrypt_authenticate_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/eax/eax_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_add_aad.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_add_iv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_gf_mult.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_mult_h.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_reset.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/gcm/gcm_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_decrypt_verify_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_done_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_done_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_encrypt_authenticate_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_ntz.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_shift_xor.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/ocb_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/encauth/ocb/s_ocb_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/chc/chc.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/helper/hash_file.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/helper/hash_filehandle.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/helper/hash_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/helper/hash_memory_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/md2.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/md4.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/md5.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/rmd128.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/rmd160.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/rmd256.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/rmd320.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/sha1.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/sha2/sha224.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/sha2/sha256.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/sha2/sha384.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/sha2/sha512.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/tiger.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/whirl/whirl.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/hashes/whirl/whirltab.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_argchk.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_cfg.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_cipher.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_custom.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_hash.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_mac.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_macros.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_math.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_misc.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_pk.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_pkcs.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/headers/tomcrypt_prng.h delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_file.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_memory_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/f9/f9_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_file.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_memory_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/hmac/hmac_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_file.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_memory_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/omac/omac_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pelican/pelican.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pelican/pelican_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pelican/pelican_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_file.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_memory_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_ntz.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_shift_xor.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/pmac/pmac_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_file.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_memory.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_memory_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/mac/xcbc/xcbc_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/math/fp/ltc_ecc_fp_mulmod.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/math/gmp_desc.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/math/ltm_desc.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/math/multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/math/rand_prime.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/math/tfm_desc.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/base64/base64_decode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/base64/base64_encode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/burn_stack.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_argchk.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_cipher_descriptor.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_cipher_is_valid.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_cipher.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_cipher_any.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_cipher_id.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_hash_any.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_hash_id.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_hash_oid.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_find_prng.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_fsa.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_hash_descriptor.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_hash_is_valid.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_ltc_mp_descriptor.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_prng_descriptor.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_prng_is_valid.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_register_cipher.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_register_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_register_prng.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_unregister_cipher.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_unregister_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/crypt/crypt_unregister_prng.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/error_to_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/pkcs5/pkcs_5_1.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/pkcs5/pkcs_5_2.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/misc/zeromem.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cbc/cbc_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cbc/cbc_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cbc/cbc_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cbc/cbc_getiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cbc/cbc_setiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cbc/cbc_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cfb/cfb_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cfb/cfb_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cfb/cfb_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cfb/cfb_getiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cfb/cfb_setiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/cfb/cfb_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_getiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_setiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ctr/ctr_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ecb/ecb_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ecb/ecb_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ecb/ecb_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ecb/ecb_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_getiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_setiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/f8/f8_test_mode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_getiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_process.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_setiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/lrw/lrw_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ofb/ofb_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ofb/ofb_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ofb/ofb_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ofb/ofb_getiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ofb/ofb_setiv.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/ofb/ofb_start.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/xts/xts_decrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/xts/xts_done.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/xts/xts_encrypt.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/xts/xts_init.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/xts/xts_mult_x.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/modes/xts/xts_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/bit/der_decode_bit_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/bit/der_encode_bit_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/bit/der_length_bit_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/boolean/der_decode_boolean.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/boolean/der_encode_boolean.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/boolean/der_length_boolean.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/choice/der_decode_choice.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/ia5/der_decode_ia5_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/ia5/der_encode_ia5_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/ia5/der_length_ia5_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/integer/der_decode_integer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/integer/der_encode_integer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/integer/der_length_integer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/object_identifier/der_length_object_identifier.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/octet/der_decode_octet_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/octet/der_encode_octet_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/octet/der_length_octet_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/printable_string/der_decode_printable_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/printable_string/der_encode_printable_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/printable_string/der_length_printable_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_decode_sequence_ex.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_decode_sequence_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_encode_sequence_ex.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_encode_sequence_multi.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_length_sequence.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/sequence/der_sequence_free.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/set/der_encode_set.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/set/der_encode_setof.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/short_integer/der_decode_short_integer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/short_integer/der_encode_short_integer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/short_integer/der_length_short_integer.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/utctime/der_decode_utctime.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/utctime/der_encode_utctime.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/utctime/der_length_utctime.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/utf8/der_decode_utf8_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/utf8/der_encode_utf8_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/asn1/der/utf8/der_length_utf8_string.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_decrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_encrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_export.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_free.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_import.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_make_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_shared_secret.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_sign_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_verify_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/dsa/dsa_verify_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_ansi_x963_export.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_ansi_x963_import.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_decrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_encrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_export.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_free.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_get_size.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_import.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_make_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_shared_secret.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_sign_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_sizes.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ecc_verify_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_is_valid_idx.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_map.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_mul2add.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_mulmod.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_mulmod_timing.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_points.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_projective_add_point.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/ecc/ltc_ecc_projective_dbl_point.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_decrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_encrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_export.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_exptmod.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_free.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_import.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/katja/katja_make_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_i2osp.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_mgf1.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_oaep_decode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_oaep_encode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_os2ip.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_pss_decode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_pss_encode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_v1_5_decode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_v1_5_encode.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_decrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_encrypt_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_export.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_exptmod.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_free.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_import.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_make_key.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_sign_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/pk/rsa/rsa_verify_hash.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/fortuna.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/rc4.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/rng_get_bytes.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/rng_make_prng.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/sober128.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/sober128tab.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/sprng.c delete mode 100755 tnl-_next/libtomcrypt-1.17/src/prngs/yarrow.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testbuild.sh delete mode 100755 tnl-_next/libtomcrypt-1.17/testme.sh delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/base64_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/cipher_hash_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/der_tests.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/dsa_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/ecc_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/katja_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/mac_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/makefile delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/makefile.icc delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/makefile.msvc delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/makefile.shared delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/modes_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/pkcs_1_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/rsa_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/store_test.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/test.der delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/test.key delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/test_driver.c delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/tomcrypt_test.h delete mode 100755 tnl-_next/libtomcrypt-1.17/testprof/x86_prof.c delete mode 100755 tnl-_next/libtomcrypt-1.17/updatemakes.sh delete mode 100755 tnl-_next/libtommath-0.41/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/LICENSE delete mode 100755 tnl-_next/libtommath-0.41/bn.tex delete mode 100755 tnl-_next/libtommath-0.41/bn_error.c delete mode 100755 tnl-_next/libtommath-0.41/bn_fast_mp_invmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_fast_mp_montgomery_reduce.c delete mode 100755 tnl-_next/libtommath-0.41/bn_fast_s_mp_mul_digs.c delete mode 100755 tnl-_next/libtommath-0.41/bn_fast_s_mp_mul_high_digs.c delete mode 100755 tnl-_next/libtommath-0.41/bn_fast_s_mp_sqr.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_2expt.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_abs.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_add.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_add_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_addmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_and.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_clamp.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_clear.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_clear_multi.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_cmp.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_cmp_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_cmp_mag.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_cnt_lsb.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_copy.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_count_bits.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_div.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_div_2.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_div_2d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_div_3.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_div_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_dr_is_modulus.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_dr_reduce.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_dr_setup.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_exch.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_expt_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_exptmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_exptmod_fast.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_exteuclid.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_fread.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_fwrite.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_gcd.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_get_int.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_grow.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_init.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_init_copy.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_init_multi.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_init_set.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_init_set_int.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_init_size.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_invmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_invmod_slow.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_is_square.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_jacobi.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_karatsuba_mul.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_karatsuba_sqr.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_lcm.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_lshd.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mod_2d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mod_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_montgomery_calc_normalization.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_montgomery_reduce.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_montgomery_setup.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mul.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mul_2.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mul_2d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mul_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_mulmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_n_root.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_neg.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_or.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_fermat.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_is_divisible.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_is_prime.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_miller_rabin.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_next_prime.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_rabin_miller_trials.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_prime_random_ex.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_radix_size.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_radix_smap.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_rand.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_read_radix.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_read_signed_bin.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_read_unsigned_bin.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_2k.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_2k_l.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_2k_setup.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_2k_setup_l.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_is_2k.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_is_2k_l.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_reduce_setup.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_rshd.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_set.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_set_int.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_shrink.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_signed_bin_size.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_sqr.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_sqrmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_sqrt.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_sub.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_sub_d.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_submod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_to_signed_bin.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_to_signed_bin_n.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_to_unsigned_bin.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_to_unsigned_bin_n.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_toom_mul.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_toom_sqr.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_toradix.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_toradix_n.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_unsigned_bin_size.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_xor.c delete mode 100755 tnl-_next/libtommath-0.41/bn_mp_zero.c delete mode 100755 tnl-_next/libtommath-0.41/bn_prime_tab.c delete mode 100755 tnl-_next/libtommath-0.41/bn_reverse.c delete mode 100755 tnl-_next/libtommath-0.41/bn_s_mp_add.c delete mode 100755 tnl-_next/libtommath-0.41/bn_s_mp_exptmod.c delete mode 100755 tnl-_next/libtommath-0.41/bn_s_mp_mul_digs.c delete mode 100755 tnl-_next/libtommath-0.41/bn_s_mp_mul_high_digs.c delete mode 100755 tnl-_next/libtommath-0.41/bn_s_mp_sqr.c delete mode 100755 tnl-_next/libtommath-0.41/bn_s_mp_sub.c delete mode 100755 tnl-_next/libtommath-0.41/bncore.c delete mode 100755 tnl-_next/libtommath-0.41/booker.pl delete mode 100755 tnl-_next/libtommath-0.41/callgraph.txt delete mode 100755 tnl-_next/libtommath-0.41/changes.txt delete mode 100755 tnl-_next/libtommath-0.41/demo/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/demo/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/demo/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/demo/demo.c delete mode 100755 tnl-_next/libtommath-0.41/demo/timing.c delete mode 100755 tnl-_next/libtommath-0.41/dep.pl delete mode 100755 tnl-_next/libtommath-0.41/etc/2kprime.1 delete mode 100755 tnl-_next/libtommath-0.41/etc/2kprime.c delete mode 100755 tnl-_next/libtommath-0.41/etc/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/etc/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/etc/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/etc/drprime.c delete mode 100755 tnl-_next/libtommath-0.41/etc/drprimes.28 delete mode 100755 tnl-_next/libtommath-0.41/etc/drprimes.txt delete mode 100755 tnl-_next/libtommath-0.41/etc/makefile delete mode 100755 tnl-_next/libtommath-0.41/etc/makefile.icc delete mode 100755 tnl-_next/libtommath-0.41/etc/makefile.msvc delete mode 100755 tnl-_next/libtommath-0.41/etc/mersenne.c delete mode 100755 tnl-_next/libtommath-0.41/etc/mont.c delete mode 100755 tnl-_next/libtommath-0.41/etc/pprime.c delete mode 100755 tnl-_next/libtommath-0.41/etc/prime.1024 delete mode 100755 tnl-_next/libtommath-0.41/etc/prime.512 delete mode 100755 tnl-_next/libtommath-0.41/etc/timer.asm delete mode 100755 tnl-_next/libtommath-0.41/etc/tune.c delete mode 100755 tnl-_next/libtommath-0.41/gen.pl delete mode 100755 tnl-_next/libtommath-0.41/libtommath.dsp delete mode 100755 tnl-_next/libtommath-0.41/libtommath.vcproj delete mode 100755 tnl-_next/libtommath-0.41/logs/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/logs/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/logs/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/logs/README delete mode 100755 tnl-_next/libtommath-0.41/logs/add.log delete mode 100755 tnl-_next/libtommath-0.41/logs/addsub.png delete mode 100755 tnl-_next/libtommath-0.41/logs/expt.log delete mode 100755 tnl-_next/libtommath-0.41/logs/expt.png delete mode 100755 tnl-_next/libtommath-0.41/logs/expt_2k.log delete mode 100755 tnl-_next/libtommath-0.41/logs/expt_2kl.log delete mode 100755 tnl-_next/libtommath-0.41/logs/expt_dr.log delete mode 100755 tnl-_next/libtommath-0.41/logs/graphs.dem delete mode 100755 tnl-_next/libtommath-0.41/logs/index.html delete mode 100755 tnl-_next/libtommath-0.41/logs/invmod.log delete mode 100755 tnl-_next/libtommath-0.41/logs/invmod.png delete mode 100755 tnl-_next/libtommath-0.41/logs/mult.log delete mode 100755 tnl-_next/libtommath-0.41/logs/mult.png delete mode 100755 tnl-_next/libtommath-0.41/logs/mult_kara.log delete mode 100755 tnl-_next/libtommath-0.41/logs/sqr.log delete mode 100755 tnl-_next/libtommath-0.41/logs/sqr_kara.log delete mode 100755 tnl-_next/libtommath-0.41/logs/sub.log delete mode 100755 tnl-_next/libtommath-0.41/makefile delete mode 100755 tnl-_next/libtommath-0.41/makefile.bcc delete mode 100755 tnl-_next/libtommath-0.41/makefile.cygwin_dll delete mode 100755 tnl-_next/libtommath-0.41/makefile.icc delete mode 100755 tnl-_next/libtommath-0.41/makefile.msvc delete mode 100755 tnl-_next/libtommath-0.41/makefile.shared delete mode 100755 tnl-_next/libtommath-0.41/mess.sh delete mode 100755 tnl-_next/libtommath-0.41/mtest/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/mtest/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/mtest/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/mtest/logtab.h delete mode 100755 tnl-_next/libtommath-0.41/mtest/mpi-config.h delete mode 100755 tnl-_next/libtommath-0.41/mtest/mpi-types.h delete mode 100755 tnl-_next/libtommath-0.41/mtest/mpi.c delete mode 100755 tnl-_next/libtommath-0.41/mtest/mpi.h delete mode 100755 tnl-_next/libtommath-0.41/mtest/mtest.c delete mode 100755 tnl-_next/libtommath-0.41/pics/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/pics/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/pics/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/pics/design_process.sxd delete mode 100755 tnl-_next/libtommath-0.41/pics/design_process.tif delete mode 100755 tnl-_next/libtommath-0.41/pics/expt_state.sxd delete mode 100755 tnl-_next/libtommath-0.41/pics/expt_state.tif delete mode 100755 tnl-_next/libtommath-0.41/pics/makefile delete mode 100755 tnl-_next/libtommath-0.41/pics/primality.tif delete mode 100755 tnl-_next/libtommath-0.41/pics/radix.sxd delete mode 100755 tnl-_next/libtommath-0.41/pics/sliding_window.sxd delete mode 100755 tnl-_next/libtommath-0.41/pics/sliding_window.tif delete mode 100755 tnl-_next/libtommath-0.41/poster.out delete mode 100755 tnl-_next/libtommath-0.41/poster.tex delete mode 100755 tnl-_next/libtommath-0.41/pre_gen/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/pre_gen/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/pre_gen/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/pre_gen/mpi.c delete mode 100755 tnl-_next/libtommath-0.41/pretty.build delete mode 100755 tnl-_next/libtommath-0.41/tombc/CVS/Entries delete mode 100755 tnl-_next/libtommath-0.41/tombc/CVS/Repository delete mode 100755 tnl-_next/libtommath-0.41/tombc/CVS/Root delete mode 100755 tnl-_next/libtommath-0.41/tombc/grammar.txt delete mode 100755 tnl-_next/libtommath-0.41/tommath.h delete mode 100755 tnl-_next/libtommath-0.41/tommath.out delete mode 100755 tnl-_next/libtommath-0.41/tommath.src delete mode 100755 tnl-_next/libtommath-0.41/tommath_class.h delete mode 100755 tnl-_next/libtommath-0.41/tommath_superclass.h delete mode 100755 tnl-_next/main.cpp delete mode 100755 tnl-_next/nat_discovery.h delete mode 100755 tnl-_next/net/buffer_utils.h delete mode 100755 tnl-_next/net/class.h delete mode 100755 tnl-_next/net/client_puzzle.h delete mode 100755 tnl-_next/net/connection.h delete mode 100755 tnl-_next/net/connection_string_table.h delete mode 100755 tnl-_next/net/event.h delete mode 100755 tnl-_next/net/event_connection.h delete mode 100755 tnl-_next/net/ghost_connection.h delete mode 100755 tnl-_next/net/interface.h delete mode 100755 tnl-_next/net/nonce.h delete mode 100755 tnl-_next/net/object.h delete mode 100755 tnl-_next/net/packet_stream.h delete mode 100755 tnl-_next/net/rpc.h delete mode 100755 tnl-_next/net/test/client.cpp delete mode 100755 tnl-_next/net/test/server.cpp delete mode 100755 tnl-_next/net/test/testGame.cpp delete mode 100755 tnl-_next/net/test/testGame.h delete mode 100755 tnl-_next/net/test/testGameRender.cpp delete mode 100755 tnl-_next/net/test/testWindow.cpp delete mode 100755 tnl-_next/platform/platform.h delete mode 100755 tnl-_next/platform/system_includes_linux.h delete mode 100755 tnl-_next/platform/system_includes_mac_osx.h delete mode 100755 tnl-_next/platform/system_includes_win32.h delete mode 100755 tnl-_next/sockets/address.h delete mode 100755 tnl-_next/sockets/sockets.h delete mode 100755 tnl-_next/sockets/udp_socket.h diff --git a/tnl-1.5.0/README b/tnl-1.5.0/README deleted file mode 100644 index 7ad4898..0000000 --- a/tnl-1.5.0/README +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 855b2a2..0000000 --- a/tnl-1.5.0/tnl/LICENSE.txt +++ /dev/null @@ -1,126 +0,0 @@ -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 deleted file mode 100644 index e0a2574..0000000 --- a/tnl-1.5.0/tnl/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index 03fda83..0000000 --- a/tnl-1.5.0/tnl/ReadMe.html +++ /dev/null @@ -1,115 +0,0 @@ - - -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 deleted file mode 100644 index c373e5e..0000000 --- a/tnl-1.5.0/tnl/cwPrefixWin32.h +++ /dev/null @@ -1,11 +0,0 @@ -// 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 deleted file mode 100644 index 8fb5d40..0000000 --- a/tnl-1.5.0/tnl/docs/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -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 deleted file mode 100644 index c1f79ab..0000000 --- a/tnl-1.5.0/tnl/docs/doco.css +++ /dev/null @@ -1,382 +0,0 @@ -.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 deleted file mode 100644 index e5556ae..0000000 --- a/tnl-1.5.0/tnl/docs/docs.plaintext.txt +++ /dev/null @@ -1,519 +0,0 @@ -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 deleted file mode 100644 index 11faf98..0000000 --- a/tnl-1.5.0/tnl/docs/doxygen.html.cfg +++ /dev/null @@ -1,216 +0,0 @@ -# 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 deleted file mode 100644 index 69e967a..0000000 --- a/tnl-1.5.0/tnl/docs/footer.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ 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 deleted file mode 100644 index 4921f23..0000000 --- a/tnl-1.5.0/tnl/docs/header.html +++ /dev/null @@ -1,64 +0,0 @@ - - -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 deleted file mode 100644 index 9a9657eb87a862823a145be09c61e07ab10b6063..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21895 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 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 deleted file mode 100644 index 1f8596ce26c540c03b7a336b61f0ad7785b8ddc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1625 zcmZ?wbhEHbT*)BEaFv1K!&$Ax{kDfzT7>(#eK>D=Xocya<%SOq8io70w3ga#+kWig zR>QPtXAdXuvJB@bO?I1SnM`T4n$l>|TIw*R$?^XKkFs>TFK>=$YIsj+w0Uq)XK|mo zrK#`#HxvFpO?z<2{Nh&2&2#Mj-%|U3TkHQVjsJJe{@*e9f5+(mZSDWJb^qTn{(oEV z{~g2sxAp(uHT{1_|NkA+|F<;%-!b`rTj&2R_5XJ*{@=6yf7j~&UGx99RR7<#{D05p z|2@0^_iX?F|1Tx&tN4?J0R(hF1jtVeZ2u3;FYwTj>OZlh=wy!7{0l2eyw*mozp@JbPC$u}*){&;KSWP0fa_ZOR>;8r?m{ef^pf zCuvWasykg@Uv2groq6-r7cSCTvczcl3IhYZHLB~@TWs89x@D`?_8sQCcAM?pXMNzH z?cpOfacf6HB}Au%`I)Mon1ZM{SziloH}jBtU0siFIcp2>9Q5eSFO=ozhTqH zt=o2N-@Rww-h+pZ9JM+2>`LOLH|LBqE;9Kl2cEsPRq*DP+}Rh;-rg=cJt{@Yecc_) zl9$&uMqlNMO zW4$u7?Ru@YzOtSiv31jxi=xYTHzXaO#QNgk@dGNE{OkU{6w|xdS@Krv?CX!p@e}KO z=ecOkSnYkd9d9Hk>>9XE}vL9_ssYI&b9Me zS)}S0v8v6@{IMWyZq|*^2h2^C1qw%)tS=@wRG2sz1Ta4|Y++y$RQWKMm0`hxd;Btg zI-K%3MG_9O7#rNY$1iN5aD-*Lj==#2g^W$93<_^{+~GWBxctyGexDC>nOOo@nV6j{ zKB)37J{dgA_R7o2Qoc7BzbwjT%~W7vu4WKw6yW6%VRUwPF=!HW`}g5)mGO$>aa_(O z3Xl0Ew>((LFq`9JL%TCi!J*opD+^dyjcN>DGB5`|=;~xxG^2l>_NSZA=T8t#X%G++ z`E|U!r7NLvNzcCn3=9l4?F>qydW+=P1w=MDEPd@e(~-;g%Ebd*^V@zMX4a|6lCN9B z$ygb>Q3jQoS{`69L-l|2@dhVb6vGkAg-Ywha zbnn~$rxweRykWqNuGOGo96 zKd1K0y6LuL>R~2#r7Q+s2AR_e46Cm9o?vr16K8neDaR|-jh{#G|BiVPnk_4pl=tuW zw7eyNolPWQ=H8$n?df;Bs%EV|`PJ$;JFmn6hHZ>2400ZJjy^A>7&IIh`4}edlu>16 zzmX7RQpCV0aKK{zj|K*x3ckM^nwjJiTp8*Gm`>eY-7wuc!DrR>oiiD=94CG3Y$+=4 zy&JPade+SgK@%=J30fZKVD4~#T5x01%eMxNhZUs1b$yVs^GWM?a`9~Hwuv*lMbbOx zW+rL=a$;o5ImyVlU@|Y~i>+F(%03t*1wTmI=Fy_Z_1Y}KrbR;6<=EmGhIVs39&60m zAzwa)qbk~PfnLZFXWL1w{mvhf4=P;|Q%Y){aL3`1;?xr}{ok}sR4!C0Sr*}bsNrqb v0gVa#lLgwNZhe}zhp{fKFfrg7#OSp(lY^9 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 deleted file mode 100644 index 439d58ba1e669e2bff015b6e0eb62a327ad39c9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1654 zcmZ?wbhEHbT*)BEaFv1K&;J!N`u~pU|2z8Oe$M~z*@yeP|G%a7|CajyyH@}2S^vMK`v0EI z|9f`-@7ezU|6fYlSMetc0|@AV2#}u`*!~}wU*Mr5)qi41(a9XE`4?7{c&&|Ee`8JA z>9=*>R=VoTN8yxsRdd{diz(V_Imp4{`>@BV8r*J^H2Xls}6>{9RP)##s~ zG-euK)U&5B#MsqWZmv3rl@zWvq* z57{0$D$Xh=UF=_3Ra@QI(9+u8*45qHGhyQ7NzME8h(dUlaJ@x7d#%&%`BZ$Er5?;s~`lai4X!0z7evpIZ{S`M7U`_%z*@KZ740%H(qtnOecL z(pAvgwCD{-s8;Cei2HNz+}fJTxxuiwM>qSM4u7M_HK`owDT#M>x@+D$dwa@z_X+jx zY<8VSsSnrd3+wB>mRN90CCAcW#@U3X=!Mf2FKt~dvN*2r@vkN^&0R|#u$g9=DD1gp zkhIZQa{IG|!9~W>#$5pg0=(vdcV}+T{dU*#M>?|;PfMJ5a-+aOjuwRkzw?z@Fa9jq zE|wAN|4rWb&v$3`#)@#>w3{EU@uo{NK0jIca_#c2YI}}lQ!~#lZ0pauxbfQmTda0p z$}iMcI|wui@ccP=kl87R{a}FDh9AtVvNZ(zLBCy1fRbq#LLyEnMI788?lS&7t3bHgf>oQ+4 zIKVVfvwXhY>Z>NQyoy=}#X74C6j&O0w*0uyqp(82p*!~92Sx@bh65b}d!%VduzdHrq?8@$96g7xkzgl#kkT#Qf zacMEf&UanRt?b&*R@+y956AG22<7exhP|A-n>W^7I=iVv% zEiwzag*XHcGWgv3J@4$Nr#^?ys($I=z99YR`uX+T(!EFKd)`iHl$E+s_K2rBB8QR1 ziD$w_)~o*>C_lPU_lKE5*+0&bfwSWF0v@J{zs-yZ-G3`Jo!uI^TC=Y2IdoQH!x_<5 zi4QT)5=)*p|9^hL?5VC!nLEpeqwDjwdrRCqcWA@nSa!wjGtaWH6?PnAOklb`gMmSzp{cWDx%vGAEDT;x7c8%F z6JgR2Wm}fiz$U`Z#(UsqLP{g!oTKaPq&CH_5Am?SYx<`3{Ept#eZ{?ZGuS#FWK0Nd zDdyvxctm!|LVw#gALoeNo4mGLXUlxS8%&2!9cb;j;c-Dy+(pi`icO?Wk*~T(*qtYF zV&A93vW8vTcH5Pu_pmedE7W_OP?+}Iu|uX$li~0Q%~Ov}Cb&Eldp~2hO_)(n-4Zvo z(-LxdB}To~hW;A2S9pX@`Q)_xOn}zb4udeiO?8PK%|_Eto=LO%JoADKv&1sbvsqD} VXWcln%xwF~vw2mQIUN}otO1W)^x6Ob 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 deleted file mode 100644 index 4a4ceac81e9ebcc014c04266434ae665da3a462c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1569 zcmZ?wbhEHbT*)BEaFv1K!#TqT2aPt*HvMo``_M|uDNS~p=U5$DZkQJB#ofyb0atHpg5Wf@Lo8TMUWOI|!Y{^7jo#VvZ88a}P14vYKD z7x&x#e>36G3bX%D)21}q{J*97|F-V`+uHwc>-@j1_5Zfs|63aW?-=~QWAy)y;r~0v z|L>aqzpelOj%m1`%l|w2|8J@NzhmTK>Oh^Z%~d z|9f`-@7ezU|6fYlSMetc0|@AV2#}u`*!~}wU*Mr5)qi41(a9XE`4?7{c&&|Ee`8JA z>9=*>R=VoTN8yxsRdY+D+1(xLE2P0soLv;P{5)tg%s+uBt-yOeu+Rr)6= zO`5DWb(-!B0|SjYbG7Er*Icw%d+Ac66)W}hbkQX^r#Jk{h5u2mq^Y_zp#jNR@tIiTeDR+W!`pMG<$o#n!(l!CVeqG zi(gz?n|%C~=pNZm&n_-bd@pAw{p;Ju%MahnJID!Gg=8cNusi*?=aMul;V@j}(j}^! zbVg#Ga#xX-!!nQUNlSXl)E+L~vvE@D>FEZ^=axinKJMEfFirR6&)|oLGWncErdlwq zbQSbAEqcQdsuj9A;{Mz_x3;G8Z7|I4(arv*!{5krO)5uvO5&ZJ?wa?`-k$Q_eL}rE zn_Z_->cjQ=!uoozB^KOL$uX3fQTw1Vdf{}%OIx*_4sx?r7`_rUU-$lsxV}Y8oO#uT zms8sWyXT(VVah*u((I!Zfh~?L89O>(o!jFp^j-Yme%|sdo7M?Tr$eWTtodrW_r=QP zpI6_DN+`3v^S9xSfC!6Foav0z!?!D6Hf|OyoLBSg9{-0eyni&FPpvA z@xkGGcGexo88|r#56E*XD72I_&rx6~;y%$jhoSR_*g=kcngWg~`X&K_&1wt=jk1zH z0teh=mT0&zu{Atu=(Z1tOq{Imr!e1I@>Y1i?WLESqkOM@G*~2*GjqprCMS`K1Ko`K z1P(Dfxd=2dI4Ml%kQM3?P!N34c|d`|V_$;`gMo;`f`v{34To4+_C8Rlk+C`XVp`-; z<@1>d&(xo_r$m*jCDf?sp7Pg!3OZHKBa7sC7(_lerMzF-@K)pf zT7!cEoIVd6w#Vj4t<#&w#JtKrby0Q8F8dFS>U-WFvp%tB=RPmSc^p@EEuPQBB%`x| zg*#(IgTay+j7*or796U)8nycnt1$n>#%u;MI&sfu-z#`$m zyh4jd_a4(JzyA-pxU&_0U+PHz)z#KhY@>JeX_JoDwcCOd-!nD3I810Tl`7gaPj!xs z@mc*FItJ&IwkR+ho-4f}@S(kk-WIMWv-dOoe3-muhu6W~CVw6uyB7z`&sNrIW?#fy^=m21coZg-5QkXT=N6dz`{#`S@;s$gPX< zsSlLo7$&t#-+geV`G&G$(2PS`zMCIxe=yzgXKsL@{O0*jCa61oh*;KgBVYnUu*RHo zBFkG9D-&63!=-qxG1-59obb0p&`8eiv6;Qgg^HGld5o)$ckr07v*;d?Ssq(ZXlmng ze2E0lzZ!$spSvG%tX$|STx2KMIz{6Vmn}2b{s|Xr)0aFHUb>B&zcipdeP)c{qXQ@0 mtUgVg(6dD4Btx55)Tc=^&MZ+gKY7xx>eJ)}B~Ahi4AuafLeo(I 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 deleted file mode 100644 index a28cdf7af7455ffe2e20d14b0c37c3a48a649991..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1381 zcmZ?wbhEHbT*)BEaFv1K!9ktY5}W@YH~fE+w0V}Pg^6EUv}0Miorj~_|GQ@YZ|nZQ zWAOiu@&7x9|8J@Pzoqv7md5{En*VQW{l9Da|F-`BJEs5d=!g3`|G#Iiso{HQxxti1 zt8hP;4`;OwEjL`;XMS<3;gm+pi(B;nKk#^PQ2*i)c5M{oA|7h9^%=Iy>;P?q(yN_4@_J^v2Ax0h*XRSi>gu-W?K7S* zk!$i4^J&vXW{Qb%&z;A+V1d!%B|OWPnXX(VDk{8=bHhfn&07q%ZMWLF%Vf`9!~F-W z4;{8WdQ4eIhe=ys*RQI&uBNH6wXLJQyQi;r;-o2)r_Y!*XWra}i1^OXx4j6AzNTW>SeXYX!CsI1Fgd4%EGO_ z&(19j-rhHNclp}5v)%#c@7YTH{PK43#q;;~%QCX^J!w3+VDo=fu402fj|GxkIz_aj zj?4&DKHm4lNzdVW!xEk{9=~f1%ZuW?rS%h!&GFp)%y*7u^&1%rrvuz-j_p=88NNv^ zOT-EduC92n(tU#B%BZ8Ormo&IHU99iD~{XJdNyZXUH8;5;i#-?q2xK!Eb;e2JvD#b zcx@)BJe=GXzA0yA#T%dF6E6G7y%1Y*h+WC##kIGL4h#6?ny%YkX*|%z%Mz0Fc-wW& zd&of~h?p4eQup&(KERx`Jo6U#3HmIGV)IoeZxEYQd=E?8vm z_CF-*Zf5yP#btMG@9cec*Z#rTu*k~l1>X;|3dDVIRAA!~Y*J+5nCQsBc*OmGL(rMV zXLBqrc$&_wzsguKH>)%E`7OH*wd%KXl$RWM;KcV$(SzMZA>l-->K)c50ak~E`5ixO z&1aSTojU1}mNr*}fA-Ik>;5^Gt?iBc=3Gx7|q3N8#S3lxs93Fj)Xa23`~ zR_XNqBz`Kve~}1(H}j*<>OJgCCNEN2lgef{3&trlF=zezaFDrNgtKvpeL&T8mTCVQ zUZxlIS@_LeQtK5v?^>@`s&3sorVN87wk4|5*Ug%q?94ZzQ-j6kU&8?x8IFZc%O;#T z`CoIBk5;$RW-Y7J>RVX$o$z14aqfiHHqRqlbptJ*a6MdPFC#FqS^mz^d;BsDKR6~$ zy}%i<`{kb7etTjsUQXY;{GNC2zSZllX6;|kwQwq59iX5pA99UG3v@;x(Y&*Q%w8ka6nPjLZgLK<%;{7 zWrFKZZ}xciucq*VezCYGfj-4fyHd`?J4J`O_{Oge8oK7 ztXr#dW48FX*U#DFSClT@Ycl(0FE7JK&ce-c0{JT6>QaR3LRUn;wcO&JWBl%0@>M52 zqs#6oZk2ZrCo(rRamo}V9D4S>b+7S@;JcPq7uu7{ts*Y2I_KR}uzTO-6TbJ|%uVMg zx=y_R>R(>^&DQj*I*+pT&)wLPZy$GNYw>x%y-#mch$Wrd$9^yKMW}9e#Y?Bvv8!}h y&EobMaCXHAJ#sj}B=waS~u)um%95JD6tx 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 deleted file mode 100644 index 3ab05374e8597105506bd0571923b7fafcdc6612..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1426 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 By9WRO 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 deleted file mode 100644 index 856c04227e7e3536772467cba4c158300dfc1526..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1655 zcmZ?wbhEHbT*)BEaFv1K!&&YBPt&F}+I%=~a%hFw;(nWpTTLDuGM&w>Sv1u)H@^Es0a8P&i99s)h@6EGJE^f2>|G*>M&!wwtiKd44 z#Vz_T9v**i*y_Uti~nyXEbcS^f5+heE%pC*&Hvxl{(oER|6Q~Hw{`yCQu}|$=>J`d z|F?Dj-!c4u$K?MVOZlh=wy!7{0l2eyw*mozpF{*_g=)r}1;t?g}H-Mu{%CQhC-ZTigFbLT8rxOmaB<*Qb%F<8H0)5fja zc5L6hXW!m~hmIVv`NvpnW|G);{HAe6(~^q|!p_d(%(=N`;e%^uXY=|PnsiFLpSxpO z^6J{wqH?Ad(I5RT`FEgjqm*#+nPXF8ZEuUmUlgtn*{`ye z>)NSH21y&b|4#K~s`O`K*&xjDXu^VRZ#nH(h8|P9zG6EgOOtsg>O`cb6;;T;5;0GVwukW2K4$3rkH;!og6ZV?zuht4=@z7qh_x1!ndso9+~?w7KwvUr6Hv z7i)Cgi36ZY-?u&JBVsr{Qkk##KG2v=`{Xd}> z4b6`tE-cyk&w^=_lZwL2cHtQl8U<7(6j&Hl84}o;RWnW`s>&H%aA4#tQfgs7Ec@Yq zg8%|<9=aJ9xZgSu|^2w1!Wy6a{>vyvJzSPsS%uOTP>S@D)+0Ht* zR9i87_NV9Z2fxiQ z)3Lw)af5--+P91itffjD)(AKS3CkT*%lPBG-KoS!l|`q+N4$Dx+5?7Ja}Vqe;nv!0 zv-;6q>gCZ}QC`|x#I5A=;V>KX1kC`Jl-&*o_pYt@&?vxg+-dWHoZm0a7H}Njd*i(O zoTZQXJDn!{S72~wUl~wg#PW~%vY+v#Cu}?l434Z!27bF4!jk?vPkZR`@4)r<=YBcV z+AsNeXwM3s^9Ps(Lp~hfoc902-)Sm0xSuogf8kuPVeRLboP}q60-g&P`7kW;-}9T# zW~&CnfxmjV^7G2Pwx#M{gKTiQOYk}*}qEgYwvt0?fyV+kq zP_y58alNGGhO>874vQ_A!7k0f(Z{F|$jQv|JnP;D?=K!9e4-Ky7{x12F|>8qhSoSR zI{fKo5_!-VS&`5w&#>^73x~bXxg#w+))O4BOftEWU%qxFgJPjyU7Dcmr4t_$ z!erdeC#1J5_}bV#xiC@w;174hI%Q?+Cmx+#nOyrcf?V@`?*3NrJl?W5FK=R_oA~L? zp6)FZrDrleRe0*$C9G=X+R%7Bqv7j`!*AYntq*aMnRfC_n$_o-7kbnr4>+97iuye3 V#+hYi+fSa&tNJ|KkAsQ98UP3Y^T+@I 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 deleted file mode 100644 index 30c6439f98c5314c1c3fd1f86a7fc040abca8d04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 964 zcmZ?wbhEHbT*)B9aFv1K!-vmhWm7CIQy)BhuBjE7mfqpvSvY0tnu`~2Z{B=l@sb^% zP6__Jz#kIa@%#6G1qJWlfBrw&FCr)Jqo(2&7Sd&?@2;xiH?v7AETmIg(^W~y``H1J z$NNOhj9g`9eJ)*kWoqa;r&V)an}(sT)8cM*Usp#(MgKFarC%HpIdk@%j+RGfsh**( z^T9)pT$Ap&lsCjram86(B+IV?*RJXP+ICSVjctp+r z|No_=eHj=S6o0ZXfPfB&0Qrf5?Z3nP0uLRj{v+&%zrM7bYv|3=vL(_R5_e2XBnVKl~x*Mx= z&zQ-rp*>~Z{CVbD3zjThwtU6PRjW%Ft=4a_TI0mDo^^{AVVeDUTZ*?RF{8HH~xZW%DlAad>d1_36; zW?CZWip14?Zy!83P$?P_x29%h`CT7&r?-JAcP!StS@_%F!}Se+7;J@Pp3eI7GfZ)% zYr1&-W0UK?WiMtlPxidA<{3+whvtl)@@c8+4onO$Sp3UOUxqyNOS;ZbAi}U^?e(~r z#|dh41so@;-wC!e5S?QB_o7p8rcdjU9!7I9fjO~Ca>_h)94rT%875ra#+&Z^E=6UM z;w-cI!V?}&kGHXYd-y_0fa8pYw1ZomWxE8^u1~A+oAGUNjh#-(Qn9w9heb^P@42ov z)n4ywLQND#DKqm3^Q!OiVqjpHuV{RUfq{V~-O<;Pfnog#bJnhx z3=9mCC9V-A!TD(=<%vb942~)JNvR5+xryniL8*x;m4zo$Z5SAMvOQfKLn>}1nOsVd z5MU5+@Zn)*VPMKQpu@(ofN`^gLIc~Gqy`2lgKoy*C73j2(l=QFu&-)(1RQ$)|Nk!! z;o|bSf?B5Je#VWUAkmR$X1UN1$s^#voM!02z&qn81EWcT*r?!WfDGNlP!`65nw01E zF$y>^PunpPii6=-z>WF{PaS5h%`|Llw$X^k6Y;~iMKc=jqwzkNlQ%O1Q-F2(zmGnw Q3=9kmp00i_>zopr08?LtHUIzs 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 deleted file mode 100644 index cb4480758e5be31a8d682915f47ef97ac4e9bf66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11306 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 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 deleted file mode 100644 index 4e5c47ee575b6f3d7364385ad6caafc357c804a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5115 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 diff --git a/tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif b/tnl-1.5.0/tnl/docs/images/layout_tnllogo.gif deleted file mode 100644 index 37a8d42ae50eff3fc5d8e05199fd1c9087acbc13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4707 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 diff --git a/tnl-1.5.0/tnl/docs/images/testshot.png b/tnl-1.5.0/tnl/docs/images/testshot.png deleted file mode 100644 index 14b3cc5373b205499c25e4b9325d855ed15d55b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13599 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

pY-3F@2v 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 E0N6+{d;kCd diff --git a/tnl-1.5.0/tnl/docs/images/zapshot.png b/tnl-1.5.0/tnl/docs/images/zapshot.png deleted file mode 100644 index 780066e33f92e31f14323d2096381ee133caf271..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12337 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 J);T3K0RSSmWY+)y diff --git a/tnl-1.5.0/tnl/docs/tree_footer.html b/tnl-1.5.0/tnl/docs/tree_footer.html deleted file mode 100644 index 3aae021..0000000 --- a/tnl-1.5.0/tnl/docs/tree_footer.html +++ /dev/null @@ -1,7 +0,0 @@ -

- - diff --git a/tnl-1.5.0/tnl/docs/tree_header.html b/tnl-1.5.0/tnl/docs/tree_header.html deleted file mode 100644 index f7b4875..0000000 --- a/tnl-1.5.0/tnl/docs/tree_header.html +++ /dev/null @@ -1,25 +0,0 @@ - - -OpenTNL - $title - - - - -
- - -
-
-
- $title -
- -
diff --git a/tnl-1.5.0/tnl/exe/OpenAL32.dll b/tnl-1.5.0/tnl/exe/OpenAL32.dll deleted file mode 100644 index 100012ff423e473554379fdcd0a6278d600a4d7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60416 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 diff --git a/tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe b/tnl-1.5.0/tnl/exe/installer/makensis-bz2.exe deleted file mode 100644 index e916466cffd36680f17edf8668bbfe8f5b0aec64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 231424 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�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 diff --git a/tnl-1.5.0/tnl/exe/installer/nsisconf.nsi b/tnl-1.5.0/tnl/exe/installer/nsisconf.nsi deleted file mode 100644 index 1f6e2b3..0000000 --- a/tnl-1.5.0/tnl/exe/installer/nsisconf.nsi +++ /dev/null @@ -1,27 +0,0 @@ -; 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 deleted file mode 100644 index c3d9281892e3a1fff86905072eedf0e198951656..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12800 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 Z#B5}3ZrI$j pd1CX*=7Y^Qn?E*8wj8#6wj#DtwhFdtwmP8Val|M6(Ewmz001S@uFU`d diff --git a/tnl-1.5.0/tnl/exe/installer/upx.exe b/tnl-1.5.0/tnl/exe/installer/upx.exe deleted file mode 100644 index b0b309ac7caf4876bfec221e7a9fc6a1ab77aba6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94208 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

t{ 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 eb#V3xO~@{9a diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce.wav b/tnl-1.5.0/tnl/exe/sfx/bounce.wav deleted file mode 100644 index a19c513190f10b674e45d6ac80e672ffd2741d3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZp6)J+(Fpl; zEUQSz`rf^qIs^5)$0tlN7M%0&KvuD-`K@!UlZ-_tJU^UKXs&+z(%kAC6Z30FCQJ?2 zw!3j`;*=mAn=6NVCMFo`Tst{GH_t|A&(#CPz4{8_S58cxlxb_Q=klSviS~Lf7Y{GW ztkYMHIKOXFZmEt!^trv0@~REhe9jzRThQ%lVZ7)3sm4ipE=HAScFoD@bhj|wcJ2Ix ziV`zDw}U56ws#kr=(-;`d7`(b%)-WU)3sy0IX(WKR>jBnZE5H)w6?ZhcX`{a(*8ng zBd<*tcFid1E3`IoT7O~liqiffdq;sB;Yv}d@xdQ|T^xPEbCMMt)qk4M_ZBWu@m7xt6} zhS&v8+qQMOL@Y!28Z&=h^+EpGF?&@2!Y47q49cArJd43_Tp?w>6EMM7H z-r8Oq5bYjVv1Z5WjZ+)TdMc9wf_-U}Cv+2;QzEJ$+Ebv9E|Hg<@fyYJkkJ7*7FIkl<3 zJ3q5}>cra8P#aAL6AfuSUDt}ur!GHwco1S$^cs-8ZkUo;mgC+R;T5 z+w!xs`({sU$jkM!P*5_}QV|qYP_zi_+b!zzS8II} z7dtb3Wo^K6&ou<--Se?>>EE=f>H+6Pn6P^9mX!OzQ5cFD}mr_j9ne z_w{jdGBvbuaBvKW%X*; zFRf_m>gnigs;{grEl5dc%&Cblo$<58pEhs9fsB7xz?(LsEdD5iG)2B_HG;v~oe;7M|ClP6D_(BI$J(*qXh>*?-nYiVk1YHVnzudA!At*dWnY-)xH)YsKiRg{&L6crVf zl$Dj0mXwqf6&4f}6@x%&S$So3Z9{WwduL~N4+!-3_xJVoba!`kc7lbvyE;2S;nvvD z*x1m}P+wnPS65fx(9qb})Cd-7sIPCRudS`FtgI+6D=RCjsI084s3{gIto0^)NTUuJ0TR>zB2sDF0 S6BvM4%^()UM_?OhP5=P-M`bhs diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_impact.wav deleted file mode 100644 index db18f37a68c33a0f424827d8739a2cc0b078d298..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvK5P(dREG=V@p z0@NWu3kk5QBku%ps1**prByNlqpklK_C$X`uh6%Ksvp> zy}h??-MY27xVU)Z#!Z_F3JMCgZr!?ZE}Q zCT8NqiOZHjG!_+Y-3r#SX%kerpWniTAf+IM6DBNM=Dl?*MA25TlFm-B{LGAu=m`^+ zdTrfWw0U#>){PsZvO7Ed7v|>9%!~mUzO8s`!M1IiqB7cj=VwpPi0WJ7yS-#v(e^Dd zxjp_1b7yA7Oz_?c5{Sv`4$PgA8MD-DYf;gTE%`l53TDSo_T64mv?U_TZ~pX{30_+_ z6>P}qTsSkP&!b?&rtq#sv$7|76%}mA_Rr6r5bwb}D$#w{(#U7fdRR?MO;MH_Mhax!{1 zZQ2&yvv_LMf}LA;W(O4J^?MbSY%1uPJ2hs}mQC9tS{KcV>GLVcUz^#saAv}?P30x) zvU`@yh?(qHp1UckGblTE(xNS!^4CUoE-Xr$ynJhU$=djy(46Vkbz#TiyxB>83%3<)+Oi?4J$Ux4tmJ^)7VZUb1%E%7lWBu(<`fiG54lx0Y|o-?kwxyUQk4>wRziDN9Obd%*xH3l^x%+(05Bo`KGe1 zD`T?qdx96{&dkk9>RaHqWqaA0lAT*O#ALO%hb}BCo|2n5p=XKz&Yi`p3k$Zbh>0m| z?+lxtTQsYnAhvJGVvlW`O4e>F*t&gfbV6Z!d&HdiMKh-4#>Dqdn&<7lrMPUvrqZoD zSFVZA&FSopm^-&PclzY)#JGuF3zqop+)`4$c1?cC#?|YSld^ML+QWk9Ehx^PI;$Wj zA*px5{Dr>$TX$AetX`X6vVF_S)zL}0xjj8?p+WQK6y{Ewk(pDFm^!g%;haUDKAX3d z7gVm^P+q!u>(*tfHFr6o<6 zIH7CK+EigI(4lT%W=I{W+Q%$_@Uwx_43_qOfZHx*Y^m#E`2{U4?d@@Kap4hj=FXTgqqMB3Xxg-CQ$fW>etue7T5@t< zUvGE!tT}UL&GPp4_Ve4ab?eskMa5OsWlNW?T)DEOq@<#9>((t>)~{cfsEz!}@ad9(d&YU@Oa(+R1d3o`K2~(y_0hKu=CD~b7S!rpVo!wns zJ+o%bm@#8UP+*|HzrX*cO`Fzl*icqhR$5W9WXZB+%a+YADgqUYYuB#bxN+mg1q&7| zSh{3sRz^lfMoLOSA*c{+Yinz6Zf@>KOiTn7sUXv)PMuN=k}55oIB_xv^yKE|flSTF z%*@Ei$;s*K?(XX9>+72{d-m*Ev!+c82nq&)kTq-8tXj2d<;tq6%F0Sm>AMI7=FgvB zR#sYCT2fM8zIyfQHEY+dS+g8e+JZ{eg&8nI%ZiGMii<(IIy*tda(i=gLP7$l1Wrs$ z0=Z)Hgb5QSP6R0^F9+2SeSQ7?6DCXmmCqp8f^bPmc6N3)$ceeR8IVe*2LxtL1p|=h zW<*7WgF$pmOw8)lt5>aBwQBY1)ytMuR8*9gg959vvT`m2%m#x}s36$prAwDBTMh!t zmMmEU@&p9WoH=_osK&_6&CAQn1F=BP0pSV=0L5ub3n-+)HCjeSMrvvr1Y~7pWlfzr zWy+MvlP66Ad$hm53>_^%^VZ} z3DvpaxIiU9DH|Mc5O3t==jZ1aLDDWX^dSif6c**67DiK36Rb4>rE_yZ@s5H)i2)S- z2n-2B5D7CD;<>6Sh>NSMySh+<49o!qIZPdthQunE1T_di7!(VrxV;^c22n|{k^M*j zl!8G{f?|-X!5EZHk#J^aX6DqXQ$ZmP$0(s#ivb`}0wF=RKrxctFeX?lL?I?wTU!H8 zEl>iKgurPC%zzMxAO^EQA%?(RU0q$^m;({uFvCXFfZYHm5beggx;m(vP+Oc(9yB?? zC|JZoXs|^PCNc?4Gx(`yL@O363u=EuLklElH@CFF9D##|>wqxoV8%kYC?re@g+@_9 GH4XqD(hNud diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_obj.wav deleted file mode 100644 index e7b425a3c9652bf9b63c4941dd5b12761efc71d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZrmi`7<;im> zxO-~bf{ub{Cw&=72vD)~%V?Of>G&Opf=B0fE$qk(u~vu3YTHE=_bl0S=@Cfw>D9xl zCsrhS8Y_b&Wwh;rvYTdaI(`#m_@k?b*UxCk4zbfwkd%~^*Rc&qt(&-F&$(NVo zB(g`;VVJdvgDlCCR0{DcrM7e^;IzlhY5h6!_5ZQiwK z&yGzi=JYibr$z>Ny1IJ!g(c_LbN=*( zU%qa`ruC~9&gg9{&rXaC2@DL0Ovo;4=$XD?#hUf&RxO@6p|!doH8w0HBs4lPyR4yW z>fEKPRq>G`6Jlaw6Vvm`8#*S;n7eTC;`uWtbv0ENXQw8_$0w%dl+?6z zO`17(!GgK7r}VbgmltHFCMG7QW*1d8wDnDyIcM&inNufpG**}7Wu~U2q-PhD*EMxc zm^yRz?3q(1cD2-36y;^6r)Om6msB^l^-h{PW5)C;6S`XJtBUipGc&XEippym+j=KX znL2&y#NN)P`l^zGob2qJ{Njqb#>zmrTdiy5y^>($jG}Kg-6&Dv3gM=GfI=Xs#dwV+DS{mxA zE6PerO3Es#>l&I`J370%x;olg8tZGSE6U5uE2^sN8X8+#J32Z#+FDy08|rJSt12q0 zs%z>R8k$;K+uGV%Tbddh>g#H%tE;PP>gpRB8k<@`psBH;p}xKj4C)&i8X6lLo0=LM z8ygxx;`JZ^Vm3knhz$~}uLmgxsRl_PiQ*6jsQ{_OX);Iwc7q!r!XO1u`@l?uD8yVe zLF`H)qF|*EVc%X3>*w8i6x2a85tNFrmWg?_SVzq zNZ`@kYv)fN-M?$gy46eP&zUi0LT_hlQ$u}Cb$MBFQGQ-#Mrul8LTpTASXf9Vx3sjfwzai)baHWZ^YrrZ3k(X4h>VF( zOis_p$uBA?ud1nUXld>2>YX@c>WtZQ<}X~lboq+aYu2sbuwm1t%@D9@(}wly*R5H# zV)>GV3+B$5F@4I!z8Kh3-YovQj-(oV`HKtBf=mcA~HHAHX$)3Ju|PMxV);S zp{cdAXTqeZGiJ}7zi{!AB}ub`y7y1ucs zqo;4eq)AhzOqw{M7i4Zd$caS-1qDULW#v_M4UH{ron1XWJw06=Z7q!rbv0EL6&2+b S6%|!g)zvjM_4V})xB&p*VBB{A diff --git a/tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav b/tnl-1.5.0/tnl/exe/sfx/bounce_wall.wav deleted file mode 100644 index d5c1bfd5cd47353fee486f505d894b189b456093..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZrmi`7<;im> zxO-~bf{ub{Cw&=72vD)~%V?Of>G&Opf=B0fE$qk(u~vu3YTHE=_bl0S=@Cfw>D9xl zCsrhS8Y_b&Wwh;rvYTdaI(`#m_@k?b*UxCk4zbfwkd%~^*Rc&qt(&-F&$(NVopnTF_IG8sucEt)`}7XzLqW)G~e5 zu9KH;+`M-F@RlVL>+_;Lt&Oxbv<ESexqW8(X=CB$u>KUB2bu$#dt=9^1WceqUWq zte=yWv5~2jOJICK!-NIvcOO1=_SDfm8x~G#EKUjWu(LEXw|4Q1&93R1xnkS?V<%4@ z-Lq-Q^tOu3Xg?QQOG{f9-{_3;)~Sov?>cz&*r7d}m(T91%S#CHbh5RzbMcKxEpC`F zch#0X2M-xmI=TB;_$c_*3adUBT z^9@bNscM}xf7PZPyLa!{yn4Zuj+%m$$N(=lH&5Tt`0TRAzL`tbZP~tK`{vb)r}s3J zWX6a3d3k#Ig~nzS*LO~xzheF7ZCf_1UOcm}sUj~WI>gV{Hy|`Ny{Ni%;_St%*KgXi ze)Zzn6WVHuGU6kG0s?}m2@tDCwe&78k@$zg`z{=$U|=g*$n*U?a2 zoR^W3n2?a1o?TQ?-_kX4`s}&$=g*lrrLVK8uDl>8BPAszH6y2}yr!|EZ_@Ocv**m7 zF{Q7wrM{{pKRY8mH9a$@sH~=;wQItZ=`&`|m^!JitF@t~yeL0AGb1xQuc)lLp{1jD z!j!2~r%svJ*VWosS5;D!pOcf5mtRy?Ro~d!)jMI*q)C$|^mes1)mN976y@jV=NA;0 zRn;}LbaeIhO_(sDucx!EsiCf_yrj6OsHnK4ysECDskNi4r?*(m{Xlre0YHX;ltEsL6 zf$AENTvJO+D+shSH8nOg)YsM3fIwYceM3V-V`CEpG&VLgG&I!10f^Vo2m@dqxpHt* z!KT0sh4AnhN|Z*3F(?j&`vW2evk}UJ+6d)AH9~n%8(}<%B#Z~q2;)Iah4a9Ya2{9^ V!K<$ag*BWH32QialtI4`002~2Xt4kQ diff --git a/tnl-1.5.0/tnl/exe/sfx/comm_down.wav b/tnl-1.5.0/tnl/exe/sfx/comm_down.wav deleted file mode 100644 index f1a97022e71b14ad5609740a203b4e70eb13a40f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZx@WD}a`5aG zOmK3~ro~g+YV+cQ-7NHUFo1!rdss?AefRWboA#f?)P3dBiCt?KPHL;lix0%AU&q|h zFDkRNu@_|jX)Fd@IlX_&vRS*(kh+k1zl6x6m&UAT7FkqcOjIJkAi zoC%E;+3|sHHds8NqhoCA9-Nd{)jVO|s;vjHI^)XegIiY2nb2I79Uts&YkY>_F%{YIVczyw{iCB}YVRE!pIy<|J8RjdJtr<<^U{?|C-#61 zsx3%~@NvWzH6SO#OzNJ#c>S)!*y0yt_{sfSSIwK+QD2%F8|ZFp4AO`NgTg2_v$Vcr z(!5n$_TzBYl`Cft?^?fXR&R4vK}v+5iw*XW($Uc~ck~X6&n|7~mh+fw{e#Us!xvK}7?|k`ZbrdUfXNRUBDJyTnVWd&6YZM{?HEL*!} z7h!K*xpD>MvrVfO&zjWTTwj`(79SDl?P5#VJ{=tcbC8V@pm3~j?w&Mj;fnQJ_a8Zp zH$8wn2+AlY5AWH!e#Jttr4zP<721* diff --git a/tnl-1.5.0/tnl/exe/sfx/comm_up.wav b/tnl-1.5.0/tnl/exe/sfx/comm_up.wav deleted file mode 100644 index 8d824232e2555e0160c14bb4d3a903a30ceac93b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZnmc-@&YHJu z)%vZw_8&QU_6kYh(%F-T_wU-We%0c6vnKU+G}c!X=cOe@g#~)MIog;T=#T>ROf76( z-2H;1;#0BvBsattVd>@7_7 zhz%b-Qww`H??8}CiYw}yJ0?t@0}7cvhffe4VHZw=ow01*tV!L?4OPY2Y4M;SA>I{W zH-JJTEw8k;p{;l7oP{gaZzbLdmp~5Kw07CN=@U8{L2;5473||iwEe~w_HI7GQSl(# z8#^XUpSNu7mR$#l^#9ot2X}3OTb&2;y0?ohQ3+Jf)XLG_FDy1CySR!(d*QbBwt)gX zB{mG?Ut_|Nu4iuR;vE=~lvz+w4+`kTtBCX}D2UguSU3w5!o}Gspa3Sum&O(#FUF_k zRn#~4PMx!C?Up@|9fv0FkHhJNyEqm~}`qIgRTfuIwEzXP&^T9Az-^kR$ b%GSZz&BGg<1q({6>Kd9_+S=M$TbddGh*@kQ diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_capture.wav b/tnl-1.5.0/tnl/exe/sfx/flag_capture.wav deleted file mode 100644 index fe7241351a85e64fa3593728f1db17b04bc9f0f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13405 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 S(BL@5tqh?JhocY*5G(+3twu}$ diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_drop.wav b/tnl-1.5.0/tnl/exe/sfx/flag_drop.wav deleted file mode 100644 index e400d53c5a0fc3237386ce8c73fc07bb0ec7fdc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13405 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 BA#nfz diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_return.wav b/tnl-1.5.0/tnl/exe/sfx/flag_return.wav deleted file mode 100644 index 77eea838c14140ffe406c7f37c71d7ff18c9ab03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13405 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 W(GVC7fzc2c4S~@R7!3iW5C8y0;w~fr diff --git a/tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav b/tnl-1.5.0/tnl/exe/sfx/flag_snatch.wav deleted file mode 100644 index 036b718037c88a7968d109c9e293b65be3210a8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13405 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 diff --git a/tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav b/tnl-1.5.0/tnl/exe/sfx/forcefield_down.wav deleted file mode 100644 index e4ab84c5183b33ea5f0e37e5b718cf7b969380e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 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 diff --git a/tnl-1.5.0/tnl/exe/sfx/grenade.wav b/tnl-1.5.0/tnl/exe/sfx/grenade.wav deleted file mode 100644 index 7a92218886900f0e18106ff9260861a54daec5c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZ+I#xCnrq7n z3(FhY`zH3cHTveVM@Dx3SK&zUu;y|yqt zIXSbWp=bL11#>2~Rpq6`C8Xrnc21qYWXaq~ZIwBR(UEcKB@KOZmaJH@XnI#|esW}J zSae!ZL*Ja`YuB$@GQG1VFCi>2AUHa$q_KbQiVd4Ltz9y`y(%Xz)Yr>9AQB`xf7Rw4 zyLN0?KC8E(ATi9##mUJdFgB~AWy-=eTlO9}uy6a?g_D{~Q^I{*?5%Aa-2y*Xo_Z~lc@$%)1rw;GhxO7%; zLwQzwh`X(co|cB1hK{kdTS!7~P1p1#>vkSKb@A$rTQ{#?xp3y_zAbAPPU);KObz#P zFx63(l@t?~kX2OIvvBkcPsy!p?wPS*&E`Ev&tAH5@8P2-&z`+_{^Z`R%cl-*TQz@j zOLbmSxVOETuA01*n1rO1w5*(hqLPx5rk=5tgGWF_QdUt_Q_s}-t2XU9cJBK9r_Wxz zdj0m@yZ7(kzkm1k&Ffds?q5HDeBb6(3#a!qR~Ba_M+bR3+n5<>sVT@SC@Lu{tEi}` zC@U)|D$2{t%1BE|ii?Rz$SA7m7+E=b1wW~i&B1_i1rD#}WV@^T;tNJ&bFi;0Q|3kwMf3h?vu3m^l2etv#IVR30W zWpy1xGb;x-pP;bV2EnTs0%kF(gPM*DV?e^V=&tAUy@CgFoPX2%Z zpb&cd=FRI@uU@`<@#6XOXV0EJefs3dvSH1N zr3>axpVHsc-cnanR#K3gk(v-29_sJo=3;MWX=bRWsiCYOEh#F*&&$il#|Lt`prDYD zu!yLrn3%YPgrt;|l$5lLjI5lTyu5;A z0>dJsViHr*bMgyIDr@SS+Pk{@Crz0)XWqgkD^{;vzj@ovo%;?PK6>)Zne!K}UcYhk z-u*|9VV(i`=E42@_wL=jd*{xb+qZAux^)u@ZXpA3#32!Puz*|FuU@%${_Lrf$BrD_ zvwQpYEt}S_UA=O}l0^&W&z?17>V)2&&i2;khWh%N%JPz;g52!Pw3Oud*qF$$(4as+ zA1`+|CntMbTT2Tw6GMGH9W70DRRjQ~MXF$BWo2b0B_$b1tk>~ zRW(g*ZEZaRBNKCT3oBcDM@JV|4^K}Y-+pW?A(Ha!jkfe@`~!( z+WMxJc2IctPnbMy#*Eo>7c5w~c-gWQtJkbqw{i34E!%hQ+`VW2zJrI3965IU z`}XYFvuoGR?K`$_-@1A8rcE0+Y*@E$?b_9AR;^mKa{2OQ%a$xzyl~+9?7?e6XZfzHnM_V)I+wwC6W=H|x6#>R$*y1KfW+S=Nh znwpxbs;a8W%F4>}^0KnBveMGhVlXHyEG#T2$S=r;fV`Z%95~3%$%cb01jqz|>`ahU zRyJ4|#LUjl%7W_5&INTa$s#; LeSLj>0|)>B4B3AN diff --git a/tnl-1.5.0/tnl/exe/sfx/mine_arm.wav b/tnl-1.5.0/tnl/exe/sfx/mine_arm.wav deleted file mode 100644 index 78dac9518755995c19cc0e057ac29de1ce6e8c02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZz@WaazM-k5 zrLn%cs-~f(qocX5qO`K1y{D(OwxqDMp>x87_S(YSqWZ2WQ@U#MGV*GBX3XrZ$xg|t z>6)qRDmX(Fr9z3zyGs%8HE4XeB!ZtXJ^OjDcF>5x^sVLorA1u z$dvQXugr;36*nu}@#yjH23J+>kj`Bfk1r_nv~%_I-lmGYjI6@ij>$7;OlYadNlneG z?wC4v?v%F5ti;5u%J%6C7S8CX%!rFkEo+;xc9HxsExEUv5lx* zxc}UV4c%!jM#i2wleeF{xNmleud$AGO!L~)*G{i(j<(Ry_bQ%$^ybxF{Ylnpnl5>B zj^4R-U`ncuvWjiijHCDNADfkFtte-nGUf2YCubMr*~&{9#P%P0{PObhVtaXUortcz z_g`FHUE!)EsTq-9p13)$l3jKN_@@D z{Yqxi+1}QUQT2=V9N9jzG}zugq-@5v zL%SB#$GAB7=k~4Jzh`MvqKBh@Zr_@{I~O-5dAS7U^{&~yePLsgw_8Yl-|C%P=Qkw# zdW07Ct=hh6ZbP!aS9nqXime-FH>3pkL>2cf-@I;SeR80GT;=3d8&^y$j|&V*ZaT2nz%d`4yW?1i(tt1=T)iW(=+oja+aFf}=+rhCSmX&sf> zsTn0r6KBorYbeS{FR1I9He*stMNVd3b=#zAliI8Ev-2vO`=?Cms4vdVD{ttTG_k9p zEI+@jp`#y^xQhzQ>RWsJx|(WAi_2=8yL!8t>&i>YY8yMcJDck(%PQ&`+dJEv>Z>ZM m>Kj|zTN~?Zs%q*RT3VYM8tQ868X6j#8XFoKK$#0AUjhIwcxB80 diff --git a/tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav b/tnl-1.5.0/tnl/exe/sfx/mine_deploy.wav deleted file mode 100644 index 383d496fbbc7316da121a0badad180e825c61371..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZS~`0tO`o%1 z>B@DRw(s75`1t9IS8m+C_vq=%*Y7`l`S#-%R`BE7mrw6rzkK@m?(J)rFPu7lX#b9_ z8&)n|FlXAN-p;1Fs*-~2l!WN;KwnQMdmA%jeJwQ=c^OGD5kWp4E=~?MB*4MN%_|@z zDlRRnq^hN3XliNa?Cu*F9-Ww)Q&3jj(AqU&%Ix_|SFGQ0<|X@7T0<`I5QQCv~?s)|MA$rzb{- z1$etV*;$wv=xC`b$;(KIi;4&d2?_`Z2nY%Zi-<`|%PFX+YwMd>*gCp-2ZTi@rsouu z*EY8GOqw}=>8kZxckVlM;>?B1H*Vd1@c8Mo=PzHqe*OB@tC!E7K7Mfb_KnLIPMth zTi35xJa77huIAdZqU@B|h(K>QCtI+`)Krud9RckbSM@ZjFvJGX9JzHsKmp?y0xuUR&4`lQaLy3)M# z#He6D4@X;b6MY>GH5FxLWn~prb!|OEGb;x-@1V$pjNHBjp{A;;rmm#}3TY=# z|M1w)ZDWA*1qZUm#^Qx7aU7huidzI_40)?#}Dq_ymr~# zDcw!gMVW~a0iI5_=EerP+S=MWx(23}_O9N+F(A!t{WBM@+PD+!kIPrCT)uSv)Uks* zH?3Sav%jsbG&?ym(97A@+{8dnS69!#*xc61GcYnayR@!t!t5n$Ht#-k{Pg*Ymo8mA z54Ld4;u-y|wZ)kU5&j;IR%XWfdin;&W;P%_Njaqros;J-U%!3-k&|aGT)cSx%!xyL zx2|0>v%j^rC?ht+*VW$A)Y!lPlo8x~!{RfG>)IyFS-Ni9-oqzOpFMx}%*n(1x36D5 zcT#74X?9`+I6O>^jZMs~>_N&iifUW>XD(i|dDp>XC(oQYbLzz5eIVtNyBf-JlcNGX zo$V~mOifKKtQ_2Z!{XBmYnpqfEm*m6$Ns}7PMtn=^7x^>+t)9jH>JC=JTEmS*xSv) z#=_jp+|tI;-7hRQy|B8eXX?D=>$mMacnNzE&( zZ||S6aK-wqyY?SEeE85oQ1)9se|leQU1?5AOo+dytE0W0oxP*0mw#AHN^WUgTi^8g z%hqk$v3LK$g9rET-LV;DdVgCzD1k-M2Iyg8wxp@VI$E4(z)VB6aox5bshHbm{ z?mw`9->&VO)-9huqra`8vLG`tD#YK*-PPII)!oxCC^9}Zx1_eYd-9A0%hqhzynV;c z9ox5VT)SfNoN0Y+4OJyMsR>bGLH@qp-rjxz!4WY@nFXaajqUwYXD?W~a_#yJ8#iuP zw`Td0`7@{Vwl&t26=bC*#6*S#2L}a*gh$3ErDhkF)ikvAOqe!%{^DiJSFT*SV)@dA z^JY(*)YH~jTUnf!m70_g8yyuD6&;(9oSv0eTwVh%)~C&wGjGAdg$oxhm^WwUv`Kwk zZB2F6Wkq?}ndvFXNl8h`De0Nnc}1m_wGGW}UA+?~Pn|wv=Iq%sXHK6sWkO$fduwBT zZBm`OLJ3WLw#LsO?7ouB^XpyRae*4 d*45QFG&D9gH8nRkx3n}jH#IdiH8wV21pq{#bVL9E diff --git a/tnl-1.5.0/tnl/exe/sfx/mine_explode.wav b/tnl-1.5.0/tnl/exe/sfx/mine_explode.wav deleted file mode 100644 index b9d9ba48865e5e9c974d643cfc3f7c6a3857a26c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvLi5(4*dfV*ID z2O01qfB*<|BLjH|PyhitI0%A+W+-?M1rH%02MmJ20L;ue1qMbS;Ns%qq67jT^SgKN9z1xElamu19GsJrbMmCIv9XJbva<5x z#kX(Yx+N?u+}*9Dw{PzC69FUX= zSmLHgcek=baPu3G;0Y5~mBlx2igYVGgfzd&3CTHO;=1_e4H0F>kmh?iA;(Qr7T*-< zb_{uQHzdbYW$}$}m5|qWLyo(u-V{{{d7YDU+-)(0VXAtg+p#$($8^zkm5{rkrm7$+ z$8C|QTb?e6AQ_8yB-R{p>AT$ zp=#aDxr@49f)if=GWD3 zA6?Yd6y|=-8OpedV7$mxmk7-T%bQ)%iuPhJ^F2qZ$&Sw~j6Z6Ov)Kj%rAP z#3Y?>RlO<9VqsUt;;g5V985b z;n%|tX@j`e^Q^Qlb-6yt%kx?QQiV)k>~edYmuIDYvCFOLTErpkOS0PGkMr`Z7eEEP zpbTprm<)&kQhN|4b%D1%*zJ$Ol(IY`yd6J9Q(QF6T!cu+^J?9wgCpIX{0tgrgVPbU#0G zzpc;w^XC-xJR{;bb1J9_YyI=u(U&DE4&tMht zf~whT?`Jsg?AbFaod#Y}O?NKjN9XSai=8>G(rIW26U*Q0;Ab@V%xRFIS5y;3Aw+QQ znbWEumC;SNZ=cVP&d=ZD;Adns_w;F1)lMUC@93u6=b^&>{>F1ppFXA9*=gh*9o=;6 z{P}|Df`UDcj{e4T=bk=wO0ClfB5~_nK|xHxo;{8r9dl2eJgL^%X$&%|>DIY(1u-!N zyLUS}`kR={J$34&x_W1)v5!woQ`60xXA2;bP5}WXCUZ`nJPDFDF@edR1<4ldc5(^` zFg2Ys=j4eK8XBFQCMG^HF-=W3Zk#y-*1l_(lQUew2@Q>o4pUQKUyzdP*Fj2RV+#s) z?Q(Vw3^X&FGv~yKl+&z z+thUJ+G!+(E-o&Cf#&Asvu7Vae(cyWs8T;aKd{=XSFfHrRajUU7Z+DpxMRl-7nh)* zAPWnN*|TRKJ9hNwQEhGQj*bpI2bkt4dgy1E@5 z9hR1smH`0)aS+W-mo8m8aRRKnFg`v$zOb-x+qP}n+}+*XK?Yb^Sy|1RHEY(9BS(%L zK79DFo}Qi_$bOJ`KtMnMNJ~>wQ`1EdICkvVvBJVausI-u3b%rQyN8EI2nbkPTU&$7 znso>U3_t*6Tn9+bIuHavCdPw|Y`OpfAh#ba0)Ye&05OV+wt#>q7=(g=Ef~xMfrDUh z01OPlpdAdrDr_P3FUX*Tghntp2L>ST9XWCYVtOJ3KsZI4!N3aw!XN-zp@Zz3IdjI0 z{V2fL*w_RFz}B|6L)F@WLNhoxI0RyNVj|e~#>U1oFaQgbqGBjWf&nPMxOfu;Y~1Jr z1L5J}5fI=A2Q%PcFC6TF12Y7Gx)4OcH9I#}g7@!IYKzRxYLlY*Lf~tT})o5TU0-%Q3WH3PZBNrLu!2vua!XvH(4V31> z73byUBR~NhK-`TK-Ys}Qb2F$Z+XV)lot+&W?QLysZLO`XEiEn0&7eX7l=?uS4FDm} BydeMp diff --git a/tnl-1.5.0/tnl/exe/sfx/phaser.wav b/tnl-1.5.0/tnl/exe/sfx/phaser.wav deleted file mode 100644 index 41f67be23dbb5f674a1793955c0e5cdd02968115..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvK5;Gn*-uBooE zzM-MMskWuMwYs&srM9`gp`oF%uDPbQx~;OKqO%+UJ1X0%TWT8{>RT#1OZo~X=1$I^ zP~2JF&{W=+J2h)cK~HskXa2N|>ABtYl@l{&WlpHBo{&B#qqm`GX40I3h6yPP(mUI- z7A8$-&Rm!Z0c3;ZU}^_el#XT}`wsSCU(FY)eN#UYz>Xs+U7lNYe3A_cJIks!vnX@_O9QW>%C;F zPx#gu-W6MGyeDo=^j^I+AYkii@0hJ~ywkSM^v>Ek#XD!~bnmpS^Sl$buJ8`pyfxT+ z>9$nwo^1`@MO){1hiupy@7=ex$vbu1+EC9KTN}O7wr-B`>e({cGkC?ea_{V|TN8Y$ zw=E0u?$|!Z*L%XYslJ|*x6bhKoUnCHfM?s5l~JCRo44h7rmWf4=ov6|+x%d^vaQ>T zd_(5!m=o$FD#>y>og1s`AZe1AZ9Y1H=>J*>g z?(N&leSFKeZ=Vq18$Ex=+EPD{%I%w{CwlqyZ{5@r>>f8~)7Ca`kF+_PwzqhDB~9J5 zvn#+mqGR*Uneje;#VdDis0r{3ZQr?lL4luV+_asW<`nq2CrsJ8X<4PGdw9$0P20P} zJ^ZpKZ`rxB+|SP^Z_du`3o3(s-LvQH*tD`e-rYT+YxSmW3roDc{4#qs?A$pm-`~$W zzH{@=P4nwxyxoIq=5N}#ZB~h&yI)Mr>@7QY&L|1>_w&h~xOMxc6+Hz3?(X50Q`c_X zwqZh!pSNF7TGO(fJGabj%n0;$_si{BwrSJWRTJ_9J$(J+ODC+|xpV7+mVzihPxp|b zo@JXiZr(D#Db3H*&o45&Y5w+|+cz!hsZ93wba#&`>7KW4)7G6Erq`tf`}+HNN9J`b z+OmD~#!yvH*DjpckQ?Fc;qB)a5}Q@oF>CeCojbN}S~YKCOJ!!1kGs3O zXFyzbW%GnND>iT2v2*9wYROl zJU=}#DkQ+$)63h(*U!%{Ff=?mJ~<<|q_UxE7oq>x^w5wo!hr<-L!V)lKHbH z_jNWkRF)KEr6oj%1^IbcYTbrSTeoiCzIDsS4QoJ_PMy%%QeRV6ke!wo7Zny9;P30>8mznHcJ+!S5P!Bb)Rq_JW~3#?M1_Y2 z2L%QM1Ox|%MMTFZr)B3ASJXANboNc2K5PEMrOQ{XUb}AH+O=y|uUxix!JHYBC-k&8 z)zy?2m1T)BGn>QyUO zEL*a0-s~AuCiHZ+G}hOY7v*PXq$I}2L`Ox0hlhtpMn=cRC#Ga%=M|M!);2V^clAx0 zI%Cefg^QOiUABD1iWSS2E?GE#?yMP8C-io!mV#W6nv@V16BQX55fL606%!ku zl$w#94>F;?skO6r!sHpV=FVTVWZAOiD?vsqS+a2coLN&RPw44rZEmQkC@IW^I3gx0 z666T55s4}3S-AxzVO1mL{+n zdD&?xN%64|Ga@2Dh9tn;QB&X4*4aB@D##rRmn>Pfe8tL@E0!-?2KLMJDHHp;+L{~c zs>+KCa8<&`vl9rK^TToO|QC-*2*wWtB z(?4;_v>CJJ%$vV(;iAP$7B5+{WXZyX3m43vH)qz2=~E|7=h*)wO%m^O9FrSkOl|oP*!?+dOAch6QnddJ0~YMFE2m8prEj@2n0$>N=i%1%gZY&Dl021 ztE#JOYHMq2>*_$wA&|Wd4NV}>($dn}+S=9*0-Yex-2(!BV9*ct=)_5rKz^M(dGh3` zFfa`Prb7Wp1k8k~nL2gqlqplDfb@azq)C$|OaKKzKgjIf-rk;`p6>20ke!|F?d@%C zZLO`XEiEn0%}q^Bjg5^EM>aIn*VotA)z#I2L3MRC$UBvll@%aRUS3`X0;Q#;C8Z@L zB_+im0P=oOQBffTz!_j}0UiL=heCnOD=r2Z4Z@{RP*zqB0w57cj^(50P`gp4fB5^0)S!*hMSw3(LoCgpi7X+hgn4&jc`7~!SEPFNaAM!0A`lz A#sB~S diff --git a/tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav b/tnl-1.5.0/tnl/exe/sfx/phaser_impact.wav deleted file mode 100644 index db18f37a68c33a0f424827d8739a2cc0b078d298..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvK5P(dREG=V@p z0@NWu3kk5QBku%ps1**prByNlqpklK_C$X`uh6%Ksvp> zy}h??-MY27xVU)Z#!Z_F3JMCgZr!?ZE}Q zCT8NqiOZHjG!_+Y-3r#SX%kerpWniTAf+IM6DBNM=Dl?*MA25TlFm-B{LGAu=m`^+ zdTrfWw0U#>){PsZvO7Ed7v|>9%!~mUzO8s`!M1IiqB7cj=VwpPi0WJ7yS-#v(e^Dd zxjp_1b7yA7Oz_?c5{Sv`4$PgA8MD-DYf;gTE%`l53TDSo_T64mv?U_TZ~pX{30_+_ z6>P}qTsSkP&!b?&rtq#sv$7|76%}mA_Rr6r5bwb}D$#w{(#U7fdRR?MO;MH_Mhax!{1 zZQ2&yvv_LMf}LA;W(O4J^?MbSY%1uPJ2hs}mQC9tS{KcV>GLVcUz^#saAv}?P30x) zvU`@yh?(qHp1UckGblTE(xNS!^4CUoE-Xr$ynJhU$=djy(46Vkbz#TiyxB>83%3<)+Oi?4J$Ux4tmJ^)7VZUb1%E%7lWBu(<`fiG54lx0Y|o-?kwxyUQk4>wRziDN9Obd%*xH3l^x%+(05Bo`KGe1 zD`T?qdx96{&dkk9>RaHqWqaA0lAT*O#ALO%hb}BCo|2n5p=XKz&Yi`p3k$Zbh>0m| z?+lxtTQsYnAhvJGVvlW`O4e>F*t&gfbV6Z!d&HdiMKh-4#>Dqdn&<7lrMPUvrqZoD zSFVZA&FSopm^-&PclzY)#JGuF3zqop+)`4$c1?cC#?|YSld^ML+QWk9Ehx^PI;$Wj zA*px5{Dr>$TX$AetX`X6vVF_S)zL}0xjj8?p+WQK6y{Ewk(pDFm^!g%;haUDKAX3d z7gVm^P+q!u>(*tfHFr6o<6 zIH7CK+EigI(4lT%W=I{W+Q%$_@Uwx_43_qOfZHx*Y^m#E`2{U4?d@@Kap4hj=FXTgqqMB3Xxg-CQ$fW>etue7T5@t< zUvGE!tT}UL&GPp4_Ve4ab?eskMa5OsWlNW?T)DEOq@<#9>((t>)~{cfsEz!}@ad9(d&YU@Oa(+R1d3o`K2~(y_0hKu=CD~b7S!rpVo!wns zJ+o%bm@#8UP+*|HzrX*cO`Fzl*icqhR$5W9WXZB+%a+YADgqUYYuB#bxN+mg1q&7| zSh{3sRz^lfMoLOSA*c{+Yinz6Zf@>KOiTn7sUXv)PMuN=k}55oIB_xv^yKE|flSTF z%*@Ei$;s*K?(XX9>+72{d-m*Ev!+c82nq&)kTq-8tXj2d<;tq6%F0Sm>AMI7=FgvB zR#sYCT2fM8zIyfQHEY+dS+g8e+JZ{eg&8nI%ZiGMii<(IIy*tda(i=gLP7$l1Wrs$ z0=Z)Hgb5QSP6R0^F9+2SeSQ7?6DCXmmCqp8f^bPmc6N3)$ceeR8IVe*2LxtL1p|=h zW<*7WgF$pmOw8)lt5>aBwQBY1)ytMuR8*9gg959vvT`m2%m#x}s36$prAwDBTMh!t zmMmEU@&p9WoH=_osK&_6&CAQn1F=BP0pSV=0L5ub3n-+)HCjeSMrvvr1Y~7pWlfzr zWy+MvlP66Ad$hm53>_^%^VZ} z3DvpaxIiU9DH|Mc5O3t==jZ1aLDDWX^dSif6c**67DiK36Rb4>rE_yZ@s5H)i2)S- z2n-2B5D7CD;<>6Sh>NSMySh+<49o!qIZPdthQunE1T_di7!(VrxV;^c22n|{k^M*j zl!8G{f?|-X!5EZHk#J^aX6DqXQ$ZmP$0(s#ivb`}0wF=RKrxctFeX?lL?I?wTU!H8 zEl>iKgurPC%zzMxAO^EQA%?(RU0q$^m;({uFvCXFfZYHm5beggx;m(vP+Oc(9yB?? zC|JZoXs|^PCNc?4Gx(`yL@O363u=EuLklElH@CFF9D##|>wqxoV8%kYC?re@g+@_9 GH4XqD(hNud diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav b/tnl-1.5.0/tnl/exe/sfx/ship_cloak.wav deleted file mode 100644 index 5a170ee4328e056367d7410f6c9e87faaaf8b83f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43144 zcmWIYbaQK1!N3si80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0KD;O9W8k^hNJG;8O zd;0tPCrp?yY4Vh5ATR|)fe8=~fu~HKJbB8L$&)8dng9a`EmNj|#QQ;@ucy1Kv%S5o zwY9masi_$Rni?A$8XD^B>uPIjYwJK{b#--hZ8eBf-vCn8+S=UO+S=OO+zinI(a}&3 zR$N;LrmCtcE6dADOG=6gi;4;h3JP*TAO{3;^9l;#pr9ZxFE=kQFE2MYCnpOIazLu{ za&vP*5@4#Zu&Ai0q@<*@th~Iksk zf@0Ey3H|;3eQ*HQG#R3ALVtfB$grMnP@uH6K|=-P$)={JCQz_|!le!r5@1h)0tFmM z_4N&nppXHDA0%8rJdhr^Ca|u0aNtx|RaKRjmz9;4l$L@*2pm2I5Ksv6V@YWV7!(y1 z6@vX;SO^Lya43NT11SI@Az4%cGOM(#tgO7UvZ|`OwywURvAMamt*yPiv#YDCySuv^ z6iT2t2l*Zn1fZk@^*Sh(fFwYQ`aq!o(gDNZ&;`l%fuy>-yFj3`vlEnVT0yCxsj(5{ z|0ZZk03{!gSL^D*Bshrb>gww1>l+%t0R;+9aPk4^0CB)+4xH@3I_m1dI%{h|Ne`5g z%0Zy4tPB)h;Gh8!An%re0sA4mv5!UGzLU1bi5(mRJgE4TJ*OJMb794p3^~-7~CR01ahy3Y;Jzg%G+FxQvF%lTM+Uh7`1r z6bP$Puq0n_je|cAz+|!N#+GSN6vADAESLS}-1r2AKh6 zgP0%;30I^7173(!SA*IS;DQ)bg@MFD%0M&{u7b!xl%W>%;L;o>fsIBo22{#JnmwSZ z8B~oofV=|^HE?i33uX`nDy(7UJu(|A1}pp#G*klARsl0Xny_K8B&c$QR~#S_WR)Q6 z;q5PQ^9$rkR16JZFa-)>GzXJwI4F|fH8VI4 zAOxu1h1I#pbUBv#7o--1q3U3DHMo5PYW<*Kuqe2#1a3e)!kVa1@v5~z(1YNewzzd05`-S zY)~T>Y!=8c2m?%l3;?Tus0BN!9o(*fr3grw0cxj0yaJ9xMDqb0WspiA(f|dwRuKgp zB+@|92gRTm1#3bv4o|TIwi>JhN z9jpRarvTLA1*?Fl2Q#4rs8I~l2VsNt7eIR#pne#%!v*SpfpA_Pq+e11HXg=?>4NbK zz`YcxB@k=DDGQpWK!ppW|5y)h|AQKcZIJ8^iYjo!8XS)x0^BtN^-Mrr5>Qun5^^UN z#)foTCQSzSa}oVsa9c4d-O&CptRDon421yquP1>G1{n^;5CM>-AXj1N z1}9-q0_+4AO^_l9+(U+@J8*IX7nG2;KeTLuCIv|29TfSHbOtSHL49wK0HPcQ@jzt< zhz2PKB^yxD1U4R=_(16$WDkgjU=R<4L25uW1cP{>vJ374P{jpK`XIAm7-9#M2XY3i z1_AZDK=E8s0!l`p?kPBZK++*78G+Ica)%z?vxhNqav=SFMEWWK>4T&w5DV1%&jpPN zfW{1Ra=;@35H8FJf;3bo8U=A0rXVD#gOfHmIfHx#%1a=Bf(u$uK@3jHpxO}BJa24- z_I1E%8Jv_si2zheA*CsBY5@`8#0*VPa0-;BAgK!?1mZ(j5E9Ga4k)>U()hG#;N%Wg z2hxT}>Zm-B-AL}i#)RfKs6H$dDA|KXPN1Uzka8Q8T_G5$0EU#iII;kAm;l;M1SLW+ z#_WB8lOs4if`?2X2@!>arb<)_p#l^?;KU8L5;PZT@*`NZk9F%#$2?{}g(inI!s05Ouz++vI1c*XHhIznsHbOH7 z3u+pO0+-1k1`LA*Km>}pAPzL;gDDUn>;|ZXFx`Y`uv4I(1XIu!1&9J=9Y|{wJZJzd z3Q}T!lbdEYNfbPMQcdoCQwySP5tvC7Hr73~m=*22>kV4U~tEf;$XN z5nLS3fMz-{1ICz9MGDA z+lyimTy&H%8UmvsFd71*Aut*O^bG-&`iL?P%^i+hyCb&{aET+U!OBKxgt;9S0$95} z;DH2a(-TBtSA?tzp#o|!%pP1ccmx?$68n%ik{Ylt;QoWR!9a~WI0uaZlEZ^xs=i0LBWLLHR#wQ*pEnE zB9J-=2D=QQ1*{OJ3DQc1c@*5wf)X$>Fbx%hc11y5GB8F6Ls?+O;65676cjvN3hp$6 zeAC(r>Xv~!FW^xRFbgph3?2Xjg%No46~q7q6NrW?1W_O^)GSEn2I55s3G*Y^hY$ih z=YWVGusZN~DwqXcVgb?xQ4AqLQ3@I?`I7Qq_8gV~@p0r2>T`54rxhfnlF{0#2Lg9y|G z7vR|f@W?JmPiYxw83ictDyu-jQU_Xe0!k>Yt?&SWFQI_I3N-iM3f$}K0`wQ|Uc+>?sFCF^mAK2T$98=27ZEOO={H$poBB zz;h*_K{N0W8i)X|u7QuQ^@En!faE~|017=&^62h{h8k$>4k7_fG2nGr;GzZON!a=u za9r1chtI%sIG}I=4ZTAG1U>`})(6QxV6~ud1C=G9sRz*Vt+G<^iW}IB0cb4}c$pD6 z^1&;YAmc=Zg#~%=DFkq!fC$jqB_u82bz4=nwRH`km0OT?NuWg0)6)kUphUtGpyQ$7 zVMx%TEbz1uELgsF<=N*u@nwmfh+8}GTKr7QgApr6k zw8#hf6tofvl+VBz9D2>5;T3R-f+z)tU@d5#wGzBs3lzackil;72z5aLWQ+_%f|qK6 z2EjoAff!=Wg^VhLNiYG`QVLneR$U8Pr`6il-r3m&@)#(Z!AsIW^Bkb@+)1FY04?$Z z5A}iNx)!BU_y4A8g{CWc6Z^gvh;5?LL1 ztO?Ta2S+F<$k8z@3P3b8(vT@oT1Mu>1~8F~A=hX~XB|@bgL>Ye4i>c1g$`SR2Nci< z@c05k8JGpGqY=wXMwf*`MwUQhYoJX~pds0kR(_Wc(@5{7KnfrDoTT5CM_{X@;%@1&yY_wSxztAY&?MI?i2B%P@p)U|0 zSso>IgBFBBFerhKE(--GQe*;>U_m4(exL<3q9g_v&*)7@gfuz}RAj?u62N9b2~b%L zvI7N!1flZ`U~#as;9WjwT@S6e(W-d(*ac|Z8NARMJZu3T!$2iK(-Pom84MGU1z@8b zu!W{beDL51vNZ_v;e$z_VM&NENFlOjf^4uWpq>O%;N}X108ctX0|Xp6;9x?JCvX&j z+i{?51#a9y+Ia{PT)jg!fPnKG2?S^!0xyP|1+xN^MmPhR1$HN#fXZNMMizl80yli& zI$;cG0DuDn(%pfjO=y~gQsBvAC>u^eQz;e-nnp>cFpPrRg_i-<22}&);iKRVLsJA7 zhcm!w2TFhw6Al8J-f&SEx{!^8urZWSLjYnlsU+O@m<+T4!{9>WfYub;UKESqqN9w_ z5Eu=C(GVC7fzc44ZwR2&N0f1B?r`MV9l42sOB`7ZRyIN-%Kf?yJ|tP8YI7SbUfT^0(Pk*Tf* zukHekSb$Dz0}XpX@aVG8(o)cX6l`p$2x%=1d;>FRrR3y-BN*PG%89gl&az+Y>96c=*+}?rAuYk63 zpw!r)Me30H8bpE*&49IS;8QD*{Vm{W4bVzr*m*CgGa8_6F5vYR;90)W(?TKbL@)_z z8;vdt1-HN<4QtR!FHo}@lrUi(Nzgt4l>R1?1O^jDA&7&a0wMsi0E|JlL3^pA%R-@n z0qXrg<71SfMF_yd8I=J}kdW>tssxA!l_ZM-=|^BBAA!2GU<~c(Vo;Ew1n>|HE@E_9 zD5#tPuRR1az*F+jr3v6t9!9_+f#VqzXQ0>uMG-h^z;OT>3j>p&p&-~8 z5HcGohCDS6VM8V0n~y=7uwjTgkRAvNLL#dK+mAF%334Mk2Du%EL4HBQAU~oALDeD| z1NJo%AI^j-1yd+yz&Ieo!66A+_y-DdSTu|-3q@V50bQK|rjQnZfX?BA?4*V5H-_*) znvv9klE~cb~vkfC;FrUJAkEQKQR3A(yd$Yj|*tPZ|MAr+6{cII#Ix2}q+8 zorIM5FcK<@RXWfYub;UKESqqN9w_5Eu=C(GVC7fzc44ZwR2&N0f1B?r`MV9l3>oOB`7ZRyIN- z% zPOxIwku}iue$XZ^Xj~bFp+XP}CI}nEfet<+grO{mYS5J^;BGCn4-MS`J9=6u==?=c zgh7tiL#%m)_v~N{(5aW8&L+4|2@`~j5W+ftqo;*}PtOF6ogxAV6mFxZg@VSEM^6i# z1U~%|be`zwX`!GS&>#~K;5)C8<}9ES7N8>qz~MD|S}5q)1Za4HPGkUG13r3M=(N#G zAYb?O4Lm_HG1w0Cd2xBKo%#t{C<4de-76?@2Dw-qR8K<{ z!SsO_mw=a+AQNCw@D>`#O(+me5K-vKV<59Y7-|i8=~Fd$^%*$lgNGzRx3PdD7!jx7 z*h6aUfLlD+2=MYDaElw#M*}m#1Xu=B3#?HEq9GQ5Sm1N`z&b#u@j)115@Y~a0Yoj> zU9i^H=xL#d!~j}Z1iKOj!X8}~3QmRyV)V37a8VB-zy&_6(F>{uU^5D!m2IFB1hRGw zw7V0uQ5r&nFM|i&YB73=JUCf_i#!l9dRk}`yc+{Hg#c|j5) z3JFP}Xe2@fXyOLcOlg2y397(A){dSQ3a$_!}_G z76pg`H!?wm2&82JUHgt6PoNlT2DdXH6K-wrW+Akh2)>F9T*HHFe9{O|Ljf;_8V5EX zD*<-}3Io(8LSU#AR{d~6s3J%+1)&$hf(8IMFd*F>P&NT!P_r9>!7Vcc7s3K3d#nUF zQ;|Vn7zVM35DC==RR-nZqu@?MQv?@>GY}aax&RxkAb@e9=?xbJQwFD@=7RYUHke6m z0%A0&B;5Cy4732l;6meo))d@c6pP@Zqm0oI7!85Z5Eu=C(GZ|-2%ywQlyPY8aOBz@ zxru;F99a!kHbNuJ?XVC4wJ0$$wAl%xFcpABVA7+@LP4!{L}-9`t*x-*Fd@^ukT8OT zIw%f6ED#OF;7$-CmPVI_!WO(j!esQc(9zREM=y~F4<>@wo^->Om9)2mXE(r$Nx)?? zbg?;T*+?Du3UtumEu>Buy+j^7k_hR^gQm40_k=^sZE)y;ZsrE(G|<2!c=b0(3usUG f=q2)?-~bP`fDRWLy+j@y9H13e;A4gd>JoVXS(ZGb diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_explode.wav b/tnl-1.5.0/tnl/exe/sfx/ship_explode.wav deleted file mode 100644 index acca79c5717e35ecf16e2e5cf8faa205c5378a23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17284 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 Jbhb4&007z`{U!ha diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_repair.wav b/tnl-1.5.0/tnl/exe/sfx/ship_repair.wav deleted file mode 100644 index a33f50c4bc40165e1c5e4307289b5a98c6269ed1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21594 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 ZF3h9^N;0GKU8D0|pqdw&4rn^x1pp1ZAFBWW diff --git a/tnl-1.5.0/tnl/exe/sfx/ship_shield.wav b/tnl-1.5.0/tnl/exe/sfx/ship_shield.wav deleted file mode 100644 index ed6bde537bab7256a8bb2e6f5c90d6e31aa1b13b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19008 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 C^G(eF diff --git a/tnl-1.5.0/tnl/exe/sfx/teleport_out.wav b/tnl-1.5.0/tnl/exe/sfx/teleport_out.wav deleted file mode 100644 index ea4231bdc1ae6eb3ddf70b8b9b8dd2d8161b4dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8233 zcmWIYbaPWwU|*EcrS)zs8CH&<3R)YR0})q!wFRaIMCM`wF& zZBtWiZAC?0ZChDcLqkPHMMX_bWo2z`Z*O^dXJ>D3Pft%xO>=WqRdI1mO-*NKVL@YK zV@XL#ab;y?Sy@$8)uc(q#YKI6lP6D}Frl)tvZbY^qM{-%ud1@Lx3@1VE32`wv7n$J zFE6jWyu7HWu(G0J=FFKhb8~YiPo6w$)~wmnrcEm^FE4LzZ!ak+DM?RHPcJVopFDZ; zhP5(o|s zL;(RH0CfqhZihZfE>o)fJP8VA@1$%Ed~Rk za3BH)LI@xz7#Uv* z9300Ezj z?7|B+-~$jR;~?Sf9c&ET@tcv6fgY?Vd{Bc7CtiXFxZwfNMiq7nTaXeVmW2m^GYNJA zr{D7O@^;_`cpS76H^6P)4&3pMBffKTaZbYvgDF)V} z)WT2>)(F5B{=wJ)Mz9wY6o3LAxg8H;qjoGIJn#?&8iBV}fh377F@c+VXapAbZNdVe zgC8gqWF!PaLaSmdIYGKK6M5WA=dr7#9_u%v%b%0R{Ik&`Ewy$l0j#vx{xAIZ5;CQ@R7 zFhK)nsCYI8K|q5(ybYV*^fgq5-rBEkuuf(8w+lo`D8Xik0Z-XwaxHGET({ z;I4u)(8^{cd%;Xd?88Y!k^{3KW5fs&t`5RLDOBdo0|z#OKnoS9dtek=q=E*qkuX|U z8jploD7iINERZ68j`_Cjz-dklv$7zAUOib1f*<_B#LBM9ReT{C}`>xrUvSThK2^D zfIwm*^dor(Ay|jxT7&|m1cM~s*474frz>&JfZF*Eb;fAHjs{ zu1A=T5UWR+iI7GFDNGh2($v%h(T!wpLqh{ZtiHY;!Kz27K==@@4oMa&hEPs5761+b BP0RoQ diff --git a/tnl-1.5.0/tnl/exe/sfx/triple.wav b/tnl-1.5.0/tnl/exe/sfx/triple.wav deleted file mode 100644 index 41f67be23dbb5f674a1793955c0e5cdd02968115..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvK5;Gn*-uBooE zzM-MMskWuMwYs&srM9`gp`oF%uDPbQx~;OKqO%+UJ1X0%TWT8{>RT#1OZo~X=1$I^ zP~2JF&{W=+J2h)cK~HskXa2N|>ABtYl@l{&WlpHBo{&B#qqm`GX40I3h6yPP(mUI- z7A8$-&Rm!Z0c3;ZU}^_el#XT}`wsSCU(FY)eN#UYz>Xs+U7lNYe3A_cJIks!vnX@_O9QW>%C;F zPx#gu-W6MGyeDo=^j^I+AYkii@0hJ~ywkSM^v>Ek#XD!~bnmpS^Sl$buJ8`pyfxT+ z>9$nwo^1`@MO){1hiupy@7=ex$vbu1+EC9KTN}O7wr-B`>e({cGkC?ea_{V|TN8Y$ zw=E0u?$|!Z*L%XYslJ|*x6bhKoUnCHfM?s5l~JCRo44h7rmWf4=ov6|+x%d^vaQ>T zd_(5!m=o$FD#>y>og1s`AZe1AZ9Y1H=>J*>g z?(N&leSFKeZ=Vq18$Ex=+EPD{%I%w{CwlqyZ{5@r>>f8~)7Ca`kF+_PwzqhDB~9J5 zvn#+mqGR*Uneje;#VdDis0r{3ZQr?lL4luV+_asW<`nq2CrsJ8X<4PGdw9$0P20P} zJ^ZpKZ`rxB+|SP^Z_du`3o3(s-LvQH*tD`e-rYT+YxSmW3roDc{4#qs?A$pm-`~$W zzH{@=P4nwxyxoIq=5N}#ZB~h&yI)Mr>@7QY&L|1>_w&h~xOMxc6+Hz3?(X50Q`c_X zwqZh!pSNF7TGO(fJGabj%n0;$_si{BwrSJWRTJ_9J$(J+ODC+|xpV7+mVzihPxp|b zo@JXiZr(D#Db3H*&o45&Y5w+|+cz!hsZ93wba#&`>7KW4)7G6Erq`tf`}+HNN9J`b z+OmD~#!yvH*DjpckQ?Fc;qB)a5}Q@oF>CeCojbN}S~YKCOJ!!1kGs3O zXFyzbW%GnND>iT2v2*9wYROl zJU=}#DkQ+$)63h(*U!%{Ff=?mJ~<<|q_UxE7oq>x^w5wo!hr<-L!V)lKHbH z_jNWkRF)KEr6oj%1^IbcYTbrSTeoiCzIDsS4QoJ_PMy%%QeRV6ke!wo7Zny9;P30>8mznHcJ+!S5P!Bb)Rq_JW~3#?M1_Y2 z2L%QM1Ox|%MMTFZr)B3ASJXANboNc2K5PEMrOQ{XUb}AH+O=y|uUxix!JHYBC-k&8 z)zy?2m1T)BGn>QyUO zEL*a0-s~AuCiHZ+G}hOY7v*PXq$I}2L`Ox0hlhtpMn=cRC#Ga%=M|M!);2V^clAx0 zI%Cefg^QOiUABD1iWSS2E?GE#?yMP8C-io!mV#W6nv@V16BQX55fL606%!ku zl$w#94>F;?skO6r!sHpV=FVTVWZAOiD?vsqS+a2coLN&RPw44rZEmQkC@IW^I3gx0 z666T55s4}3S-AxzVO1mL{+n zdD&?xN%64|Ga@2Dh9tn;QB&X4*4aB@D##rRmn>Pfe8tL@E0!-?2KLMJDHHp;+L{~c zs>+KCa8<&`vl9rK^TToO|QC-*2*wWtB z(?4;_v>CJJ%$vV(;iAP$7B5+{WXZyX3m43vH)qz2=~E|7=h*)wO%m^O9FrSkOl|oP*!?+dOAch6QnddJ0~YMFE2m8prEj@2n0$>N=i%1%gZY&Dl021 ztE#JOYHMq2>*_$wA&|Wd4NV}>($dn}+S=9*0-Yex-2(!BV9*ct=)_5rKz^M(dGh3` zFfa`Prb7Wp1k8k~nL2gqlqplDfb@azq)C$|OaKKzKgjIf-rk;`p6>20ke!|F?d@%C zZLO`XEiEn0%}q^Bjg5^EM>aIn*VotA)z#I2L3MRC$UBvll@%aRUS3`X0;Q#;C8Z@L zB_+im0P=oOQBffTz!_j}0UiL=heCnOD=r2Z4Z@{RP*zqB0w57cj^(50P`gp4fB5^0)S!*hMSw3(LoCgpi7X+hgn4&jc`7~!SEPFNaAM!0A`lz A#sB~S diff --git a/tnl-1.5.0/tnl/exe/sfx/triple_impact.wav b/tnl-1.5.0/tnl/exe/sfx/triple_impact.wav deleted file mode 100644 index db18f37a68c33a0f424827d8739a2cc0b078d298..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvK5P(dREG=V@p z0@NWu3kk5QBku%ps1**prByNlqpklK_C$X`uh6%Ksvp> zy}h??-MY27xVU)Z#!Z_F3JMCgZr!?ZE}Q zCT8NqiOZHjG!_+Y-3r#SX%kerpWniTAf+IM6DBNM=Dl?*MA25TlFm-B{LGAu=m`^+ zdTrfWw0U#>){PsZvO7Ed7v|>9%!~mUzO8s`!M1IiqB7cj=VwpPi0WJ7yS-#v(e^Dd zxjp_1b7yA7Oz_?c5{Sv`4$PgA8MD-DYf;gTE%`l53TDSo_T64mv?U_TZ~pX{30_+_ z6>P}qTsSkP&!b?&rtq#sv$7|76%}mA_Rr6r5bwb}D$#w{(#U7fdRR?MO;MH_Mhax!{1 zZQ2&yvv_LMf}LA;W(O4J^?MbSY%1uPJ2hs}mQC9tS{KcV>GLVcUz^#saAv}?P30x) zvU`@yh?(qHp1UckGblTE(xNS!^4CUoE-Xr$ynJhU$=djy(46Vkbz#TiyxB>83%3<)+Oi?4J$Ux4tmJ^)7VZUb1%E%7lWBu(<`fiG54lx0Y|o-?kwxyUQk4>wRziDN9Obd%*xH3l^x%+(05Bo`KGe1 zD`T?qdx96{&dkk9>RaHqWqaA0lAT*O#ALO%hb}BCo|2n5p=XKz&Yi`p3k$Zbh>0m| z?+lxtTQsYnAhvJGVvlW`O4e>F*t&gfbV6Z!d&HdiMKh-4#>Dqdn&<7lrMPUvrqZoD zSFVZA&FSopm^-&PclzY)#JGuF3zqop+)`4$c1?cC#?|YSld^ML+QWk9Ehx^PI;$Wj zA*px5{Dr>$TX$AetX`X6vVF_S)zL}0xjj8?p+WQK6y{Ewk(pDFm^!g%;haUDKAX3d z7gVm^P+q!u>(*tfHFr6o<6 zIH7CK+EigI(4lT%W=I{W+Q%$_@Uwx_43_qOfZHx*Y^m#E`2{U4?d@@Kap4hj=FXTgqqMB3Xxg-CQ$fW>etue7T5@t< zUvGE!tT}UL&GPp4_Ve4ab?eskMa5OsWlNW?T)DEOq@<#9>((t>)~{cfsEz!}@ad9(d&YU@Oa(+R1d3o`K2~(y_0hKu=CD~b7S!rpVo!wns zJ+o%bm@#8UP+*|HzrX*cO`Fzl*icqhR$5W9WXZB+%a+YADgqUYYuB#bxN+mg1q&7| zSh{3sRz^lfMoLOSA*c{+Yinz6Zf@>KOiTn7sUXv)PMuN=k}55oIB_xv^yKE|flSTF z%*@Ei$;s*K?(XX9>+72{d-m*Ev!+c82nq&)kTq-8tXj2d<;tq6%F0Sm>AMI7=FgvB zR#sYCT2fM8zIyfQHEY+dS+g8e+JZ{eg&8nI%ZiGMii<(IIy*tda(i=gLP7$l1Wrs$ z0=Z)Hgb5QSP6R0^F9+2SeSQ7?6DCXmmCqp8f^bPmc6N3)$ceeR8IVe*2LxtL1p|=h zW<*7WgF$pmOw8)lt5>aBwQBY1)ytMuR8*9gg959vvT`m2%m#x}s36$prAwDBTMh!t zmMmEU@&p9WoH=_osK&_6&CAQn1F=BP0pSV=0L5ub3n-+)HCjeSMrvvr1Y~7pWlfzr zWy+MvlP66Ad$hm53>_^%^VZ} z3DvpaxIiU9DH|Mc5O3t==jZ1aLDDWX^dSif6c**67DiK36Rb4>rE_yZ@s5H)i2)S- z2n-2B5D7CD;<>6Sh>NSMySh+<49o!qIZPdthQunE1T_di7!(VrxV;^c22n|{k^M*j zl!8G{f?|-X!5EZHk#J^aX6DqXQ$ZmP$0(s#ivb`}0wF=RKrxctFeX?lL?I?wTU!H8 zEl>iKgurPC%zzMxAO^EQA%?(RU0q$^m;({uFvCXFfZYHm5beggx;m(vP+Oc(9yB?? zC|JZoXs|^PCNc?4Gx(`yL@O363u=EuLklElH@CFF9D##|>wqxoV8%kYC?re@g+@_9 GH4XqD(hNud diff --git a/tnl-1.5.0/tnl/exe/sfx/turret.wav b/tnl-1.5.0/tnl/exe/sfx/turret.wav deleted file mode 100644 index a5cdf4f50ff3a10eee1efe6480c45cf6b5ad2a86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1768 zcmWIYbaQ*a#=sEn80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x19*cccZPJes7AxWM? zEobNZPlw9&xy1wK-2HxcPM`#jVfnsyACEOy@e4V1p8NcATcIAWgwMoFpPz5a)#a1$ z>OK46)t+h#L1Ej5{jWZp>-U%8(@0u$`_sdXMW(`{)>S*6e7H6*K}S%^wPDY*cbDfR zXbVcaH0*f%?#A*QQ&BOCycIXzKHl5pqbRHr*m2;=o2x4dY@|f>#pTsC-Wn2$_PKLUJbrd*b&ao< zq=HS_lmqvk-`w6AXD%nL8(6pE{NqPwSJVXR%gUQXwXD1N_`&IAb-_mRaz-I_%TC^Z zba_j6ik+IQx?@`3*2@p?om|lnZKW!&<(f5N>!thm&a7)scGOf*w~cLBarD;xtNZ6w zhgqm8>AI%2uR3w_-j%)cY9p;Rl(p?+8|Lr3eCNiAH9grrCTgmN?y0TI4qmx^?da;> zJbw#KH9e=e+SxnK-ne;o=e&j_cOwl=6VK#^xjW8WzkY7lg64D|3mr`Z$B2^t)dw$J zyL4>RjJgzW3tep^r^w=-<$F$FzI1Zu!uEnNClg(LORvPr2`l!TzIfr-_QhSLF&>tN z2Iejic`b7`96Wvg%%M&5+KXa5txb$9oI^6|CoSK3^vs!KyH-tW$c^%}H8Zt#4Nb4< zTexZe@l(h4ZJgg-ogU_HYhhvM5tdQiGk@Lg!^e*u*t&dLOL1bbo1L|dqjy9`RmZGV z+x8zma$v`rd42Wyae?j*w)QT*k?G|vQx>n^wg2G$T^pB9@2ts*5At+&baL~HNGWdU zo3mom&b|9~Z(F-~T1RbuQn;Uoi;KHYXnb}>^MpCeH*DLrd*_z5i)Z#Wlx4+-`FXi} zcn5?h}F=0Ug{sBQ@ z(TSObRSg{zX3Sr@YTbqn>({PaGH?2Xj)tnD?Bv+U(4fG;;IPQ}l$_$~hK~Mea~3UI zwRYXQwX2pdnlr7xqp`L$KO-qNGAtxGBs4rKJ|(N5ysoKp!nD~7mMmYjdiCm+%NEa{ zHKnhksji|ZJ1sFTDk3Z_EIcwMAvH6V%&5riSXW zqTI~1W0R)?*7TsX3m+vaM9w$ix(}JH)rOwNqt>yO${{_ zCHXm-X~~HR@$vET2}vnwnK=a|$C8wmOXJ+RWmXuf5H8i(%_Dq;Ob^6R%bLPyQGiUa!nbW6E>hJAp zZ*HissVpll$jiyfNKZ>mO-)Tp&&4T~StCn4g=Sm6-tonOWJnc?Cr!<(1WS4Gqn$9bG+r6DCcbI&IqY z>C>lAn>uCk#0h;po$am74GncQl@+DMMFn}eIoa9SS=re+Il1`-g~g@imDRNk4UNsM z?Va7d{Szimnml>RlqpjtPo6Y!LVs^}S4Ue*Q$s_2ZFOZuSxIqGVL^UgUS4iqUS57d zVNr2OS$So3ODECv!lJOwWX=4 zp`oFnuC}JS3S>}OX=!N*7?hTlm6exQR902j)YjF56g4(Ax3spkw|8`Oc6LEQXJ=Z+>B%E}5jsI084s;aK8sjaQ62OHMV*x1z6+|tt8+S&#J z?d|O#s;#xPwWXz{8D<*P#JalL+S(crs0INLqo$^|wzjset{!S0NM%DqVW?ldQ diff --git a/tnl-1.5.0/tnl/exe/sfx/turret_impact.wav b/tnl-1.5.0/tnl/exe/sfx/turret_impact.wav deleted file mode 100644 index 41f67be23dbb5f674a1793955c0e5cdd02968115..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3061 zcmWIYbaQ*l&A<@u80MOmTcRMqz`(%Bz{nt|%>c%X3>*w8i6x0AxfvK5;Gn*-uBooE zzM-MMskWuMwYs&srM9`gp`oF%uDPbQx~;OKqO%+UJ1X0%TWT8{>RT#1OZo~X=1$I^ zP~2JF&{W=+J2h)cK~HskXa2N|>ABtYl@l{&WlpHBo{&B#qqm`GX40I3h6yPP(mUI- z7A8$-&Rm!Z0c3;ZU}^_el#XT}`wsSCU(FY)eN#UYz>Xs+U7lNYe3A_cJIks!vnX@_O9QW>%C;F zPx#gu-W6MGyeDo=^j^I+AYkii@0hJ~ywkSM^v>Ek#XD!~bnmpS^Sl$buJ8`pyfxT+ z>9$nwo^1`@MO){1hiupy@7=ex$vbu1+EC9KTN}O7wr-B`>e({cGkC?ea_{V|TN8Y$ zw=E0u?$|!Z*L%XYslJ|*x6bhKoUnCHfM?s5l~JCRo44h7rmWf4=ov6|+x%d^vaQ>T zd_(5!m=o$FD#>y>og1s`AZe1AZ9Y1H=>J*>g z?(N&leSFKeZ=Vq18$Ex=+EPD{%I%w{CwlqyZ{5@r>>f8~)7Ca`kF+_PwzqhDB~9J5 zvn#+mqGR*Uneje;#VdDis0r{3ZQr?lL4luV+_asW<`nq2CrsJ8X<4PGdw9$0P20P} zJ^ZpKZ`rxB+|SP^Z_du`3o3(s-LvQH*tD`e-rYT+YxSmW3roDc{4#qs?A$pm-`~$W zzH{@=P4nwxyxoIq=5N}#ZB~h&yI)Mr>@7QY&L|1>_w&h~xOMxc6+Hz3?(X50Q`c_X zwqZh!pSNF7TGO(fJGabj%n0;$_si{BwrSJWRTJ_9J$(J+ODC+|xpV7+mVzihPxp|b zo@JXiZr(D#Db3H*&o45&Y5w+|+cz!hsZ93wba#&`>7KW4)7G6Erq`tf`}+HNN9J`b z+OmD~#!yvH*DjpckQ?Fc;qB)a5}Q@oF>CeCojbN}S~YKCOJ!!1kGs3O zXFyzbW%GnND>iT2v2*9wYROl zJU=}#DkQ+$)63h(*U!%{Ff=?mJ~<<|q_UxE7oq>x^w5wo!hr<-L!V)lKHbH z_jNWkRF)KEr6oj%1^IbcYTbrSTeoiCzIDsS4QoJ_PMy%%QeRV6ke!wo7Zny9;P30>8mznHcJ+!S5P!Bb)Rq_JW~3#?M1_Y2 z2L%QM1Ox|%MMTFZr)B3ASJXANboNc2K5PEMrOQ{XUb}AH+O=y|uUxix!JHYBC-k&8 z)zy?2m1T)BGn>QyUO zEL*a0-s~AuCiHZ+G}hOY7v*PXq$I}2L`Ox0hlhtpMn=cRC#Ga%=M|M!);2V^clAx0 zI%Cefg^QOiUABD1iWSS2E?GE#?yMP8C-io!mV#W6nv@V16BQX55fL606%!ku zl$w#94>F;?skO6r!sHpV=FVTVWZAOiD?vsqS+a2coLN&RPw44rZEmQkC@IW^I3gx0 z666T55s4}3S-AxzVO1mL{+n zdD&?xN%64|Ga@2Dh9tn;QB&X4*4aB@D##rRmn>Pfe8tL@E0!-?2KLMJDHHp;+L{~c zs>+KCa8<&`vl9rK^TToO|QC-*2*wWtB z(?4;_v>CJJ%$vV(;iAP$7B5+{WXZyX3m43vH)qz2=~E|7=h*)wO%m^O9FrSkOl|oP*!?+dOAch6QnddJ0~YMFE2m8prEj@2n0$>N=i%1%gZY&Dl021 ztE#JOYHMq2>*_$wA&|Wd4NV}>($dn}+S=9*0-Yex-2(!BV9*ct=)_5rKz^M(dGh3` zFfa`Prb7Wp1k8k~nL2gqlqplDfb@azq)C$|OaKKzKgjIf-rk;`p6>20ke!|F?d@%C zZLO`XEiEn0%}q^Bjg5^EM>aIn*VotA)z#I2L3MRC$UBvll@%aRUS3`X0;Q#;C8Z@L zB_+im0P=oOQBffTz!_j}0UiL=heCnOD=r2Z4Z@{RP*zqB0w57cj^(50P`gp4fB5^0)S!*hMSw3(LoCgpi7X+hgn4&jc`7~!SEPFNaAM!0A`lz A#sB~S diff --git a/tnl-1.5.0/tnl/glut/glDedicated.h b/tnl-1.5.0/tnl/glut/glDedicated.h deleted file mode 100644 index 0707c23..0000000 --- a/tnl-1.5.0/tnl/glut/glDedicated.h +++ /dev/null @@ -1,2126 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 deleted file mode 100644 index 5d549e0..0000000 --- a/tnl-1.5.0/tnl/glut/glut.h +++ /dev/null @@ -1,724 +0,0 @@ -#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 deleted file mode 100644 index c25583d44b72d67e32a8bb20bd542bef43d01161..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28728 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 - -#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 deleted file mode 100644 index 42ccf85..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/aes.c +++ /dev/null @@ -1,595 +0,0 @@ -/* 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 deleted file mode 100644 index 03a81ef..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/aes_tab.c +++ /dev/null @@ -1,977 +0,0 @@ -/* 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 deleted file mode 100644 index ba4ea6b..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/authors +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index a772b80..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/base64.c +++ /dev/null @@ -1,109 +0,0 @@ -/* 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 deleted file mode 100644 index 60e3a43..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/bits.c +++ /dev/null @@ -1,199 +0,0 @@ -/* 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 deleted file mode 100644 index 80284b8..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/blowfish.c +++ /dev/null @@ -1,519 +0,0 @@ -#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 deleted file mode 100644 index ab2ccc5..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/cast5.c +++ /dev/null @@ -1,659 +0,0 @@ -/* 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 deleted file mode 100644 index bd08bee..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/cbc.c +++ /dev/null @@ -1,111 +0,0 @@ -#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 deleted file mode 100644 index 39c9105..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/cfb.c +++ /dev/null @@ -1,101 +0,0 @@ -#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 deleted file mode 100644 index a64248f..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/crypt.c +++ /dev/null @@ -1,541 +0,0 @@ -#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 deleted file mode 100644 index 304e47803511d9e8a8b00e602ffb633e7d394ab6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 456096 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у;D+u4zqGMN+2!#HQOcm0uI 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

G~k#F%hRQ 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≈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 != 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 deleted file mode 100644 index 2cbc5e0..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/des.c +++ /dev/null @@ -1,1803 +0,0 @@ -/* 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 deleted file mode 100644 index 78b9948..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/dh.c +++ /dev/null @@ -1,491 +0,0 @@ -#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 deleted file mode 100644 index fb10a7e..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/dh_sys.c +++ /dev/null @@ -1,406 +0,0 @@ -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 deleted file mode 100644 index fe0e75a..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/dsa.c +++ /dev/null @@ -1,498 +0,0 @@ -#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 deleted file mode 100644 index 0c04881..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/ecb.c +++ /dev/null @@ -1,49 +0,0 @@ -#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 deleted file mode 100644 index 13c23da..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/ecc.c +++ /dev/null @@ -1,975 +0,0 @@ -/* 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 deleted file mode 100644 index cae3614..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/ecc_sys.c +++ /dev/null @@ -1,424 +0,0 @@ -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 deleted file mode 100644 index 47f9255..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/gf.c +++ /dev/null @@ -1,295 +0,0 @@ -/* 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 deleted file mode 100644 index 9ebb2d6..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/hash.c +++ /dev/null @@ -1,92 +0,0 @@ -#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 deleted file mode 100644 index 236e5cf..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/hmac.c +++ /dev/null @@ -1,512 +0,0 @@ -/* 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 deleted file mode 100644 index 01df75e..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/keyring.c +++ /dev/null @@ -1,852 +0,0 @@ -/* 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 deleted file mode 100644 index eb0b532..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/libtomcrypt.vcproj +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/libtomcrypt/makefile b/tnl-1.5.0/tnl/libtomcrypt/makefile deleted file mode 100644 index db830d7..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/makefile +++ /dev/null @@ -1,168 +0,0 @@ -# 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 deleted file mode 100644 index 90e1395..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/md2.c +++ /dev/null @@ -1,204 +0,0 @@ -/* 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 deleted file mode 100644 index 6a2afad..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/md4.c +++ /dev/null @@ -1,258 +0,0 @@ -/* 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 deleted file mode 100644 index b387de1..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/md5.c +++ /dev/null @@ -1,247 +0,0 @@ -#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 deleted file mode 100644 index 41a1c12..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mem.c +++ /dev/null @@ -1,19 +0,0 @@ -#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 deleted file mode 100644 index 38f4777..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mpi.c +++ /dev/null @@ -1,7942 +0,0 @@ -/* 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 deleted file mode 100644 index bed0896..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt.h +++ /dev/null @@ -1,80 +0,0 @@ -#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 deleted file mode 100644 index 8f38e54..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_argchk.h +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 deleted file mode 100644 index 02107fc..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cfg.h +++ /dev/null @@ -1,78 +0,0 @@ -/* 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 deleted file mode 100644 index 25d1953..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_cipher.h +++ /dev/null @@ -1,376 +0,0 @@ -/* ---- 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 deleted file mode 100644 index 200097f..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_custom.h +++ /dev/null @@ -1,91 +0,0 @@ -/* 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 deleted file mode 100644 index 331065d..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_gf.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* ---- 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 deleted file mode 100644 index 40a4fc7..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_hash.h +++ /dev/null @@ -1,293 +0,0 @@ -/* ---- 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 deleted file mode 100644 index 6dc16cd..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_kr.h +++ /dev/null @@ -1,81 +0,0 @@ -#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 deleted file mode 100644 index 0d5f636..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_macros.h +++ /dev/null @@ -1,241 +0,0 @@ -/* 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 deleted file mode 100644 index b5e804c..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_misc.h +++ /dev/null @@ -1,17 +0,0 @@ -/* ---- 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 deleted file mode 100644 index 0945243..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_pk.h +++ /dev/null @@ -1,198 +0,0 @@ -/* ---- 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 deleted file mode 100644 index b96fa43..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/mycrypt_prng.h +++ /dev/null @@ -1,66 +0,0 @@ -/* ---- 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 deleted file mode 100644 index d2c8156..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/noekeon.c +++ /dev/null @@ -1,280 +0,0 @@ -/* 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 deleted file mode 100644 index 808e32c..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/ofb.c +++ /dev/null @@ -1,67 +0,0 @@ -#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 deleted file mode 100644 index ccb681e..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/omac.c +++ /dev/null @@ -1,244 +0,0 @@ -/* 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 deleted file mode 100644 index 44da445..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/packet.c +++ /dev/null @@ -1,41 +0,0 @@ -#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 deleted file mode 100644 index 4837a0a..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/prime.c +++ /dev/null @@ -1,70 +0,0 @@ -#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 deleted file mode 100644 index a352f7c..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rc2.c +++ /dev/null @@ -1,305 +0,0 @@ -/**********************************************************************\ -* 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 deleted file mode 100644 index e60cada..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rc4.c +++ /dev/null @@ -1,97 +0,0 @@ -#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 deleted file mode 100644 index 135db08..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rc5.c +++ /dev/null @@ -1,257 +0,0 @@ -#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 deleted file mode 100644 index 3a0d974..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rc6.c +++ /dev/null @@ -1,269 +0,0 @@ -#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 deleted file mode 100644 index 89fa5b6..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rmd128.c +++ /dev/null @@ -1,353 +0,0 @@ -/* 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 deleted file mode 100644 index c429215..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rmd160.c +++ /dev/null @@ -1,412 +0,0 @@ -/* 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 deleted file mode 100644 index 0673e1c..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rsa.c +++ /dev/null @@ -1,477 +0,0 @@ -#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 deleted file mode 100644 index 4c562b8..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/rsa_sys.c +++ /dev/null @@ -1,262 +0,0 @@ -/* 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 deleted file mode 100644 index 89d50e8..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/safer+.c +++ /dev/null @@ -1,499 +0,0 @@ -/* 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 deleted file mode 100644 index 664ec7d..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/safer.c +++ /dev/null @@ -1,457 +0,0 @@ -/******************************************************************************* -* -* 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 deleted file mode 100644 index 79242cd..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/safer_tab.c +++ /dev/null @@ -1,48 +0,0 @@ -#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 deleted file mode 100644 index 049feb2..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/sha1.c +++ /dev/null @@ -1,213 +0,0 @@ -#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 deleted file mode 100644 index c7c5787..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/sha224.c +++ /dev/null @@ -1,82 +0,0 @@ -/* 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 deleted file mode 100644 index 0695250..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/sha256.c +++ /dev/null @@ -1,293 +0,0 @@ -#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 deleted file mode 100644 index 8d05bcf..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/sha384.c +++ /dev/null @@ -1,96 +0,0 @@ -/* 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 deleted file mode 100644 index f6cb5c9..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/sha512.c +++ /dev/null @@ -1,271 +0,0 @@ -#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 deleted file mode 100644 index 68f4027..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/skipjack.c +++ /dev/null @@ -1,279 +0,0 @@ -/* 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 deleted file mode 100644 index e3e4b2b..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/sprng.c +++ /dev/null @@ -1,42 +0,0 @@ -/* 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 deleted file mode 100644 index 2bd4297..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/strings.c +++ /dev/null @@ -1,72 +0,0 @@ -/* 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 deleted file mode 100644 index f326c36..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/tiger.c +++ /dev/null @@ -1,762 +0,0 @@ -#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 deleted file mode 100644 index 1af3396..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/tommath.h +++ /dev/null @@ -1,513 +0,0 @@ -/* 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 deleted file mode 100644 index 6199cc6..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/twofish.c +++ /dev/null @@ -1,652 +0,0 @@ -/* 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 deleted file mode 100644 index 99f7aba..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/twofish_tab.c +++ /dev/null @@ -1,477 +0,0 @@ -#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 deleted file mode 100644 index 6c528d3..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/xtea.c +++ /dev/null @@ -1,158 +0,0 @@ -#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 deleted file mode 100644 index ee4d016..0000000 --- a/tnl-1.5.0/tnl/libtomcrypt/yarrow.c +++ /dev/null @@ -1,156 +0,0 @@ -#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 deleted file mode 100644 index 5dbdf7f..0000000 --- a/tnl-1.5.0/tnl/master/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# 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 deleted file mode 100644 index b39c509..0000000 --- a/tnl-1.5.0/tnl/master/config.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 8f097e9..0000000 --- a/tnl-1.5.0/tnl/master/main.cpp +++ /dev/null @@ -1,647 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c66fc75..0000000 --- a/tnl-1.5.0/tnl/master/master.vcproj +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/master/masterInterface.cpp b/tnl-1.5.0/tnl/master/masterInterface.cpp deleted file mode 100644 index 208998b..0000000 --- a/tnl-1.5.0/tnl/master/masterInterface.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1871245..0000000 --- a/tnl-1.5.0/tnl/master/masterInterface.h +++ /dev/null @@ -1,144 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 4ca5bc4..0000000 --- a/tnl-1.5.0/tnl/masterclient/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# 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 deleted file mode 100644 index 6a62587..0000000 --- a/tnl-1.5.0/tnl/masterclient/main.cpp +++ /dev/null @@ -1,456 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 90bae01..0000000 --- a/tnl-1.5.0/tnl/masterclient/masterclient.vcproj +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/openal/ALut.lib b/tnl-1.5.0/tnl/openal/ALut.lib deleted file mode 100644 index 67cde9f676b7dbead6771de243a29cdf1b73f6be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4702 zcmY$iNi0gvu;bEKKm~>d24+TvhGypGsNx1tu92}Nl$F56z`(%8z`(SG7;JAJ@9Yq7 zVC3cP=;lzAWUu1r=)eFKH1Tlq@p4GZEwML6758#;^mQoCEyzI?_V@L6b4W=nNkkF$ zcX0FZaC30UEJ{r-3C=IgOEGqVD2PwYDJ^lW$Sh$1vpn-)ET8| z#RR41q$U=p#yI+vmgwatWifE+!x9}d#lg+9fC@k{$ zX?=*3fx(^u0`yWqNuw+k!ee02V_;y|!vy0&X)XZ<<+4d{`J5Vxa19 znHRvsz>vnmz_5)C;u1l)d5I;75Fs!LvL}HZ%!CsVe_*OhB~o1$5$Zs}k&jg!rhkjr z85o+NYH|7Z03!oK4?6>c4=2PMpx{ve#~Y@3C7cWlEl_p1%mc++A14FDJS26v%v-_9 zz_0^J9VmYFU0mH9Lw!PgJe{nRN=q|S^l~zjloW6XgA!%{1H=eVSF4zSqWrAXlz6d;ub|7y`gFgls+{ zaCpLm2@^n}Cd9zNz{UVdUi=IU3?dAm909^23?d8+47^}5l!6>&9D@v)WB@q}%mTTI zogpk7Y)SWrFfg6P(ES6JCwn=yp-jX+HF!lQHP!GqC9_y)6)Vh;zDq zR8)eS555V6#7XlJnU}{I7#Mn8R0MW`oyO74WPPGE31qnnf9q-n28Qk_Dh(jYMMb2O zsri6B)Swg1M_5`&|S*_iWK7m zJ3*PB`Pb*wX{%Sg4(at#5!eB?Qm~uD`eLa`Se8w%i;4|2+`3&<61u0T%wS+(Xg$#F zqM{PaKlNbqfg>GU0dS|k=I{1V5ebI-g$HC$u=3>~h>C6(6@}&_JPtd5{Qv)7<)8M6 zZWk39=7XIsDl+`7LI3{$hbU`4!V(`H7u$R!0h%m9S!03|0|SF0IB$3`KGEoC0U9U|?X-0joO%7gJ`0sWW0^V9*5XaAss+&;YB;VPs%X1&d9FtJ}uNz@P$_ zJp&he3)c%uo)A;`nPBFbF)=VGf=vOn${4`)T3T+20z**}C{P((nHU&Ad4`Qa9+aiP zH6lEhfC5SYIhT}xa!CdxcXa!x)Eo!rtm6!zeA4>%7$XCJOBo{rL-*C@qdeVAoh~Xo z-A*jsUL3svjLnb!b^54?K(c`Ve~TX|&xD0{yE1ggvUIvYlRPMab;hWObQ?Aw<>+Rx zK2}=T{k5Ad&6bg&(?vz4+mEHYj-#_iMW?%rr?W)GfWP%I0|SHcfwblt6*b0EB@k`I z(Osfa0m}-VY~7HQ-O2HCI|Bm)stQo_dpKmX6QDwK2{n6(xSpxTG!nJ zPT{@5@tF*;M<6|*`VvHg>Rk|R4c4QV25Odr_zVpH{xdM7vyff6ft!@c5TihC zt>paN0=>+X5M=`fP}#xEfZQ?!6}!xgdT`Y+2DEhsZWV$ODl;RfT?mtf(8w)9P(8!U z2&zRu{#u~>#fO0bWHv}8NCZSPGbli7Gf?dZ5&^X$L8e1;E2@Y&gbQkoF)%S8w<DaUmOq3qh41Gb5X>j85f?g8llj0dgytr2;sg~^s3!Aam<&p#2sNMINwOhKwuhQ5 z05&;3ttb^1$B=Z0Y!@hvAj|>zUjS?ur~*M59Z2>~%uaRA&ja=GoJ)&}QuDyW2g%Mw zsfi^p3D6KhGN>W#l3JFToC+JzAaW=o*%_1^p<3e;bCO+Bi%W{~E1|Z64R=p1fpUwH q6oNz{Zh}gJ)RvY&hcCe68PEX*6OzVIaE-*E4oiT;32GPip%MV0Y^yi` diff --git a/tnl-1.5.0/tnl/openal/OpenAL32.lib b/tnl-1.5.0/tnl/openal/OpenAL32.lib deleted file mode 100644 index 86de42002459c4b3e4f37d9bfd092afa9f491dbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16866 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 -#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 deleted file mode 100644 index bbca6c3..0000000 --- a/tnl-1.5.0/tnl/openal/alc.h +++ /dev/null @@ -1,97 +0,0 @@ -#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 deleted file mode 100644 index 436fcfa..0000000 --- a/tnl-1.5.0/tnl/openal/alctypes.h +++ /dev/null @@ -1,125 +0,0 @@ -#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 deleted file mode 100644 index 8aa99c6..0000000 --- a/tnl-1.5.0/tnl/openal/altypes.h +++ /dev/null @@ -1,332 +0,0 @@ -#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 deleted file mode 100644 index 5a746bb..0000000 --- a/tnl-1.5.0/tnl/openal/alu.h +++ /dev/null @@ -1,41 +0,0 @@ -#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 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 z 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

V7iT4ce32~wbeF9=J{&r8kB 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

6J&W03pj;< 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

kZ}JXZ%~j!`gM@_ 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�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

o^#p?vWD<)DMoK=+38L+>x=XJ7!|U(V0K0KUH* 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�Q_z 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

4FXiR)*j0kPWKlc~u2@!AstlZi9{* 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

DfTS9aO2L=H)}u4`dbv)EhwV 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 z

?j=o3CobNg223zavBpqY27vPxl zESdSXGZ(po*~!d&E14_aSMI1_aur|}ESz|yv?(=FmznoHhk_TAfoRIH5{~1kyG(7v zm`p@CJeZutn0b1cvV~HZ3s)97GFNQRW_DqUX5=`YUagxnZw+(AdycuT9CJB@IYi`>o6G}LAm~&P#=?XG|u6*`&^zrd`RsbJ^%>_Qv5^^COd?RQwLt0U4p+b3TW>JcQ zYKlTxv4Uy}=t`hGbg^)-lA_d-(xNU) zD#aFsErx2cNpXc(4Iw5oewtO1@j(aPz7bnf(Qd2sQYw5 zT?>!_4858R44`HVXg4qDx)b<;?x52(At!2r)PWofIcyi?eUJzP1E}VMuozH}$%ouM z1-)Mke0I9CV?an~kgL0E2>i%($Te%=Bie)GF>l^Qy5ywp7(h48lqABhRz%!vL+Zu8uu= z7j)ki?DF2soK(=gB*i(YX`pL-(x6ueLoeiU0o~pe;u-|Lf)R4_FX+OV)PiE%*ZzWT zu!3AX3%ThJ_4?oV66iI0;M=A!ZvF*b%7c8lDfH@Jkfn(wrNs>SMVaZDd5JlYTarO3 z2YS5*;`$BP&0(P1xAIEBH~qlw14+(FP0Rz`n+iTK8hl9|=qA(DA_j`C0)}100Zwp! z{(i0uu$l;bZEZa07P=&8X&Vo@ln-*@2I#Vmc%-X;CK zI4}MMT}2AN^A{02&N(?p>beT(H3jEF-(ryO^-R6dLb#{C_^)3g7T+<7>KZ~MUfeTCXA@@Ts(3N!f?+->?Nmr1V0=`5Lly5=J2*|~#@Y0?EbaxxLltHak z!F@3D?hl3(SFj)?_Wt1H{DMkQ;}PUWXzM;6>AFtrR|vx{lcV_dU{F&Q>}7EF$|}t* z0Nt(>pE*pf5C(O?FuKx1`Cehjb#pHrK*`#vvLw|Xa!Hya!K;N47X#E{$Nm@4GMK|HJOrMP>_>a6ki6r_Y`ihUx;gv zpQ8`-{$Nl!;7gBNf#adg5Jw+pjN5?`t*ZQN21vaI?fZcWfAAf^s8@*QrIv&5*@PA0 zpey7E-U$r5Nf3HJHBGMv1_i6LzaQxSZqWEHxWPh~i-F_Q^GcKB%M!tNfr762OeXqj zVB8l0rxio4?*zB_$h-fSnwR|MmFC7ndV|HF8^}qz;x`X;y=*c07yN>om_Fd%o}*80 zVo6bE1q0}IMEK34X^F`t`QQuNk*@lUk4N-VVQCh6wJweB`h`RosJw`W4EKR=_=Q|E zNwa%?k*}bIwd6^^;@U-*r;i75rixsZN8I90%IJB3vz z;En`na3v)L)Y^_msz9+_;|sZ*7E+H<@A_WYRrk=k7(AGY?C@fEw+=EChI$n$#CJs9 z<(opn1-_u#DYpQ2r#SoqQb=zK)YFG_^BLmvb5dXI33j0`Xp|Z=?Hk?*Djjc!1SW=|gCcv7$R1vUQMJbhdl9DSg-`oaPp z^%~oOyyF*q6FvBvThK5I?mK?tlZm_7H!n3cB{hX1J{~&$5f2`q2U`#i8~%e-CeVxc zFs}L?z0Ef@sWd%4Co?aVL9Zwu)TY)eE-5n9Gi1;!8Zwvr%7fOpfzI%N&YwCkpiZZP z=DtBvpkrg9$A^Kq3~Le?7#x@&cNc=TGlM2$L3hrAR=j}tuzOAwKE#DF9~9MCkL5l zg0_6a>}^6bufZDo9l&*X~IjON3BgY;jtW?(o0N^BqwR1Rb&Xzc=s1}~*yU|^UTj{Oec z>rg#V?F@6nVJrv@G6TeVjzyg}NCJvs>OhA(AVoXFi*U$2icng&>`~_Px0+NqsU|@i)5draw7#J8X zFflNI*0g~5;5&pt`_32`!FLFQPVR)QX#vUiGB7Z}*06y1vq1K0g=oMBB0ZpK};|fViIBirE@R`dS~!k z7zfJ#1PTvE$bHqIJBWFa5)ddIilFhO(fFV{Kw(CL)H|cehoJGnYg~}m3ZhMZK-;(04U^+o)Pr$}FurSo;}dgSKrIQ3rY`7yVdUF~ z89?cYNs)m;1ayb65(5M1pb*f#wV*m1M1$_(2GOAV7eMMZLDhjS0sx601(orj(|Z^p z_ufWS7}jut&cb3~*bky*7#KkJe6naTFo5dL(ff@V7(itk=)S4Z`;8&@F^%4D3<(F& zrg~7icm&$%Ai)4WkqN~A0p&A8?;qxa(xOmW0ZM~5?}F5uLHUkQ8njywBpwdsCqd~< zC=JTrAo*%2zYR)Hgwk`MG$_A=)NO+D_d@9tP#SbN6G;9Zl>ZV+e}K}zp)?bX)rMCf%1<-=}S=hE|h)& zr9VUIe^45ZkptK06FAKW23QB`cPXpOw2j%-f=_n|j0j0~JbPJT81f>^1>0MCz zER=o&rN2XIHqb5>(EV&sS_VpMLunf*?FOa&pmYqB&VtevP`V9DPl3{lp!5bPy$?#C zh0>ryu0Z~L4dwrY((It!G@$z@p|lB!{lo(-i}Lg^b&`W}>i3#C6p>0eNq8?-YLbiW{!R)W&HP}%}YJ40zd zC>;rElrP5|q9Rr9lVrfWqN3ln>s!DZ#+N z3EH(N!N4E^r4^vG9+b9$(&11#4NB)h=@KYi1*IFI^aLmkI?V%Q?|dkK9h3%b;s%ND zf$|SQ>61_zbf6VT{sEN#3`)O+(tn^d3-tbFE+{PkrNy8$=-dvFIm%Ez=->_z-v!DK zhSF(Jx&%s3hSJNR^cE<68A?Bc(qEu7GiaA2DE^_e3Y0d6(r!>X1WG4E=`twY0;MNI zY1sYGtDyWHQ2G*-z6+(9z=uCDFz7>RJ1Ff2r9mg5f&7~Ut#Kxrn>j#vo>1_3B72c>nOv=x*Fojd@tKLW~6fYP9o`$6JOQ2qocJr7E+ zfzrF6^mQox6iS1RvIpsB6oJ(5{7_mJN;^PlPbeJ@rBk7FF_dnE(*00+E|gvkrFTN< z<52o4lzt4QKSJsMP?{IC*HMCjK^jVHL1{}U?E$63p>!IQE``!9P7?r)BV^7El|J(TW;((|G89w_|^N`uZX0oj`m+G;Mrz)%6D+oAMyD2;w^ z@?NO;87O@lN&q3)cQ2G{>egLJPLFqS8`V*A?0i{8Q)`HAq0quSUou~z+1)#JTl$L?gN>Ew@ zN`ubc2I)6}^6jBC>|W(aC_fQO7eMKHDBTC8=R)Z3U^bIKe0!n{|((KTCkA1HTB4N5P8(wm|5F(`coN?(G~H=y)ADE$OVzk<>qp!7E=4ZD|_ z8+0s?1OtO0l!o2UoCf6&)IH4J(0h`Dp>!gY&WF;qP`VpR&xF#;q4ZWL4ZDAt7j&eI z1OtN}l=gQB+)j?;;NH8#%L1{ZE?E|HwpmYY5E`!qDPN{fPyE|FkhP=wO%P&yY%&xF!jq4WtT{S-?7fYPF%Q%58i7-07x2SNE! zP&xxjmqFy0LfU&mP+9^?%Ry;vDD4TQLqRkP14A~52Hh_WqFERiYCyCE149Rh2HnmCIw1vg zWD#iYP!zKF8Fc@!4U`WWhX?V&_a%!mFeHG)nHU&qK(r_W1L!hEkUVIf40NyY5|B6( z19)x+#6JS%KLF99(EE}>lZv3zTtpcdKzD9|^eaI5ple@2d?Ve;w&>?lO2_yyvhET(kolnEV zf}7v4px#^xyNY--Nbw)|J%g4kd?ix} zK=&Yn=HM7$_aKLISc;gJL^Ru&|1VJhIpmm6v+EnUWA1|;1G|^>Pq!-v*vjtEH=Qiz z-L3+?HRc?hEua|&hHh7$?oyFXCYWQkfqV+S=D77hDd%w(bI{oWucviF@4S5d7IYnI z=uXg#JlxSTsDak$qr%a<8{}Wm?Uaa{4dE=53pINugKRWBfP9Z^w=ah!4^xS_Tk`>* z=Houli*{c&ACUov?{O9;kgK}g9Z;@Db_XSKhSxVczk%5_RS2B<5CRFYv9%29T>7d3u{Suz>GE=ICuUAm&!&7ogcO*hR;nt6qDzfbIfh zfZj73YIvaYY51=H%nS_ZmmM20GW2d{0g;f)j=}K-x#zg~pbzTZ#?1#}yec1qgAC1l zP}BuCzY#!SNx9=OnOMg0jpLEwgv1A7&v=_~XVwzo_#5C5v z06DJi88o2@fGz3XA`EgFC`r`{bQ*MnF6|cJ03Gbl(0TCl(r%DJBHfN2o$TF?KAr9? z-HrjB?i}5YA)W3#z0Dj3j11i+0s)}Qe+{}_U%Xxc&u@_Y*e#*0^M(H40a&oeq)br(EY|f-R>NnP66GZ`;9|Dd1Erj zA)PKp0i7paABCh!aC#ExjQxTdUY(^sz}Fgg*8Zsv{R7To*#}~JO9eVzKXiwF09^y! zA_cOrcZw7!NPDX|J}+%P<8L1w_i4|HX*xKs0inC4?K&|8bq?-@6| z)H#J2I+|_7`;7>V<#c z>x?~_85p`lC9Ff&l&Iczl`y;naRFnu>zbf|`#LJkM>y_%ywMAC2gEf<7ya^Y4_yVm z?AP)_i39)kLjm2cBDYyonvbw_vZ&mgyX7DBs^*)mAnp9y4g^4CZ|nt0K`pv>5@POc zSDBl8pZ)v)A7UB*_Er!ljhBHZt+VwBD8$x+$oqS5fY~6)?p6@Hv-QM3(4D=Yu(bxW zK{qjj!jBPj6Ej2-Oil$|i_3VRv-QZo|Nkuy@i*H*?_++#$iUDIzTmmL7i3H?=9SFQ z&=lxy1qY>z3J>H$VsN}cVh~ytFm45@gQ_ziLyZ|Bwo@O9B(vKMrFaQ9S@D;Q6J z4R96cghmdinuADngQHgy;^?VhjZ;D1(7e#F7wkJoa^i2f3%NMnr?*B0QlI_l1}B5= ztx%_Wd|uj(NDfm$G2bbo^1|-V|NjkpLFtXLM6?@hcH&+F z{lnn&+*zU`!oU4Mcc=uYD%&a0z`)SE^#>@8fo?~3UDFw&A_1u{c=)%ut^y@aEJ4 zM4}0HUMKhh@8$>pAQ8goDsb^tCper8FHHcM2f9~T?%Fg%RzIYzyS7<|()_&#B71_n{&8;r$}FBcX^ zzFb%Wbhj}~k0k8+V=2fb$_@iH*Tf)qoqGv;PskOQ?s0!#T7ok5_}%TY|1UW@TVV0NuF<8X{(j1|8A~x$+o1hsVYw2fBL;a^>+!(5wj? z(<#u6Rgf!>CxZHY98AYSM^!E?Bm%mJ1#;!_1JHe@ z>`c-i5tJ*BLBp9$kSmWt*LtzAFoCYqV}e|Hd>C@&u>)wy66DI`=b+U?R!nC=H=RK) z5S$OXdcqle=I${8_?5@oKupM$$G?Rb7?=@P9-l#6c`U)rcno|3I|Ii=4h9AZ#FfW^ z(hLj|h%1jlbB+>-E06bp&cH=nc?_D-ln`eG4RkXpi*TrbWF;8SfK8TQV7(0LEORgw zfNqB11|3<+)Cyukt~}ldVnVJw2A!|S47u{SRfK^7dgXDlGy?;(6!>&uJt+nT=#|Hy z8%mfJz=nb5lb9h_9)DwHV1QnE+zGlF0CMHAssIB6Gvvx+f6%2SENYx#pxA(4c`So+ z<#8R#mB-qk)oAc5k3pAQu)wc8z6QFN0CDBdXxD~~fku0mXSyb)v`;>zRWtdJ{@PlMKX!LK|{1Kk4)zw)>rWFGv= zV-t`{_?5?pK{t~Ty7Cy3OfjxJHUl{Yapmzs(4q1y_MA2#%i&iZ_kynGLtJ_MQi_2A z>B?i!g`=P=kHOA|UwI66KK#mKuoH1#c?>!}p9ON|u_)-447^t!SAZfX4bPRwQ$g-S zz4F)#v;>dvmB-Lo2)C3If%dVcnK)=U|xB=4wM@qR~~~FWU@f6JO*9jNXnJR|3JY* z+?B_lK}ns|E06s_7csVS`^21G>A84Sr2b zI_Uaf_%$(wAT#0D#HjKzFtAC1+ylBM2DJ8`4RKA(L3Rd)8=%WSL6rd~125=SNk%>p z3A-kSiyd^LJV+fAXoi$c1|+~Votc4w9dZlw4=x4<4#+LgO`Hr29FSX}L1D%Lxdr+X zNK_ScA1Cty&>C5GCKFImtpVCJ#3TeN+90<;?~!I;;DFo$?F72V8FCA>j|2k)2jr^P z0+3CRTcD#v85lT>N;nu8n4KWEKraMcv~1i45&_-z#KF$=5Tx81q=pH!c$>opB*`QQ zQrKQqWjX?K*o0n?@$*<17&ySUK#S;uf`DTZ=SI+7!IMBd(4BQ$_ME7< zK!a|r;Fu%@C>Z2S$Su&I-8&r9!D_EFF)(mI zZh>|LnJ^P93c9(A19A)WNsx=@fJI+{!Uu8-^k>S$%srr+8P|Y)m;o|uJ=kR&pzzrMcG+u?zc+(L!$3CzZ2^l4fi6~t+yX5Gis)US z>)4q3LE3iPaDmbo*htVUJI5YhumH$kOfx`n0J#NP3KX{BTcDY2c^Mcu^-4g=9<&bb z91{b>6iz)3KLG{?KE#zkpi7kb1Q|i5fvyB<<7Z&t6M}L%IBY?;s|rK8JRF-r*OZDt zxdI%Zi`n=@pTuM9ZeW#TWD{awU{W^V0A0e%r@+Vq=9+N0fL0zNt^^WbVqoA? z10Si)q-?{n4aC)8`~XUB$_^atAd3)J0zHysVBkYs3G@>bIC_lcV3XZB*g-xrVsr;{ zJvh`r_qv$L# zc(~;_*MRORmVty111IR1Uv62DSxg}HjiBqtTc>ZB+$aO!}r(=C$%^H?~afbKtrUk{`KvcC$FWq3HhflB{s2u}cfkq}QU z$l0LlfnI>_?W+?4-D;#P!N~_Qv)%&Cli_>_S{T|83Fawqnt;rNUk|j4nSp@^em&4m zkjvoL1A*@4;(=ce#08C8f3EFSMv*Ghq#$@p`Fz}XvR#$?JU|@;^ zxhev*u9JtQ9i)2~ND|cE04snb8PLTYd?5Gofr1Ref+rpZrU{@3i#-aq;55jL_i!^1 zI>FjOUgQH23{0;?7#MgGe}OeI2rw}4gOU`)*&r4ls3!!>~s)|52Ogxd;<*`EC8uZ%>b*-16?Lp1yT#Xr89@eynV@{kvz9Xfl$O_lV;YpNSQ!|2)`PMs$SSbm z8$hZ-*Zy#63oGP_^AK`gGizv1A`8?2`6YGmD>m;1advd z5N>0TK9C_|4PZs4;$TJkAVuP!^~2mIHlR(COrX7I+@>Itm`a%$7`P#K2Z2TrxgmE4 zb%L%0gxnppU5tT&8*+D$BnJZnuQuq4KOPoP6tVtbVPN3fzy_+5OhE4B+s5e&x=DOH zNCf1pXN(LCd^;eO6bt8KP|bpLchGsTuR!I$EU30&2ldGLPD?t1riCTXgVym$t^*DE zNQUwhB*s$E4XB_t1fw+Q zE_HB91r=6&pcr8g1udE9%VwMnQneMdEEb^(l(3+xDnXT5G2=mys@ot{;N%B33&e$$ zsh~BS1Beh^{aL0|$Q^XDjGFQP|xq72l;RA%5*W@2CvsD#FbUM& z6A>3-U}zA`;RIbSDwqx8fmCp*i!d;N3;@TkJOk4bVFm`l9MDcmrcf>h1_2u{kb6!^ zF)#@DfSe}(PK1G>B$q))poKFAR5L?s3kJ>!+zbo?(At89b23N{T3c{%f^GyA=zutj zhx3al1A_qg${o;s%T^$j(3(Vq^P?aGgFrV#r37auC=hxeJQ>a}{0s~Ny%3%P=T}Y! z1_4MjTv>&)l#hWyUvYi3orem>m_$iN^X1Bnp^PF7IjkcBvg zg@NfG69a>Yau%rGWhoG4V32;o%fP_M#t6E~SCD~0MMR79E(-&Lh&DtA1Lq$J1_lvG z=Si7`6SPB9L>CmvptA2IHv@x+9z-P%XAtOWMSTcQfU{YMfkDIol!-tU{dNWh1`$Ju zoCN1{kV+#^_5j@jxC-PXV~9!x1|~Bp1_lw6GEoKwrUZ5d1`#Vz_e&%~jDf*G#EsJ* z}T@q7W?TBMC0)B`2ZkmJVuO=o22GI_XUMBGU&mf~E*d-VkSVa3IGlW470PSmMWRQ>n3r>}^2Cb2i zlm;!lXJ7)Yw-OUj2i37Gpm<=q2O2||4i1o+oD2-&dTJntUuI`u5H~sk>d}1SVqg%r zTMS}aF*7iTJMRQBzk|+o@VEtH`tmX`i2FVTF(pAgh@f>KrZz}z1h~yF%)!7Qp27<% zU5rE-7{v2H6#$bc8v}#*e(> zwbGbCJ9x#9fk(!jK$qu!hw?sbXlPt=tLV(sDQ)B9_(*W z*DZ*hfkDE-1*Co^sM?Tlg{XH%QSSnh19kPdR!T82fHZ?^ASMQ;21W)33D**k{+m(^ z3^Ed45d9t~`aMB%VEv%Mb+~?32Bu8VZHZo6K>8&?qZtzZ5dFR=`u!mB#=^k#8{`@P zFCg`v(x6)tLm=vdP}B!Qc#I58tf2Xz5EW?#29Zjz`H>Ly;Sd!JkTeqkx|2T>n`qCPen6pzYG3`{1VIFDf0uP zL_lF~EzH0mkqj*i7u0)_c*2oH3dD#%t5CpiWN2Z{5XI-oRq2vm!K43z~1#!1i>m7rp43g~|AQxF~p zCm+Z~XFzcbs@o+&dFL$16j00T5U9L32gzs}3|v8S3=E)KT>>gfK#{QmRP8T?@GLklb1*PSEQ9bI zIG2I!Uk>4Ua4rJ5dj*6SzzN#wBC!&}i{NYl1ctOMP*y#~Td;uHs&vKGQi z;k*Ijt%vB#-~^Qt5*r}A0!~R#rrHSMRdD_UMa5i2O}qF zeokWlO$HEm4kM>9$jb9i!Lkb&A<=#jRAe(NKVam{1x3ddP?}~|e!|GP9#o=U1vMm@ zmH#kumVpYqYY=V&6K4e|hui>_Xw1qjOq`2Aif@8SD`w>mCeA!iX>|u8+ruOby3>2>mx{!%fPt_l*k`Lcs!h$pbN*J zKw?>f^C&1eJ_DK0q-?;zbPi`m zer;A@U=aDH0J?_$FQ+~zJ^cjnKpMaq{};@@+{6L~iQkYc!@>Cpl%D?l0bhR2!@$D= zvXh4e)aqd>1I5wbtqKebqF$hM&cG20kwk0kQ!s!N9`; zax4!EsL0}B0o@X*RHMki@C0-tx&$*LhdiioW?=-0f$qCM0}38i#vbrB$N~&pAO^gR z%+J8X!mG%@Ai4^qij6Tqk%2)OwDur?hk>DjQG$b!<0}KGWx)uFL6C7;p!_QbzQvJA z*@S};lo1pdK?kicDO+$=$S(K3m7@{L6K(;zW9<^c?ly&2S~joqp30|*{@*a zPy-of4Yr$E`3@5YXkD;`4U~VEi33ziN;oloR|2Vjz{C*_DtcYO_i8dLzhL6X1SMBD z#!RqzZsurY86k9u|-$9u`oJ6$Kr5BjLpeaSQTo^djL4zI2pqvA$Yrq@lRX{-j>POmuw$H0V z4UIysJPrg`)DsIpO*Iw<2G!T93=Hj{-Is}A8$cUibQl>JU^XOxYye#| z47MT>luTe&B!XNCvmz16iX@m7n$l_v468s*{%S_hE& zs#IfOU_1wkxXIwGdx4RG0o0>}X_^Gp1o7}BP@uzHGYM=)xEeTeCWBnV7@(aG8vLCC zc61nn=4>?v2GHyV<66cEObiTkVR1Wl?8fs08(-_ksiC0}}%SXcC(d zdJXYzkoAlK>fqSi4Gm#Xox`{XWFhR*<2@i_K$jkaBXcjPLSPI4`Ewu09;S&I3_L8L z_*M;9XJC*A4WXY0TepCjfk6tC6rt9g2U`~ozV!G!#7rJ_u$ku}K@T$X0?16pKnBhA z>I@9C1sNC^A2KSiFff2-C>TRQmmc2-tAM)tK18QF*wqifNf3JJ@dJ^U|@knfl$uBg{{1IfeqFY5Hc@y8AhbLNRJYC-oPb3l0)YW3?u zS&$QI+WA`jV9=g?E^rCSJn=&<_}*h~=)K1`>h$M-W@lhPzO$Geac40**qFqkbjXd%Ihjc?y~QOdkUNXn85lsvi$m^J2A?Spz3Uiu zQ!~iU%yh_2&Fl=YyJnDF1U+~hVgl$Uj|%X)?s^%ZX$qJ+$lc2@9s~H^W~7^#8DQ5Y zpJ!l%TtgfJxi&eu*wxxx=U9l2ZhM5r6OO)i=JI4_5f1Gz=E{0W+hB7m8INTISe?`I2sC=xj{CR)z7ie`M|N`@ofc-5{+FADBtJI2g8 zo1;J2+91iw;=>M(9iKQ-6*O!#IP^F?LLinF^%sF`z0Axd%Uq_-%$DHmy_q%o-rrY5GO zH0Gx=^CUA_h%!s{rZ8tbWENryXEaN(NJ$N6PUO&Lu8>V)=B#I~c$m!`%%sY=khw~m zBXxJ8MT$jJ3A5+>n+D9~+W)U7G$p2TG^QjmaWgP7=0Y#egPgyqp_-xzPSucmp%6)% zfq|jH9yG8EYCJI_-H!~qrWe$p0AWz00@uC3pe6xm&JZl`1ig3I4RJ3qsAiuByLZ?f zArCtr8dQmc&bfr?$96X|s6GarHw#vSbiXppji8zsbbc#X-U)GcG0YB7)ma5|gA4fn zW|uY==Vn$0$R1#jA3?QZ8%zzvjL3H8Hqdw!NSXmuyOqG?vA6+LlU2j+M|Oew)3=!w zbj~hl3orx2B~1nfP?HB#@PW=9gY9 zFGt3>2pM)&64LF*uuG#rN3}w)Km;9@&M@3=IEHy0%asI>J2ye2jjKsXWRM4Fk;A9H9HV$;@LsDf)Dg)%!7DueN8+-c4!><8^-jalJw=v>!1<<`a zh-GEnfZAPCD2O+Q7c)fn2==zlEIK zYl$Jr0h;Pbx||q#S5G|B&A*Uqh~rUjzXKI{u&dP*o%2)E(%?l2^ztL|&Lr@}?UuucIe7QtP@c*sS=hzo>4HiND}0~I{E zpnL_1PH=k@oYR9`9bFh8_b`L*I>mC^FsPP;UC~Q}3y0&0y<-@02Nk%*0lNwrd_gPr z3x-kdvx9jdKCLt_8FZN>qLj}pE-oobP0Y>AO9z+unRyJ3K7sMhjy^t4j?Ugrp>A%j zK@70KhV;M~P;R3w$p@#tjMSpc5^zL-ugwb#bqxhwV&xJa91`jTQjrg>IMVVMz{QtB zW?l)T3IJVB4{jO7gDTJX5{6RnmDPEPxvAiLAv4o5Q;Wc+`Z`8<`i2IBTw0l$Si}HM zpGq-ns_8*&bAyfyxNipb&<%oczQR25=+X+1)k7G1SG=-`T^_&(GBd zboD9&_!c$j&B9Q9psP>8mkfjQKIA&L)S{yNA_nSSHVmsgQSKK8m(vWeK4L+Behx!$ zQ8KtK3BK_Q|K-AA98?N}^G!hs=t9qu-1w^eyi^AGMa4*0B!X>(B?)-dj&{Rv zT25j*=+-x4FBAsZ?NnI;yFwY&SfrjPoSBlElUNC@rJxs*#DlI>1m_4?^8%XE!QBH; zQ3q|GGk`CbEKUVAG&A!`pl!f-aLglaSjKhTFvylv26*og^^RfWYt2EagD&?CW4mV< zcI7%EN#18AUYXc%BEc5wPC&P>lsO;G@O716DQ-|>k1K4MS{q7;;q2HC~Lpmc?} zDHNP|;=xyyhrw>)hE$rM!~x6Ah}M2`L1}z$VsSPDO4G?VI6f`2sJH~&AOiK1p)Kb4 z_~L@hJWzKKBnZx?44@7a_*zA9{|emvCHbmiPzHrwDhq47LL198x~Uk{7sWmni2V*@ z*qC8F{1zpe-DeEWWyv}D#i^id2AvCtC;dj__;?)m7{fyt<8oA&_<_FJI5$2yAJk^2 z^`*whmqvqXTu8qVQspAXZ9t<6`Jgstd}dw=q{R;D93$Oz3_cVRatUyJF#|FWH1b5@ zg~#yv0emSjwJ$zS$uB6#NiB*;v^(JgCaHNT4Def=<3Se;gIjB$GBA~>yN3V@jUO_DjNOV&1(qqU4^N5@7 zQc^*^3a~Zt#qiM=$Osb3<=vn$;gEdi{JgSM&V^J977zzeH_TxPzgh3 zaZzecVo7FMDkvY6!Wwzt&XJS9uam!@YfzAX5LgfBHu(6=JkT(GeqJiLYKDw$LPs(| zZA?&ZhUYI(Vj%AFV^GS-&(DDth43qoVf`G8tB#8jOEUA}F@Sn0H1yhdaNj5~Co>&X z&N@Q}3!#Y~+~~~AD=h|%%R*Wk&>kiH>O+^*oRUO_qWm22Fi=`za!Gy>c&rg}O*c3Z zfI9SfCE$){w~WeR26ty?D+LXAzfesDV?AR%69pp!0}}%?BVz>(_td3u0NTm205U5Kl84PxgVx@H%maymF&6{F za)dJYxqhI1N66}y^FU^o!Fr%>1hMTHK!*f?SP*QI%)pQU+QdZQuH;HH28ME&r;yA; zzbknP^p0WB9l0Dx;eviw@&`)>26c!Nz$D1+APhQF3q*rfi-II1tWfU+28AC8gHBQg zsROA2VHqpXDoPLwfcTk z32O$1W1vI{;y~RFlHUtugSKmdr225&sr&@04x|QzC*inL`3n|xh&ydT_XLAJkXu0(gY0EwU}lg5aTpjFKD3;>jM)5186M_NFKDi5VrOO#0MQ416$_;;)C1)!^{|WDuZ$iOcu1q9+cvd`LNJ{ zh+(@^86pEAL3bd7_HROXAd-t=C1?XPhzZ7A;Jco|OfUgDX9~;!6U+>v4B#W?!8`^A zAtqslQ&2XD0=Wis?mmbO!XW-r5Ce)q{CA)`sTmm3M_H7Efq_Mffx#C zSU_oKDD4HML!opGlun1zc~H6%N`uOEka?i?2#B5p6$h24ApUwNA9T?Hh<^~uKLMpL zL+M*k8dNTV)O~>Re?w_D&?0R~1_n_m4LU0hqz-)FvLpio_`YRH28IZzd^(f{?F|_d)5iQ2HvA2H&?V$-n@*#~ftd zf2cTUyCH~g1X^tm3NI)f0i{7l{ea~2p!`}W-2Q2(LF>^$?&Ah+u8?G45QEZ+P#V1HLXv^O7|OSU(w0MCzD3rbcrEf#&XHfbhl>P&ynL+(W(209cS`kV+KxxpK zV<7v(p!`HAodc!Ip)}|aO^~`?D1Qc&UJRwzLFt`P`UsQ;-7^o;cMHmY3Z*|l>EBSA z4YcPBln3Are1*I#YbR(3W0Hx2*+gFO)t5rEf!N(D9QX z_x^|4?*b*Q2IWU z25p}Png0XI{|BX6co`T#;#^Q#07`?7#sP`TK>12gS_4X(Lut?vnILs8P(J7+5fFbC zl)nN>Z-dfDp!6ju{Qye8gVKMXG#6;o5a{#;D6IyiL5G8Y%y)wF1E6#qlrD$Tpz|(4 z>UyDk@O{aW3=Auw{OwTsD3k_m^9QMa2;~cd_CZN9FjzwAC@5VHrFTQ=4^Y|&w9iVC zfguh`*F))cC_NQQgAOqR*|QPK2b~oT;$MOCUqR_lP#V;c2Fde*Hs(n(Fz7&OS126} zrL&-PDU@!6(mhamI+ODf?v zF_hj2r9lVefZTNk%D)e#pF`;c~s42lP+xDAx{g3_5#x&}&j zL+NQydL@(wo%;te?Kxxq7n;>x^@JT`p46;yK14>&%X-6m>0HwkA z3QICDq(b@GP`V0AH$dq&DBT04XG7_QP4{K!29yThi!8~&upY|a2BnWe>9bJ!GL*gvr5`})_fYyfl>Q5)SwQy`gX&Ev zEe)j=p|m=b)`il>P}&Mg`$FkxD4hkRYoT;Elm?xV4hpBeQ2uEs{R&F|h0@%h&9{;a z3{p^97fOQ;RRie<-+L^{zz_=+&xX=fP`VdN&xX>gp!7~CeGp2Yhte;h^cN^C2|5Q! zl7YbuN{2$}SSXzhr7NLy2b5k3rME-rqfq)Xlzs@M-$UuYP?{Tbf3PG2gCvwzhtj4{ z+8Ig*Lg@r3oe!nUp>!LRo(ZLwL+Pzh`Y@Ef2&LaaY4E+pk_-%7p!Rj}1*LaF=@U>Ie4nu-1H(5c{~wg*0o_{+N{3Kd z14^4iX*VeC2c=`6bS0GTh0?R3^lB)*4@#eb(l4MiGw9x8P(K7pheGK%D4h$XCqwDQ zPrV zFGFcY&^^VH3=CyZx(!PAL+N=?dL5MB2c?fe=`&FJ5|q9HrSC!MCs6tol>Pvvzd`9g zP?|{v;$IFZ%?G7LptKZ}2H&F$>c2qwI#AjON?Sl_XDAK6Zy8koK=~O^8hqcfBm)EZ zzGX=U2Jn5$k_-&s`<5jc7{K=}OENHk?^~8+U;y8@EXlwCzHb?Hx*+KOV@U=EtoJQT zLhoCaWMBZ_w+u2Ls(v1bW@2Di1f{owXh{Z!BT)Jxl>Pvvzk_Hd28Q2IS`l>62dMo7 zqL~;N44||th?Znv2!hf%P`VCEw}NOU28K>3y#Pc@GBB(L(M${s>!I{v5DoG_lzt7R z`9b#{gYp@OW@2EFgVOdOT9Sbw21+M`XeI`RbSPa3q9qv^+Mx6zD7^(r!|qw$58^X1 zFgym)k__;BmOq2|p!sFc{l}nqhtj4{+677nL+NBFT@0n0q4Yv1y%9=ZfYJ}3^am)- z0J;wubc!#ORsqpW3=A4jS{Fov;vGbT?%9UY;UF4R-$ChQC|v-h`=InJ5Y58CumMC% zGBE4`(V+2d5G~2Ta27;^#*jhdW}t(gK;w^M&~a2I=y<6Z0|WS8W+ny((AC7C6KcWZ zq)ZG9paV2PeDJ-@OppsOKz#7M%uEand!XhW0MSeg40k}Z7y|=neh4&f3z|p=sYkhw zS&V@J{7iuZ=deuGPr3B#nW+ggf|9~%(gxm(*4e>Vv%$n8%org+fKzGc# zsBnNh?4rWb?c~$#0J@YEtgky3>>bGc(#>y(G>-%9cx(niu5x|-5gI;dQFGIk2cn>} z^hamypSv&bKbXhg&cw*T01>`<@)k&_EbOK$&v6zN(1a@_Dmz_Ncy`Q&-0jH$5xN_r zA^>s**c&^T7l7|pW+_^z+-@ z8!y?w4A}k7osiqcb-HUgz*-;~V#y#sVT z7swZIkFj*RzUgM_41EDhbl^Y;ebLPX6KFlqd90)o5;KOEx*383AZ*Buy4?&nd_h4q;4sizSEFE;OTaK(^;Z|6i+PR5bh3ru@f9Gpo?3XUVi=e z|Nq?^FV}+ZDK3NFU3?I`gfCUREKSHm`1%(iQ3uv~q@jqzZl)vR80|P^Se&c^e1qOza_)fSNz$r-|a-}#& zx9f-FEGnQ$T#yA|FYI7~r7N_eUPx!AVrLVFVmq+2Emu0J71e?1vpBSn`;FG_*;Gc|NoC-#I^&? zKNw4nHUD6GJqe4%j^-as{H0!~Gpt_NBV@VDrI@54S|c(T{^NT-jA zOs9*AM7NU;C^dGvsEB|rVF%s)>?#8BJ-9dq1p+ixce?HYnR17TfuY;=KzD#b^CKqy z*4a?5?}4<=3XN{pBbJUT{LP@10e?C#9CO{x*d2PHxAp|+q96vtZ=Y9#Zf6Ev65Q>3 zfPcRuBJFKEV0o-qqTBTd-0?13PqZH3pX$2X?e(RG+T9HNt)TS@-L88Kzx9^EW3M~( z0RMg`G;`RyUACTZdwsjxcgv2=pbM}el{ct*0F?#s+F%DOEPEk@wt|8gT)%DshbvsB zJ9NvA?GQ9l>%K09(n-eeBT4jha@_k-gLX3>2&(g?Rufp z=}Wikl}@K0-L5w}o&I#Y-syCdc&YyX|9@ovf|R>#;sB|4*~A0V;Ic`e`4|f*7;e7& z`46Vr_duu1Mi#K@jU3I#m_YK+U*7!p|NjmaSPX-+KO)y7d2`1UXso_8{r~^}t}aFf z2Cz#yOH>59L$^Sq!$pN>KdA87SIx-404;fTl!A1IsIY)S5u5_RwI!NWpb&p~3smiZ z7Bn#Qg6eLDP-xYX(_Jb9)(NRvj=Np}l?Sk#%fIbFr|S`;hTd3Q)$XB(CzTxcmrzz+kcz| zbZagH#JAn0ppuklhaJdRXl5t@rx{3LiZfUZ55V$3T4#YqcYsQFDNkqU9fW@_fG%FY zW_aoQx9(DrZr1~v*Z9|e0A03Tq9VY*-(3Te7eLKvj&64yWdC%!Ug-|^==N9XE)}sn z)meIjzdeqXfuY;o$MOPyndZhD|<{|#|pBn%DuV-K==d>)n!ru;BzR>ON11|2| zJwUMv^(&~yAPs&%$aA>(VQoAB&i~eXrcCebwzMVt6UY@KQjx>lH|AC&=(p zAe0pVq4~GFzJfMwUflb6@8r$g7x!x)+{}H|?fRh8^#;ftt`|B_7+(5bdZat_0^@~F zcOQ_y_dNg=q~SWC#L`{5r8D$Ir|TJ5upuP?{%sdP`PlVFCo~Xmbi0aZUIP__>p$|Z zKV%86S2|sH6l;QuFK}9fl_j9^8+2b@Cs?%GbqAyt>IP*}5zsyE;HZWa{9q+8jiBb$ z4$$hq?$8sRE-EtJr98c^pl+1}DAR?gh=5|yMMVHwfrY5>begDu><1?;khOlGVz_k6 z4pC-E%O37Eca_!y{H=FE^>>L1wCvj{2~ovk_zl#5f<_nEtZvsg;IOkUm+5p@Db||+ zZLh(^L6&yAY=;+Ttp`d{I$gH2xLKFW6y54BJz{tXR5EtEgQ`D)Zr3;8zZqTvWd%?Y zfI8nrg`?LUZUV&QZ=LQwJ3uK3Y=JAhj_r08dCB?r|NkAz5GS*MA`e>czI^xR|9`mq zKsJM_S%l5t6oB9E(k(k|p$5Z4%=O00>3{zJM^s+ms6rHN$5}ufe}-;Xj_y!U9fs5( z+Q9=cj00pVI6Pl^{rUfY=QmK&2UU&W^5CW2|Ns9RYwv(oua~JAUfRLXz`y`Xui+k+ zhss1P!+rSML2F5&9awOA)>wPz|9@tNa*l3y4{LXyqR`fp{4L6V|NrkSQIY8m-2zJZ zp!SBl$9~YVBar=|?APsj2O7I*-7C=5Rw$+F%fV9{)&+C&rc0%02@^TNzjU_4y-Jw^y-F>=C?|>cb?$H^d zA_6LSKxGh8i8BqNkE7dl3)H2c)P>|)-z#9(dRQJRX6yDn!oU6$p<>AJ5>i0~txa&1 zN6r2UES;`5I!}BrJ@T^TH>frR#oGQ~|NnQF9(lRx*Z=>WJ}M&J?j8u&AqDP^M1=F< z?mq7B1FFEl#q^Qm?j9fx|N4(Fvp|N1ZrQI3(o>@XYC(bh39U)HOQGWc;B4r+1r%8O z^g(J%AdMohVt9A%Wy{b1|5?~ye*N+PKO{VNZUHFcPLM%>l>IeK-Gb( z2&^s;>2?M6y*00aO$4t$tN=)9(R4pG5A;cveH@sC7z=#g$n1q;oI zB9MRt*|K9RNRbP;mktUPunVnApFnEYC*7qYhL`x)f9(A5z4S?UxKC&3gHG2My)0bd z>akp-+g+zS^hl@cjU8$%3=E)V0XT0#S|i=QJe@p{t`0anUckcR1x9#)Dwgh09!T?v zfBgqoID*0oR0zT(jzQ|t;shkKL26Djfx{CVn8!eA3|eJC`$&eDKy{rDs1$${%Ha3_ z`xT_S4MjJ&riP5efNTl90P_Ug5ugGP)N2Qg^SNGtC1g-h2d#{6fXf%(JH4(SKt&6v z3kR-@LG33VsMA0RO#~6YAP0i_MEjyZ0a>EL(p`F_6Ix+)`>V8`Ixm8H8qmtw6{-J;{-N9V2&h&s0|kVO3JWaw zyF*1@c7iI{bf^TV4+Zt*%REq(UZTc;>V^ZIt|w4ME_9ck067dC9^e)SHdlcfg)S;6 z&I&!UqZMi|EOB;+zIgfLH?+pz9|V*oL1H%N%6GhRjm-t)a z|G=vFBZw*MRU1X9U^nu^FZhX}+EkU@-Y-y=JuAp)Q{csUuAeL#&&U$BuSpw{J^ zeV-xahXk}p0aXh=DlD*whS~;BmEHb6-K9^uUEeUCvpm*WdWF9UbgdVpikIm0eb8Nc zrSn90=#$QJ6~+rMXaD~HzqgE`+xJQ*r~!nM6ibk6dVinShq_CT?D!9H2ur7l%F7p! z2983v?-Ou+5AvrBs0{SMTHoJ>Xyxd3Jpy$wDEUJi?e1ai`lRz9sITz^R55pliohx$ ze;@w!7dtP2+PzOYU0=L>4XR7sJziFT0_vFNIl}|3m-wd~@K8MVGUXRE{=gXlSH-;) z;SRV1U=??{is4CUz1{igrN}REBH8)#|Nm~^Bm0U#8bKp)(Bc+adqd&`+G*Tb0vcy> zJp!s{U^Ow=i}10xmy#gkLXSYS?feBY)J25{!Ubyqb*Z5_4q9!4=SMU;YyWiDa&*Ri z0UHRduuFfm{x8Yn?*UDpb=rU`NW*WS6bM$cV+}NAK}|;tmsgV-du7q-i3={0DsW38a3<5)73ui~s-s&nUwY!3%jEutSJRq$?tPCJZSPe{xKqMF#L_w}#U=R~#VCJ&{-9rd+9s`2} z)K+c=21$^~2=)7tM8L$sHU|yF6bNRSgLCP2yRCmoEJ!CS1A`KX3pSONfk9c6L7j(zK?OvCe4?ty$S7>j1Bn!n9|akO7#+A6 z7}QwdA6 z%)r3H&UBrdfq_{GwCkMtI%vwCg9&uSFS9b}PD|!4(55kVrZjd?z5(fCTEqofN>T{A zb1WZp6)-!~BQXXBW(`o=f;k1WCYX)sBWSsaCdf#p5*Y>tW-ZX%Ju_&bI}>UX+c_8*n2kXf z<1#PhWnkc7XPOCej5SCN({4Tn24)+OBok;QJ#)uD(7wK>Aj>+z=6QlF>jEEk#lXPA$^=?S%RJ#T z$oO|G3=GT@K^|b83cB%|c@kSa=w8)HARg$lJ@%!H3=AN74iJNp0T$?oK@Oh;+8W68 zMudTZc{0cXrfdNQ2IeVXciDj~oCWb0Df4u&T3L`iGr*$$AV16mi~a<~ z#cYs;Ol2TH%mIrY0EOyYu;@}yC@cUoZ9$@o!OUV%$Swn`4P#?qU|tPohJylR4cMdn zAj8&!T?V=bn|TA+Wmc>V49uIsqM+mUnYVyN_ksdt8`#`S(hLmDyFfc4nXEuX@9vf0 zO^IM5#X)j=c7X*BFflMN$AA{_voVQ-e6t^{eGe!J90L3CEiVHDi{1;+9!JoIX%S`y zhAAw1+&2Um7&v(t!K#%RxcT`R7&rwPL54CZvv7lMV&)WrayhtPi!m^83PZU(++1u7 z44fiRt^juzF9QRoD3mM0JyD#2fm001mEblLVqoADhjL}OcY^GdfN~YMT|pPENI|(O z+$tcWq@i35?p2^2q%u&h4!0V}k#dYRpu1O<4Y(hG>JtUVCNS58`CCI?QsmHh$ zY_dD|K9Ki~7(x4On3O%Z*MdA~%?OShWgl)99tH+ZM@Bu+4Y|r8+}t3p6OQXIU;^zaV6g+m4o|Bf0|S#QBPap!fUY!VN@4^>ATKCYu&@U6 zl?X5}um*y172i>D1_st3kOTueXjdpG6@c>zGXv`<7EqQCVFT?RV)cW@FIzV=0|RUD zJQfB9&<$lwpFjqLfV8qIfp&7T$+6`KGcd5pK*EQC4YYTkO%`MpSp5w#1_m~{zbqhY zSs54v*pwma6(NBDRj&k5&%wYX%g(^SrmV}#z`(zV6;xQN2^4_}SOM^!DS;iJd%6Xp zL0L{fAGE7f;42pc1FL{02Ll6}KqLbL1G@ldo{~f0Jt(O$@NWkjVj-XgDkcTWB|!x? z({D)z26hk7g_N8uCs-L61b>4z=z)AJ1Y!w2U}InqN@izZ5XuA*B_N^!M1Ylm2nJ3T z&;lkduu2{V1{-#JHqfpl_ELY)t-{I-Y@7KR7}(1ufa8{hO$&6fas@~ylQIVzyA%Th zdle+h@UVe)!Le6Ecmiyo>wVa3LC$7U7GdiXV_;yfYhwq6z69F}keT&sz&shYWguTP zoCWg~*g!W?vbR8NP+=2fVPIfyh43`k@_85-*xMjH9X3vG1_t(a2+x4c9mMN`@J!ek zr5PC5dmt&&f`OCe85;uw7bqk^mjbJ>JFunjGBB`Dt^!-iz?K1W&=d%dg)IWan*lM3 zgG~t3jGF`D@vxPNFfgz~3PEK7wr?QkEeZt(l?XV=urG!r0SUI3Aa5;q2FochaI%1+ zfRiPkoq<6ZR2FlxfUM(Wfv`a*#xOO2O!J-yx`v5mIy(b{ASi?wLFpY5ogk$QOs$~A z;kO;EYA;9?DCEG|3#^KP3A9^=-Twwy0qCkH5%9K1sAMQ8$|67;Bsp1rgLH$!2%#I2 zWI$q&Bm)XE2n(Kg7(`i^d_aDS1>M2T$>PYtz#y0k+NlT%BO!!dkcWjpo&*yNOcO*I z7}yg*d#X8E%0QYxi3(yhh$S?egMmQ^lsp+YS*CF?FbIP(H7CnLP(j54Qo%G46fr5A zzydo!CY*&^3t|a@6ftnJfSkbO1X7!N53KeH=mPf-AhlrUF>rxmMUa<)L4@6j%}aoR zfjtWpMoh{KYE>NQ&J6 zQVqIxlzky50|O}0ii0YD1}06ALpH7f8yn5Zz`%N)lYv2p&4dkPKbsLq2;_Q@3)zf8 z`ap*8egi8qS%nES-@s-HGKuK`GXn#gIjF4#TFAq|W&w&z zCO^<6&X(XRB0-#ifz1k395X%UU|`_T26a+6SwK-F;SSnnzkv%>D>bk&Fz|40V|y>k zz`(g3Bm#04=)?}r9gu2@g-r=mx9kC1pv=L*$>Pcd3M^0!APK5(@<5yNIZq3m2A#|y zFa@*)L?Drmfq_ZD7u4KgUKs(DUtMv$>QOF%Xz zF}~(vU=U;l?Zxb1VqgF#1tCyzB?O8Q2A+kWdMlezkeh))P#aYhC}BZW`GKm!Vn%b2 zsz8t`kVhb9fw)2-E(0eEs9N9=2ZcfzV=_o>F^XCSCeYqsmIzSY!@8K8fq{c7jqN!% z0|QqI$N(l~2C1UdTn4UG2#vu`ngzzO6$9|HroDmZ~$12Hu~#xq&SFfedy zr|>W^Fk6D|_+(*n6J%iE)++;vbbziOXJJ|kQf>@VE@29?+lncdmw|!X0VKi{D8azM z?F=@SLzsbq+bxoZfq}^uWQb=r4+8_&6CMVJ4+0Df96aT0eo_n!JQa_@EgS~6ASMO| zo=RANaQ)|DU{D41+iv5ocgv;SGUEg@Ww{T{62}n1O*e z3Dizywc%x8XyDCZO95%l2JyhnbRS*@29N>Zaj<;_HBvet z&f;O4CC0$O(+S}Tu)P53gI0YaYzu@K70i|>%WeovzR#QF(h6X-)aQ}o)4#Wd{+?9`k0TeJW zk3ZvQVBnLN17+3!3=9nXMj!=TEqn|N1wsrA90Jm8HlQ`qGLRTyU^_3&z#t$CvH{$} za%5&;5K!*t1Lf$cd<+a?(?N}TE>M$qqaXu=ihvf|I#C7&0d0s52DaOvmFnOwAgKJD z4AQO(ieykx4caj+pa)UO!}dy?fk8kY!V_Rq1=(u=%JZO>3FxdK0YiwK1lvr|rLabj zB3_0KbY_x(F+`;T0~3cd1A~AGXj3uMbI_?DR-l}~TFcMCU?AYeCMUwcAmA7c^1dESnz4nGsOM zY*iqKL_&BhY>HwG3<6OwXB`7wmm3X{<6-jy*&74#fB*v%D4GOfkAj?GCIE6q3Y(`4 z1A{;^L_Gro6KMOcK#IHo0|V1XJ_ZJX46uwi$cky8gu$N!(kEymP$0^{z#wn~bV>jN ze zCo=G#0V_xs0G&U=Ag~o|K9`^%149NVp$WFI$%7gRt)NB#s2TztBO}-biCh-8MbZom zg7Exxf{B4aumhx*NtuU%lLcfnKWN`Ii(sFCIp|;)0d>%6BMkhGf(#5Sf>Q-pL3OCW z1rgBkXH44}7#M^Ed_eUK3n(6#Oh6rt>EHm#;9_79)&rd-!jukb));Al3aE?R3=G0{ zoFFFX_#9zpc@WcznSnvr!vVzn%gewZ?CT9;p5kF(5DpRnF)Kj|BEX%LyCB0-ib0}R zL>U-_^FXy4Qz9D!gYbTEnXN7eYD9qx>N|W448jM&&Y1=}TP@f`zk1_t5RF(4-Bu4du) zMWAkW8|dIZ5e5bx5lJ?65e5bkDUb*#3S77t7(}G~KxMcx3md3_5RrlKKrMkDP*0f! zT*A*~Vqg%F^%r7bklX_rO8}M5BJu)HL0c{a9Knr(SkUk+1Cu#F1A~b2T#(9JLJSON zK)opuRe?>QRW=Mv?jUp2kAq}cgc%q>J1AL1GzA`k6JIK5KePboBs(Ssrk8vS3?jNu zK`J$b85s70&QcOF5MTqXBNm7ORhSG+F{}&>BF6l}3=EQ>J?h6mRho#YKpUumBcLq? zYNUusg7V60P!%n32b4J(nCd~zPitdg1_stXVFm^c5eK#vq6`cocA#5%L7@T;BYUvF zm01{=Ko_x!IDj_4v+e_xRU)ns_0A~jT|jc6l9L^D^)W~@xFBX?V4B9rz#!r}6J*~% zVFm^n5if{-4;1~LAUUvpJ`n~6xPDd!CN2R61`)5DApM{n@*E=m5dFR=`u!mB#=^j4 z$j!hY;x8$}z`&XZ>eq^dK-34Js1Jtl7#WyA$5e@gc!Jc=69I)sBt(5ULtl_2%!L>L%YMB*UoV^Gw`>VnlXF)$^A;yi98=)Q2!&U?`5H5?*|Y@pLI zM3O)vpfKkGrORY!VZgx2!U4)cN+2UZL!u%nH$grrkYZpENmm9n<5)C7QDzECF+w1h zF|bC7g2FZz;@WHw57Z0;T}mgC15&}HEWyB@CCb16vIHDAtPD&(AX9Qd#&E3>WnehY z4$39@Y!#ryR{#w zOC@EdFo;xwWtAD&dIcF6M5-aKVqxQzU|;AYSf0iaR_9LNv?Bqr3)!@wW} zN^)R=fs+N~L{1iv=b3^)*>dt;Q3eLCr(z5YDKel$G6UkxnV`%JYOgR!g2G_dDKQ2H zR(p`8B74|6LB-KF5DygW_8`x0heQGkBv^KWoC2!Be}dBBE(ni@trnzmH-rc3`+;m_ zT_n!H;2?6IjTIDvhd>n|$k2Lr1_qIn2S7tx$}DULKrTH6;c>9-13BXiD0zUI1(J)nH)XB+kG93QlM`k_BB(tpV~7qsSb#*U}6OA`3vp0LaD~ zP=UA*!V_Ry3W}vg5S{|W)Fq%&h)LOiEf8e?QV7q2t%H++L1Y<(=fL(CCt(H#k&O^u1=|WxSZoIIn3WqC*_uGyJ)q+wn3X#i+4w*qydRVzn3d-+ zvfTh>m-DWmac1QOjF4!*2rBKFl^-y&seu$<0c8Ycj9OO z*C5;mCN@n_wz>f-44IW%nAq4rif@8a9kX%=6C0Zt1B1vNh-?p&R52*S-2=r6v+@Kc z2Bub!JMM#GiffuA1H%kn1_l$6hio1oUq6DB)(mV#Ab&oF@OaojC*_GefyA-|+Z0f8 zdZ7DyTJ7F243 z1^}3xLE-jpA!zF^mlOko1f$4TNOAQUlzu?kCxg<^7f?aUtUQH@fk_4A*sqTz85mf@ zK&?ZOzidxHiTx*t2hsp8Eq=l5%S|j`5cv(sG8}B@K@R>CBLylSK#eGnot!M71``wL zXateJqM-iAEl~PoV5|g%);!RO3Xoh5VhSyhVqg#g9m4<-16jks$pUgLC(C|N&zl8Q z7|7p|VqgFr`XnO4%*YKc*I5`rVob^m+{&N?&&v1)>;1SM%DMo_GQhU23^?F$vg zuV9mXxH&*xQ-yK^xE(=}V#N3xEE~ej532V}7(s~)lzF&8XQqglLir0AxnF>sY0d~q z^Gg`H<3Q>y89_%tFe|TMypMyaVYZOPk@Ref5vcG1_rKgvJ4C*{0s~NqH1j4gcuk^)h$5H6J-Xr=^&m4gvZ3z!_L4U zstHMiENoFs3=E=L5FQ7cvI)Ml3)C?^^)u!9&NtH2S(1|}I9*iXqZFn}BnGA428Mo6 zOp4mGb+a)rh&q5G2;>HR5YJH@9GWZ)OzWi?7(|_}g7i4ZGcahdf|eV&K-}$$;%+yH zO9j9+kf;YpHIuRk13T!T50G^*R~!d<#FJB=fr05XF9U;UYMMM~SR+TCfk6a(_y?qT z1EnYirvHKr45DcrU=@Ax3=D$vK*xK4e-pw3HZ_s)ZRCL~|a4mAwQh`-M;jYK}25edK3g5G`g^06C9afq_B90Cd&| zl0l&KDpU(hyZB(pHetl~|O5 z!wO7*EMZ{!3v%V`EnrQ%K$>pi(gc!V;A8=%OeWBV9MSo&z`8zwbn$}@KtZ?))B*($ zTnm9D7&uu#xr)n9iGg80sNXH71Hy+^+Ab& zVI3O-Lx{Kl+i7VA25~`1BbkBih!_KdxDX`&u&}YQFffPC$vr9kdsQr2MO0G*;C4N)1uz|Nq|z#y&+E#x^FLp5w3}CDQol?)>3mRU7Y5@0C83Q01Y9Jc4l9L%2 zYeAYAgBUnjyk!{}wBM*OFx&ynd3S1LIUs1C=p=K_eGrz<orwWuVnw*^G<|>bC4Nrp@9%cY)C^M#m zTYZcH2B4-7V+Obt%@|++>OnAOGJ*UmF2?^sVV4Ism3iWxdZSDR#(b##;KNajSA$aHTt-mWk7=TZu_`F5 z&V#g6C+@CiU@%PwoqMwoG~yt}1a`p(E(V4qP|^rB0EfLG6EyH49ui^#g+9|n9*B>G znLu>_V}L<0C_+V;Kt5ucC<5`4D3mK<0QQp@SSw=~#82W(AU`pN8{30)Nf=UL=W11LZrVG+43+5UdgVyWGF@c6~8N-aT zK||E?U>?)N0Aov#LIp6FG0<2alnNBVj$@kWV;l<#VkNLCpddR0a-K31sGwjB00poL zSc);sI2JSzrV8eP;^GrXp&ApofSu@I0y^;A*b)@5tHBn5;)j93bQS1)pVgrB63Yw@ zZ_vb$B&Z7r4ev;1l<;t^_26VMcCozx^ z&IFsnG%>;$9Ku;pkAXrs8!W{bW&+yr1qs8CV568OhA=Sb{Qw0a_hknq^GB!2)Y;|8G7wnVooyZiB8F&W1@;nQc_aW^fDNj z7#K<_3sQ^qG8mW{7>Y|$GV}E^7+4q}m(@a;@$T`-`FUxX=@2gX@@xpRxFjX92qetJ zz>t%f1k+nwl9H2|1W}Th12dnMfuSTbHx(ibzL*zkX=ZwHY6+a3mzV=l0=?V~rk$CA z0V)EO&M(fa00)U)1_K+y8|+~3!gMi!c&Qa7Fg^zZLt=6~_#R2U305u&FbCTnW3sMuaQ;YO6KsQ{01fcf;!UW>Mw_romGcd4%*Pt*zXJAwa;)r-- z^MCc$)N34`J3>~?vf{AjkmpF@=;yHcprxbFv1TrZ)kjTTeGZS@MI1I=X&e)o41}4* zIO>`6jxs3={$u8Jw<<_uF6F3a(h_Fo<@n2y#-uC^QX|e$&zyUdNmKBjmJTzgHj|!k zAV;L>&SK^gj$Vk`?K_fmZ2Cb?;P6q41xzZ89M(*_LL3duml%@eHNy{IeR9?M zIEU5zh9>69LS|Wx*~-jSp&Zf7RqpoxS21(fGjlT8F}5;uKeRUY+-c=y+R9v|t>4HI z{wTqIu61}VN4Tp!$0H6Mj(+BY3{1+5%r5oJT1+a8%#lnQjJh+KbyqS)imc}N$ehCQ z*V>M`($d;0B_$;#jX5V&cTQ1J4s-cY-8p&8UPn0^S2LGgX3n0?Ash~JK{JOn^K3>A zcVG&n&IY++J7j#ms5RTyDwCX~~gdp<~CS zA(CjVX`Q`l5r+_yg>Z>2lbcW~^C<>xW}%~A!PfZ}Hf>idn0dA{msm3MXfu~uGILvA z;gD-dnZWU%$xfV^x1Pg#HHU%Pr$%$@IUL1)%w_J(yva-^B6B&cne*$JMK~TZnTc{( zGke!_G&1Q5GpB_z_tbM(GHWpDGcqgvZR8MRt_)?;6Jw6(WwH?oH{aRF%u{Gn@EINnrkMCS>Qc$pC;{;Z6cF;-%x!hEk-{NK=Zi@OlPWYM{5XV|OodBqt+cEn z66~1oG9-Ign_Jh|OyTHD(qZO43J!!`jt@+F0t-@@l!Ta!1wkRf0}cs8<|^&a9L46= z$Cxw(TA3@{nYojh!bPmjt^Y%UV>>e!Qv@T2HM3`Zcrb@GlZG(!$2ul8MrKWphs;Xu zjZF4p%n=-xOg18^=DM2Jso>BEuw%}d4GWGK4ofCCk$KEKmdq9IHpM1Zi=n3VpVJphwS2QXZRH#-kB$cM6r4}hwc6cTgXQ}cpL zic%AEGxO3RCNeOjW#;54fNqOaD9Kky%}cRTC@O{oj2=8#Kz@Z>=$)CDj$*%+LUMj- zPKpB9GHB(>z>t@(P?VpaYo(w84rfprC@uhziC_{O;F=5!45>-r*tSvt#Ys(3F(@{Q z3&4ja!tDmdc~NR{YKa2m_ErT0NEFr-fHh%@LXZ{)Y`!f9r!+(W=P9VBfUai*tx5!S z!WkJDYdCmVSUMOP7(mTkkiS6~)Khlk<7j1a=Vf(kX7y`l4sK&%fSh3ok_YvTK}R@( z)j098dbY7Nv&ObFgYFCh$%7gfz6=ZuFnPCTW(JrXsDBH(YY|ya2CRvJ0o0W>XGGS= z8r9C+#sZTE^;ALk?;!NDwz0H>ZeN2K0P2l`PLlKix!r>oG>Hk80Ch*-!_0;F39Jw1 zCQ$#<66RhPUe@4dgqfhOBr8nLiI)|o2h^Q(MG^=35#~-%m+}ZR)E`Lp!Q??*v?6w> zyc0N#!R~>{gSr%;zAwz5j_u4|&8%&pliR@l0kxTBVEzH=Z)XNY6F81SL2GHis#3HV z7(jz1i8;ycsU_fR!JIP^^YT)2z{!FEG)9t`lN^jq4m2o%l9M4?K;sTDVQ}V!2!low z5_6pLbCdk@T#JhGiy*=cs-SikB;#d5gg}D?umT5^yTda}GGN!eLsWn|{)suBd6^|X z`PrEa;%Xo>+%oer!CY-H7h)t@nFs3B!;FTMWoQaOJ!Mn{AQwPv1@-E1=OA!!f+7dp zr~@^O!6J~33zW%l33L(@2Lr=NP6mc>E(QkB#W=>G^;J*>?|B#){_rp`SP4P;=V}5B z45tJb7&`eG7(k1{p~@H}L>L&PMHm>qfDS8{VqoBxU|`q;T8(*1{Sjhl4COIRqh@lXqEFKiakR+F!4XXVZ;`4J-VAp>a zr6#7pf(De*+&sb2TUwl&oS&Cc434@e_p+!`1h<^YmFEW7A zd~#wzNof%%XbYf04bBt=49TFj8@%-ktyU13#L*`>-pAD~B$xsHuKFT|`1rKqw9K63 zyb@5{c>2fZCiMa*E44~W&xyC*| zJ}D;~5;B>2B^ICnf@PEBoYcg;(gIi*fzo$wVo`Q#5kpyG4mb~k3mizydxB%o(I+WC zAEb>TJ~0{6@&H{?ngg%Lb5ir-As5%fYLcA%#FW&O`23`-)MQZ2_~GohugUx;gv zpQBGaBt=6?-uM(y4+2^YgVs>QyT_*$ z-~|;V--dYly1IZeE!eS;HbHz*erZW&9w_TTLk?PRK`L`_4+Wfbz*RFi<>W(B10*d$ zYn#lx{P+^^SYRFlIB`Jpty5`QDyY(kk1xrO&r8e&)k_#HKTsTi0x`L?C_Xtqr!*I2 zMk%a~P?DNkz>t{Z>FWrtnn109l2k~g2FvW}d8NtmWr>gy2U5<3XQq^7FeEzXr>3RB zg8^2%ySljs1-ZH~#K(h6i{gU({G9l_{1ikexcUZ!M8X?1$tes0`Nf$fnfZAP8Hsr* zIjP{R>*Me24L930BEZMf*)t?Q*x3VOG&o4g6U$Q5a!VKzOG;AnO2K7%Zej&Pa(-TF zW?o)uQDRv7;s~`D z5{-WTpjHTK-x(5U@$s2?W%^H$FYLBtI>U0g^T1K~V{Bg1UwJ z_{95%hCrI7NcCPxJ~#rM{ry5*BSIL!Bg^rSoaE>O%E=Hmr0H7(N}G^mmsSd@lt4)n zoO>L7oL%BU?M8-VXyp(eUyzuR0;&i=w!zC@M;|9h`2>qLNQML#PR<^#&fcJ02~yVsg>Yb2U1fpq@;pM3s7u;n?CW$8KBTCEX@ZMgYh7zLEH|i zG@#8ru%iqaz!d1-YDkR?s+>SYd`3=YQam(O!yFu+R+^U#YSct83nFcK+U%J5{6Q68UU9eWuQU=k_UYqBRqXWgF#NJOie6e0Hq`aFac^{ zf{IP(z&l6G!H>4U4w(cg($?I1tmq`Rtu;c2lq+9 z?gbO@b}iWTkaC>C(FdFq!1bncuxp58sEen+vxlRfpQ{hZbWq*|2M(-Jn+a_(=H+DO zftoBZ2SHL@kgIcOP%yOp2C9=7ic6D|Q;Unikpe01~uP{ z3sS*-sz6Bo14T7BXMp1XRD4wBgDO8z$(LGG%uoWUJs4cTohYz@s0k)DF9q5XfH)G= zG)XQifu{jb=M~!VVo1p>N=*h=8lXZjHz_j@)Xj~DWIss50^TDAmCBhVP@{A6Q^4sw z9@_kXCSkBFZ2SYcjStGku#PS`l|XW1c#vm^E4=>&YcQBW`<(Eg067`l;AY4#%1n=k zHujS93o1de0ZtUYuD%Q~$AJ3pAibc(7GIE43aT1FkqhlCgA2>@Fc1bEt12w%E zlEDrE1tO$zm7mQ3Z9B!sgA11Uf}+g)B2W(kG*(eukO~@nhxL-dl@6pTDfcVQ1vLpk zrA}T+K?%5M2Q|%LIVKr04jWS!C#bG z0uG$S9Pm(@CwLA46ablNnXu6gXLl@RMrKKBE-30i(Fm_FJ%i(Y9D_sPfe&u)Ir_xI z`d7(`IXR$`64J&?hK}Mud-NbrGQiuRX^F)p;D}7hOo<0~&>29ztsqZ#kC0$c(E%D- zEC!Xz<)E%gK_(~_z(xzf(*=+y1NELDoegjhLnma z?Vkk;Y z2MynWax1JVgF4JHIMUDABgo&+KQtIr&VWJ&G_D9LO^g^|V^Q$VJt!WaVV{{FpPZ9l zoC?Zwup9?zYGr~ngPKc_=mE8p;=$n)pP1v43JQT>XrYx$EU!uFG^*eR*aO!pp{2rQDQCwWB?6W8f|n05-G?X zxlFJ-KrIq*J0w0H*5HbdFD_5Y0X4l~84f087XGk`|MK*<0U z<+-5Y18BQ4KE6CTBZ&b#r^k?zT3k|;Ul|YW@E{e*#mV^vsi1l{3G7r*J^+np<|XF1 zSnW;G`kd7d7Nr>9ufH@RW;l;xpnh9zFfD(5}B4jupmT|%6yZePII4gixJt-I& z7?>EC85t{RxTofoZ0Gm<*_wm3U0|f!7)Wgy!i-+Vp zcm;>3P~H9fgIpn_P{Gg{XpncIqeKOXMJ1Vupgtw65{OUC3C;jb8e@!-fClYRMu4Dg zpMw0H%;ZW~^9pNEGHwIAm@ZH1?0#hXR>j zk{h2{oKjrE-~vgVuvRLh4hPK;R^PKM&U+q=6W4*$pe=;Wd6Tv~&O^3?I+n5LZ9f zAW+@`johUcm8GUIK!$}tlT<~iIf*5iWvQUicu;OPGy{#Tf!hK8zE1vr;C?)~UIEu+ zU}<o2pwjV*wQ&2gGG@TP4p9~uE&H*hq10_7zI9Cd|s(}O$cnJt(%$^}W9y-feKgfNFglogBzoe?CIzO z=>UR*$KO8y6f~eYIdCi#<>!Fi0Bc3S;}>E+s6ku;4uozVmBZaKDu)@|ot>=|G~E3{ zH6gi|{H)EOS6rD}l9FmW2Q&(*SCkLZ3NqVJ&yWGeO)f4mfpdyWiVXEY+|(SX;b}#nkxeAC3QChe z9k^l!B(X%$SYImKL8!dqk|GAZ^t@6%P>&tdb=51;i;oAb2GvVXEr~BkjxWh5&CAwH zt{_TTQU!xvUVcfcp1WVDZZW8wWzb8`&&^HED}hZM6Q<=scY880fEG%E6+1AXPGN)A zg@7bLN2emqTr;d_WMEL>U|^7f>Iba_;b3530G%oWS^x`K9m~K_1JVdG0E$8CKum20 z1_qFNWOX1uNDhQy>cC5pK>|<=GVcdu&K)cQvJ1ojo%R7^gZL$K3=E*v4j?uN!{qE3 z7(lB#K|)}BqLYEaKn&s!&>(WAOpi4G<6{HPPA}gSir#WfdLXOyioH% z{sHZaMbget6U@L6i6j7H&O$Tq!vaLOfQ}vk`2l1e=x$Az9*{e(hM=xHg2}BzGw;U& z1_n^t1ckF8lKT##`S)uG149PLU?_%}cOI$^l)gYxv7rnMb)fYeAP!Uxq!x6b42TA$ z4Up9BLP*$x*dPp&1Jj`WIY{~FJ`QynP<0?ZAp96~paO^i#W3?Mu&4u_=mJ#+PAecb z$nUT`1mf!zF)%p741xLsBn}cn$~Fua${83wure@!vZpaL{6OIeO3TRR9jIksc#0$d zG6!THIz|>}VfY9-DGRQI8SYw$5Hn~=IfMx&nUR*yfCQKskTM$RSY>$W1d?T7U}oT8 z0Hq-i50r)&G4yjWh=VQ^Wn^Fg9`W5XsCS45Hu|v2qL|#LNIXI10iBk<1KYAPSC|8N?Yp;XDw7 z3+xXN3xc^Bf}wE+a51!l);2;o3?O+>IRsvy2^QmF z0NqU217?E=9)_6=3=9WAOfcqQn9slfb|aX}z{LQ%+wld219tgp1_lPu$x#p?9)^ve zdJCQic^I}cFfgPb@j+WdKbV#WGcYh9?B`-Q$-uy{1R@D`FQ|L~l_d}%E{3ZN z3=Eeb9I!m-md3Y8{D%w-3^S1IgG+(auLQ$$r~qgkr4R!n19AotViIEj-IoPb0xs8d z;ATO}Ia4&gI~pH!F)(ZmCdhoy`B}*3HKD1WjK*KWh*)b0(hoY_4_W^KH1%iD_%|6D z7+`BLLHggI$^Ss(LpDP|Yyg!zB1{Ynu(g^X{pv`Cl@OCCgB=ndq&|X)fdRIL6Qn*J zO}-qB--5;mU9APN9TL7vnHU&gYd%5d9Y$0C2y`_M8w0px0?EH+Vqmzy#=rnt?+M}~ zw@ENF%TbMqqIxusKHN47djOu{G0^Dj4G3ef*sqed7Jy+=5+0;zK|KsPUjF#bog4 zvYQVm7<}@Rvz_zvzlj2EQWJ+%a;3^cY1*^~sGz5w+ZPz10Itb;}~ zlSY=ai#THJ< z6(AdN40ym+-$GYyfx`zBV375^AdT*+B~T7n5)yV$5s-r*ZUawF!3+b9En-<-gI^kH zg>fQcRZ?0}DtI{ycryq3z$MH;XVA*d%qs9s4v>=}u5&9&P4zFzgl;n^X2?y<$;nS< zh>uS!E>0~fiBC(+%mJzP&CkovOsn)yO9KrH!pwv$kifJtKET;G2(+#vGp&-LC>3I6 zZfb6F0cg=E#Ab+IP$)o#X7DUy21`M7fvZPQ%ZAB>0o+32GG$E85kBp)q(0~PB8|Coly0lqcuS4xj<{tO&Ayi z7#SEq=7Z`zW-|r`(4Ar|RtyYIj0_Ac)(i|$P<07Vb!m(Y3?Ov{AbBeWhHemT1F3U4 z#Tgh@LDg@7s^7`Tz`!ZNz;FRXOENIL1kq9q41Yj0=)@(^If!-)3=*Jw7R(qJK*v_F z*fTJgLirA$YX!s@7(l1(vY0b4fDYedabRHR1L?D1U|0c?mu6r99kk41$G`xp4?yAe z8FWyjDFXxeS^^mc23}?c22NQ91~m{Z$G~6-qQw{(+?W{{K>9!@gM$1O58~T1Fo14Q z0`Wn21%kqFDoEU%fngblc3@!G1iIwHiGg7sh<0XRxB?P)VPH^TVPF7-uRiD?25ANc ze-Ph}fuRs|V5b`cLpcj1yz4+mjJh*0ECPv}Ffgouii55w0@(+;dw|80f#C#5zZV0; zCy;sa3=Be`gZk|l7!*MlT$nL1XoL9n3=H-l+M9u)9z^>vFsy*muR*j60|N^i0|Sc- z1A_sG_GV!41)ck^z`zg-;@dGWB!e#3Fk@gS1M%${7-q6DFo42wKImk7Q^=_sEPf0O zx1i#n6a7Ky<{8Kw76yh-Q2G~?W(S`S&%nSBI&M3Vfx!rL6ut=qg9SUp|E?f;F$RVJ zkh~`YLj;KSVqlmDqJtS2-hk*31_sa}@*sEfg0>HbGBB8c=s*SrXAteezz`3*AH1?KLZ0xI0FOdJZ2Ve1_oPxNIByU61Qhyhy$rphn!di3SV{s1_n+I z1_nvc8NGH441OTKCIdqpl)n^2M=>zG0f}odFz|qm)wN?_SPeQuSDS(12$cT?M0+zZ zuz=2n)nQ;z6oQloHXyz(149^y)?;9Z1Br(*Fw_e{@?!mt1vM91&P}+Fz|pbn=xYmU5&*6D(67Qwu0irA9UrB4+BFhh>m1n zxFO8Iz^Tf>@DaqfV_>iVolNS@z~Bs`LFpbu`!Fz6L+ME(-~(kC=0o|rp!`E1eiQ@4 zB`E(ci0{L|@CC~M1*Jjfld||QFsO?%Ft9{3Foc2+C1qd$ongxo%)rnH68B_am<B0`gw`XAR2Hh2-&cKic;@dGWJO%Of z85q7p`Pvc;44j$_4DJ$;cJ69xt|DM-2qkz!zA ziDO_$2B{NcV8{dUJsB9fK(rSF!)g%i&A@ODByY&T06Jt6l>b4;34+r1Hz|leIi(pG zSj-t1WI(h%1A{S$wt$QiGlGux0gWxOL;6mPpz~8fd?p6)o<2q)$i6@j4cbEpqSZk1 zLJSOsP}%}YJ40zNC>;u=W1uu>oC2gDbju8gu7rxWK&_1{72LG2O{4eHB-=r2%tQ2!jn2enr~v?ypiP6*OY0r9n=d^0Ew8gm1Q`#|~O zP&x@pXF}-`DBTXFK}Su1^sR;RK^M1z_=lnVb5I)8zXpjvf$~9n7eV}AP(G+X4dR2Y zZwJxRprdSr7#P%`v>}wXfzqG@q(SOH?Hdps3l-0R(#24^4oY`I=_ycpK9t@7r4K@B z(1GJ1^DaaA_nJJmN;^Ple<&RXr9oFRgUqRc^1Gq* zEGWGaO7DQu$D#B!C=D9R1nK_*;x>bD(q$lx~O8 zlcDr-C=F^?f$X~mbOn^I zgVHTfx(iBAfYQ^T^c*O?8cJ`3(mS9u8|Y9TAqECMC@lk}wV<>Gly-yCAy7IAN*6%s zIw;)(rDs9u6;OH`ls*EbFG1? z3`(~^=|xa_H5WkO z0F*ufrLRHhmr(j6lxE>&U;w#`2TDsrX+0?I3#B8VbTX8#gwpL$dMcD&45c?h>HSdp zER??3`(~`X;8Zu~pfnrkKqk<+u~1qAN}EGz&;f)XfBHiC2~au>N|!?EYAD?Wr9t=kf%MIX z@@~sGzmVwerP+Aj8TR>?CDD4KNeV{bx;8&3UBB1u(x9ta zK;n;}{0~t2AC%?+oth`az#s*sHK4Q^ly-sAK~OpYO6Ni88Yq1LN}q?)*P-+?C=I&q z732?3`(~^=}Ay}A(Y+#rT0VWb5Qy&lzs!He?w_5 z&@q^xc!ts%P}&_zhe7E$D4hePtDtlTl%5WyLAP6i{JRdy-vgy@Lg}|q8g!Q@NF6um zI7A@^2019L1EoEnG^oD{QU~g{9K;?z zC@lk}wV<>Gly-;GVNf~_O6Nf7Dk$9nrKdsZ(@^@B9K@bSQ2GOu{tu=3z$bV!Fo;2E z6)0^4r30aK43w^e((|G8CMbOqO8zk7J_M!TLTMJzfzzP=1(cS8 z(q2%y6iTmx(hs1t6zIrlAqEB|C~W|x?V+?Eln#T^DNwoyN;g31RZw~dls*QfuR!TX zP+AUrq%#A9E|fNf($-Mg5lXv5X#i# zo(iRBL+OQ3dO4Kd1f`Ec>C;g9B9y)krSC!Mk5KwQloke^zYHojKr|BrgA$b11kpka z3}#T;6G{hwXeI`R5GWlDqJF)-Ld=^zj-#K4dMrSqV44V3PJ(#xUr zHYj}wL<=%7TnEuY3=Gep^j|2=sm{Ov8b9QP(jp*Qh=D;FN*h6G2Po|irQ@J<6_oCT z(lem+awxqON*{sJ7ohY#DE$^n|Ax|BptF-f^(2%whSE+@IuJw)GBAXJXdwoMTqs=$ zqL~;NYN2!sh!$dCm<**CLFo-pdOwuD1EpU>>0eM9G;x>bD(rJl%5Kr1sND-foLHHh7C}92Z&~3VAunt&x2?o28N$d`ahIr)q90Utd8%!O+ma(8$=-%+f$X!O+0K z7)*l14GhdoOcWH1j7$tnz{de5aMio|xIvB=hO8W7WI$b6Sp!-G&A`9_J|>(&gMp8M zn}Jb~QGiW|QIL_DPnu7aPZ)H$pcn%)pB1+?wLG>xaiz{~+*vI;XY z3UhOV6frQc@xs-EZbxQkWMmWuY2{F4@D$bu%@6W3aDxrw0%-#o2hqq4)yV284ARI0 zwU-s7nO7Xi20o}lup#^`NHPK%49t8oybKJ2qKu5f>O3H=LaYoRN>~j{i9jS67(_v? z08el+^MUTV69+kufk6UlD>nm!B*11VKPy}(omasA~D2Xzt^DrFoD6|T(3LDP!tOyF5y zB~Wr;o(;-?98943WoBj2MVQQ~pldDJnLs11%qk#VOcOa77?@Q-E0LMwK=aM)OjAI2 zK4^fh+hpDh8o6L&vI0$jX@ZPoDwkwnVAcX%z{xxnl%80b4uS4H)&`l*)Gfxqzzn{= zmIbthhlQ2N5;P^P3%2M2D8(6p)>JctCXhK;nO?9nFfbc~aw~Hw4+8@SI}_->HfC#( z8m3fU1_ovukR;Oz(7bcUKhSEEtsu)f!RB2PWnf_L0yFzT6Y||4KQLVd&EfWd)k+I8 zFfjLm707|q_JNrWphXb<;M>udK=W{{OyD~%CV(z?V44S#oCsPk$~qNv!8!9JHd|%} z2Ifg19+NTy13T#Ma*#aqS{zuQuL6bQq&m<-lRgH|dtPXW726|{zBD%f4N zAlFUnwNPS*xY{-3=GV>Ko@~C`GP`s_e#)G7#6UR0U)_Opfxd&JJgwZLBp18Ow&QW z*$>t}9h3wPf&I7_v_?P=bd@<*H46j74JHPLDJ**25uhn|9!9WgWd`njpqYO`Mv$RQ z$}HSRK@ zG87n_K#MPwO}Lvulgdg^A6alqfdWho%C+GJ-Qvcn!3e(mR@s634#-{|MsQ|QcHzDS znpoCl1Z71gWjF3GAV=ykf^L*&Qg-Jq0D0et5p;Jv=*l$EwVa&RjNr&o_TdIC{@`>3 zUnRk$9Ky{4@`4kT8^H}4+U0bCIwOW#6=bp-BWNKBlX3zBQyyp~gB>V#cE)fO>Ho3nn3=FJ6tPBhSY|0SzijY8ns#k)j=U`x}W@BJrQ`Ti=VBlW_ zTBF3SCJ+g#P6gOOGc5v(LF+68K$l)K3;2W9?g-ogxmKWx9dzXlsI|f_5CJL{1i&kq z82Gn?4Y3da4u35tATth1Y!w+Rxt@BvokOV zWrBzj5YYf4z)C;_11Afp`M?EI$<58cV8d?DCc(|Xz+URl3A#Cqfi0bnfq}gYaP z4D8S=s14XaGgIu)YuruPtRxs1*n9NAw;)+CaI%2badCk{0(5=33cCZF2@eAU`(#jX zGbuB$@q-*R1;S%t`_Ie3z&-oP*j*|t#2JL5K(gT_1JrR^K zS*EiyFbIM|h!K?DA<+p^%D@ELLc#6_Dt0+p_JUM_LJpk0z^WLS)(A2%u>0Qt8*>kI z6XGlIBqS(BFfcWPTov&ZED2hCCI|{6gl%eiX%)lnW%D}+B9uzH1$}AAWH-J=w?jB`d$jQI}O0?pjRsaK2JIEm$*MN3w20^XoC!UEqxO-}(KP;DRpx{sBafgMx}fszKeyaz42vg2Z4V86`8 zzyKFDX5ax;^PJv{AY*y{fox1-e9gtcAjk@u83x_;4o(U}pyCQNn8Luo1DaFj%w`ni zW?&H1MpXq$SWs1hpsKK#5wxIDFc72)Bz)--?z`(&> z&Q>GNz`$Mc7}OY5W?%#L!nrF!^*5-_DiCx`7P9|HqVHi!pq81Lg@U;r5aP5|-@ zOrQ-WJUP=r7gFBkVqoC50qrVc+AYDr!0iKaniME_N^%)=xLepjKH!E{C=6_%<*3}y z3WbG@ori&e8(N`ou%)sxFmQK3oW;WyE5g9Q-3j3du}d1sE8(yCHHC zY?GN77`S^NJQ=pBpaANH@D$jNfbOh=G}x6@*g%(Ca!&!JEhc3R1|}yF1_oa6?R>1u zc^McQc;&%80$w=~5A5;nybRzSb1;uj4PWG)5c-+4w;YiG=W2*xrDYN5P!+6BL5c5IG*U zH6VLqARZ84VDeyOVBn862eoonfSr-T<|E0#z@H3J&%nT>3yQ!L(3$N_3wRkA_%pyV zpvhkTX`md#e-ETjz(yb#v^7-VJ*diK;QtI3bPAan?nbeZOZ%smP&)MraDFbEw3m*i<6M; zHenV>^tl^oMCFkP1B1}(7!Z>eWbykV&{h!GItm_PNj448dPgac2q+3b_ooX>9{`o% z$}DV*ybKJ&G7ui9?)?W^FU|rk;VYOJ7=&d(3pXV7gcumMf>u%s%L_Pzh86|3f~#Q{ zP*PxEx(6~unIANK?IXm%@EFv85mprd-H*WlxtUd1-4Y~Q25KyWRu&6u3W$Oep9g3? zf&geoFB1b3=!$n?-EfdfkOvzPrTupDYXv!p4mtHJ~-;1)%l# z!lnXM;LAk52{SM-2}}j8sTNqp1-c+~yD(_2Fw7mysNW@85}-vDU_7sN~qOtp** z48pG5!VCIE4Kn`h8LK z`$6K3g@GwWgn>cWzZ<0f0VoWFLm=vdP}B!Qc#I58A3*L4*$q-JAi}`FAsh)&9}ZCg z4UdSe;Lu@VV0y~Mz#ts?8l>ISIvU$AVHblQI(n6KLD4a2)9F2(A(l28M9Z zWv#-AY}>dQ7=)8RBA}GW4N8~E(87R$lcfsei76l}O+o5XyhRuonC6KyFbJnl1vRo* zW`izIUk+YL0&*Dx>lqPH*yciFFB`;TQf80_U4kH-15&}HEWyBjM}&a^WC=KKSQ(hi zK@pz|GKLE@Hpj&d+NF@srUXjF1t1ZS+rEITErgiC!j>Vxz#v=%;em1qm?aESQv6(m zfr0gpC<8-`@MLMwm7v0vU|D4bw&(l|48qkASFx~#3oM0gKd1t$Z8@HP++6zso2p4|?K1QtlJ>;yRlRD*v4rNLbg z9uJ#3C;)duc%a@E$W~SnaRvql;qz<~k_-&Ohd>n|$k4lN3=G02jRZkq#=_>w%D^Ce z3c}-Hs|LB~3@CYkngvXtFgpt}g-Ka}trMj393+owFtCFfJD?DOrX!gh5)2GSL_x;^ z2+v`Y0fp}ZP%!|qQ5h723n4rKHV;tPEQ0V9Af_$>l|oF)25ihA`C3PJI471Rc0 zR{q1t2C6=VuR*vCOl&JaY4ZlCFl1J4VPZ=GDZU9xaLmdbOl+Vlk%jL-WP6yTLDvim z-vh-8v+@Kc2ByuRJb51!Q(U0yoilhC7)*p8vSomL{RmQ8Gq5#-{P`Hd<6#5sd=!2H ziDe14W>9i`1~Q*X*?@t`3{)gNKP$z|ab6z6if$<6~xE5Pk)+78Kjyuy_sO zu|Udzx1drR)a7QH1PaD?!jcROvNe(n3=)jOUm?ZSXHfb9X;%Pw_zS2YWmcZT#K7bN za_rYoNd^Yi6Os%J0>XdUCW8|DPY@5J0bE-Ag4vgwSim6s8*cw3&{&P+el-5Cw zD3G0;ET9GxQ#vS){Hot zWC1yrlf@7;pv(d)4CMTz7#KElg7PpkBR9BQXJG`1F)1@}p92LCD`T7#$Q1$%>>viH zHw(@={0y8dpxs403qh*b7?q?L804NwF)*BD1Qq67jPl9J48q)ud@>;24BVidj>5dq z(PI{FaN#J-2ugWO${gJ5K_Mf;2y!KpG7mTCN_AmTC|7_RT*`_wf|@T($|BsL#ks-~ zjG)_;K{bN{$cl^H3=9>F!W@j;?-@W%Ax2QT0eRvJDB;OLjWXfB07@7Nj90)RYr$;` zO43SS`GVwJ24P1imxY0oMM{Q&fgR*AH5usj@vIE&y)q08DN;~A2ZJEU zpU z*$?bbP$P_!;sr6_f`xm>C#E zG$1@CwpVNn3?iD4M99Jh+RH7X1>te9se>|^Hbf;4n=vl~gNP1<$H%~Qg^__lM3-Hb zfq`p>ECa(^P+LqypKT(@JOfa8gX}sFs$>iydYIVcgc%q_j6hW{sL%ZnwARxY!ee7# zS_d-Eq!?tLm>dH`A1eccgNPa1bkKOGImkC4^Yr)`7(^@}<_WNYR>F%|LU=-Kav+sf zAibbbdQizGVxuDm%83RH>>vinDsVn#1Cxvl>^5=?3?Rot`An4{<82Rv+)yCLz_3@G zfq_HBp6v@O1A~YID1tz4m=EGPc7hsvp!W7{2?hocC(vR)u1#_b3`bcQ7*s@DAntZW zakm@9r2=eVw|Rh6GbxKOupg3RU;tSMbH!)SK(}W#$myUx7$T`RC*BbBNXKs7?c>9{(yXt zsRtG^k!N5K@dD|AG?zf76Qq&E)B{R3IiX->(I90x2xXw=7z5KBJ_ZJn;&QNxT9ArG z2o+$1KVSMEa+J z70&^gyBlOK$RH%ggZ%>X6$8@`&C>b&^{RQQg=^w#L zzk`%YgH~6fDFtf+6Cg_%m|lQfIa^H;Wl*!}++N(N02CORy zq^l8C7pMga9x4_BNicA-fN~Yr21N#jK+sNOQ7v%(5!D7|KUn?|)q&(6CI+TFaRvra z-F8I=2CgI}1_p6928IwZ0k-cF3=Cp|kVY~CTbT$0gP0H`|FE!aWCkr-f$-Sawz4uX zh>3v4gqf5%q(NtOiiv{U#H1_$?oWw{K}->00}l*>M_P@kmfhgM z0;ywqDbBzkCIb>+TEfY|APyd0=YOKaz`!CdArK8(zh5QqZp zxfh5BP3#KnWC6{i-UrQu2~1=Goe9YFnwfz?TxqEi0|TpwG6O?`gaVt11OtPF9EisR z?MF(;LtGrgz^emgK|&p5JJU-+1_lXTMio%fW>;Zg5R?I}E(H-naDsu8 z<+U;cgBW;Ytk`SNb}ZG6ps9;K&~y$Xqv}!6=uba{!|(+(cE<1yG;BAtuBm50S};e4 z8|sJTt@K67Wr?6m=ovuwqQ(~`mlUO@>Ol^@#JCw0`D}jo(F;I92X;a4GyxxL4?A8O zbj~yAQZA}q06G#c{ftN4pGeQ!JwaDXf{x&Zod^!Tfrud)=e?ew8y@mfb3oTAfKEDx z+;bLB#d|#=7n)J)63-y#_~1xiCx0KLYdjr&f*_Y8!O}3~A}H$I;|agn0DgHGD1@;x^ohK zl~69|j!Ba5mV_pNF!0@s18~t~Np3vSrIMiP6Vg@&_u~;aNK*6G$avUgk;r$ffh$Gi z3({O1LmWZl2cYgvelY{tS4GChgRWG>dp#sL4xIe`eHapRijqMWq~?Ne9VhQ#gI2W_i`oJ9d*K``jvHxNq^bWR88 zt_TnZer5%f13K>j%2Y?YClHr;I#BbV+Q4UE>;pLjDga}G?*D_aK~kR>85lrk2Z7ii z43o10?e7K&Kyi*M1A~MR1NhD?(CuU(e}Hy9fX}UlssT~fY77j>cOAjZ3xm4P0Hlb4 zfdO=`Ors=}1C;}*O@y*xGFu#BEC>x!17d;J)WX;xK1dxg_rv{nWMBZ@9SG6`!Z0&H zGo1_tms=Nt?SW>CH(lm?%3&cVO{KIfc+fdPEZIR^s+_?&YN1_tms=Nt?S;B(G7 z7#P6koO3WRfX_MSU|;~BbI!rQ06yoOgMk5j&N&AI1NfYC4h9DBIp-V<4B&IlIT#qg z=bUpeFo4fF=U`v}pL5Q^zyLny92D;0V@?L@DE^>)@Hyw8tWl;R>a}=bUpeFo4fF=U`v} zpL5Q^zyLnyoP&V@e9k!s1A`>!R16LV26ZS6KIa@%jzRh0bIw8e3Cahba}FxEpnUK- z=Nt?S;B(G77#P6koO3WRfX_Jx`5&qde9k#&J3r{0aSjFs@Hyuk&~wf?7#P6koO3WR zfKHPDg&+8wbC5fr>cQunb1*P~&pGE{U;v+U&cVO{KIfc+fdPEZIR^s+_?&Z4`3cpx z97==FIS085$_Jlw&H+8=oP&V@e9k$jTm$WX<6vN@htiIkY4CaJ91ILbP`(wE_JGpSP&ye( zmqBUp`RJfHSdp6qE*UF$KjBl>ZY-vx9abgX#$=tqi3Np|m}e2A_w{!N3p= zo(l)eO|Z$ar7P#Sy=ItK#-2WY_?s62zxQczk0N}EAx7bqPB zrNQT-gVG0-UjwDPp!7^Ay#z{chti;9hd}Xo8OnbMr5X4k<%ckoR)W&HP}%`X`$6d# zD4hkRE1+~cl%55pS3>D6PzC1A`-!9|EP5pmZaYo&u%8=bnS=St$Pql)eO|A42Ib zP?`y}ixiYjp|lE=HiFWQP&xogM?mQ`DBS?1yP@<3C=I%A3KV{CpnULo=b-upbRIdV z{RpL1p|l&64uR51P`Ut0*FotXC_M{GuYl6qpfqSBBFNrLQ2qlb{SHcl&T0e6JAyWM zaxgG>LTS)FRUq+fD8CX)gYK&WiG%i1gJ{sbRUjI4&<}_{2UT|mO22~AKcF-l=sa=` z1_n(i4LbY?q|X7$2cLru>W4u2;B(MH?JOuCd=5IOJq+b9g3=qH^gbwk21!YPeADlQ2HK}2A_it z>OVmFoS<{bLG21CtpKI)udJ2?Y1f@4Z=>t&u1eCr8rJq3QPf%J0v~7fgfk6vOTR>?yC>;W&CqU`h zPeo<0pv0lDD;q!aJ$M`BJC=fos*8wz0 z1Ro2f==@&9p|@lIcMbJZWg`qA2AO0(XeE6>@R3Z2X zTrtoQy)YxhVTb=pK#uyA6lQ=N?JEUxECYiyNHM}|GKjNuL0*#u4aGrD>V=>2D-UuZ zGyG6r@JYR}Lw&*L^g>Moozx384eEYnB%Q1b3@RWl*qy8l460D2U>~Sq9O4T)G9EIZ z$$~rz$^dEtfv$sf09DmYlAsH2g+Rl@%%J1J7}=N_LFZ$5&#j>2>_8Vd+k&?3Gpn(Kj>KSA&jqPaW?)wZ zZ4%Rf@R-;+K}Y9m)`R6(*o{CZ;%Y&79PAFDgNL;tDtXvJ2Zb=}KzMu%Ocz0?>*}&H zGBB`hV`N|eU3|mAtj`WQkCEBH6Koy>dkM${Lx>(G_Bo(qX^o=6axCmppwn!PAv`t) zrqv+xObS8fi7+uRfG*Z^U^Zh1ozlc?4)P6?G6Os4fX??( zVRnHy-xbCAZV(3xK%D3SQq80+!oYEyiGcxR9n2NeK_@_aHh>aU0_Ys#)VrVqj#wUp zj#c{tN{&3Bc;W#?JOk5t&>_ufpo7e~SXh}E7X;sD(RooNgf0^O6%4IUH)tLM4Nz`(!*@+t$9Ht4Y8oG7re1ZD;X?n02!5M>}H z0~bp<$i@XAVNl|PNP!&(5<{2;F^~&%?<@losAtMtyb)~dc95}mK>8ti!M20=JjX%q z023fF1}>IMpa2JL0%k6K3)cG?q?ZLW{0UJEVlr^CfUIXq1$nw!6m;h{i!=)Z121^k z6>JhroC(o46G_(1@$0N zRnTRc%)XG5)j^woSv5eVI+Kk!0|Tojs5obu1v+I!3sjCX&E;WWVATd2)C)SGM+f8t zCeXp&th!(`CxcFZGKvCa7SQM-2P@Nkb_NDk;~bDk5)b$g^+_OyS%cIt`S3C@u-bqm znPzh{FtB!juH<9_-HXWD2{!KrXk%^{m(UE;H5%#h?lZbT%&QM3Bn`McEk`I9MmKTY=7bo&@57jv(St zWoKXj$-_#Q8K97w^be$Y8t8bi$sm)N?(i`%uucIx2y}Wn>r}9VK!+o+P6N9Fbb31L zbg){`6b$POu;>Di2{XZ>y`XcUW`k^EVgq?}4pFn&Wnf_40u~Jc ziEaa%D+Y?_T`xf11RcJ}x?70@R04vHjFw8i$S>(LP?-gHN~M^86hc-owp-rGeLKPT4fw?9^ ztzrxe+)7X%SqO=PDjGE?*G6bBh^xVP4HT5h4nmhf_UbT#^Nq5L5a>Q`Ze2!jK2vrR zIt_B99wTVwv7+oF^a11yM@CToXHpIk`VQhc zLAen^^FXI?xiC2Ei220eb8q?D3%UuKl3# z%YF}ZXmhXt=-@xl!5yISDE1JLR>3J;3=BLRa_o_U3=AAHknmw(2OXQvAqz4KbjAu( z4(NmvxqQ&UyGOVf7z8+!A?g(&fdEyn1X0hyz*Nr0z`&tAp9^$40qCv}PBn4xvFYM3 zL4$_kNuXoX#h-!B_7?}8(aa)#3Y4G4^FYU@i-V6%7Y_v;n=TF-Sm$IA(*zr0Asz%8 z_Z5E(IuDJ3$qjVYy@v_tEL#>UZUzS4T+l2C$j3Y&7Ecfl0|O6eW`gH7i1iFad;$?* zB_M)gYFL~1FczLQf6U)4LXXy0;H2k znS(tDWPcST%kZ!t0-eQO4dDr}>oGGhaMpsH4QkC9gU-RL`vGeIDoe2Ify}Iz1GTD^ zW!SkvrZj*iLYR~l*yBLF7KjZh?4afaXDfuK!5$4dkiQMW(_y~{Iz+l1!ZTn8UGc%$ z1>u>nyMnHb?}4O93kEKh2v8XS3JK8otqP|DyBZGz1Lx#7UAUqy+1tA6oPDtseEWkdCg@J){5ooRh9D4T+;0;ksvAl0D5*Ej_E z85lrGRtnVHVPI+oIb@>@=;Uga(|imJg6{kb3_2Vp?4TppIE+9-AlHKo;V=g20~sQc z23BM$3Ra{KQY6a5$H2g00-AGU03VvpVG1&dshXLAfx{f!ngXrz;jjP&Dii1mO%6+N z1p%53;IIM}#!MgB85p>L8H4;L;wHHr9bo@CHr8!9|T3gh7=&w>KlmSYgohHrz>!pwm`(!P9Y| z@nvvQ-~km@JfIk15Uv89gq_XUD8RtLI~!EUB2KVBmv{YbY}?u-z79U;xc4vG9dJ zq(VWKfm*RlO@a&zd`Y18p5R|W28IT{9QLbx3=DkPARb5s2d@wV1IPey{K_*hfhGj` za-M+>!TiO^z`$!`0CLY|2?hpUACS}JKsOwN&P3;JVZQ*X1EIAA1G^)L2dynw*nfg} z(At87JrvYc>VPC&0cAq!L<_h_LSfMPD~WPJ(>`69WTp4}>Sf4mw4K zw->@wU4&%mG}sKpLCTS!nFqJx25O`L&25Yl;4 zW?}bZW?&H11w}HbqR$2${I3U5$-_QLlz~A|AHox02i?RiXaLGYpgItACc2;@L{5So zbZfDo5h%$sDa){L1UbnVqEdl@33QdOph*nq*k2vc^&eKC?w6pQ2m^zGpd0&BkarwG z*H44WkT0N8&k5vtkaIxyBnY~IRDz1)N*)FVLDx?pbCfk0IQ&2cfL5b|609@>(>gW= z20^#K!VC<8pxb{~1bx{-$CV2DKpe@yzywgU-q`S_SISEC!w8X4eT~ zf|dx1IL`+$L8}TyJPv@ED?n$r`JM(b7lZ2lpeZ1x3FtV)2ymMpba9GE3TRy!6X=q1 zkvvcZz;qaNTHbzex2P3#KHvdxEm;IQ4e=n@IiNGqMGk?IF4H8Cxko{*G^WjP`U$29e{SB*o+pI)d#4cxWLX#5@HyAri!Vz8_Sq9RVE_{Tg(m1{3IpCXx4`lTlVLB)Uipq=ogO;6(gO0yt6bE&tm>8Ij@-i@pDuY_#(zC@G7{I4u ziK>csfrsLmp|w|E(56qoq`5h zFUlfnAU+4QKw8`b)K6hxddb4TAZmO8q()wXfdO=z2aBkwcqr&hbn(NW3@tt#lsv>+ zL0vlWD$t4M3{1Uj3=E>ypu=PZL9^c+q7Lj%!VC1_l99SBQFN(103Ty$eVVRC03kOE55iG=mFbCI+S|Mg|5^SJ2f6f}q>O zWkkIo`aMwedxGS^`p+ZlXJue2;bUMB^#V=63;qYq42b$e^!uXd_k+Y63j>pz2m^zt z|1FSv^+Bh$iiSYcgRa6w_%9fun~{O(Ey#T#T#^h7f}mM=4$(-6`f!K}21uHT0FD2F z+{bhd+<~?NsqY8JUmQez42t?#&}cjOOmu5doX2HJGBB_mmSkXX2c3y7n#jJAn}I_2!+ zlR;2gih)5!G#BF9Y!DCBt^u8iE}8>zy95J=wiE*c$P#eeure@#YERKzkTGnzQVa~B z;V>T2e0D)l;wu1+B!k@cA7pJI#0(bps{#xRqD2rM2LqERNV3>W3RH(kGcd%6PL=_k zhAvtOQNh3tx^+gh8sZ)n_GO|B45BpYfN-{8rHbFvB zgB?`Fh&Dsybl8`Hg0v0fVkTt+b}>*kXov7@*fT&O*$GkU!Tt~A+AavshrJ5K>je$k zGbsnKbBQr9i1veSkY`d3VXp$YY$Ajg!N7DMWa#7yDFz0%Y-t9DE^tiGfVg-jC`W=C z9ZZ`*nq~z^GcX7qm1bZN5#7U{4k}Z&fq0;>lK|Pc9TJi(>|h`61eaRM9PFUO^+k6< zcs%T4ps?5t;R!Hsv4Ct9)R19da1cGuZU735L!ep=Waw>B4nElk8pKd$VYg&uU=Te8 z;c>7>f?RY46vv>t-4c{{&Vo!~QWjvZ1gSg+$!Ho392PPR44{yKCI)%X-R%cK=YTSb z&S3}L6(YI-l$Sv^GJ(ul2;m8^gBFvDE`snBAf_$>6(yj^cnZpWOCdZ9_6E?>&1Ddt z1A8pU{^by!2fGI-AFY7!0@$lTK3oamMX-Y|0uWsd&c4bC?ClZ^45Diwyd-we5^vG9 z5MByETC2o6Uf7& ze`m`vFbKzj(kBDse>nyQZt&6;aG}TpV)AIoGcfQNfC!KcUcnusVfqY$`oW?=-0F)1?$9R>vtD`Sy7X#7@yfdj;VcbEAYxL7`e95D@~ zijC1so`FFTv~K1Y=wNeEE=Hx~WCl@gMkPg%ZU&(sP~7oC$9GwTz~!7UBPiuDDRT%- z1BHwTBgm;t$~;2ypf-splq(D) zqY&s|b5R*aP`Uwm0@SG%m4g~(BD4>bFccVHfJ4?oC>4~Xl_0Zl${s?KK$X4Q@h zAEA?=0#_Bv4G_8rO0-6dpd)KRBi7eI`OJh7l*m8_n+pkm${89^xwRL-k_!hu87iBaeeKd3PT_8OBigA(Xq zb5TbqmxY0gMNg4|fdk|*E6^#npe__E1II!|28IgIdCVX_2Lmt2pC3whf1<52FycrRK{Bn$HBqa4*PleqeusS}MW|Kn0OM z<6T7t1~xk-1_sbI9V}v6;E8-OZAjJ1zz&+o7t?`E8#J~VL z+BZa8fSq5Gfk9jlQav%SgOPSh2K@YvYbu`)1-i-1;gFe!7$fQ}Rv z7lqVE0y3cHh`1QU6cP4!ybKKD;7&c0vIKj8C`#Zw8C%|Ysz zK}8IS-I=#E7RA&}F=K&RufNJxmwf%Y7VYk~WA0-zp+_$g4|PFx%`g(7YXn$Qzp z3p!F*95m3wE)KdFf`ftS0W$-Ggp#o`1B2iq&`G|M3hee03=EQTAReq4CMgebaSQ{; zCS?W&c=-{@Ab4Gwfq_F(RVF#Hh(S`BK?Ph;$bgO%mQ;c8SQywqj5yGd!V>e@ABZzB zNQ!`54JtoD$v{$#4Xh262tme)#HlbaBuJ{MCNW5ggUVvnOa@5_P;ydDV~~^tjMpTGBTC!{r=OXZoKu>Ts_*E- zfXdS^EiTf}$xPBuPfpea(V1ozX1WC+c3x?PZhBs+zOkOMo(aqZ2CxR0aY>ma#V8^S z;O*HcLi)v(#UM))OH(rQlk@Y+Qj1F9TRov`_`s(MBhLM00?DUVlz=wb7wcs(Ff%X| zm!zbmrs-ucurM&dgjvDDnfZDd3~USx<)EXbAk27o&=HbpnduNN_*5ncv$!NBu?Qs0 z!oZM|nFP~YT#}NLnFLW%l9>xSxtEQB0eohMoCD;+c$hBGnZe2Ni75rixq2C(eX+F-MUX?(LPLD~9bLlwgPc5r!AJg}9iijm8H|3yaAJ;cu%kE`L<$`Bu4TAT_x0u+4UW<2Lk-E=esYX7De{OwB7vEXmBzV}Km)ZD!r)h$>z0$4Ud#Y8 zCccCLRFFWAT#GMGEn!G0E{TVqnFcziF)uYWB{d~Jttda20dh7m1Nbl-`W!1KDa+4H0VS)F#FElt1`3ZBh81s+13ZIVokN3yJ;Pk%{Q@B6A>G>kcFvviAg!B(DM}Oa;k8Ad|pmwUN+d7Mfs&AnR%%U@Z*l46@#Z=KxhcKpdj&7 z;f#Qy)RfHRlKdi2VCBc>CFZ6wfI<{x9rlBT3!rCpr{|R>$Co8SO4Gr1gfOVgOiE17 zE-i>pN-PEiSW0PbZY8JhY1}!;)iK01 z-o-V<(b)r}23jZk`Gcxv2GB`t6rCZAa)1)a2MRm-l!6Y61XWP+Ir(|%pn?i|$}YXm z6NVkX8y^p-m^Ldp_XfwTn|zvq2dFR0DwX zYieE!1ITnxB>?SCfo`4fbM%P^A3YAL_`s(ngB|AS9}h}0@dY`hphN^7U5Jk_%E`2nbQd1Pby*~IQ4rz(SC7=d9LsDi+Jj7*qj}L|%XN=@t@M)AFM}r*-ZZv|c zv&4deR9O2kIUih+fm3v9dE+i6zMy3=|&_ z40lm{3fN#!ySz9*IUCerDq$$j$S=)Fi7&3qOJ;!GxZ~*K6d&N~=i=$-9`EAn;~L`1 z5TBP?0VIy$Aa|Kii?tABNoNrtdj~J@PKtu zK*}vZxx~{y9$ebPTKkD9Dd1uepC1e^gq(x1G)PD}QW*Kba(J^A>U20C)Zi>FNv!~%a2g+<4sJ&|`XptRq-Cb& zq(It6kn-Cx0F?4jOGTJ_Amb&7BaSmc6(p!}T#}fa4T>Iy_;_&N0c^gzU#Nn!0(hKX z!N|bC#K6qRSV6-*HLoN;U%@9cue1Upsas^IqflI2pbJuJq-&(3P>`9bYoTYZXQs&j z8tO{TgS3!Kzy&iXbByFOhOyrQLf!3pCQdw^zsLsIO2=J6CMl$ zeb_KK6CkHNc(Gkvke{Ces%(pkQgaeZGRsmy!=j+v32ya6H2V8G`TK#}e2D5BEDahh z1D}--87+hMK0w`BP)U)Pnp}&Xb3s!?8$5568zBXQsy|mgMJVCdZe+M!rB3w(*cWz_5gfGl(le z%Z0%vK?s<6=w}dv)Dd$A@ewED&LA#uCGHGj1vdr;(3W(F>lonvh4EoD%-taVU_OHw z-k1WNn*mA>plwJXnw^0Gv>t*HbcZ#F&&0q0TBr!5TGl%55pS3v3QP#Ux*3=~eV^M~(1#a}^b&{^Ifc{b1i z7oc-kp|lf}4usN?P&yq-mqF=PDBTOCXG7_gP#XOlVbBVHkbPpHH5j0Ch@f-;lwJ;{ zA46$w(1{Kl3=9rXx(Z4!h0=SVG-zWw$lOa%J`-q34F>~*E|gA!(lem+1t@(RNzP0j)&6eP`V6Cw?gSDP1oJ@8@0Etq zpdB0_|AKZIfoKn?csP_!gVLo?x&=y4hSIR}f;U3>2cYzMC=J>q4Kf$BRS!h}go?95 z&+V0j(xCG)K=PnP%^*4qDxM0ZE1+~6l!l!TyaLMK2BnWe=^Ie`9+Z9prC&j5(3t@s zd%i*Wf1orIXlDrMyjm#D2c>19v@(>|g3=XGx&cb}LFqYAdKHx30i};Y=_^qB5tN3V zBm57_=K<}R;$UEqg3=mL8oZZ^gMq;X%8!N8sZhEYN`nrg0{O2W%AX6RS3~KYQ2IEO zhMgBI589;%DxaWqER(NH=aN*6)tS}5HCr9mfKfy|o+<*$d*yP)(TD18A+ z--FVBp)@OKvn}YHZ73}WrD5mvxP`V6CgZ4^->^%YHKY`NUp|l9}d|GuV?E!jZ?u63Qq4X*!y$MPmh0X*B9L$qfznD)+5k%XL+KYqdDZ&3OVlx7AUf(JSW6iUlOX)P#i z3Z=n^<$=!0g!03nbRv|_fzstrx(P~yj#2`-Zw8bPJ4bgNl)n>7AA!>6q4X^%{S-=n zfYQIAH0*p`(6%d(`LfXSZndGbC6o?<(#cRd8%h^K>2fFy+M^CKrx(hf3Z>^j>D5qr zGnC#5rT0VWV^I1kl)ek4A4BO^Q2Hm7W`v%L%MPVMM>&D)7l!gBp)_bmBuLyC%6Ej) z0Z=*_N*6-u2~c`5l->xXVdwKchVnl`X$H{FInX(_P+Ad6gEm@$>~)6n1EF*RlrDzS zpu2QH>R{*d&WDOGhtgZ2^m!A6sPHI&{7 zrH@1Dt5Etel>P{%|3hhB*!j6oS`$i}LuofC9SWsmp>z(Eu7}dSPr5T{- z^YTGyStzXorA?r;6O@jJ(#24^5lT;l(y;S?H$nO5p!7>9{RK)}L(lbffzrWHx)Mrv zLg@uidOeih2c^$K={r#RHI)7jr8yNK^^ydXR)^ANP}&trhd}9MC|v}lo1pY0D7^?u zZ-UZ?p!6ju{Rm2bg3?UTbApASv_6!Mh0>Rx^dl(!8cP3y(p=DUeWjqZ5|lQ8()Li= z4@!qY=@ckk1f?6G^eQO514_fr8NLGLKZ4S7puH=gemIo2fznP;+5<|%&KnMa@}r=1 z0+ddJ(m7DN7)rN6={r#R36%Z>r9D8~G&mR-f}wO3lx~I68=>@eD7_a-pMui*hL#G* z0DfMvp@M>;fq^lYQ~;CUgNlvJ%`FVT8VH|P{KpqGlEwhOYmI?HgF%Wx93lWELpz_w z9_}qsW9Z!jy2gzGgTD(jBH8)0@r?xw14C!*mluEj|Nq~37&LU*S^A^98Dx&(x6ax> z-4?xIPG^V;M`!Dk-~a!2x~Q;p+Ngka!06TkCG6b=0j=Lk^gC@-c7RSc=yXxx=!RS4W-26rdYzrjbAd%M1(CPXH<~+ko ztq1s9_!$`(x+?;@T?H)NIrv-3LEKUSSje^<;O~fKWMDY(gPDKdg>F}#&TBKj|LYDF z>2y&M=ynJBg{Rw902EZ+?mV3$pjd*&jq3-HJTxdk=J0}y_Wb}h>Hz=xgO;v5ovt7F z`#@Kpb(iwMtn572?fL=aGSKnFV1r%Xbe5>Fz?|Lb`e7Gn#JDp=MW#3OLuZJJ1js!h zDk9yX0-Yf$0^Q*}VD&C49GxL5JV>tSJl6WH#1JIe4USQcZdVStvCy>C9r~g9h)(B) z=(zaU!@ZzkQwDh0xv22$01fPdTm_CiP*g&b2-Ks7mtG&}G*JPCl#2?7;Q^2ea5Qv> z@^prNcv=1b|Nl-Fm6wA5|Nm!UfBEL$|Nj$M*k8{1_y2!)sEB1a4}WVdh+WFl?aI*| z3i3H9kXbrKAZe=8^~1}^|Ns9p3Ni|?2{8&XGV@9EsqzVf4w;4?<;@K``kPsW0d!`z z9q2ee6$WMwZf+2hRhW@c7<@c7Hv6&nB4-fBg6#}rdS5o8o%bl_rOP}5^%6h;Vp3d1DSSs5T|J%vH%oobjcFmr&kLb#fU zuLqB#Go9cBZCwT(Rl{5f+Ly@AWCS{WTLq+xNfC4mvMOk{iWxL)$imL_Oq79vSp!t1 zFgJq+G}xHtf=*`E1R2T1EzQ8dthE4i@&IVGjER*gjF*9dSsP?J6R01>tg{#C==2>R z({;fX{S{$gU^W6xaWIE~&f#Tc0u9G98@~aW1v&wdgPlnNq}&>$27CY@vkgd+Nf&e& zT*p7qS<;>$%R0g4>48q%?gBHpKpyM{`GIL6==|#*uv!Mt!Nd)a`F%QA zEog3oc?MV%e9HSwu;^cq+h&6-WU2@GVGdXnbOtC=?cenV?gVm=}YYA|NZ4 zfz|4Q&LCb5W|o1@a9;!Vs1(Ss^k0~2Vjm3cR4riPORY~*^->G6AZfzAwNIRH968hmRR8&fDKM)rfXgHAkR zJ_Pn-ATI+0i{1;+A?ejD3=D5T=k&7Zaf=BsFmUoPf>kRsaF_8hFmMVof(&I+X5j|i z2gWG`<#KSp7iD1J6oztnxbJ}uSrmbC1-L2A*Ov*0Y_L2+? zoVtvltjMJ7#tk|Xgj0`kE!bpt?%g2o8!_$$b3M4Xfjnr<2#y?OAMSjRGaMQ9Ku2dO zhj5pHxK2=R1UKk-D^3@vGh(wF1{c+q?x_85kJY1#&>eg1~Oj8J!IL z+gU*+u7!XrsF)ORkpLCgOv@!07}z}yff6Ij304LM!QY_SK#-4xKrEpLYzz!S$)Lm4 zGC@QMh-d&2U?m`efs=)ije&s+q_UQqfx(8|o(*)BB73Pn=#C3z1~$+@J$u;%aNM%6 zF)=eRuvdU|GAVPgflec1uYzP59ySdQ1_t(O2v2~`6{NBj(_vJGHf{@Uo@Nr^AynmCDG(kD+jh`-&@&)Laj;DU9rrv3!sB7f6=q;yhZKU!0&FK)7#P?Wg@S`h1e|2p z7ekVO1lv@QN0vK->+m6_~*+rg^#f>eP*4xGKfsu-A-2{ACR``-X7xCc7P4s-$? zBUBP}oF03`SFq%7kZw>IA#_8M3`k4}^rnNxhsbAoIm$gQl}NSv)~UNV9-a0@ox?28LCjoXozKtrnD;*MZ|&nSm{m zm4ShMJt(7stOBRl4ItH^(}dU;axyT060JC>@@D|wCd0mQ4cORd(23sHIT;vq*i6{2 zf{ubP0tta!4>E+!7^Dwm2=6zrB2zxFB7Kk|KG0d`Y$l*1MH!fOfr>a&kV#CFm>C$@ z%t37}a66FA0u+}_UqENGS%RyGOfd!qHY-qZ%#;I~M%4y2wK>7HuY@Y70NTI>s+Gdo z7#Mgsx3PhaqU78T5&=02bW$(p4oEe{!j=H4c=v!UQ08FZWO3zUVBll{)c}&9Ol-x@ zz`(+JT7VO@#6|#gJRYOKUQlfy;14?1oPixw3xSdbxV#5x1s&VTewhoY7BFVu0af#y z-i#n)c}{_BOk#WuI%S;|G!fgu#J~Vf3PPabN(dAq3_PHzSZzb+7z=%Iy{jI<&bMWQb=rhzUAbm51#Z4+8_2H7^6hUC`N5 zJghR1qos6ZLDfA2_hZP>QlO9rHSQKlF))Y}J_tEl z3c?lO2AvcxD$WQ#Hd0xHn;CSblLVtN*klO?3D6m*JRD5FK?f;wgPklO!N9=72M$0R z5K|D$Oc7yV;1K}_pdpAU4i3Q0QVa|{Qs5lc1iB7J7VJ}DF$M-61+ZbSLF){aK>-N9 znTkgZ6mm?~AO)HrwGvOk;vBW-uR%UR4 zjwin^zyLa5nQa^BuwQM64hA;RA%KG5o-n8yNd;-w1w}Hbfd5Oe~09^{;>paR$hq>@RQhfM)=7_lqp z!edZKvriE~D!`=~n3O?gyEzLmFtBbDU|?Vo^kuUE9hvL{aU=r+lQ9begP`wxP_IE5 z6eIzl48bZb2tHq#?Fz`55m3c!hd~aBgz#9{lt3pWN5PyG2T~agk>g>L0@)h_@qhpW zQw;cg*n)0t6HH-y06Nq&8KRznfk_+`kSS`Qlf)xH$4O^^Wh6jWOamnh{$h|m zAsc}T5m0)_0(Afw_&dOYE&|PU) zG6;Y#@D^YOjsFQqg1XBL{FlKB(gj>V!=wW4VDq^ogcum?*%%lEgj(1@EkvPKP+JI8 z8-p&F5Nd-&E(@E76a#}0Jbx_!Rg4`Vy`b}zIaxqP^BaRkdxZJ~EJ5c(3n+nBWHRuB z7M8FGO%<39I$v4fj4)`qFViLl1_oh)V9;F_ETDK`Vh8oNrh^0IIrx0#$)Hgo4p4i{ zNDEXz*?`VAw&Mgb!$D^zJIjNZJRqir1BjW(%fKMw>kVR>f?8}rA|R$WNI?X+ua*Wf zETtGEdIxmOaUQ60XR=^pU=Z04uDVh|2PGc>7q_6&O5`BeISHUsmk)uGE|Ut#+@s*4 zSyYOFLF5>?JU$F+Iv)omDW*BX3=ASCzym}FLCjNN6PAIP&)q;C0^P$W@;U~@^aCC2 z{Jsb@+5oz)fJvBvfk#x54YVFcR0=Gj%)oXSbjF~xAGpF{VFRtf5|x4QKn)_$+80h1 za7EVxI$uy0e9k(k0%8Z1&Z6=H8$nCz1!jQOwh4fH(hN+~K$V#C63~h4pu3&pKu73{ zstPOwr3nTmGmtsz=RmUDA`A?TQVa|%qM8C#;KY{;TC*YmKIo2tDF9@S?i-LweGvwR zsZ1c11_Ge@i*g&WGi`s!2UZ8{t4kLT8zd`3Kw}Xya zbO4>L&UzGNf~YG*y)%k>7mysN>2V5dFR=`u!mB#=^j~9(1~+zXIqi zyi!mYh=xGa2cf7BhVU2}m{>q@5&}Bik98^7{78uUaEJ;9NScX&v_n`Jn8LY17Zf#s z%)bgc@mw?xqCN&ieJp4Q6MVjM5Xk(v4WbMTT%2MI3@ceden@1q1~qSzKq8_1`M1m{9+6Y!b+foxg2C&3iv)rM$kEv>7XS*oGb=n3=ASRpj9_QAeS+)f>!*< zh~`3En+@WDTBD$Yu|#t~Dwvcd7}yKN7#Kj7fa8XhfyoDS5@jyP7_QA?3=F00pj?vA zc7>OLL9_rQ0&-g<$l5}P87yoTpoUiwga^tcU{)FEINIVG&|uC)aqub2Qjk-Y!LrH> zY@0zxY*s^D#lpr2I+VEvA}7NJZrRm=QZSRU0vp)2Mu?mW8@P$s1PMzGwib}PnjvyJ zY@i#jMB6|sm6((b*xW$pWVS`LN}Jc)bV2L2c3iwgiw{ z`a$cfn3O}x`&MebeQfo5DygW zvq7HS4v7R7NU-b#7kJ7XY$>2bu?xcEVY>-Zxf{Y0VBll{*~+?70(>+x+aypU`w*xC z1R3fL%FHK^gKnKrW?{PzvhWmy$H8_SjXs4LGq{u z13T!NaZrdr(~+Dn=x}dw1_lvE(K&1{KykeQR1AP@ybUVI7D9LeY!#qbS_I)KKulc% zDuqBX7zMI_DTHUiCIu>+mqB@&r4G>-d+ZWIgup1$~3bs9 z)?5K)1klmUZ1>q17(}mv+MuALnc3PwW#u&pw}FX`8I-MVfC@v<(ada@K#FgIQXS}M zW;S+EL3alt+ruOUIhq+1E0Cj^L09XE-Ur1L7id-1AIQ5bYC4EK9HngF^Wk$b9h8%%G)?qR%6w7#O(jOEEBjZp9Q3eaWT-I=uE3$XZZr zgTvxAgvSCY1Kxs4ZO}LfQxYiL-mQ>gV2~G-h8)cdDXu<)(ho>`1t?Q|0TrZ>qnWpX z9Q*Z^6axb*Xr-5c=wCK(PKMSZZPE@u9g@sF6O?b=7(o}&Gb_Jg;s&j7 z74=}e23G%piF+w1h&-Y8e_>+aWMP#7b^0Egx6nh9K|TjHKsZ?}Wf>UQK^_CGt^-FDD+Bu)Sq6rm z(hLk>J_my!$e~~(gg_dx5e%FxAWfVspfKZU1(iKsj37rVh{!Q8*nmb|M12^!!ObmS zMvxdNhI2uV^8@=6;u_FY6c4D^F6z(tLY9Gnt6h$P;W8fsgMgSC+jl_*1~GLDP(wkP zfo(O2rvc$Hu|=>mFoQ!S9=4~v3=CpA5FQ@`(+frh z1~FYVIR*x<>v9YXE@BJ}9Af%x|JfKA#0)^;4a#}ypmUfFA$pkDEF>8i#Ed|dAjmGz zDg9!`5FQ%?(;<*~CX+zsnaVRTd}3u_a1b+N6XIlG5Hkn)25cV4?G_O81lW887#PGX zAv__rY7PblF)NT>P#+mo#)#Q?%Y*W@0RuaT0kR4lF>GLxk%2v0o`C`6cqpIA9Auy^ z=$v-0et8B41xb*f?Abv3ti&8Z5d?ArGsuUI;^5F^VPFcCVqg$+N|R?`;JPT!z`zE& z=v>SN;%-+Ice_DcDgdqv#5_Q%L3c*8Ka^)+09glf1!x^93^ zc?Jd%KG4!Ya2W$mObkrCpb$xuQ~;%Nc?Hmz0Z0WnwSl6Mfr$a+zH}?F0tW>K24zO3 zERYW}eZfM(3JeS)nIJt7Q$aNpq`AV>Cd9xXmQw;&Rs~YljZg+^7%?z`E{+o`o(5Ji z2c+U4LIv0$P&+ZC+I8>A@K=Kb01Jgwb z1_p86WuU{&8y(3Z+0JLy+bw1KSBv1_lWsNd94AI|@3fTo}S*V*?%T zE+GOQYE|Zt0`2^l5Cyr3Nm)P&)U%NggP0=12D;8v0z5v*q%6Umh6@GOf+tM$Kocec*FpUN z0cOxO(E<%z3=C`n{Gi!bfof2PPyn4+8_A zKrRad1HZs=Nd^W10nmMSf&vAs3=Bd7Z^aoH{{R2~pPhk8kcELk(tf8h1A{8#PS9F@ zXYjxS=)!KsP*q0I9p#Mfp!*I$cW5v$hN`isGB7ZLriU5*!0BCqfq~&GX!CKXI;ii( z=nYC=OcOcO_kf0$d_YN#F+g1#w2jOcl-!vn3TPx}rZ6!2gQdbXl9L%21Hh&RXo7CV zVhjY;yNqF4YoR7+`_YhcW0degSO@ZUbvLz{tRG9IQcy z@e63zZ#P)@0_d;-u&|o48Uq7k6KDi*G9$=qpkw?&ORyM2)j@SMV?QX9GEL;r&0}Dk z08+p-kp~h;6Cr^l012c?Ag3@*6wydYEn{Gu0``8mCa9&#I29sQ0CDp)2rma5X4Aor z4gjqWV$k0P3Zf+-X-z>;WGn@xdd4sY2C*WLkHqGKw#^yvf#$CIK=XNwj0O&%k*0nq zCl+)8*aRrYT!?`|N*iPtBO?RoY9b~EAikJ^VO&CI;~7EQnL;!AHuoFu;$aXJKGK zK8~J+fdPCdALJx^_;K`1h~wy4z^B?nj-zJ**$z7I1Y|xdh?9)O1D%lqH3xKHHT0l- z@G0qVHsqvw76#Z6XfW-}a1n?J1;{7Wvmrdi4zd*Gr1~7BgZV+{*b_dvJ|#7&6m;f3 z1IVmo*jdba8K6Zv3=FK`S!d=$42;&ttxu^kSA=r3B{5fNJLqt%YVfdP=5gnkt78$y zTsoWMN`sb;4u=&p7l%7XMx31v$FT-29fRUk4NV-yVa!EGIf|GCF3W4`u94T&UC-gL zs$rh>UXD*p>Vh0s&8<^TuHp!1=4G;C^x+6^v|=uQ&!i*Z#NokQu#&luNtuyJk%5sB z^HeQFv?qg(|5C`yFHuNN%*)TqtV&e?okPaOpst~y0Y89IK?!semXfA|MsZ?pK~82~ zx-RIzX9d+1O-;}g00X4hWMp8h;oxCm>0o4F08I^m)(3$wsL*ue<7j1a;$?-2gC@g~ z#X-d-NG*s4O~``PyYsSoHnaM*v3R$GCJ;bpQGnEdi!25P2Cy0@URJke*6?=bHWrxK zpb`pncOzKd1z{(sh(Z>JnFlJLo-m@A*T&M$%&;7^t`TfuiW&ohuL>xtJ@Yb4oFTb} zAptDnmYJ6c6DbCZKzSgg@vade44^VNF$XFNJt_$-0V<2(62T>jMI~V2bXAZ|Q1!tj z`2}FnI%HAz)DoA(l0>is$b}%UfYTi4E(wqT0|Nu7$b~W)l$jV9WSJQl444@hW`V*I zDiQAvI`9m9vQ>OBs9jK!np*%lkPCW*t-EUo{7@vwiM-&`c7x;nTwPrPJVTs45C<#z zIs5wtfDVj{hn^n|J=)mc8*)rn3FyE#a8VHtKe^M<#~F005(6|%!cNN1EG{lB2AzSJ znu0in8g$T^Z)r(tg{KRs0Lld2ya75;33Tomw=v0 z1i4Y67+j`MAn9F(3qbAU`ZwgO0j~9y^*`T2z#p zR{}nl5q@+v;w(n+*^S^*!zCV)1sUL{7*cveLwr2!_;~Q)WCaY4J}%H>coTDwi)Ke3 zSkZ#ye`wK)enuVWC`sfi7^rz|gA3>|+7Q3%Z`9C^an}7N+2W6LLHz_!P_Z#LPSfv~wtnpr>x5U+CcI;|x8u4ph^} zXXYh?0tJ5BWoBLp_>@d|VgOyp06H5Va;F6-k>@5BWv3P~z^>$goR}Bt=H?pY2|g{4 z@_QVh#VP9H%aE%ah`iSU^|k`=q0NZXZ%Mq`AuqK&9)7C>;?P=@`yC)hB7#mKPby6- z&Mz%WP6ZuD4mxBXd;%Y|h=89j49a8i;N!^S5qAtgvSf&-ud55_f(*o=!SV4_zs>=6 zT6lbX2~l@BARS={&X16jAYoY)+YJx!q>S98fmNx_j(*OrplgcUT!X;(Da3=%_JkbH zn3tadYEM8?fvayoNF==3k(|O1kYAh$K0F+HYCfo3@bP!{hF{g-8WG^*>FgO29}K;Q zAu}&OzJ#GXu`CtTlSV$8HL-#LbfP2D{U`D9DTDO-2XH=vw%y>@4}gzzEMdTQ*gg2_ zA;>*O;22|Y2bB^?cO8^M?tuW^KLZYY@U0A>gHcOTi@?pT`1q3C`1IV8{IoO%NScl> z$j{G#Hw)cDeSG5mLqotfip1w8Rv=wH0E!i7f4>k=GZ|b-LeI~2^l^5H2Ok5=0BLlB z&)x;K^GZ_FNd|hT!VuAgPc8FoxMSM3#15klsE(8Y7EHf&DgJh0AD|Wa@_;S0r3zQ#K#YoOCCT0 z9~kNy>I$uLLY+Y8dXjwa1IQR(#|Tf~&|uIp_LZrLMUYemPHN!m6dVyZ6_w=17pEq} zTL>lK0vFWZ1lLqaNY|^tE`f-Lw@2Lk9DSh4+Ql_EB*;G!T#JCp(ab7_`1t(N5>Wre z(Fc4{53B$QcJ>c&jR&c84Gsp|0;vxRK*vQRpCk=-FPK1Slg2|zUk2!95RlA;?a<`- zc>LExz#IfgWhgfsf$9oyEI9l7g}DZWKyQqI94DWgpHs|Go(aA_3KZDR{(f$r?hKG) z=;J{rg@dk|NG&SLFJhqNq6pYUVYn}hfE>RZ47%RT(Fc_K7#w{-5uBL^IT;z8=V7PP z!rBG-dC8z7>x&CgQ&YfKk$|%tsCfX+72s$96(3dkpi77#O@?9ylry#={Y6MxK~&BV zcY+QvPc8$UOb&^DPzMol_ZL~$M}Uvn&r8e&RV@%pq3vdHBOf$81ugqPU0PTl5}Ym| zOryg10kkjo@Mu?so`Jsx_u1+lkBfbRQ&6yovmi0dOjB^SIQ z86O_x7{CC(QNq#38FG7HF776&REcgbfKo@)DgU@{j--Q`p!jNB-nGSMxT53@-Lp->r56bx9bN0cBDlHFm zi%v-fm;>&i6f=N^0>Q0;Tu|+nnBxk{FrIlSsTB+$4`rrhrb4e?#Ck^y#vL4xiyY{B zu|#r4VqRWqPBEyQEeAFA3o=0$1c2&gNV6OqN{H(mKn|JZi&R4WM^kj&~+?@pp)0Zm2PrA;*tqaphCu9Ah`l^t~)$i#K(iy6u|GG zK*~NKC0H)-fD{6-><=D=Oaj`^T1bhIQlq)+t}cy9Qbf< zaDONsKI{PU2m|bxec0L8@yU>D1HiQuC`g0-LxY?Vtp;cd)zuGrA1ACthF<=IR9=9b zOWi9g5=&AUic-@-H;00nN3bde>LkbDNIz$fAb&sq&|uIx(Tp@6#gSg*5yUIs(OTP+-YoI%w(qFez70&?RV za=8U4C1h5mW-`R14Jkmn5y<@~w5u(UFCZlAdJE89AfR*rs{V69*D6A4e}?#Y@YRm6 z3nQSN5v2Qkij(sTK!rkX64;UPB@B6`x$w#a{hWI^p8{*b@B!X@6`>*%I7T zh7On%CntjM^>l{ct{D$0bRk&~xe*i(xemtB#~GZh;de*6`}qgCLI&T!B@Xl+w1UK< zlFUR`3vT_PUSt8PMtuDJ13+N`nlA$1JVW%g7Tq!`hv{^+MNw*w9(Yh*58S}e zODZmA&;!pc$0sHw6{VIj=z)|#L^AWz@{##DpqpFuit<5P^@>Z14D}2dP`D<@s?&-< zof;(L3QChe{hVTCMTwyMeN*9XK;;#e6fx+f=auS#u8#%v?DR_X;^Q;TEX?%MQ%m9t zlH*G z(AsMd8-zjTfM|4#EKc|?6=WM27?@E)3d9GkFhSVB%m52jh!``tWPq?iBr|034u}cH z%nYD|9>7d6!OQ?knP4WEU}gZNEHD#HFoSPV0W-k_Gw2vCFbhI3Gk`XnLf9aZ8D*6W z$i1RyI=IkIzT{>AE%X3kkbVXX_lhxq?j8ckfqX8+z{sEvU7rKv+cH4XJ7|p!NZuc$ z7>b3ML>NGaTSB>D-+=NdGQSnZftouVjlT?y4?2?rCIm_spnQPLzX0Pv&AX4r2OX{m zTkivMFB4J%0huQVI^20i^E7ABH(D)3AIiPu7q?LJkKF$UVdOpsEAi@ZANf^=+B-A-> zcwZCLHUzH?!cjfPyZiV%Ir_x=ySW9shQx<}1~1|n;$fpYZayHUPkwT?Gjz=Wi0__S z0^>pygn|cFU}D7uMVWaeX`uCm{spOdkTG1anZXE+Aafux!Kt9d2G9m9v=t6^GRP62 z>oOtA7~pE;}dhBH$6fw-A&Ai4{-Jk0^PQlnO4b=o0yZ6pA2>& z#Hygw#1s(M2|S1G3|$WgT4u$No0^+kP|1*1l$r{<@f|d(kp`Yf0Lg%Qq70yVkx7Dq z0dyY{mm~v&Bj|WKDFy~`JuJw;kOHcMq!}1;K(q`41L&S37Fh;{J)n95*E?k@tFFTlva05V?^bSRz_1A{Ij=$JPK2GIRQEYb`N zpgr>}G7JnUj0_Ac$_xxGAX=7zVI7nP-9H2}=L6K7Z%}iXLHnX*7#P$+v^oPrB8b*t zV8{p2>I@9CK(rzT5UtC=V8qP8z^uo>0J>L* zQ<#Av0wk`_z)%RH4Hy`9fM_iSa7oMvT9^&0$8g<0#m4|H?-=_!S_$` zLBbovcLtfm$H3qPr9+`~43tiX(x8KJLF&QxPw_D@v_Qqd_fPRLFieB;LG?dK-3lmw zGn59!6G$9XZh`3AQ1M4l8dP3^#KHA59|OaGs5mJ8K;ojHCDI`OKxu6#4JxNV@{Ulx z50nmv(n(M{6H1prY0ySTkiKP5{#qyvI^Go|4!S1}M1$|4;$vXA36%$}cLa&Qhw^_x zY0%15khlP7VKX1-{2T@b5MK?-H-yqQP}&_zgEnV_)PdT-AUXpoUJRw{pmZmco&u%k zL+K4r`XH1BozVd@=Q5Ok4@$p<(xCJQl4k)ez(Eu7T3+PBNN38lgJbMY}SghKhC!y7>6t%dT>LFv~}+7PtefscU!bb1F! z-3loG3Y7i|rNQ@GfewfQood3zz#s{w)uFU0l=gzs2~au%N|!-t@cmYN3=H6Vt@s!i zc0Is;0B@7dyGV3-Q!uYl6qq4XgreHBVShSH!d)*$o$ zL;0Y+tRTJ&=-gC31_pg74LWufB<>02hd}9cC=EKR10-Jq`cUK`3cgVK&r+6PKUL+NBFT?nP?q4X>$y%I`qgworgH25AcQ2hnv zUxw1Rq4Xmt{Siw4gwp?^G-zWD$elc(vyVXe1xkYs5(9~ALiynP!uS{%?4f*jDD4ZS zgQ0XJl#YkeX;8WnO1DGlX;6A4l->@d!S{&qF))Dd5#wWE03DzSa)%gb=OG^hgC>+V zhth6PIuc5!L+LUo-3g_qL+NEudMA`V4yCU_>8DWoEtLKZrA0v}{earvP}&tr7eVPp zC=EKb0p#B4Q2tUVy$ed;hSD#g^mi!D3OeWpRBl3PMJTNgrEQ_KHElrP8kD{Vr9oR&LGA-x)C;2dBp~&Q43yS_(iTuU6iS2d)8b=b0Nyf%-R4abD0KSx~xz(wb1(97?-F>0l_G2&MC(bS;$b zhSH#uUqSv_0p)Lp(#N3mRVe)gN`HpZOrZO(K;<-)R)Es_P}&bl$3p2;C|wMtK_`iU z>;>P$#mB%f4=TPEN^gbIhoLm+>^zYAFHk;{G$bB`ptLHKHipvvP&x}rmqO`1Q2Hp8 z2H&g2$H4Fl%I5;zXT`_BAOfY8p|lZ{c7)OaP&yt;=RxUODBTOC=R)bVPI-G$G{*9rLCZJ29&-FrQbs7Z%~>QbRQKceL!h#C~XX-9ig;8l#Yec z*-*L?N_Rl%=}>w;lwJ#^cSGruQ2GXxeh#JIL+QUznj3VF6{sB!rPZNy43y4>(#24^ z5lT;h((|G8awxqON*{*OkD&BhD9sN#$AOQ5!2n7-L+LCi-2^ld2320Dm=raijRST14{EjX%Q$b1*H|Bv>KGwfzn1$+5$>DLur2~9R{MA7#O0U zbP|Z>V_?Vx(M${sxlp3oggh3`Gnj3}Gm)31%o^ zC}PND$YV%{n`gkF$6&~S-5hs@RE83`%dzQ3bq%`j6&N6<>o6!VI5Xrk6fjhR?N4XO z0Q=sE!GOVl!GuA9A)X - - - - 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 deleted file mode 100644 index 174c3922a7949c33e36825ce607450d345670962..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11692 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 diff --git a/tnl-1.5.0/tnl/osx/Info.plist b/tnl-1.5.0/tnl/osx/Info.plist deleted file mode 100644 index 0ddc1e8..0000000 --- a/tnl-1.5.0/tnl/osx/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - 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 deleted file mode 100644 index 63920d0..0000000 --- a/tnl-1.5.0/tnl/osx/MyOpenGLView.h +++ /dev/null @@ -1,38 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index dc88280..0000000 --- a/tnl-1.5.0/tnl/osx/MyOpenGLView.mm +++ /dev/null @@ -1,166 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 TNL::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((TNL::U32) rect.size.width, (TNL::U32) rect.size.height); - else if(serverGame) - serverGame->renderFrame((TNL::U32) rect.size.width, (TNL::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, TNL::Address(TNL::IPProtocol, TNL::Address::Any, 28999), - TNL::Address("IP:Broadcast:28999")); - clientGame = NULL; -} - -- (void)restartAsClientPingingLocalhost:sender -{ - delete serverGame; - delete clientGame; - serverGame = NULL; - clientGame = new TestGame(false, TNL::Address(TNL::IPProtocol, TNL::Address::Any, 0), - TNL::Address("IP:localhost:28999")); -} - -- (void)restartAsClient:sender -{ - delete serverGame; - delete clientGame; - serverGame = NULL; - clientGame = new TestGame(false, TNL::Address(TNL::IPProtocol, TNL::Address::Any, 0), - TNL::Address("IP:broadcast:28999")); -} - -- (void)restartAsClientAndServer:sender -{ - delete serverGame; - delete clientGame; - serverGame = new TestGame(true, TNL::Address(TNL::IPProtocol, TNL::Address::Any, 28999), - TNL::Address("IP:Broadcast:28999")); - clientGame = new TestGame(false, TNL::Address(TNL::IPProtocol, TNL::Address::Any, 0), - TNL::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 deleted file mode 100644 index 911a021..0000000 --- a/tnl-1.5.0/tnl/osx/main.mm +++ /dev/null @@ -1,32 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index a95a461..0000000 --- a/tnl-1.5.0/tnl/osx/tnl.xcode/project.pbxproj +++ /dev/null @@ -1,4879 +0,0 @@ -// !$*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/tnl.xcodeproj/markf.mode1v3 b/tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.mode1v3 deleted file mode 100644 index e5dde51..0000000 --- a/tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.mode1v3 +++ /dev/null @@ -1,1468 +0,0 @@ - - - - - ActivePerspectiveName - Project - AllowedModules - - - BundleLoadPath - - MaxInstances - n - Module - PBXSmartGroupTreeModule - Name - Groups and Files Outline View - - - BundleLoadPath - - MaxInstances - n - Module - PBXNavigatorGroup - Name - Editor - - - BundleLoadPath - - MaxInstances - n - Module - XCTaskListModule - Name - Task List - - - BundleLoadPath - - MaxInstances - n - Module - XCDetailModule - Name - File and Smart Group Detail Viewer - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXBuildResultsModule - Name - Detailed Build Results Viewer - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXProjectFindModule - Name - Project Batch Find Tool - - - BundleLoadPath - - MaxInstances - n - Module - XCProjectFormatConflictsModule - Name - Project Format Conflicts List - - - BundleLoadPath - - MaxInstances - n - Module - PBXBookmarksModule - Name - Bookmarks Tool - - - BundleLoadPath - - MaxInstances - n - Module - PBXClassBrowserModule - Name - Class Browser - - - BundleLoadPath - - MaxInstances - n - Module - PBXCVSModule - Name - Source Code Control Tool - - - BundleLoadPath - - MaxInstances - n - Module - PBXDebugBreakpointsModule - Name - Debug Breakpoints Tool - - - BundleLoadPath - - MaxInstances - n - Module - XCDockableInspector - Name - Inspector - - - BundleLoadPath - - MaxInstances - n - Module - PBXOpenQuicklyModule - Name - Open Quickly Tool - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXDebugSessionModule - Name - Debugger - - - BundleLoadPath - - MaxInstances - 1 - Module - PBXDebugCLIModule - Name - Debug Console - - - BundleLoadPath - - MaxInstances - n - Module - XCSnapshotModule - Name - Snapshots Tool - - - BundlePath - /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources - Description - DefaultDescriptionKey - DockingSystemVisible - - Extension - mode1v3 - FavBarConfig - - PBXProjectModuleGUID - 1D9949A910DED6E0001B3AFF - XCBarModuleItemNames - - XCBarModuleItems - - - FirstTimeWindowDisplayed - - Identifier - com.apple.perspectives.project.mode1v3 - MajorVersion - 33 - MinorVersion - 0 - Name - Default - Notifications - - OpenEditors - - - Content - - PBXProjectModuleGUID - 1D9949AA10DED6E0001B3AFF - PBXProjectModuleLabel - tnlMethodDispatch.h - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1D9949AB10DED6E0001B3AFF - PBXProjectModuleLabel - tnlMethodDispatch.h - _historyCapacity - 0 - bookmark - 1D9949B510DED7A1001B3AFF - history - - 1D99499610DED630001B3AFF - - - SplitCount - 1 - - StatusBarVisibility - - - Geometry - - Frame - {{0, 20}, {729, 673}} - PBXModuleWindowStatusBarHidden2 - - RubberWindowFrame - 56 59 729 714 0 0 1280 778 - - - - Content - - PBXProjectModuleGUID - 1D9949AD10DED6E0001B3AFF - PBXProjectModuleLabel - tnlMethodDispatch.cpp - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1D9949AE10DED6E0001B3AFF - PBXProjectModuleLabel - tnlMethodDispatch.cpp - _historyCapacity - 0 - bookmark - 1D9949B610DED7A1001B3AFF - history - - 1D99499510DED60C001B3AFF - - - SplitCount - 1 - - StatusBarVisibility - - - Geometry - - Frame - {{0, 20}, {729, 673}} - PBXModuleWindowStatusBarHidden2 - - RubberWindowFrame - 56 59 729 714 0 0 1280 778 - - - - PerspectiveWidths - - -1 - -1 - - Perspectives - - - ChosenToolbarItems - - active-target-popup - active-buildstyle-popup - action - NSToolbarFlexibleSpaceItem - buildOrClean - build-and-goOrGo - com.apple.ide.PBXToolbarStopButton - get-info - toggle-editor - NSToolbarFlexibleSpaceItem - com.apple.pbx.toolbar.searchfield - - ControllerClassBaseName - - IconName - WindowOfProjectWithEditor - Identifier - perspective.project - IsVertical - - Layout - - - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C37FBAC04509CD000000102 - 1C37FAAC04509CD000000102 - 1C08E77C0454961000C914BD - 1C37FABC05509CD000000102 - 1C37FABC05539CD112110102 - E2644B35053B69B200211256 - 1C37FABC04509CD000100104 - 1CC0EA4004350EF90044410B - 1CC0EA4004350EF90041110B - - PBXProjectModuleGUID - 1CE0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - yes - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 186 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 29B97314FDCFA39411CA2CEA - 1C37FABC05509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {186, 445}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - - XCSharingToken - com.apple.Xcode.GFSharingToken - - GeometryConfiguration - - Frame - {{0, 0}, {203, 463}} - GroupTreeTableConfiguration - - MainColumn - 186 - - RubberWindowFrame - 266 219 788 504 0 0 1280 778 - - Module - PBXSmartGroupTreeModule - Proportion - 203pt - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1CE0B20306471E060097A5F4 - PBXProjectModuleLabel - tnlTypes.h - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1CE0B20406471E060097A5F4 - PBXProjectModuleLabel - tnlTypes.h - _historyCapacity - 0 - bookmark - 1D9949B410DED7A1001B3AFF - history - - 1D9949A510DED6E0001B3AFF - - - SplitCount - 1 - - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {580, 285}} - RubberWindowFrame - 266 219 788 504 0 0 1280 778 - - Module - PBXNavigatorGroup - Proportion - 285pt - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1CE0B20506471E060097A5F4 - PBXProjectModuleLabel - Detail - - GeometryConfiguration - - Frame - {{0, 290}, {580, 173}} - RubberWindowFrame - 266 219 788 504 0 0 1280 778 - - Module - XCDetailModule - Proportion - 173pt - - - Proportion - 580pt - - - Name - Project - ServiceClasses - - XCModuleDock - PBXSmartGroupTreeModule - XCModuleDock - PBXNavigatorGroup - XCDetailModule - - TableOfContents - - 1D9949A710DED6E0001B3AFF - 1CE0B1FE06471DED0097A5F4 - 1D9949A810DED6E0001B3AFF - 1CE0B20306471E060097A5F4 - 1CE0B20506471E060097A5F4 - - ToolbarConfiguration - xcode.toolbar.config.defaultV3 - - - ControllerClassBaseName - - IconName - WindowOfProject - Identifier - perspective.morph - IsVertical - 0 - Layout - - - BecomeActive - 1 - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C37FBAC04509CD000000102 - 1C37FAAC04509CD000000102 - 1C08E77C0454961000C914BD - 1C37FABC05509CD000000102 - 1C37FABC05539CD112110102 - E2644B35053B69B200211256 - 1C37FABC04509CD000100104 - 1CC0EA4004350EF90044410B - 1CC0EA4004350EF90041110B - - PBXProjectModuleGUID - 11E0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - yes - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 186 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 29B97314FDCFA39411CA2CEA - 1C37FABC05509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {186, 337}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - 1 - XCSharingToken - com.apple.Xcode.GFSharingToken - - GeometryConfiguration - - Frame - {{0, 0}, {203, 355}} - GroupTreeTableConfiguration - - MainColumn - 186 - - RubberWindowFrame - 373 269 690 397 0 0 1440 878 - - Module - PBXSmartGroupTreeModule - Proportion - 100% - - - Name - Morph - PreferredWidth - 300 - ServiceClasses - - XCModuleDock - PBXSmartGroupTreeModule - - TableOfContents - - 11E0B1FE06471DED0097A5F4 - - ToolbarConfiguration - xcode.toolbar.config.default.shortV3 - - - PerspectivesBarVisible - - ShelfIsVisible - - SourceDescription - file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' - StatusbarIsVisible - - TimeStamp - 0.0 - ToolbarDisplayMode - 1 - ToolbarIsVisible - - ToolbarSizeMode - 1 - Type - Perspectives - UpdateMessage - The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? - WindowJustification - 5 - WindowOrderList - - 1CD10A99069EF8BA00B06720 - 1C530D57069F1CE1000CFCEE - 1D9949AD10DED6E0001B3AFF - 1D9949AA10DED6E0001B3AFF - /Users/markf/Work/Torque-Network-Library/tnl-1.5.0/tnl/osx/tnl.xcodeproj - 1D9949A110DED6DE001B3AFF - 1C78EAAD065D492600B07095 - - WindowString - 266 219 788 504 0 0 1280 778 - WindowToolsV3 - - - FirstTimeWindowDisplayed - - Identifier - windowTool.build - IsVertical - - Layout - - - Dock - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1CD0528F0623707200166675 - PBXProjectModuleLabel - MyOpenGLView.mm - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {949, 318}} - RubberWindowFrame - 226 46 949 600 0 0 1280 778 - - Module - PBXNavigatorGroup - Proportion - 318pt - - - ContentConfiguration - - PBXProjectModuleGUID - XCMainBuildResultsModuleGUID - PBXProjectModuleLabel - Build - XCBuildResultsTrigger_Collapse - 1021 - XCBuildResultsTrigger_Open - 1011 - - GeometryConfiguration - - Frame - {{0, 323}, {949, 236}} - RubberWindowFrame - 226 46 949 600 0 0 1280 778 - - Module - PBXBuildResultsModule - Proportion - 236pt - - - Proportion - 559pt - - - Name - Build Results - ServiceClasses - - PBXBuildResultsModule - - StatusbarIsVisible - - TableOfContents - - 1D9949A110DED6DE001B3AFF - 1D9949A210DED6DE001B3AFF - 1CD0528F0623707200166675 - XCMainBuildResultsModuleGUID - - ToolbarConfiguration - xcode.toolbar.config.buildV3 - WindowString - 226 46 949 600 0 0 1280 778 - WindowToolGUID - 1D9949A110DED6DE001B3AFF - WindowToolIsVisible - - - - FirstTimeWindowDisplayed - - Identifier - windowTool.debugger - IsVertical - - Layout - - - Dock - - - ContentConfiguration - - Debugger - - HorizontalSplitView - - _collapsingFrameDimension - 0.0 - _indexOfCollapsedView - 0 - _percentageOfCollapsedView - 0.0 - isCollapsed - yes - sizes - - {{0, 0}, {316, 185}} - {{316, 0}, {378, 185}} - - - VerticalSplitView - - _collapsingFrameDimension - 0.0 - _indexOfCollapsedView - 0 - _percentageOfCollapsedView - 0.0 - isCollapsed - yes - sizes - - {{0, 0}, {694, 185}} - {{0, 185}, {694, 196}} - - - - LauncherConfigVersion - 8 - PBXProjectModuleGUID - 1C162984064C10D400B95A72 - PBXProjectModuleLabel - Debug - GLUTExamples (Underwater) - - GeometryConfiguration - - DebugConsoleVisible - None - DebugConsoleWindowFrame - {{200, 200}, {500, 300}} - DebugSTDIOWindowFrame - {{200, 200}, {500, 300}} - Frame - {{0, 0}, {694, 381}} - PBXDebugSessionStackFrameViewKey - - DebugVariablesTableConfiguration - - Name - 120 - Value - 85 - Summary - 148 - - Frame - {{316, 0}, {378, 185}} - RubberWindowFrame - 247 201 694 422 0 0 1280 778 - - RubberWindowFrame - 247 201 694 422 0 0 1280 778 - - Module - PBXDebugSessionModule - Proportion - 381pt - - - Proportion - 381pt - - - Name - Debugger - ServiceClasses - - PBXDebugSessionModule - - StatusbarIsVisible - - TableOfContents - - 1CD10A99069EF8BA00B06720 - 1D9949B710DED7A1001B3AFF - 1C162984064C10D400B95A72 - 1D9949B810DED7A1001B3AFF - 1D9949B910DED7A1001B3AFF - 1D9949BA10DED7A1001B3AFF - 1D9949BB10DED7A1001B3AFF - 1D9949BC10DED7A1001B3AFF - - ToolbarConfiguration - xcode.toolbar.config.debugV3 - WindowString - 247 201 694 422 0 0 1280 778 - WindowToolGUID - 1CD10A99069EF8BA00B06720 - WindowToolIsVisible - - - - FirstTimeWindowDisplayed - - Identifier - windowTool.find - IsVertical - - Layout - - - Dock - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1CDD528C0622207200134675 - PBXProjectModuleLabel - - StatusBarVisibility - - - GeometryConfiguration - - Frame - {{0, 0}, {835, 206}} - RubberWindowFrame - 382 5 835 730 0 0 1280 778 - - Module - PBXNavigatorGroup - Proportion - 835pt - - - Proportion - 206pt - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1CD0528E0623707200166675 - PBXProjectModuleLabel - Project Find - - GeometryConfiguration - - Frame - {{0, 211}, {835, 478}} - RubberWindowFrame - 382 5 835 730 0 0 1280 778 - - Module - PBXProjectFindModule - Proportion - 478pt - - - Proportion - 689pt - - - Name - Project Find - ServiceClasses - - PBXProjectFindModule - - StatusbarIsVisible - - TableOfContents - - 1C530D57069F1CE1000CFCEE - 1D9949A310DED6DE001B3AFF - 1D9949A410DED6DE001B3AFF - 1CDD528C0622207200134675 - 1CD0528E0623707200166675 - - WindowString - 382 5 835 730 0 0 1280 778 - WindowToolGUID - 1C530D57069F1CE1000CFCEE - WindowToolIsVisible - - - - Identifier - MENUSEPARATOR - - - FirstTimeWindowDisplayed - - Identifier - windowTool.debuggerConsole - IsVertical - - Layout - - - Dock - - - BecomeActive - - ContentConfiguration - - PBXProjectModuleGUID - 1C78EAAC065D492600B07095 - PBXProjectModuleLabel - Debugger Console - - GeometryConfiguration - - Frame - {{0, 0}, {650, 209}} - RubberWindowFrame - 247 373 650 250 0 0 1280 778 - - Module - PBXDebugCLIModule - Proportion - 209pt - - - Proportion - 209pt - - - Name - Debugger Console - ServiceClasses - - PBXDebugCLIModule - - StatusbarIsVisible - - TableOfContents - - 1C78EAAD065D492600B07095 - 1D9949BD10DED7A1001B3AFF - 1C78EAAC065D492600B07095 - - ToolbarConfiguration - xcode.toolbar.config.consoleV3 - WindowString - 247 373 650 250 0 0 1280 778 - WindowToolGUID - 1C78EAAD065D492600B07095 - WindowToolIsVisible - - - - Identifier - windowTool.snapshots - Layout - - - Dock - - - Module - XCSnapshotModule - Proportion - 100% - - - Proportion - 100% - - - Name - Snapshots - ServiceClasses - - XCSnapshotModule - - StatusbarIsVisible - Yes - ToolbarConfiguration - xcode.toolbar.config.snapshots - WindowString - 315 824 300 550 0 0 1440 878 - WindowToolIsVisible - Yes - - - Identifier - windowTool.scm - Layout - - - Dock - - - ContentConfiguration - - PBXProjectModuleGUID - 1C78EAB2065D492600B07095 - PBXProjectModuleLabel - <No Editor> - PBXSplitModuleInNavigatorKey - - Split0 - - PBXProjectModuleGUID - 1C78EAB3065D492600B07095 - - SplitCount - 1 - - StatusBarVisibility - 1 - - GeometryConfiguration - - Frame - {{0, 0}, {452, 0}} - RubberWindowFrame - 743 379 452 308 0 0 1280 1002 - - Module - PBXNavigatorGroup - Proportion - 0pt - - - BecomeActive - 1 - ContentConfiguration - - PBXProjectModuleGUID - 1CD052920623707200166675 - PBXProjectModuleLabel - SCM - - GeometryConfiguration - - ConsoleFrame - {{0, 259}, {452, 0}} - Frame - {{0, 7}, {452, 259}} - RubberWindowFrame - 743 379 452 308 0 0 1280 1002 - TableConfiguration - - Status - 30 - FileName - 199 - Path - 197.0950012207031 - - TableFrame - {{0, 0}, {452, 250}} - - Module - PBXCVSModule - Proportion - 262pt - - - Proportion - 266pt - - - Name - SCM - ServiceClasses - - PBXCVSModule - - StatusbarIsVisible - 1 - TableOfContents - - 1C78EAB4065D492600B07095 - 1C78EAB5065D492600B07095 - 1C78EAB2065D492600B07095 - 1CD052920623707200166675 - - ToolbarConfiguration - xcode.toolbar.config.scm - WindowString - 743 379 452 308 0 0 1280 1002 - - - Identifier - windowTool.breakpoints - IsVertical - 0 - Layout - - - Dock - - - BecomeActive - 1 - ContentConfiguration - - PBXBottomSmartGroupGIDs - - 1C77FABC04509CD000000102 - - PBXProjectModuleGUID - 1CE0B1FE06471DED0097A5F4 - PBXProjectModuleLabel - Files - PBXProjectStructureProvided - no - PBXSmartGroupTreeModuleColumnData - - PBXSmartGroupTreeModuleColumnWidthsKey - - 168 - - PBXSmartGroupTreeModuleColumnsKey_v4 - - MainColumn - - - PBXSmartGroupTreeModuleOutlineStateKey_v7 - - PBXSmartGroupTreeModuleOutlineStateExpansionKey - - 1C77FABC04509CD000000102 - - PBXSmartGroupTreeModuleOutlineStateSelectionKey - - - 0 - - - PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 0}, {168, 350}} - - PBXTopSmartGroupGIDs - - XCIncludePerspectivesSwitch - 0 - - GeometryConfiguration - - Frame - {{0, 0}, {185, 368}} - GroupTreeTableConfiguration - - MainColumn - 168 - - RubberWindowFrame - 315 424 744 409 0 0 1440 878 - - Module - PBXSmartGroupTreeModule - Proportion - 185pt - - - ContentConfiguration - - PBXProjectModuleGUID - 1CA1AED706398EBD00589147 - PBXProjectModuleLabel - Detail - - GeometryConfiguration - - Frame - {{190, 0}, {554, 368}} - RubberWindowFrame - 315 424 744 409 0 0 1440 878 - - Module - XCDetailModule - Proportion - 554pt - - - Proportion - 368pt - - - MajorVersion - 3 - MinorVersion - 0 - Name - Breakpoints - ServiceClasses - - PBXSmartGroupTreeModule - XCDetailModule - - StatusbarIsVisible - 1 - TableOfContents - - 1CDDB66807F98D9800BB5817 - 1CDDB66907F98D9800BB5817 - 1CE0B1FE06471DED0097A5F4 - 1CA1AED706398EBD00589147 - - ToolbarConfiguration - xcode.toolbar.config.breakpointsV3 - WindowString - 315 424 744 409 0 0 1440 878 - WindowToolGUID - 1CDDB66807F98D9800BB5817 - WindowToolIsVisible - 1 - - - Identifier - windowTool.debugAnimator - Layout - - - Dock - - - Module - PBXNavigatorGroup - Proportion - 100% - - - Proportion - 100% - - - Name - Debug Visualizer - ServiceClasses - - PBXNavigatorGroup - - StatusbarIsVisible - 1 - ToolbarConfiguration - xcode.toolbar.config.debugAnimatorV3 - WindowString - 100 100 700 500 0 0 1280 1002 - - - Identifier - windowTool.bookmarks - Layout - - - Dock - - - Module - PBXBookmarksModule - Proportion - 100% - - - Proportion - 100% - - - Name - Bookmarks - ServiceClasses - - PBXBookmarksModule - - StatusbarIsVisible - 0 - WindowString - 538 42 401 187 0 0 1280 1002 - - - Identifier - windowTool.projectFormatConflicts - Layout - - - Dock - - - Module - XCProjectFormatConflictsModule - Proportion - 100% - - - Proportion - 100% - - - Name - Project Format Conflicts - ServiceClasses - - XCProjectFormatConflictsModule - - StatusbarIsVisible - 0 - WindowContentMinSize - 450 300 - WindowString - 50 850 472 307 0 0 1440 877 - - - Identifier - windowTool.classBrowser - Layout - - - Dock - - - BecomeActive - 1 - ContentConfiguration - - OptionsSetName - Hierarchy, all classes - PBXProjectModuleGUID - 1CA6456E063B45B4001379D8 - PBXProjectModuleLabel - Class Browser - NSObject - - GeometryConfiguration - - ClassesFrame - {{0, 0}, {374, 96}} - ClassesTreeTableConfiguration - - PBXClassNameColumnIdentifier - 208 - PBXClassBookColumnIdentifier - 22 - - Frame - {{0, 0}, {630, 331}} - MembersFrame - {{0, 105}, {374, 395}} - MembersTreeTableConfiguration - - PBXMemberTypeIconColumnIdentifier - 22 - PBXMemberNameColumnIdentifier - 216 - PBXMemberTypeColumnIdentifier - 97 - PBXMemberBookColumnIdentifier - 22 - - PBXModuleWindowStatusBarHidden2 - 1 - RubberWindowFrame - 385 179 630 352 0 0 1440 878 - - Module - PBXClassBrowserModule - Proportion - 332pt - - - Proportion - 332pt - - - Name - Class Browser - ServiceClasses - - PBXClassBrowserModule - - StatusbarIsVisible - 0 - TableOfContents - - 1C0AD2AF069F1E9B00FABCE6 - 1C0AD2B0069F1E9B00FABCE6 - 1CA6456E063B45B4001379D8 - - ToolbarConfiguration - xcode.toolbar.config.classbrowser - WindowString - 385 179 630 352 0 0 1440 878 - WindowToolGUID - 1C0AD2AF069F1E9B00FABCE6 - WindowToolIsVisible - 0 - - - Identifier - windowTool.refactoring - IncludeInToolsMenu - 0 - Layout - - - Dock - - - BecomeActive - 1 - GeometryConfiguration - - Frame - {0, 0}, {500, 335} - RubberWindowFrame - {0, 0}, {500, 335} - - Module - XCRefactoringModule - Proportion - 100% - - - Proportion - 100% - - - Name - Refactoring - ServiceClasses - - XCRefactoringModule - - WindowString - 200 200 500 356 0 0 1920 1200 - - - - diff --git a/tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.pbxuser b/tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.pbxuser deleted file mode 100644 index e5c0185..0000000 --- a/tnl-1.5.0/tnl/osx/tnl.xcodeproj/markf.pbxuser +++ /dev/null @@ -1,416 +0,0 @@ -// !$*UTF8*$! -{ - 1D99495A10DED558001B3AFF /* TNLTest */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 0; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - dylibVariantSuffix = ""; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = TNLTest; - sourceDirectories = ( - ); - }; - 1D99495B10DED558001B3AFF /* testserver */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 1; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = testserver; - sourceDirectories = ( - ); - }; - 1D99495C10DED558001B3AFF /* master */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 1; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = master; - sourceDirectories = ( - ); - }; - 1D99495D10DED558001B3AFF /* masterclient */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 1; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = masterclient; - sourceDirectories = ( - ); - }; - 1D99495E10DED558001B3AFF /* ZAP */ = { - isa = PBXExecutable; - activeArgIndices = ( - ); - argumentStrings = ( - ); - autoAttachOnCrash = 1; - breakpointsEnabled = 1; - configStateDict = { - }; - customDataFormattersEnabled = 1; - debuggerPlugin = GDBDebugging; - disassemblyDisplayState = 0; - enableDebugStr = 1; - environmentEntries = ( - ); - executableSystemSymbolLevel = 0; - executableUserSymbolLevel = 0; - libgmallocEnabled = 0; - name = ZAP; - sourceDirectories = ( - ); - }; - 1D99499110DED559001B3AFF /* Source Control */ = { - isa = PBXSourceControlManager; - fallbackIsa = XCSourceControlManager; - isSCMEnabled = 0; - scmConfiguration = { - }; - }; - 1D99499210DED559001B3AFF /* Code sense */ = { - isa = PBXCodeSenseManager; - indexTemplatePath = ""; - }; - 1D99499510DED60C001B3AFF /* PBXBookmark */ = { - isa = PBXBookmark; - fRef = 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */; - }; - 1D99499610DED630001B3AFF /* PBXBookmark */ = { - isa = PBXBookmark; - fRef = 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */; - }; - 1D99499910DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; - name = "tnlTypes.h: 300"; - rLen = 0; - rLoc = 10996; - rType = 0; - vrLen = 548; - vrLoc = 10825; - }; - 1D99499A10DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6505FD107700D882FA /* tnlVector.h */; - name = "tnlVector.h: 42"; - rLen = 0; - rLoc = 1446; - rType = 0; - vrLen = 428; - vrLoc = 1271; - }; - 1D99499B10DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - comments = "error: expected class-name before '{' token"; - fRef = 66D85DB705ACA1F0008DC9C1 /* MyOpenGLView.mm */; - rLen = 1; - rLoc = 32; - rType = 1; - }; - 1D99499C10DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; - name = "tnlTypes.h: 299"; - rLen = 75; - rLoc = 11001; - rType = 0; - vrLen = 555; - vrLoc = 10747; - }; - 1D99499D10DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6505FD107700D882FA /* tnlVector.h */; - name = "tnlVector.h: 101"; - rLen = 0; - rLoc = 3314; - rType = 0; - vrLen = 500; - vrLoc = 2821; - }; - 1D99499E10DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; - name = "tnlTypes.h: 300"; - rLen = 0; - rLoc = 10996; - rType = 0; - vrLen = 548; - vrLoc = 10825; - }; - 1D99499F10DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6505FD107700D882FA /* tnlVector.h */; - name = "tnlVector.h: 42"; - rLen = 0; - rLoc = 1446; - rType = 0; - vrLen = 428; - vrLoc = 1271; - }; - 1D9949A010DED6DE001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66D85DB705ACA1F0008DC9C1 /* MyOpenGLView.mm */; - name = "MyOpenGLView.mm: 32"; - rLen = 0; - rLoc = 1382; - rType = 0; - vrLen = 388; - vrLoc = 1327; - }; - 1D9949A510DED6E0001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - comments = "error: #error \"TNL: Unsupported version of GCC (see tnlMethodDispatch.cpp)\""; - fRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; - rLen = 1; - rLoc = 300; - rType = 1; - }; - 1D9949A610DED6E0001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; - name = "tnlTypes.h: 301"; - rLen = 75; - rLoc = 11001; - rType = 0; - vrLen = 586; - vrLoc = 10672; - }; - 1D9949AC10DED6E0001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */; - name = "tnlMethodDispatch.h: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 2815; - vrLoc = 12328; - }; - 1D9949AF10DED6E0001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */; - name = "tnlMethodDispatch.cpp: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 800; - vrLoc = 1327; - }; - 1D9949B410DED7A1001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; - name = "tnlTypes.h: 301"; - rLen = 75; - rLoc = 11001; - rType = 0; - vrLen = 535; - vrLoc = 10672; - }; - 1D9949B510DED7A1001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */; - name = "tnlMethodDispatch.h: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 2815; - vrLoc = 12328; - }; - 1D9949B610DED7A1001B3AFF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */; - name = "tnlMethodDispatch.cpp: 1"; - rLen = 0; - rLoc = 0; - rType = 0; - vrLen = 817; - vrLoc = 1310; - }; - 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {670, 1064}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{1310, 817}"; - }; - }; - 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {670, 4872}}"; - sepNavSelRange = "{0, 0}"; - sepNavVisRange = "{12328, 2815}"; - }; - }; - 29B97313FDCFA39411CA2CEA /* Project object */ = { - activeBuildConfigurationName = Development; - activeExecutable = 1D99495A10DED558001B3AFF /* TNLTest */; - activeTarget = 8D1107260486CEB800E47090 /* TNLTest */; - codeSenseManager = 1D99499210DED559001B3AFF /* Code sense */; - executables = ( - 1D99495A10DED558001B3AFF /* TNLTest */, - 1D99495B10DED558001B3AFF /* testserver */, - 1D99495C10DED558001B3AFF /* master */, - 1D99495D10DED558001B3AFF /* masterclient */, - 1D99495E10DED558001B3AFF /* ZAP */, - ); - perUserDictionary = { - PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { - PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; - PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; - PBXFileTableDataSourceColumnWidthsKey = ( - 20, - 341, - 20, - 48.16259765625, - 43, - 43, - 20, - ); - PBXFileTableDataSourceColumnsKey = ( - PBXFileDataSource_FiletypeID, - PBXFileDataSource_Filename_ColumnID, - PBXFileDataSource_Built_ColumnID, - PBXFileDataSource_ObjectSize_ColumnID, - PBXFileDataSource_Errors_ColumnID, - PBXFileDataSource_Warnings_ColumnID, - PBXFileDataSource_Target_ColumnID, - ); - }; - PBXPerProjectTemplateStateSaveDate = 283039064; - PBXWorkspaceStateSaveDate = 283039064; - }; - perUserProjectItems = { - 1D99499510DED60C001B3AFF /* PBXBookmark */ = 1D99499510DED60C001B3AFF /* PBXBookmark */; - 1D99499610DED630001B3AFF /* PBXBookmark */ = 1D99499610DED630001B3AFF /* PBXBookmark */; - 1D99499910DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499910DED6DE001B3AFF /* PBXTextBookmark */; - 1D99499A10DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499A10DED6DE001B3AFF /* PBXTextBookmark */; - 1D99499B10DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499B10DED6DE001B3AFF /* PBXTextBookmark */; - 1D99499C10DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499C10DED6DE001B3AFF /* PBXTextBookmark */; - 1D99499D10DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499D10DED6DE001B3AFF /* PBXTextBookmark */; - 1D99499E10DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499E10DED6DE001B3AFF /* PBXTextBookmark */; - 1D99499F10DED6DE001B3AFF /* PBXTextBookmark */ = 1D99499F10DED6DE001B3AFF /* PBXTextBookmark */; - 1D9949A010DED6DE001B3AFF /* PBXTextBookmark */ = 1D9949A010DED6DE001B3AFF /* PBXTextBookmark */; - 1D9949A510DED6E0001B3AFF /* PBXTextBookmark */ = 1D9949A510DED6E0001B3AFF /* PBXTextBookmark */; - 1D9949A610DED6E0001B3AFF /* PBXTextBookmark */ = 1D9949A610DED6E0001B3AFF /* PBXTextBookmark */; - 1D9949AC10DED6E0001B3AFF /* PBXTextBookmark */ = 1D9949AC10DED6E0001B3AFF /* PBXTextBookmark */; - 1D9949AF10DED6E0001B3AFF /* PBXTextBookmark */ = 1D9949AF10DED6E0001B3AFF /* PBXTextBookmark */; - 1D9949B410DED7A1001B3AFF /* PBXTextBookmark */ = 1D9949B410DED7A1001B3AFF /* PBXTextBookmark */; - 1D9949B510DED7A1001B3AFF /* PBXTextBookmark */ = 1D9949B510DED7A1001B3AFF /* PBXTextBookmark */; - 1D9949B610DED7A1001B3AFF /* PBXTextBookmark */ = 1D9949B610DED7A1001B3AFF /* PBXTextBookmark */; - }; - sourceControlManager = 1D99499110DED559001B3AFF /* Source Control */; - userBuildSettings = { - }; - }; - 6649E0D505FD01D700B3DD8B /* libtomcrypt */ = { - activeExec = 0; - }; - 6692C08706247BE000D5ADFE /* ZAP */ = { - activeExec = 0; - executables = ( - 1D99495E10DED558001B3AFF /* ZAP */, - ); - }; - 66BA0C6305FD107700D882FA /* tnlTypes.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {519, 6496}}"; - sepNavSelRange = "{11001, 75}"; - sepNavVisRange = "{10672, 535}"; - }; - }; - 66BA0C6505FD107700D882FA /* tnlVector.h */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {888, 5390}}"; - sepNavSelRange = "{1446, 0}"; - sepNavVisRange = "{1271, 428}"; - }; - }; - 66BA0E5B05FD467E00D882FA /* master */ = { - activeExec = 0; - executables = ( - 1D99495C10DED558001B3AFF /* master */, - ); - }; - 66BA0E8805FD473200D882FA /* masterclient */ = { - activeExec = 0; - executables = ( - 1D99495D10DED558001B3AFF /* masterclient */, - ); - }; - 66D85DB705ACA1F0008DC9C1 /* MyOpenGLView.mm */ = { - uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {888, 2268}}"; - sepNavSelRange = "{1382, 0}"; - sepNavVisRange = "{1327, 388}"; - }; - }; - 66D85E1805ACBA97008DC9C1 /* tnl */ = { - activeExec = 0; - }; - 66D85EDD05ACCC36008DC9C1 /* testserver */ = { - activeExec = 0; - executables = ( - 1D99495B10DED558001B3AFF /* testserver */, - ); - }; - 8D1107260486CEB800E47090 /* TNLTest */ = { - activeExec = 0; - executables = ( - 1D99495A10DED558001B3AFF /* TNLTest */, - ); - }; -} diff --git a/tnl-1.5.0/tnl/osx/tnl.xcodeproj/project.pbxproj b/tnl-1.5.0/tnl/osx/tnl.xcodeproj/project.pbxproj deleted file mode 100644 index a2151ae..0000000 --- a/tnl-1.5.0/tnl/osx/tnl.xcodeproj/project.pbxproj +++ /dev/null @@ -1,2081 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 42; - objects = { - -/* Begin PBXBuildFile section */ - 1D3CACCC0694D76300313D6F /* goalZone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D3CACC90694D76300313D6F /* goalZone.cpp */; }; - 1D3CACCD0694D76300313D6F /* goalZone.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D3CACCA0694D76300313D6F /* goalZone.h */; }; - 1D3CACCE0694D76300313D6F /* retrieveGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D3CACCB0694D76300313D6F /* retrieveGame.cpp */; }; - 1D3E3EEB0666A7EE005D645B /* loadoutSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D3E3EE90666A7EE005D645B /* loadoutSelect.cpp */; }; - 1D3E3EEC0666A7EE005D645B /* loadoutSelect.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D3E3EEA0666A7EE005D645B /* loadoutSelect.h */; }; - 1D3E3EEF0666A871005D645B /* UIEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D3E3EED0666A871005D645B /* UIEditor.cpp */; }; - 1D3E3EF00666A871005D645B /* UIEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D3E3EEE0666A871005D645B /* UIEditor.h */; }; - 1D49BD0D0691F71200643C72 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D49BD0C0691F71200643C72 /* IOKit.framework */; }; - 1D49BDC70691F8E000643C72 /* input.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D49BDC50691F8E000643C72 /* input.cpp */; }; - 1D49BDC80691F8E000643C72 /* input.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D49BDC60691F8E000643C72 /* input.h */; }; - 1D8DCBB806557E6D00BC4809 /* controlObjectConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1D8DCBB606557E6D00BC4809 /* controlObjectConnection.cpp */; }; - 1D8DCBB906557E6D00BC4809 /* controlObjectConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D8DCBB706557E6D00BC4809 /* controlObjectConnection.h */; }; - 1DC6ED450652D22A00BDEE0B /* journal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6ED430652D22A00BDEE0B /* journal.cpp */; }; - 1DC6ED460652D22A00BDEE0B /* tnlJournal.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC6ED440652D22A00BDEE0B /* tnlJournal.h */; }; - 1DC6ED4D0652D24B00BDEE0B /* gsm_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6ED470652D24B00BDEE0B /* gsm_decode.c */; }; - 1DC6ED4E0652D24B00BDEE0B /* gsm_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6ED480652D24B00BDEE0B /* gsm_encode.c */; }; - 1DC6ED4F0652D24B00BDEE0B /* gsm_state.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6ED490652D24B00BDEE0B /* gsm_state.c */; }; - 1DC6ED500652D24B00BDEE0B /* gsm.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC6ED4A0652D24B00BDEE0B /* gsm.h */; }; - 1DC6ED510652D24B00BDEE0B /* voiceCodec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6ED4B0652D24B00BDEE0B /* voiceCodec.cpp */; }; - 1DC6ED520652D24B00BDEE0B /* voiceCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC6ED4C0652D24B00BDEE0B /* voiceCodec.h */; }; - 1DC82048064C5C9000F61B0E /* tnlMethodDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */; }; - 1DC82049064C5C9000F61B0E /* tnlMethodDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */; }; - 1DC8204D064C5CBC00F61B0E /* lpc10.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DC8204A064C5CBC00F61B0E /* lpc10.h */; }; - 1DC8204E064C5CBC00F61B0E /* lpc10dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DC8204B064C5CBC00F61B0E /* lpc10dec.c */; }; - 1DC8204F064C5CBC00F61B0E /* lpc10enc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1DC8204C064C5CBC00F61B0E /* lpc10enc.c */; }; - 1DD229E3070B4A02000DFF1F /* HTFGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DD229E2070B4A02000DFF1F /* HTFGame.cpp */; }; - 1DE1EC7606909AB400D93C76 /* engineeredObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC6906909AB400D93C76 /* engineeredObjects.cpp */; }; - 1DE1EC7706909AB400D93C76 /* engineeredObjects.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE1EC6A06909AB400D93C76 /* engineeredObjects.h */; }; - 1DE1EC7806909AB400D93C76 /* flagItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC6B06909AB400D93C76 /* flagItem.cpp */; }; - 1DE1EC7906909AB400D93C76 /* footballGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC6C06909AB400D93C76 /* footballGame.cpp */; }; - 1DE1EC7A06909AB400D93C76 /* gameObjectRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC6D06909AB400D93C76 /* gameObjectRender.cpp */; }; - 1DE1EC7B06909AB400D93C76 /* gameObjectRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE1EC6E06909AB400D93C76 /* gameObjectRender.h */; }; - 1DE1EC7C06909AB400D93C76 /* huntersGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC6F06909AB400D93C76 /* huntersGame.cpp */; }; - 1DE1EC7D06909AB400D93C76 /* huntersGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE1EC7006909AB400D93C76 /* huntersGame.h */; }; - 1DE1EC7E06909AB400D93C76 /* LoadoutZone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC7106909AB400D93C76 /* LoadoutZone.cpp */; }; - 1DE1EC7F06909AB400D93C76 /* rabbitGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC7206909AB400D93C76 /* rabbitGame.cpp */; }; - 1DE1EC8006909AB400D93C76 /* rabbitGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE1EC7306909AB400D93C76 /* rabbitGame.h */; }; - 1DE1EC8106909AB400D93C76 /* UIInstructions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EC7406909AB400D93C76 /* UIInstructions.cpp */; }; - 1DE1EC8206909AB400D93C76 /* UIInstructions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE1EC7506909AB400D93C76 /* UIInstructions.h */; }; - 1DE1ED0D06909D0A00D93C76 /* gameWeapons.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1ED0B06909D0A00D93C76 /* gameWeapons.cpp */; }; - 1DE1ED0E06909D0A00D93C76 /* gameWeapons.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DE1ED0C06909D0A00D93C76 /* gameWeapons.h */; }; - 1DE1ED3406909FA300D93C76 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DE1ED3306909FA300D93C76 /* Carbon.framework */; }; - 1DE1EDF50690BA1600D93C76 /* osxInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1DE1EDF40690BA1600D93C76 /* osxInput.cpp */; }; - 6645D4C405ACD81600EFFB5D /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6645D4C305ACD81600EFFB5D /* main.mm */; }; - 6649E18705FD02BA00B3DD8B /* aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14305FD02BA00B3DD8B /* aes.c */; }; - 6649E18805FD02BA00B3DD8B /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14405FD02BA00B3DD8B /* base64.c */; }; - 6649E18905FD02BA00B3DD8B /* bits.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14505FD02BA00B3DD8B /* bits.c */; }; - 6649E18A05FD02BA00B3DD8B /* blowfish.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14605FD02BA00B3DD8B /* blowfish.c */; }; - 6649E18B05FD02BA00B3DD8B /* cast5.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14705FD02BA00B3DD8B /* cast5.c */; }; - 6649E18C05FD02BA00B3DD8B /* cbc.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14805FD02BA00B3DD8B /* cbc.c */; }; - 6649E18D05FD02BA00B3DD8B /* cfb.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14905FD02BA00B3DD8B /* cfb.c */; }; - 6649E18E05FD02BA00B3DD8B /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14A05FD02BA00B3DD8B /* crypt.c */; }; - 6649E18F05FD02BA00B3DD8B /* ctr.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14B05FD02BA00B3DD8B /* ctr.c */; }; - 6649E19005FD02BA00B3DD8B /* des.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14C05FD02BA00B3DD8B /* des.c */; }; - 6649E19205FD02BA00B3DD8B /* dh.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14E05FD02BA00B3DD8B /* dh.c */; }; - 6649E19305FD02BA00B3DD8B /* dsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E14F05FD02BA00B3DD8B /* dsa.c */; }; - 6649E19405FD02BA00B3DD8B /* ecb.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15005FD02BA00B3DD8B /* ecb.c */; }; - 6649E19605FD02BA00B3DD8B /* ecc.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15205FD02BA00B3DD8B /* ecc.c */; }; - 6649E19705FD02BA00B3DD8B /* gf.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15305FD02BA00B3DD8B /* gf.c */; }; - 6649E19805FD02BA00B3DD8B /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15405FD02BA00B3DD8B /* hash.c */; }; - 6649E19905FD02BA00B3DD8B /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15505FD02BA00B3DD8B /* hmac.c */; }; - 6649E19A05FD02BA00B3DD8B /* keyring.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15605FD02BA00B3DD8B /* keyring.c */; }; - 6649E19B05FD02BA00B3DD8B /* md2.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15705FD02BA00B3DD8B /* md2.c */; }; - 6649E19C05FD02BA00B3DD8B /* md4.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15805FD02BA00B3DD8B /* md4.c */; }; - 6649E19D05FD02BA00B3DD8B /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15905FD02BA00B3DD8B /* md5.c */; }; - 6649E19E05FD02BA00B3DD8B /* mem.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15A05FD02BA00B3DD8B /* mem.c */; }; - 6649E19F05FD02BA00B3DD8B /* mpi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E15B05FD02BA00B3DD8B /* mpi.c */; }; - 6649E1A005FD02BA00B3DD8B /* mycrypt_argchk.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E15C05FD02BA00B3DD8B /* mycrypt_argchk.h */; settings = {ATTRIBUTES = (); }; }; - 6649E1A105FD02BA00B3DD8B /* mycrypt_cfg.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E15D05FD02BA00B3DD8B /* mycrypt_cfg.h */; }; - 6649E1A205FD02BA00B3DD8B /* mycrypt_cipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E15E05FD02BA00B3DD8B /* mycrypt_cipher.h */; }; - 6649E1A305FD02BA00B3DD8B /* mycrypt_custom.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E15F05FD02BA00B3DD8B /* mycrypt_custom.h */; }; - 6649E1A405FD02BA00B3DD8B /* mycrypt_gf.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16005FD02BA00B3DD8B /* mycrypt_gf.h */; }; - 6649E1A505FD02BA00B3DD8B /* mycrypt_hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16105FD02BA00B3DD8B /* mycrypt_hash.h */; }; - 6649E1A605FD02BA00B3DD8B /* mycrypt_kr.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16205FD02BA00B3DD8B /* mycrypt_kr.h */; }; - 6649E1A705FD02BA00B3DD8B /* mycrypt_macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16305FD02BA00B3DD8B /* mycrypt_macros.h */; }; - 6649E1A805FD02BA00B3DD8B /* mycrypt_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16405FD02BA00B3DD8B /* mycrypt_misc.h */; }; - 6649E1A905FD02BA00B3DD8B /* mycrypt_pk.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16505FD02BA00B3DD8B /* mycrypt_pk.h */; }; - 6649E1AA05FD02BA00B3DD8B /* mycrypt_prng.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16605FD02BA00B3DD8B /* mycrypt_prng.h */; }; - 6649E1AB05FD02BA00B3DD8B /* mycrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E16705FD02BA00B3DD8B /* mycrypt.h */; }; - 6649E1AC05FD02BA00B3DD8B /* noekeon.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16805FD02BA00B3DD8B /* noekeon.c */; }; - 6649E1AD05FD02BA00B3DD8B /* ofb.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16905FD02BA00B3DD8B /* ofb.c */; }; - 6649E1AE05FD02BA00B3DD8B /* omac.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16A05FD02BA00B3DD8B /* omac.c */; }; - 6649E1AF05FD02BA00B3DD8B /* packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16B05FD02BA00B3DD8B /* packet.c */; }; - 6649E1B005FD02BA00B3DD8B /* prime.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16C05FD02BA00B3DD8B /* prime.c */; }; - 6649E1B105FD02BA00B3DD8B /* rc2.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16D05FD02BA00B3DD8B /* rc2.c */; }; - 6649E1B205FD02BA00B3DD8B /* rc4.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16E05FD02BA00B3DD8B /* rc4.c */; }; - 6649E1B305FD02BA00B3DD8B /* rc5.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E16F05FD02BA00B3DD8B /* rc5.c */; }; - 6649E1B405FD02BA00B3DD8B /* rc6.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17005FD02BA00B3DD8B /* rc6.c */; }; - 6649E1B505FD02BA00B3DD8B /* rmd128.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17105FD02BA00B3DD8B /* rmd128.c */; }; - 6649E1B605FD02BA00B3DD8B /* rmd160.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17205FD02BA00B3DD8B /* rmd160.c */; }; - 6649E1B805FD02BA00B3DD8B /* rsa.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17405FD02BA00B3DD8B /* rsa.c */; }; - 6649E1B905FD02BA00B3DD8B /* safer_tab.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17505FD02BA00B3DD8B /* safer_tab.c */; }; - 6649E1BA05FD02BA00B3DD8B /* safer.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17605FD02BA00B3DD8B /* safer.c */; }; - 6649E1BB05FD02BA00B3DD8B /* safer+.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17705FD02BA00B3DD8B /* safer+.c */; }; - 6649E1BC05FD02BA00B3DD8B /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17805FD02BA00B3DD8B /* sha1.c */; }; - 6649E1BE05FD02BA00B3DD8B /* sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17A05FD02BA00B3DD8B /* sha256.c */; }; - 6649E1C005FD02BA00B3DD8B /* sha512.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17C05FD02BA00B3DD8B /* sha512.c */; }; - 6649E1C105FD02BA00B3DD8B /* skipjack.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17D05FD02BA00B3DD8B /* skipjack.c */; }; - 6649E1C205FD02BA00B3DD8B /* sprng.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17E05FD02BA00B3DD8B /* sprng.c */; }; - 6649E1C305FD02BA00B3DD8B /* strings.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E17F05FD02BA00B3DD8B /* strings.c */; }; - 6649E1C405FD02BA00B3DD8B /* tiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E18005FD02BA00B3DD8B /* tiger.c */; }; - 6649E1C505FD02BA00B3DD8B /* tommath.h in Headers */ = {isa = PBXBuildFile; fileRef = 6649E18105FD02BA00B3DD8B /* tommath.h */; }; - 6649E1C705FD02BA00B3DD8B /* twofish.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E18305FD02BA00B3DD8B /* twofish.c */; }; - 6649E1C805FD02BA00B3DD8B /* xtea.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E18405FD02BA00B3DD8B /* xtea.c */; }; - 6649E1C905FD02BA00B3DD8B /* yarrow.c in Sources */ = {isa = PBXBuildFile; fileRef = 6649E18505FD02BA00B3DD8B /* yarrow.c */; }; - 6656DD850635C66F00E30126 /* libtnl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66D85E1905ACBA97008DC9C1 /* libtnl.a */; }; - 6656DD9C0635C8EF00E30126 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6656DD9B0635C8EF00E30126 /* OpenAL.framework */; }; - 6656DDD40635C95C00E30126 /* CTFGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6656DDCA0635C95C00E30126 /* CTFGame.cpp */; }; - 6656DDD50635C95C00E30126 /* CTFGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 6656DDCB0635C95C00E30126 /* CTFGame.h */; }; - 6656DDD60635C95C00E30126 /* gameType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6656DDCC0635C95C00E30126 /* gameType.cpp */; }; - 6656DDD70635C95C00E30126 /* gameType.h in Headers */ = {isa = PBXBuildFile; fileRef = 6656DDCD0635C95C00E30126 /* gameType.h */; }; - 6656DDD80635C95C00E30126 /* item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6656DDCE0635C95C00E30126 /* item.cpp */; }; - 6656DDD90635C95C00E30126 /* item.h in Headers */ = {isa = PBXBuildFile; fileRef = 6656DDCF0635C95C00E30126 /* item.h */; }; - 6656DDDA0635C95C00E30126 /* moveObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6656DDD00635C95C00E30126 /* moveObject.cpp */; }; - 6656DDDB0635C95C00E30126 /* moveObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6656DDD10635C95C00E30126 /* moveObject.h */; }; - 6656DDDC0635C95C00E30126 /* sfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6656DDD20635C95C00E30126 /* sfx.cpp */; }; - 6656DDDD0635C95C00E30126 /* sfx.h in Headers */ = {isa = PBXBuildFile; fileRef = 6656DDD30635C95C00E30126 /* sfx.h */; }; - 6661401405B3965A00320653 /* udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6661401205B3965A00320653 /* udp.cpp */; }; - 6661401A05B3966700320653 /* platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6661401905B3966700320653 /* platform.cpp */; }; - 6692C0AA06247C2300D5ADFE /* gameConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C08E06247C2300D5ADFE /* gameConnection.cpp */; }; - 6692C0AB06247C2300D5ADFE /* gameConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C08F06247C2300D5ADFE /* gameConnection.h */; }; - 6692C0AC06247C2300D5ADFE /* gameNetInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09006247C2300D5ADFE /* gameNetInterface.cpp */; }; - 6692C0AD06247C2300D5ADFE /* gameNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09106247C2300D5ADFE /* gameNetInterface.h */; }; - 6692C0B006247C2300D5ADFE /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09406247C2300D5ADFE /* main.cpp */; }; - 6692C0B106247C2300D5ADFE /* masterConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09506247C2300D5ADFE /* masterConnection.cpp */; }; - 6692C0B206247C2300D5ADFE /* masterConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09606247C2300D5ADFE /* masterConnection.h */; }; - 6692C0B306247C2300D5ADFE /* point.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09706247C2300D5ADFE /* point.h */; }; - 6692C0B406247C2300D5ADFE /* projectile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09806247C2300D5ADFE /* projectile.cpp */; }; - 6692C0B506247C2300D5ADFE /* projectile.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09906247C2300D5ADFE /* projectile.h */; }; - 6692C0B606247C2300D5ADFE /* ship.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09A06247C2300D5ADFE /* ship.cpp */; }; - 6692C0B706247C2300D5ADFE /* ship.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09B06247C2300D5ADFE /* ship.h */; }; - 6692C0B806247C2300D5ADFE /* sparkManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09C06247C2300D5ADFE /* sparkManager.cpp */; }; - 6692C0B906247C2300D5ADFE /* sparkManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09D06247C2300D5ADFE /* sparkManager.h */; }; - 6692C0BA06247C2300D5ADFE /* SweptEllipsoid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C09E06247C2300D5ADFE /* SweptEllipsoid.cpp */; }; - 6692C0BB06247C2300D5ADFE /* SweptEllipsoid.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C09F06247C2300D5ADFE /* SweptEllipsoid.h */; }; - 6692C0BC06247C2300D5ADFE /* UI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C0A006247C2300D5ADFE /* UI.cpp */; }; - 6692C0BD06247C2300D5ADFE /* UI.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C0A106247C2300D5ADFE /* UI.h */; }; - 6692C0BE06247C2300D5ADFE /* UIGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C0A206247C2300D5ADFE /* UIGame.cpp */; }; - 6692C0BF06247C2300D5ADFE /* UIGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C0A306247C2300D5ADFE /* UIGame.h */; }; - 6692C0C006247C2300D5ADFE /* UIMenus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C0A406247C2300D5ADFE /* UIMenus.cpp */; }; - 6692C0C106247C2300D5ADFE /* UIMenus.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C0A506247C2300D5ADFE /* UIMenus.h */; }; - 6692C0C206247C2300D5ADFE /* UINameEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C0A606247C2300D5ADFE /* UINameEntry.cpp */; }; - 6692C0C306247C2300D5ADFE /* UINameEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C0A706247C2300D5ADFE /* UINameEntry.h */; }; - 6692C0C406247C2300D5ADFE /* UIQueryServers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C0A806247C2300D5ADFE /* UIQueryServers.cpp */; }; - 6692C0C506247C2300D5ADFE /* UIQueryServers.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C0A906247C2300D5ADFE /* UIQueryServers.h */; }; - 6692C15E06247D2000D5ADFE /* GLUT.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6692C11906247CF900D5ADFE /* GLUT.framework */; }; - 6692C15F06247D2500D5ADFE /* libtnl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66D85E1905ACBA97008DC9C1 /* libtnl.a */; }; - 6692C16106247D2700D5ADFE /* liblibtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */; }; - 6692C18B06247DB900D5ADFE /* glutInclude.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C18A06247DB900D5ADFE /* glutInclude.h */; }; - 6692C1FA06247F2000D5ADFE /* masterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0E7805FD46F600D882FA /* masterInterface.cpp */; }; - 6692C2390625E7E800D5ADFE /* barrier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C22D0625E7E800D5ADFE /* barrier.cpp */; }; - 6692C23A0625E7E800D5ADFE /* barrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C22E0625E7E800D5ADFE /* barrier.h */; }; - 6692C23B0625E7E800D5ADFE /* game.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C22F0625E7E800D5ADFE /* game.cpp */; }; - 6692C23C0625E7E800D5ADFE /* game.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C2300625E7E800D5ADFE /* game.h */; }; - 6692C23D0625E7E800D5ADFE /* gameLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C2310625E7E800D5ADFE /* gameLoader.cpp */; }; - 6692C23E0625E7E800D5ADFE /* gameLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C2320625E7E800D5ADFE /* gameLoader.h */; }; - 6692C23F0625E7E800D5ADFE /* gameObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C2330625E7E800D5ADFE /* gameObject.cpp */; }; - 6692C2400625E7E800D5ADFE /* gameObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C2340625E7E800D5ADFE /* gameObject.h */; }; - 6692C2410625E7E800D5ADFE /* gridDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C2350625E7E800D5ADFE /* gridDB.cpp */; }; - 6692C2420625E7E800D5ADFE /* gridDB.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C2360625E7E800D5ADFE /* gridDB.h */; }; - 6692C2430625E7E800D5ADFE /* teleporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6692C2370625E7E800D5ADFE /* teleporter.cpp */; }; - 6692C2440625E7E800D5ADFE /* teleporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6692C2380625E7E800D5ADFE /* teleporter.h */; }; - 66BA0C6605FD107700D882FA /* tnlAssert.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C4A05FD107700D882FA /* tnlAssert.h */; }; - 66BA0C6705FD107700D882FA /* tnlAsymmetricKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C4B05FD107700D882FA /* tnlAsymmetricKey.h */; }; - 66BA0C6805FD107700D882FA /* tnlBitSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C4C05FD107700D882FA /* tnlBitSet.h */; }; - 66BA0C6905FD107700D882FA /* tnlBitStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C4D05FD107700D882FA /* tnlBitStream.h */; }; - 66BA0C6A05FD107700D882FA /* tnlByteBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C4E05FD107700D882FA /* tnlByteBuffer.h */; }; - 66BA0C6B05FD107700D882FA /* tnlCertificate.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C4F05FD107700D882FA /* tnlCertificate.h */; }; - 66BA0C6C05FD107700D882FA /* tnlClientPuzzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5005FD107700D882FA /* tnlClientPuzzle.h */; }; - 66BA0C6D05FD107700D882FA /* tnlConnectionStringTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5105FD107700D882FA /* tnlConnectionStringTable.h */; }; - 66BA0C6E05FD107700D882FA /* tnlDataChunker.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5205FD107700D882FA /* tnlDataChunker.h */; }; - 66BA0C6F05FD107700D882FA /* tnlEndian.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5305FD107700D882FA /* tnlEndian.h */; }; - 66BA0C7005FD107700D882FA /* tnlEventConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5405FD107700D882FA /* tnlEventConnection.h */; }; - 66BA0C7105FD107700D882FA /* tnlGhostConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5505FD107700D882FA /* tnlGhostConnection.h */; }; - 66BA0C7205FD107700D882FA /* tnlHuffmanStringProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5605FD107700D882FA /* tnlHuffmanStringProcessor.h */; }; - 66BA0C7305FD107700D882FA /* tnlLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5705FD107700D882FA /* tnlLog.h */; }; - 66BA0C7405FD107700D882FA /* tnlNetBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5805FD107700D882FA /* tnlNetBase.h */; }; - 66BA0C7505FD107700D882FA /* tnlNetConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5905FD107700D882FA /* tnlNetConnection.h */; }; - 66BA0C7605FD107700D882FA /* tnlNetEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5A05FD107700D882FA /* tnlNetEvent.h */; }; - 66BA0C7705FD107700D882FA /* tnlNetInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5B05FD107700D882FA /* tnlNetInterface.h */; }; - 66BA0C7805FD107700D882FA /* tnlNetObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5C05FD107700D882FA /* tnlNetObject.h */; }; - 66BA0C7905FD107700D882FA /* tnlNetStringTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5D05FD107700D882FA /* tnlNetStringTable.h */; }; - 66BA0C7A05FD107700D882FA /* tnlNonce.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5E05FD107700D882FA /* tnlNonce.h */; }; - 66BA0C7B05FD107700D882FA /* tnlPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C5F05FD107700D882FA /* tnlPlatform.h */; }; - 66BA0C7C05FD107700D882FA /* tnlRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C6005FD107700D882FA /* tnlRandom.h */; }; - 66BA0C7D05FD107700D882FA /* tnlRPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C6105FD107700D882FA /* tnlRPC.h */; }; - 66BA0C7E05FD107700D882FA /* tnlSymmetricCipher.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C6205FD107700D882FA /* tnlSymmetricCipher.h */; }; - 66BA0C7F05FD107700D882FA /* tnlTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C6305FD107700D882FA /* tnlTypes.h */; }; - 66BA0C8005FD107700D882FA /* tnlUDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C6405FD107700D882FA /* tnlUDP.h */; }; - 66BA0C8105FD107700D882FA /* tnlVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0C6505FD107700D882FA /* tnlVector.h */; }; - 66BA0CE405FD17F600D882FA /* asymmetricKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0CE005FD17F600D882FA /* asymmetricKey.cpp */; }; - 66BA0CE505FD17F600D882FA /* byteBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0CE105FD17F600D882FA /* byteBuffer.cpp */; }; - 66BA0CE605FD17F600D882FA /* clientPuzzle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0CE205FD17F600D882FA /* clientPuzzle.cpp */; }; - 66BA0CE705FD17F600D882FA /* symmetricCipher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0CE305FD17F600D882FA /* symmetricCipher.cpp */; }; - 66BA0CF605FD182100D882FA /* liblibtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */; }; - 66BA0D1005FD195C00D882FA /* liblibtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */; }; - 66BA0E6B05FD46C000D882FA /* liblibtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */; }; - 66BA0E6E05FD46C300D882FA /* libtnl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66D85E1905ACBA97008DC9C1 /* libtnl.a */; }; - 66BA0E7A05FD46F600D882FA /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0E7705FD46F600D882FA /* main.cpp */; }; - 66BA0E7B05FD46F600D882FA /* masterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0E7805FD46F600D882FA /* masterInterface.cpp */; }; - 66BA0E7C05FD46F600D882FA /* masterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0E7905FD46F600D882FA /* masterInterface.h */; }; - 66BA0EA005FD477500D882FA /* libtnl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 66D85E1905ACBA97008DC9C1 /* libtnl.a */; }; - 66BA0EA105FD477500D882FA /* liblibtomcrypt.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */; }; - 66BA0EA405FD478900D882FA /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0EA305FD478900D882FA /* main.cpp */; }; - 66BA0EB905FD47A900D882FA /* masterInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66BA0E7805FD46F600D882FA /* masterInterface.cpp */; }; - 66BA0EBC05FD47B100D882FA /* masterInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 66BA0E7905FD46F600D882FA /* masterInterface.h */; }; - 66D85C2105AC8772008DC9C1 /* testGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85C1E05AC8772008DC9C1 /* testGame.cpp */; }; - 66D85C2205AC8772008DC9C1 /* testGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D85C1F05AC8772008DC9C1 /* testGame.h */; }; - 66D85C2305AC8772008DC9C1 /* testGameRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85C2005AC8772008DC9C1 /* testGameRender.cpp */; }; - 66D85C9305AC8DC7008DC9C1 /* MyOpenGLView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D85C9105AC8DC7008DC9C1 /* MyOpenGLView.h */; }; - 66D85DB805ACA1F0008DC9C1 /* MyOpenGLView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 66D85DB705ACA1F0008DC9C1 /* MyOpenGLView.mm */; }; - 66D85E7305ACCB91008DC9C1 /* tnl.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D85E5C05ACCB91008DC9C1 /* tnl.h */; }; - 66D85EA605ACCBBA008DC9C1 /* huffmanStringProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9305ACCBBA008DC9C1 /* huffmanStringProcessor.cpp */; }; - 66D85EA705ACCBBA008DC9C1 /* assert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9405ACCBBA008DC9C1 /* assert.cpp */; }; - 66D85EA805ACCBBA008DC9C1 /* dataChunker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9505ACCBBA008DC9C1 /* dataChunker.cpp */; }; - 66D85EA905ACCBBA008DC9C1 /* netStringTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9605ACCBBA008DC9C1 /* netStringTable.cpp */; }; - 66D85EAA05ACCBBA008DC9C1 /* ghostConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9705ACCBBA008DC9C1 /* ghostConnection.cpp */; }; - 66D85EAC05ACCBBA008DC9C1 /* netConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9905ACCBBA008DC9C1 /* netConnection.cpp */; }; - 66D85EAF05ACCBBA008DC9C1 /* log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9C05ACCBBA008DC9C1 /* log.cpp */; }; - 66D85EB005ACCBBA008DC9C1 /* random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9D05ACCBBA008DC9C1 /* random.cpp */; }; - 66D85EB105ACCBBA008DC9C1 /* netObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9E05ACCBBA008DC9C1 /* netObject.cpp */; }; - 66D85EB205ACCBBA008DC9C1 /* connectionStringTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85E9F05ACCBBA008DC9C1 /* connectionStringTable.cpp */; }; - 66D85EB305ACCBBA008DC9C1 /* rpc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EA005ACCBBA008DC9C1 /* rpc.cpp */; }; - 66D85EB405ACCBBA008DC9C1 /* netInterface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EA105ACCBBA008DC9C1 /* netInterface.cpp */; }; - 66D85EB505ACCBBA008DC9C1 /* netBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EA205ACCBBA008DC9C1 /* netBase.cpp */; }; - 66D85EB605ACCBBA008DC9C1 /* eventConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EA305ACCBBA008DC9C1 /* eventConnection.cpp */; }; - 66D85EB705ACCBBA008DC9C1 /* vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EA405ACCBBA008DC9C1 /* vector.cpp */; }; - 66D85EB805ACCBBA008DC9C1 /* bitStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EA505ACCBBA008DC9C1 /* bitStream.cpp */; }; - 66D85EE705ACCC6A008DC9C1 /* server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85EE605ACCC6A008DC9C1 /* server.cpp */; }; - 66D85EF005ACCC8D008DC9C1 /* testGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 66D85C1E05AC8772008DC9C1 /* testGame.cpp */; }; - 66D85EF305ACCC8D008DC9C1 /* testGame.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D85C1F05AC8772008DC9C1 /* testGame.h */; }; - 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; }; - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; - DB9525D00636109800B8795E /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB9525CF0636109800B8795E /* OpenGL.framework */; }; - DB9525D10636109800B8795E /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB9525CF0636109800B8795E /* OpenGL.framework */; }; - DB9525E4063610C200B8795E /* certificate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DB9525E3063610C200B8795E /* certificate.cpp */; }; - DB997D2A0638AFC1002745B0 /* gameItems.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DB997D270638AFC1002745B0 /* gameItems.cpp */; }; - DB997D2B0638AFC1002745B0 /* quickChat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DB997D280638AFC1002745B0 /* quickChat.cpp */; }; - DB997D2C0638AFC1002745B0 /* quickChat.h in Headers */ = {isa = PBXBuildFile; fileRef = DB997D290638AFC1002745B0 /* quickChat.h */; }; - DBAFF49B06471A4200683BA4 /* soccerGame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DBAFF49906471A4200683BA4 /* soccerGame.cpp */; }; - DBAFF49C06471A4200683BA4 /* soccerGame.h in Headers */ = {isa = PBXBuildFile; fileRef = DBAFF49A06471A4200683BA4 /* soccerGame.h */; }; - DBAFF4A906471AAE00683BA4 /* UICredits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DBAFF4A706471AAE00683BA4 /* UICredits.cpp */; }; - DBAFF4AA06471AAE00683BA4 /* UICredits.h in Headers */ = {isa = PBXBuildFile; fileRef = DBAFF4A806471AAE00683BA4 /* UICredits.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 66BA0C3605FD0E5B00D882FA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; - remoteInfo = libtomcrypt; - }; - 66BA0E6005FD468600D882FA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; - remoteInfo = tnl; - }; - 66BA0E6205FD468B00D882FA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; - remoteInfo = libtomcrypt; - }; - 66BA0E8D05FD473A00D882FA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; - remoteInfo = tnl; - }; - 66BA0E8F05FD474000D882FA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; - remoteInfo = libtomcrypt; - }; - 66BA0E9305FD475500D882FA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6649E0D505FD01D700B3DD8B; - remoteInfo = libtomcrypt; - }; - 66D85ED805ACCC15008DC9C1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; - remoteInfo = tnl; - }; - 66D85EE205ACCC3C008DC9C1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; - proxyType = 1; - remoteGlobalIDString = 66D85E1805ACBA97008DC9C1; - remoteInfo = tnl; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 1D3CACC90694D76300313D6F /* goalZone.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = goalZone.cpp; path = ../zap/goalZone.cpp; sourceTree = SOURCE_ROOT; }; - 1D3CACCA0694D76300313D6F /* goalZone.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = goalZone.h; path = ../zap/goalZone.h; sourceTree = SOURCE_ROOT; }; - 1D3CACCB0694D76300313D6F /* retrieveGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = retrieveGame.cpp; path = ../zap/retrieveGame.cpp; sourceTree = SOURCE_ROOT; }; - 1D3E3EE90666A7EE005D645B /* loadoutSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = loadoutSelect.cpp; path = ../zap/loadoutSelect.cpp; sourceTree = SOURCE_ROOT; }; - 1D3E3EEA0666A7EE005D645B /* loadoutSelect.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = loadoutSelect.h; path = ../zap/loadoutSelect.h; sourceTree = SOURCE_ROOT; }; - 1D3E3EED0666A871005D645B /* UIEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UIEditor.cpp; path = ../zap/UIEditor.cpp; sourceTree = SOURCE_ROOT; }; - 1D3E3EEE0666A871005D645B /* UIEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIEditor.h; path = ../zap/UIEditor.h; sourceTree = SOURCE_ROOT; }; - 1D49BD0C0691F71200643C72 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; - 1D49BDC50691F8E000643C72 /* input.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = input.cpp; path = ../zap/input.cpp; sourceTree = SOURCE_ROOT; }; - 1D49BDC60691F8E000643C72 /* input.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = input.h; path = ../zap/input.h; sourceTree = SOURCE_ROOT; }; - 1D8DCBB606557E6D00BC4809 /* controlObjectConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = controlObjectConnection.cpp; path = ../zap/controlObjectConnection.cpp; sourceTree = SOURCE_ROOT; }; - 1D8DCBB706557E6D00BC4809 /* controlObjectConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = controlObjectConnection.h; path = ../zap/controlObjectConnection.h; sourceTree = SOURCE_ROOT; }; - 1DC6ED430652D22A00BDEE0B /* journal.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = journal.cpp; path = ../tnl/journal.cpp; sourceTree = SOURCE_ROOT; }; - 1DC6ED440652D22A00BDEE0B /* tnlJournal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlJournal.h; path = ../tnl/tnlJournal.h; sourceTree = SOURCE_ROOT; }; - 1DC6ED470652D24B00BDEE0B /* gsm_decode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gsm_decode.c; path = ../zap/gsm_decode.c; sourceTree = SOURCE_ROOT; }; - 1DC6ED480652D24B00BDEE0B /* gsm_encode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gsm_encode.c; path = ../zap/gsm_encode.c; sourceTree = SOURCE_ROOT; }; - 1DC6ED490652D24B00BDEE0B /* gsm_state.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gsm_state.c; path = ../zap/gsm_state.c; sourceTree = SOURCE_ROOT; }; - 1DC6ED4A0652D24B00BDEE0B /* gsm.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gsm.h; path = ../zap/gsm.h; sourceTree = SOURCE_ROOT; }; - 1DC6ED4B0652D24B00BDEE0B /* voiceCodec.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = voiceCodec.cpp; path = ../zap/voiceCodec.cpp; sourceTree = SOURCE_ROOT; }; - 1DC6ED4C0652D24B00BDEE0B /* voiceCodec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = voiceCodec.h; path = ../zap/voiceCodec.h; sourceTree = SOURCE_ROOT; }; - 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = tnlMethodDispatch.cpp; path = ../tnl/tnlMethodDispatch.cpp; sourceTree = SOURCE_ROOT; }; - 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlMethodDispatch.h; path = ../tnl/tnlMethodDispatch.h; sourceTree = SOURCE_ROOT; }; - 1DC8204A064C5CBC00F61B0E /* lpc10.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = lpc10.h; path = ../zap/lpc10.h; sourceTree = SOURCE_ROOT; }; - 1DC8204B064C5CBC00F61B0E /* lpc10dec.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lpc10dec.c; path = ../zap/lpc10dec.c; sourceTree = SOURCE_ROOT; }; - 1DC8204C064C5CBC00F61B0E /* lpc10enc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = lpc10enc.c; path = ../zap/lpc10enc.c; sourceTree = SOURCE_ROOT; }; - 1DD229E2070B4A02000DFF1F /* HTFGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = HTFGame.cpp; path = ../zap/HTFGame.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC6906909AB400D93C76 /* engineeredObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = engineeredObjects.cpp; path = ../zap/engineeredObjects.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC6A06909AB400D93C76 /* engineeredObjects.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = engineeredObjects.h; path = ../zap/engineeredObjects.h; sourceTree = SOURCE_ROOT; }; - 1DE1EC6B06909AB400D93C76 /* flagItem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = flagItem.cpp; path = ../zap/flagItem.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC6C06909AB400D93C76 /* footballGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = footballGame.cpp; path = ../zap/footballGame.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC6D06909AB400D93C76 /* gameObjectRender.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameObjectRender.cpp; path = ../zap/gameObjectRender.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC6E06909AB400D93C76 /* gameObjectRender.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameObjectRender.h; path = ../zap/gameObjectRender.h; sourceTree = SOURCE_ROOT; }; - 1DE1EC6F06909AB400D93C76 /* huntersGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = huntersGame.cpp; path = ../zap/huntersGame.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC7006909AB400D93C76 /* huntersGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = huntersGame.h; path = ../zap/huntersGame.h; sourceTree = SOURCE_ROOT; }; - 1DE1EC7106909AB400D93C76 /* LoadoutZone.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = LoadoutZone.cpp; path = ../zap/LoadoutZone.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC7206909AB400D93C76 /* rabbitGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = rabbitGame.cpp; path = ../zap/rabbitGame.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC7306909AB400D93C76 /* rabbitGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = rabbitGame.h; path = ../zap/rabbitGame.h; sourceTree = SOURCE_ROOT; }; - 1DE1EC7406909AB400D93C76 /* UIInstructions.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UIInstructions.cpp; path = ../zap/UIInstructions.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1EC7506909AB400D93C76 /* UIInstructions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIInstructions.h; path = ../zap/UIInstructions.h; sourceTree = SOURCE_ROOT; }; - 1DE1ED0B06909D0A00D93C76 /* gameWeapons.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameWeapons.cpp; path = ../zap/gameWeapons.cpp; sourceTree = SOURCE_ROOT; }; - 1DE1ED0C06909D0A00D93C76 /* gameWeapons.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameWeapons.h; path = ../zap/gameWeapons.h; sourceTree = SOURCE_ROOT; }; - 1DE1ED3306909FA300D93C76 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; - 1DE1EDF40690BA1600D93C76 /* osxInput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = osxInput.cpp; path = ../zap/osxInput.cpp; sourceTree = SOURCE_ROOT; }; - 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = ""; }; - 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; - 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; - 6645D4C305ACD81600EFFB5D /* main.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; }; - 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblibtomcrypt.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 6649E14205FD02BA00B3DD8B /* aes_tab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = aes_tab.c; path = ../libtomcrypt/aes_tab.c; sourceTree = SOURCE_ROOT; }; - 6649E14305FD02BA00B3DD8B /* aes.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = aes.c; path = ../libtomcrypt/aes.c; sourceTree = SOURCE_ROOT; }; - 6649E14405FD02BA00B3DD8B /* base64.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = base64.c; path = ../libtomcrypt/base64.c; sourceTree = SOURCE_ROOT; }; - 6649E14505FD02BA00B3DD8B /* bits.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bits.c; path = ../libtomcrypt/bits.c; sourceTree = SOURCE_ROOT; }; - 6649E14605FD02BA00B3DD8B /* blowfish.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = blowfish.c; path = ../libtomcrypt/blowfish.c; sourceTree = SOURCE_ROOT; }; - 6649E14705FD02BA00B3DD8B /* cast5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cast5.c; path = ../libtomcrypt/cast5.c; sourceTree = SOURCE_ROOT; }; - 6649E14805FD02BA00B3DD8B /* cbc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cbc.c; path = ../libtomcrypt/cbc.c; sourceTree = SOURCE_ROOT; }; - 6649E14905FD02BA00B3DD8B /* cfb.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cfb.c; path = ../libtomcrypt/cfb.c; sourceTree = SOURCE_ROOT; }; - 6649E14A05FD02BA00B3DD8B /* crypt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = crypt.c; path = ../libtomcrypt/crypt.c; sourceTree = SOURCE_ROOT; }; - 6649E14B05FD02BA00B3DD8B /* ctr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ctr.c; path = ../libtomcrypt/ctr.c; sourceTree = SOURCE_ROOT; }; - 6649E14C05FD02BA00B3DD8B /* des.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = des.c; path = ../libtomcrypt/des.c; sourceTree = SOURCE_ROOT; }; - 6649E14D05FD02BA00B3DD8B /* dh_sys.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dh_sys.c; path = ../libtomcrypt/dh_sys.c; sourceTree = SOURCE_ROOT; }; - 6649E14E05FD02BA00B3DD8B /* dh.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dh.c; path = ../libtomcrypt/dh.c; sourceTree = SOURCE_ROOT; }; - 6649E14F05FD02BA00B3DD8B /* dsa.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dsa.c; path = ../libtomcrypt/dsa.c; sourceTree = SOURCE_ROOT; }; - 6649E15005FD02BA00B3DD8B /* ecb.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ecb.c; path = ../libtomcrypt/ecb.c; sourceTree = SOURCE_ROOT; }; - 6649E15105FD02BA00B3DD8B /* ecc_sys.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ecc_sys.c; path = ../libtomcrypt/ecc_sys.c; sourceTree = SOURCE_ROOT; }; - 6649E15205FD02BA00B3DD8B /* ecc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ecc.c; path = ../libtomcrypt/ecc.c; sourceTree = SOURCE_ROOT; }; - 6649E15305FD02BA00B3DD8B /* gf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = gf.c; path = ../libtomcrypt/gf.c; sourceTree = SOURCE_ROOT; }; - 6649E15405FD02BA00B3DD8B /* hash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../libtomcrypt/hash.c; sourceTree = SOURCE_ROOT; }; - 6649E15505FD02BA00B3DD8B /* hmac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hmac.c; path = ../libtomcrypt/hmac.c; sourceTree = SOURCE_ROOT; }; - 6649E15605FD02BA00B3DD8B /* keyring.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = keyring.c; path = ../libtomcrypt/keyring.c; sourceTree = SOURCE_ROOT; }; - 6649E15705FD02BA00B3DD8B /* md2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md2.c; path = ../libtomcrypt/md2.c; sourceTree = SOURCE_ROOT; }; - 6649E15805FD02BA00B3DD8B /* md4.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md4.c; path = ../libtomcrypt/md4.c; sourceTree = SOURCE_ROOT; }; - 6649E15905FD02BA00B3DD8B /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = ../libtomcrypt/md5.c; sourceTree = SOURCE_ROOT; }; - 6649E15A05FD02BA00B3DD8B /* mem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mem.c; path = ../libtomcrypt/mem.c; sourceTree = SOURCE_ROOT; }; - 6649E15B05FD02BA00B3DD8B /* mpi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mpi.c; path = ../libtomcrypt/mpi.c; sourceTree = SOURCE_ROOT; }; - 6649E15C05FD02BA00B3DD8B /* mycrypt_argchk.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_argchk.h; path = ../libtomcrypt/mycrypt_argchk.h; sourceTree = SOURCE_ROOT; }; - 6649E15D05FD02BA00B3DD8B /* mycrypt_cfg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_cfg.h; path = ../libtomcrypt/mycrypt_cfg.h; sourceTree = SOURCE_ROOT; }; - 6649E15E05FD02BA00B3DD8B /* mycrypt_cipher.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_cipher.h; path = ../libtomcrypt/mycrypt_cipher.h; sourceTree = SOURCE_ROOT; }; - 6649E15F05FD02BA00B3DD8B /* mycrypt_custom.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_custom.h; path = ../libtomcrypt/mycrypt_custom.h; sourceTree = SOURCE_ROOT; }; - 6649E16005FD02BA00B3DD8B /* mycrypt_gf.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_gf.h; path = ../libtomcrypt/mycrypt_gf.h; sourceTree = SOURCE_ROOT; }; - 6649E16105FD02BA00B3DD8B /* mycrypt_hash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_hash.h; path = ../libtomcrypt/mycrypt_hash.h; sourceTree = SOURCE_ROOT; }; - 6649E16205FD02BA00B3DD8B /* mycrypt_kr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_kr.h; path = ../libtomcrypt/mycrypt_kr.h; sourceTree = SOURCE_ROOT; }; - 6649E16305FD02BA00B3DD8B /* mycrypt_macros.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_macros.h; path = ../libtomcrypt/mycrypt_macros.h; sourceTree = SOURCE_ROOT; }; - 6649E16405FD02BA00B3DD8B /* mycrypt_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_misc.h; path = ../libtomcrypt/mycrypt_misc.h; sourceTree = SOURCE_ROOT; }; - 6649E16505FD02BA00B3DD8B /* mycrypt_pk.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_pk.h; path = ../libtomcrypt/mycrypt_pk.h; sourceTree = SOURCE_ROOT; }; - 6649E16605FD02BA00B3DD8B /* mycrypt_prng.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt_prng.h; path = ../libtomcrypt/mycrypt_prng.h; sourceTree = SOURCE_ROOT; }; - 6649E16705FD02BA00B3DD8B /* mycrypt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mycrypt.h; path = ../libtomcrypt/mycrypt.h; sourceTree = SOURCE_ROOT; }; - 6649E16805FD02BA00B3DD8B /* noekeon.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = noekeon.c; path = ../libtomcrypt/noekeon.c; sourceTree = SOURCE_ROOT; }; - 6649E16905FD02BA00B3DD8B /* ofb.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ofb.c; path = ../libtomcrypt/ofb.c; sourceTree = SOURCE_ROOT; }; - 6649E16A05FD02BA00B3DD8B /* omac.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = omac.c; path = ../libtomcrypt/omac.c; sourceTree = SOURCE_ROOT; }; - 6649E16B05FD02BA00B3DD8B /* packet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = packet.c; path = ../libtomcrypt/packet.c; sourceTree = SOURCE_ROOT; }; - 6649E16C05FD02BA00B3DD8B /* prime.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = prime.c; path = ../libtomcrypt/prime.c; sourceTree = SOURCE_ROOT; }; - 6649E16D05FD02BA00B3DD8B /* rc2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rc2.c; path = ../libtomcrypt/rc2.c; sourceTree = SOURCE_ROOT; }; - 6649E16E05FD02BA00B3DD8B /* rc4.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rc4.c; path = ../libtomcrypt/rc4.c; sourceTree = SOURCE_ROOT; }; - 6649E16F05FD02BA00B3DD8B /* rc5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rc5.c; path = ../libtomcrypt/rc5.c; sourceTree = SOURCE_ROOT; }; - 6649E17005FD02BA00B3DD8B /* rc6.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rc6.c; path = ../libtomcrypt/rc6.c; sourceTree = SOURCE_ROOT; }; - 6649E17105FD02BA00B3DD8B /* rmd128.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rmd128.c; path = ../libtomcrypt/rmd128.c; sourceTree = SOURCE_ROOT; }; - 6649E17205FD02BA00B3DD8B /* rmd160.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rmd160.c; path = ../libtomcrypt/rmd160.c; sourceTree = SOURCE_ROOT; }; - 6649E17305FD02BA00B3DD8B /* rsa_sys.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rsa_sys.c; path = ../libtomcrypt/rsa_sys.c; sourceTree = SOURCE_ROOT; }; - 6649E17405FD02BA00B3DD8B /* rsa.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = rsa.c; path = ../libtomcrypt/rsa.c; sourceTree = SOURCE_ROOT; }; - 6649E17505FD02BA00B3DD8B /* safer_tab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = safer_tab.c; path = ../libtomcrypt/safer_tab.c; sourceTree = SOURCE_ROOT; }; - 6649E17605FD02BA00B3DD8B /* safer.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = safer.c; path = ../libtomcrypt/safer.c; sourceTree = SOURCE_ROOT; }; - 6649E17705FD02BA00B3DD8B /* safer+.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = "safer+.c"; path = "../libtomcrypt/safer+.c"; sourceTree = SOURCE_ROOT; }; - 6649E17805FD02BA00B3DD8B /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sha1.c; path = ../libtomcrypt/sha1.c; sourceTree = SOURCE_ROOT; }; - 6649E17905FD02BA00B3DD8B /* sha224.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sha224.c; path = ../libtomcrypt/sha224.c; sourceTree = SOURCE_ROOT; }; - 6649E17A05FD02BA00B3DD8B /* sha256.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sha256.c; path = ../libtomcrypt/sha256.c; sourceTree = SOURCE_ROOT; }; - 6649E17B05FD02BA00B3DD8B /* sha384.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sha384.c; path = ../libtomcrypt/sha384.c; sourceTree = SOURCE_ROOT; }; - 6649E17C05FD02BA00B3DD8B /* sha512.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sha512.c; path = ../libtomcrypt/sha512.c; sourceTree = SOURCE_ROOT; }; - 6649E17D05FD02BA00B3DD8B /* skipjack.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = skipjack.c; path = ../libtomcrypt/skipjack.c; sourceTree = SOURCE_ROOT; }; - 6649E17E05FD02BA00B3DD8B /* sprng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sprng.c; path = ../libtomcrypt/sprng.c; sourceTree = SOURCE_ROOT; }; - 6649E17F05FD02BA00B3DD8B /* strings.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = strings.c; path = ../libtomcrypt/strings.c; sourceTree = SOURCE_ROOT; }; - 6649E18005FD02BA00B3DD8B /* tiger.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = tiger.c; path = ../libtomcrypt/tiger.c; sourceTree = SOURCE_ROOT; }; - 6649E18105FD02BA00B3DD8B /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tommath.h; path = ../libtomcrypt/tommath.h; sourceTree = SOURCE_ROOT; }; - 6649E18205FD02BA00B3DD8B /* twofish_tab.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = twofish_tab.c; path = ../libtomcrypt/twofish_tab.c; sourceTree = SOURCE_ROOT; }; - 6649E18305FD02BA00B3DD8B /* twofish.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = twofish.c; path = ../libtomcrypt/twofish.c; sourceTree = SOURCE_ROOT; }; - 6649E18405FD02BA00B3DD8B /* xtea.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = xtea.c; path = ../libtomcrypt/xtea.c; sourceTree = SOURCE_ROOT; }; - 6649E18505FD02BA00B3DD8B /* yarrow.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = yarrow.c; path = ../libtomcrypt/yarrow.c; sourceTree = SOURCE_ROOT; }; - 6656DD9B0635C8EF00E30126 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = /Library/Frameworks/OpenAL.framework; sourceTree = ""; }; - 6656DDCA0635C95C00E30126 /* CTFGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = CTFGame.cpp; path = ../zap/CTFGame.cpp; sourceTree = SOURCE_ROOT; }; - 6656DDCB0635C95C00E30126 /* CTFGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = CTFGame.h; path = ../zap/CTFGame.h; sourceTree = SOURCE_ROOT; }; - 6656DDCC0635C95C00E30126 /* gameType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameType.cpp; path = ../zap/gameType.cpp; sourceTree = SOURCE_ROOT; }; - 6656DDCD0635C95C00E30126 /* gameType.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameType.h; path = ../zap/gameType.h; sourceTree = SOURCE_ROOT; }; - 6656DDCE0635C95C00E30126 /* item.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = item.cpp; path = ../zap/item.cpp; sourceTree = SOURCE_ROOT; }; - 6656DDCF0635C95C00E30126 /* item.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = item.h; path = ../zap/item.h; sourceTree = SOURCE_ROOT; }; - 6656DDD00635C95C00E30126 /* moveObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = moveObject.cpp; path = ../zap/moveObject.cpp; sourceTree = SOURCE_ROOT; }; - 6656DDD10635C95C00E30126 /* moveObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = moveObject.h; path = ../zap/moveObject.h; sourceTree = SOURCE_ROOT; }; - 6656DDD20635C95C00E30126 /* sfx.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sfx.cpp; path = ../zap/sfx.cpp; sourceTree = SOURCE_ROOT; }; - 6656DDD30635C95C00E30126 /* sfx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sfx.h; path = ../zap/sfx.h; sourceTree = SOURCE_ROOT; }; - 6661401205B3965A00320653 /* udp.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = udp.cpp; path = ../tnl/udp.cpp; sourceTree = SOURCE_ROOT; }; - 6661401905B3966700320653 /* platform.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = platform.cpp; path = ../tnl/platform.cpp; sourceTree = SOURCE_ROOT; }; - 6692C08806247BE000D5ADFE /* ZAP */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ZAP; sourceTree = BUILT_PRODUCTS_DIR; }; - 6692C08E06247C2300D5ADFE /* gameConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameConnection.cpp; path = ../zap/gameConnection.cpp; sourceTree = SOURCE_ROOT; }; - 6692C08F06247C2300D5ADFE /* gameConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameConnection.h; path = ../zap/gameConnection.h; sourceTree = SOURCE_ROOT; }; - 6692C09006247C2300D5ADFE /* gameNetInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameNetInterface.cpp; path = ../zap/gameNetInterface.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09106247C2300D5ADFE /* gameNetInterface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameNetInterface.h; path = ../zap/gameNetInterface.h; sourceTree = SOURCE_ROOT; }; - 6692C09406247C2300D5ADFE /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../zap/main.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09506247C2300D5ADFE /* masterConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = masterConnection.cpp; path = ../zap/masterConnection.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09606247C2300D5ADFE /* masterConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = masterConnection.h; path = ../zap/masterConnection.h; sourceTree = SOURCE_ROOT; }; - 6692C09706247C2300D5ADFE /* point.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = point.h; path = ../zap/point.h; sourceTree = SOURCE_ROOT; }; - 6692C09806247C2300D5ADFE /* projectile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = projectile.cpp; path = ../zap/projectile.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09906247C2300D5ADFE /* projectile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = projectile.h; path = ../zap/projectile.h; sourceTree = SOURCE_ROOT; }; - 6692C09A06247C2300D5ADFE /* ship.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ship.cpp; path = ../zap/ship.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09B06247C2300D5ADFE /* ship.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ship.h; path = ../zap/ship.h; sourceTree = SOURCE_ROOT; }; - 6692C09C06247C2300D5ADFE /* sparkManager.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sparkManager.cpp; path = ../zap/sparkManager.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09D06247C2300D5ADFE /* sparkManager.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sparkManager.h; path = ../zap/sparkManager.h; sourceTree = SOURCE_ROOT; }; - 6692C09E06247C2300D5ADFE /* SweptEllipsoid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = SweptEllipsoid.cpp; path = ../zap/SweptEllipsoid.cpp; sourceTree = SOURCE_ROOT; }; - 6692C09F06247C2300D5ADFE /* SweptEllipsoid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SweptEllipsoid.h; path = ../zap/SweptEllipsoid.h; sourceTree = SOURCE_ROOT; }; - 6692C0A006247C2300D5ADFE /* UI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UI.cpp; path = ../zap/UI.cpp; sourceTree = SOURCE_ROOT; }; - 6692C0A106247C2300D5ADFE /* UI.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UI.h; path = ../zap/UI.h; sourceTree = SOURCE_ROOT; }; - 6692C0A206247C2300D5ADFE /* UIGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UIGame.cpp; path = ../zap/UIGame.cpp; sourceTree = SOURCE_ROOT; }; - 6692C0A306247C2300D5ADFE /* UIGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIGame.h; path = ../zap/UIGame.h; sourceTree = SOURCE_ROOT; }; - 6692C0A406247C2300D5ADFE /* UIMenus.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UIMenus.cpp; path = ../zap/UIMenus.cpp; sourceTree = SOURCE_ROOT; }; - 6692C0A506247C2300D5ADFE /* UIMenus.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIMenus.h; path = ../zap/UIMenus.h; sourceTree = SOURCE_ROOT; }; - 6692C0A606247C2300D5ADFE /* UINameEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UINameEntry.cpp; path = ../zap/UINameEntry.cpp; sourceTree = SOURCE_ROOT; }; - 6692C0A706247C2300D5ADFE /* UINameEntry.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UINameEntry.h; path = ../zap/UINameEntry.h; sourceTree = SOURCE_ROOT; }; - 6692C0A806247C2300D5ADFE /* UIQueryServers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UIQueryServers.cpp; path = ../zap/UIQueryServers.cpp; sourceTree = SOURCE_ROOT; }; - 6692C0A906247C2300D5ADFE /* UIQueryServers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UIQueryServers.h; path = ../zap/UIQueryServers.h; sourceTree = SOURCE_ROOT; }; - 6692C11906247CF900D5ADFE /* GLUT.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLUT.framework; path = /System/Library/Frameworks/GLUT.framework; sourceTree = ""; }; - 6692C18A06247DB900D5ADFE /* glutInclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glutInclude.h; path = ../glut/glutInclude.h; sourceTree = SOURCE_ROOT; }; - 6692C22D0625E7E800D5ADFE /* barrier.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = barrier.cpp; path = ../zap/barrier.cpp; sourceTree = SOURCE_ROOT; }; - 6692C22E0625E7E800D5ADFE /* barrier.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = barrier.h; path = ../zap/barrier.h; sourceTree = SOURCE_ROOT; }; - 6692C22F0625E7E800D5ADFE /* game.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = game.cpp; path = ../zap/game.cpp; sourceTree = SOURCE_ROOT; }; - 6692C2300625E7E800D5ADFE /* game.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = game.h; path = ../zap/game.h; sourceTree = SOURCE_ROOT; }; - 6692C2310625E7E800D5ADFE /* gameLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameLoader.cpp; path = ../zap/gameLoader.cpp; sourceTree = SOURCE_ROOT; }; - 6692C2320625E7E800D5ADFE /* gameLoader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameLoader.h; path = ../zap/gameLoader.h; sourceTree = SOURCE_ROOT; }; - 6692C2330625E7E800D5ADFE /* gameObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameObject.cpp; path = ../zap/gameObject.cpp; sourceTree = SOURCE_ROOT; }; - 6692C2340625E7E800D5ADFE /* gameObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gameObject.h; path = ../zap/gameObject.h; sourceTree = SOURCE_ROOT; }; - 6692C2350625E7E800D5ADFE /* gridDB.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gridDB.cpp; path = ../zap/gridDB.cpp; sourceTree = SOURCE_ROOT; }; - 6692C2360625E7E800D5ADFE /* gridDB.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = gridDB.h; path = ../zap/gridDB.h; sourceTree = SOURCE_ROOT; }; - 6692C2370625E7E800D5ADFE /* teleporter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = teleporter.cpp; path = ../zap/teleporter.cpp; sourceTree = SOURCE_ROOT; }; - 6692C2380625E7E800D5ADFE /* teleporter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = teleporter.h; path = ../zap/teleporter.h; sourceTree = SOURCE_ROOT; }; - 66BA0C4A05FD107700D882FA /* tnlAssert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlAssert.h; path = ../tnl/tnlAssert.h; sourceTree = SOURCE_ROOT; }; - 66BA0C4B05FD107700D882FA /* tnlAsymmetricKey.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlAsymmetricKey.h; path = ../tnl/tnlAsymmetricKey.h; sourceTree = SOURCE_ROOT; }; - 66BA0C4C05FD107700D882FA /* tnlBitSet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlBitSet.h; path = ../tnl/tnlBitSet.h; sourceTree = SOURCE_ROOT; }; - 66BA0C4D05FD107700D882FA /* tnlBitStream.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlBitStream.h; path = ../tnl/tnlBitStream.h; sourceTree = SOURCE_ROOT; }; - 66BA0C4E05FD107700D882FA /* tnlByteBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlByteBuffer.h; path = ../tnl/tnlByteBuffer.h; sourceTree = SOURCE_ROOT; }; - 66BA0C4F05FD107700D882FA /* tnlCertificate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlCertificate.h; path = ../tnl/tnlCertificate.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5005FD107700D882FA /* tnlClientPuzzle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlClientPuzzle.h; path = ../tnl/tnlClientPuzzle.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5105FD107700D882FA /* tnlConnectionStringTable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlConnectionStringTable.h; path = ../tnl/tnlConnectionStringTable.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5205FD107700D882FA /* tnlDataChunker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlDataChunker.h; path = ../tnl/tnlDataChunker.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5305FD107700D882FA /* tnlEndian.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlEndian.h; path = ../tnl/tnlEndian.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5405FD107700D882FA /* tnlEventConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlEventConnection.h; path = ../tnl/tnlEventConnection.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5505FD107700D882FA /* tnlGhostConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlGhostConnection.h; path = ../tnl/tnlGhostConnection.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5605FD107700D882FA /* tnlHuffmanStringProcessor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlHuffmanStringProcessor.h; path = ../tnl/tnlHuffmanStringProcessor.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5705FD107700D882FA /* tnlLog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlLog.h; path = ../tnl/tnlLog.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5805FD107700D882FA /* tnlNetBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNetBase.h; path = ../tnl/tnlNetBase.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5905FD107700D882FA /* tnlNetConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNetConnection.h; path = ../tnl/tnlNetConnection.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5A05FD107700D882FA /* tnlNetEvent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNetEvent.h; path = ../tnl/tnlNetEvent.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5B05FD107700D882FA /* tnlNetInterface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNetInterface.h; path = ../tnl/tnlNetInterface.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5C05FD107700D882FA /* tnlNetObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNetObject.h; path = ../tnl/tnlNetObject.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5D05FD107700D882FA /* tnlNetStringTable.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNetStringTable.h; path = ../tnl/tnlNetStringTable.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5E05FD107700D882FA /* tnlNonce.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlNonce.h; path = ../tnl/tnlNonce.h; sourceTree = SOURCE_ROOT; }; - 66BA0C5F05FD107700D882FA /* tnlPlatform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlPlatform.h; path = ../tnl/tnlPlatform.h; sourceTree = SOURCE_ROOT; }; - 66BA0C6005FD107700D882FA /* tnlRandom.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlRandom.h; path = ../tnl/tnlRandom.h; sourceTree = SOURCE_ROOT; }; - 66BA0C6105FD107700D882FA /* tnlRPC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlRPC.h; path = ../tnl/tnlRPC.h; sourceTree = SOURCE_ROOT; }; - 66BA0C6205FD107700D882FA /* tnlSymmetricCipher.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlSymmetricCipher.h; path = ../tnl/tnlSymmetricCipher.h; sourceTree = SOURCE_ROOT; }; - 66BA0C6305FD107700D882FA /* tnlTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlTypes.h; path = ../tnl/tnlTypes.h; sourceTree = SOURCE_ROOT; }; - 66BA0C6405FD107700D882FA /* tnlUDP.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlUDP.h; path = ../tnl/tnlUDP.h; sourceTree = SOURCE_ROOT; }; - 66BA0C6505FD107700D882FA /* tnlVector.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnlVector.h; path = ../tnl/tnlVector.h; sourceTree = SOURCE_ROOT; }; - 66BA0CE005FD17F600D882FA /* asymmetricKey.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = asymmetricKey.cpp; path = ../tnl/asymmetricKey.cpp; sourceTree = SOURCE_ROOT; }; - 66BA0CE105FD17F600D882FA /* byteBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = byteBuffer.cpp; path = ../tnl/byteBuffer.cpp; sourceTree = SOURCE_ROOT; }; - 66BA0CE205FD17F600D882FA /* clientPuzzle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = clientPuzzle.cpp; path = ../tnl/clientPuzzle.cpp; sourceTree = SOURCE_ROOT; }; - 66BA0CE305FD17F600D882FA /* symmetricCipher.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = symmetricCipher.cpp; path = ../tnl/symmetricCipher.cpp; sourceTree = SOURCE_ROOT; }; - 66BA0E5C05FD467E00D882FA /* master */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = master; sourceTree = BUILT_PRODUCTS_DIR; }; - 66BA0E7705FD46F600D882FA /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../master/main.cpp; sourceTree = SOURCE_ROOT; }; - 66BA0E7805FD46F600D882FA /* masterInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = masterInterface.cpp; path = ../master/masterInterface.cpp; sourceTree = SOURCE_ROOT; }; - 66BA0E7905FD46F600D882FA /* masterInterface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = masterInterface.h; path = ../master/masterInterface.h; sourceTree = SOURCE_ROOT; }; - 66BA0E8905FD473200D882FA /* masterclient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = masterclient; sourceTree = BUILT_PRODUCTS_DIR; }; - 66BA0EA305FD478900D882FA /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../masterclient/main.cpp; sourceTree = SOURCE_ROOT; }; - 66D85C1E05AC8772008DC9C1 /* testGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testGame.cpp; path = ../test/testGame.cpp; sourceTree = SOURCE_ROOT; }; - 66D85C1F05AC8772008DC9C1 /* testGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = testGame.h; path = ../test/testGame.h; sourceTree = SOURCE_ROOT; }; - 66D85C2005AC8772008DC9C1 /* testGameRender.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testGameRender.cpp; path = ../test/testGameRender.cpp; sourceTree = SOURCE_ROOT; }; - 66D85C9105AC8DC7008DC9C1 /* MyOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MyOpenGLView.h; sourceTree = SOURCE_ROOT; }; - 66D85DB705ACA1F0008DC9C1 /* MyOpenGLView.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = MyOpenGLView.mm; sourceTree = SOURCE_ROOT; }; - 66D85E1905ACBA97008DC9C1 /* libtnl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtnl.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 66D85E5C05ACCB91008DC9C1 /* tnl.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tnl.h; path = ../tnl/tnl.h; sourceTree = SOURCE_ROOT; }; - 66D85E9305ACCBBA008DC9C1 /* huffmanStringProcessor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = huffmanStringProcessor.cpp; path = ../tnl/huffmanStringProcessor.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9405ACCBBA008DC9C1 /* assert.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = assert.cpp; path = ../tnl/assert.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9505ACCBBA008DC9C1 /* dataChunker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = dataChunker.cpp; path = ../tnl/dataChunker.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9605ACCBBA008DC9C1 /* netStringTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = netStringTable.cpp; path = ../tnl/netStringTable.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9705ACCBBA008DC9C1 /* ghostConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ghostConnection.cpp; path = ../tnl/ghostConnection.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9905ACCBBA008DC9C1 /* netConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = netConnection.cpp; path = ../tnl/netConnection.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9C05ACCBBA008DC9C1 /* log.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = log.cpp; path = ../tnl/log.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9D05ACCBBA008DC9C1 /* random.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = random.cpp; path = ../tnl/random.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9E05ACCBBA008DC9C1 /* netObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = netObject.cpp; path = ../tnl/netObject.cpp; sourceTree = SOURCE_ROOT; }; - 66D85E9F05ACCBBA008DC9C1 /* connectionStringTable.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = connectionStringTable.cpp; path = ../tnl/connectionStringTable.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EA005ACCBBA008DC9C1 /* rpc.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = rpc.cpp; path = ../tnl/rpc.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EA105ACCBBA008DC9C1 /* netInterface.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = netInterface.cpp; path = ../tnl/netInterface.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EA205ACCBBA008DC9C1 /* netBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = netBase.cpp; path = ../tnl/netBase.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EA305ACCBBA008DC9C1 /* eventConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = eventConnection.cpp; path = ../tnl/eventConnection.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EA405ACCBBA008DC9C1 /* vector.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = vector.cpp; path = ../tnl/vector.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EA505ACCBBA008DC9C1 /* bitStream.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = bitStream.cpp; path = ../tnl/bitStream.cpp; sourceTree = SOURCE_ROOT; }; - 66D85EDE05ACCC36008DC9C1 /* testserver */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testserver; sourceTree = BUILT_PRODUCTS_DIR; }; - 66D85EE605ACCC6A008DC9C1 /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = server.cpp; path = ../test/server.cpp; sourceTree = SOURCE_ROOT; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* TNLTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TNLTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DB9525CF0636109800B8795E /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; - DB9525E3063610C200B8795E /* certificate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = certificate.cpp; path = ../tnl/certificate.cpp; sourceTree = SOURCE_ROOT; }; - DB997D270638AFC1002745B0 /* gameItems.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = gameItems.cpp; path = ../zap/gameItems.cpp; sourceTree = SOURCE_ROOT; }; - DB997D280638AFC1002745B0 /* quickChat.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = quickChat.cpp; path = ../zap/quickChat.cpp; sourceTree = SOURCE_ROOT; }; - DB997D290638AFC1002745B0 /* quickChat.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = quickChat.h; path = ../zap/quickChat.h; sourceTree = SOURCE_ROOT; }; - DBAFF49906471A4200683BA4 /* soccerGame.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = soccerGame.cpp; path = ../zap/soccerGame.cpp; sourceTree = SOURCE_ROOT; }; - DBAFF49A06471A4200683BA4 /* soccerGame.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = soccerGame.h; path = ../zap/soccerGame.h; sourceTree = SOURCE_ROOT; }; - DBAFF4A706471AAE00683BA4 /* UICredits.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = UICredits.cpp; path = ../zap/UICredits.cpp; sourceTree = SOURCE_ROOT; }; - DBAFF4A806471AAE00683BA4 /* UICredits.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = UICredits.h; path = ../zap/UICredits.h; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 6692C15706247D1800D5ADFE /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6692C15E06247D2000D5ADFE /* GLUT.framework in Frameworks */, - 6692C15F06247D2500D5ADFE /* libtnl.a in Frameworks */, - 6692C16106247D2700D5ADFE /* liblibtomcrypt.a in Frameworks */, - 6656DD9C0635C8EF00E30126 /* OpenAL.framework in Frameworks */, - DB9525D00636109800B8795E /* OpenGL.framework in Frameworks */, - 1DE1ED3406909FA300D93C76 /* Carbon.framework in Frameworks */, - 1D49BD0D0691F71200643C72 /* IOKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66BA0E6605FD469900D882FA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0E6E05FD46C300D882FA /* libtnl.a in Frameworks */, - 66BA0E6B05FD46C000D882FA /* liblibtomcrypt.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66BA0E9905FD476D00D882FA /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0EA005FD477500D882FA /* libtnl.a in Frameworks */, - 66BA0EA105FD477500D882FA /* liblibtomcrypt.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66D85F2E05ACCD61008DC9C1 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0D1005FD195C00D882FA /* liblibtomcrypt.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D11072E0486CEB800E47090 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 6656DD850635C66F00E30126 /* libtnl.a in Frameworks */, - 66BA0CF605FD182100D882FA /* liblibtomcrypt.a in Frameworks */, - 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, - DB9525D10636109800B8795E /* OpenGL.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - 29B97325FDCFA39411CA2CEA /* Foundation.framework */, - 29B97324FDCFA39411CA2CEA /* AppKit.framework */, - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 19C28FACFE9D520D11CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - 8D1107320486CEB800E47090 /* TNLTest.app */, - 66D85E1905ACBA97008DC9C1 /* libtnl.a */, - 66D85EDE05ACCC36008DC9C1 /* testserver */, - 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */, - 66BA0E5C05FD467E00D882FA /* master */, - 66BA0E8905FD473200D882FA /* masterclient */, - 6692C08806247BE000D5ADFE /* ZAP */, - ); - name = Products; - path = ../exe; - sourceTree = SOURCE_ROOT; - }; - 29B97314FDCFA39411CA2CEA /* TNLTest */ = { - isa = PBXGroup; - children = ( - 29B97315FDCFA39411CA2CEA /* Source Files */, - 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, - 19C28FACFE9D520D11CA2CBB /* Products */, - ); - name = TNLTest; - sourceTree = ""; - }; - 29B97315FDCFA39411CA2CEA /* Source Files */ = { - isa = PBXGroup; - children = ( - 6692C0E606247C3B00D5ADFE /* ZAP */, - 66BA0EA905FD479700D882FA /* masterclient */, - 6649E0F805FD023500B3DD8B /* test */, - 6649E0F305FD022D00B3DD8B /* master */, - 6649E0EE05FD022100B3DD8B /* tnl */, - 6649E0E705FD020E00B3DD8B /* libtomcrypt */, - ); - name = "Source Files"; - sourceTree = ""; - }; - 29B97317FDCFA39411CA2CEA /* Resources */ = { - isa = PBXGroup; - children = ( - 8D1107310486CEB800E47090 /* Info.plist */, - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, - 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, - ); - name = Resources; - sourceTree = ""; - }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1D49BD0C0691F71200643C72 /* IOKit.framework */, - 1DE1ED3306909FA300D93C76 /* Carbon.framework */, - DB9525CF0636109800B8795E /* OpenGL.framework */, - 6656DD9B0635C8EF00E30126 /* OpenAL.framework */, - 6692C11906247CF900D5ADFE /* GLUT.framework */, - 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, - 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, - ); - name = Frameworks; - sourceTree = ""; - }; - 6649E0E705FD020E00B3DD8B /* libtomcrypt */ = { - isa = PBXGroup; - children = ( - 6649E14205FD02BA00B3DD8B /* aes_tab.c */, - 6649E14305FD02BA00B3DD8B /* aes.c */, - 6649E14405FD02BA00B3DD8B /* base64.c */, - 6649E14505FD02BA00B3DD8B /* bits.c */, - 6649E14605FD02BA00B3DD8B /* blowfish.c */, - 6649E14705FD02BA00B3DD8B /* cast5.c */, - 6649E14805FD02BA00B3DD8B /* cbc.c */, - 6649E14905FD02BA00B3DD8B /* cfb.c */, - 6649E14A05FD02BA00B3DD8B /* crypt.c */, - 6649E14B05FD02BA00B3DD8B /* ctr.c */, - 6649E14C05FD02BA00B3DD8B /* des.c */, - 6649E14D05FD02BA00B3DD8B /* dh_sys.c */, - 6649E14E05FD02BA00B3DD8B /* dh.c */, - 6649E14F05FD02BA00B3DD8B /* dsa.c */, - 6649E15005FD02BA00B3DD8B /* ecb.c */, - 6649E15105FD02BA00B3DD8B /* ecc_sys.c */, - 6649E15205FD02BA00B3DD8B /* ecc.c */, - 6649E15305FD02BA00B3DD8B /* gf.c */, - 6649E15405FD02BA00B3DD8B /* hash.c */, - 6649E15505FD02BA00B3DD8B /* hmac.c */, - 6649E15605FD02BA00B3DD8B /* keyring.c */, - 6649E15705FD02BA00B3DD8B /* md2.c */, - 6649E15805FD02BA00B3DD8B /* md4.c */, - 6649E15905FD02BA00B3DD8B /* md5.c */, - 6649E15A05FD02BA00B3DD8B /* mem.c */, - 6649E15B05FD02BA00B3DD8B /* mpi.c */, - 6649E15C05FD02BA00B3DD8B /* mycrypt_argchk.h */, - 6649E15D05FD02BA00B3DD8B /* mycrypt_cfg.h */, - 6649E15E05FD02BA00B3DD8B /* mycrypt_cipher.h */, - 6649E15F05FD02BA00B3DD8B /* mycrypt_custom.h */, - 6649E16005FD02BA00B3DD8B /* mycrypt_gf.h */, - 6649E16105FD02BA00B3DD8B /* mycrypt_hash.h */, - 6649E16205FD02BA00B3DD8B /* mycrypt_kr.h */, - 6649E16305FD02BA00B3DD8B /* mycrypt_macros.h */, - 6649E16405FD02BA00B3DD8B /* mycrypt_misc.h */, - 6649E16505FD02BA00B3DD8B /* mycrypt_pk.h */, - 6649E16605FD02BA00B3DD8B /* mycrypt_prng.h */, - 6649E16705FD02BA00B3DD8B /* mycrypt.h */, - 6649E16805FD02BA00B3DD8B /* noekeon.c */, - 6649E16905FD02BA00B3DD8B /* ofb.c */, - 6649E16A05FD02BA00B3DD8B /* omac.c */, - 6649E16B05FD02BA00B3DD8B /* packet.c */, - 6649E16C05FD02BA00B3DD8B /* prime.c */, - 6649E16D05FD02BA00B3DD8B /* rc2.c */, - 6649E16E05FD02BA00B3DD8B /* rc4.c */, - 6649E16F05FD02BA00B3DD8B /* rc5.c */, - 6649E17005FD02BA00B3DD8B /* rc6.c */, - 6649E17105FD02BA00B3DD8B /* rmd128.c */, - 6649E17205FD02BA00B3DD8B /* rmd160.c */, - 6649E17305FD02BA00B3DD8B /* rsa_sys.c */, - 6649E17405FD02BA00B3DD8B /* rsa.c */, - 6649E17505FD02BA00B3DD8B /* safer_tab.c */, - 6649E17605FD02BA00B3DD8B /* safer.c */, - 6649E17705FD02BA00B3DD8B /* safer+.c */, - 6649E17805FD02BA00B3DD8B /* sha1.c */, - 6649E17905FD02BA00B3DD8B /* sha224.c */, - 6649E17A05FD02BA00B3DD8B /* sha256.c */, - 6649E17B05FD02BA00B3DD8B /* sha384.c */, - 6649E17C05FD02BA00B3DD8B /* sha512.c */, - 6649E17D05FD02BA00B3DD8B /* skipjack.c */, - 6649E17E05FD02BA00B3DD8B /* sprng.c */, - 6649E17F05FD02BA00B3DD8B /* strings.c */, - 6649E18005FD02BA00B3DD8B /* tiger.c */, - 6649E18105FD02BA00B3DD8B /* tommath.h */, - 6649E18205FD02BA00B3DD8B /* twofish_tab.c */, - 6649E18305FD02BA00B3DD8B /* twofish.c */, - 6649E18405FD02BA00B3DD8B /* xtea.c */, - 6649E18505FD02BA00B3DD8B /* yarrow.c */, - ); - name = libtomcrypt; - sourceTree = ""; - }; - 6649E0EE05FD022100B3DD8B /* tnl */ = { - isa = PBXGroup; - children = ( - 1DC6ED430652D22A00BDEE0B /* journal.cpp */, - 1DC6ED440652D22A00BDEE0B /* tnlJournal.h */, - 1DC82046064C5C9000F61B0E /* tnlMethodDispatch.cpp */, - 1DC82047064C5C9000F61B0E /* tnlMethodDispatch.h */, - DB9525E3063610C200B8795E /* certificate.cpp */, - 66BA0CE005FD17F600D882FA /* asymmetricKey.cpp */, - 66BA0CE105FD17F600D882FA /* byteBuffer.cpp */, - 66BA0CE205FD17F600D882FA /* clientPuzzle.cpp */, - 66BA0CE305FD17F600D882FA /* symmetricCipher.cpp */, - 66BA0C4A05FD107700D882FA /* tnlAssert.h */, - 66BA0C4B05FD107700D882FA /* tnlAsymmetricKey.h */, - 66BA0C4C05FD107700D882FA /* tnlBitSet.h */, - 66BA0C4D05FD107700D882FA /* tnlBitStream.h */, - 66BA0C4E05FD107700D882FA /* tnlByteBuffer.h */, - 66BA0C4F05FD107700D882FA /* tnlCertificate.h */, - 66BA0C5005FD107700D882FA /* tnlClientPuzzle.h */, - 66BA0C5105FD107700D882FA /* tnlConnectionStringTable.h */, - 66BA0C5205FD107700D882FA /* tnlDataChunker.h */, - 66BA0C5305FD107700D882FA /* tnlEndian.h */, - 66BA0C5405FD107700D882FA /* tnlEventConnection.h */, - 66BA0C5505FD107700D882FA /* tnlGhostConnection.h */, - 66BA0C5605FD107700D882FA /* tnlHuffmanStringProcessor.h */, - 66BA0C5705FD107700D882FA /* tnlLog.h */, - 66BA0C5805FD107700D882FA /* tnlNetBase.h */, - 66BA0C5905FD107700D882FA /* tnlNetConnection.h */, - 66BA0C5A05FD107700D882FA /* tnlNetEvent.h */, - 66BA0C5B05FD107700D882FA /* tnlNetInterface.h */, - 66BA0C5C05FD107700D882FA /* tnlNetObject.h */, - 66BA0C5D05FD107700D882FA /* tnlNetStringTable.h */, - 66BA0C5E05FD107700D882FA /* tnlNonce.h */, - 66BA0C5F05FD107700D882FA /* tnlPlatform.h */, - 66BA0C6005FD107700D882FA /* tnlRandom.h */, - 66BA0C6105FD107700D882FA /* tnlRPC.h */, - 66BA0C6205FD107700D882FA /* tnlSymmetricCipher.h */, - 66BA0C6305FD107700D882FA /* tnlTypes.h */, - 66BA0C6405FD107700D882FA /* tnlUDP.h */, - 66BA0C6505FD107700D882FA /* tnlVector.h */, - 6661401905B3966700320653 /* platform.cpp */, - 66D85E5C05ACCB91008DC9C1 /* tnl.h */, - 6661401205B3965A00320653 /* udp.cpp */, - 66D85E9305ACCBBA008DC9C1 /* huffmanStringProcessor.cpp */, - 66D85E9405ACCBBA008DC9C1 /* assert.cpp */, - 66D85E9505ACCBBA008DC9C1 /* dataChunker.cpp */, - 66D85E9605ACCBBA008DC9C1 /* netStringTable.cpp */, - 66D85E9705ACCBBA008DC9C1 /* ghostConnection.cpp */, - 66D85E9905ACCBBA008DC9C1 /* netConnection.cpp */, - 66D85E9C05ACCBBA008DC9C1 /* log.cpp */, - 66D85E9D05ACCBBA008DC9C1 /* random.cpp */, - 66D85E9E05ACCBBA008DC9C1 /* netObject.cpp */, - 66D85E9F05ACCBBA008DC9C1 /* connectionStringTable.cpp */, - 66D85EA005ACCBBA008DC9C1 /* rpc.cpp */, - 66D85EA105ACCBBA008DC9C1 /* netInterface.cpp */, - 66D85EA205ACCBBA008DC9C1 /* netBase.cpp */, - 66D85EA305ACCBBA008DC9C1 /* eventConnection.cpp */, - 66D85EA405ACCBBA008DC9C1 /* vector.cpp */, - 66D85EA505ACCBBA008DC9C1 /* bitStream.cpp */, - ); - name = tnl; - sourceTree = ""; - }; - 6649E0F305FD022D00B3DD8B /* master */ = { - isa = PBXGroup; - children = ( - 66BA0E7705FD46F600D882FA /* main.cpp */, - 66BA0E7805FD46F600D882FA /* masterInterface.cpp */, - 66BA0E7905FD46F600D882FA /* masterInterface.h */, - ); - name = master; - sourceTree = ""; - }; - 6649E0F805FD023500B3DD8B /* test */ = { - isa = PBXGroup; - children = ( - 6645D4C305ACD81600EFFB5D /* main.mm */, - 66D85EE605ACCC6A008DC9C1 /* server.cpp */, - 66D85DB705ACA1F0008DC9C1 /* MyOpenGLView.mm */, - 66D85C9105AC8DC7008DC9C1 /* MyOpenGLView.h */, - 66D85C1E05AC8772008DC9C1 /* testGame.cpp */, - 66D85C1F05AC8772008DC9C1 /* testGame.h */, - 66D85C2005AC8772008DC9C1 /* testGameRender.cpp */, - ); - name = test; - sourceTree = ""; - }; - 6692C0E606247C3B00D5ADFE /* ZAP */ = { - isa = PBXGroup; - children = ( - 1DD229E2070B4A02000DFF1F /* HTFGame.cpp */, - 1D3CACC90694D76300313D6F /* goalZone.cpp */, - 1D3CACCA0694D76300313D6F /* goalZone.h */, - 1D3CACCB0694D76300313D6F /* retrieveGame.cpp */, - 1D49BDC50691F8E000643C72 /* input.cpp */, - 1D49BDC60691F8E000643C72 /* input.h */, - 1DE1EDF40690BA1600D93C76 /* osxInput.cpp */, - 1DE1ED0B06909D0A00D93C76 /* gameWeapons.cpp */, - 1DE1ED0C06909D0A00D93C76 /* gameWeapons.h */, - 1DE1EC6906909AB400D93C76 /* engineeredObjects.cpp */, - 1DE1EC6A06909AB400D93C76 /* engineeredObjects.h */, - 1DE1EC6B06909AB400D93C76 /* flagItem.cpp */, - 1DE1EC6C06909AB400D93C76 /* footballGame.cpp */, - 1DE1EC6D06909AB400D93C76 /* gameObjectRender.cpp */, - 1DE1EC6E06909AB400D93C76 /* gameObjectRender.h */, - 1DE1EC6F06909AB400D93C76 /* huntersGame.cpp */, - 1DE1EC7006909AB400D93C76 /* huntersGame.h */, - 1DE1EC7106909AB400D93C76 /* LoadoutZone.cpp */, - 1DE1EC7206909AB400D93C76 /* rabbitGame.cpp */, - 1DE1EC7306909AB400D93C76 /* rabbitGame.h */, - 1DE1EC7406909AB400D93C76 /* UIInstructions.cpp */, - 1DE1EC7506909AB400D93C76 /* UIInstructions.h */, - 1D3E3EED0666A871005D645B /* UIEditor.cpp */, - 1D3E3EEE0666A871005D645B /* UIEditor.h */, - 1D3E3EE90666A7EE005D645B /* loadoutSelect.cpp */, - 1D3E3EEA0666A7EE005D645B /* loadoutSelect.h */, - 1D8DCBB606557E6D00BC4809 /* controlObjectConnection.cpp */, - 1D8DCBB706557E6D00BC4809 /* controlObjectConnection.h */, - 1DC6ED470652D24B00BDEE0B /* gsm_decode.c */, - 1DC6ED480652D24B00BDEE0B /* gsm_encode.c */, - 1DC6ED490652D24B00BDEE0B /* gsm_state.c */, - 1DC6ED4A0652D24B00BDEE0B /* gsm.h */, - 1DC6ED4B0652D24B00BDEE0B /* voiceCodec.cpp */, - 1DC6ED4C0652D24B00BDEE0B /* voiceCodec.h */, - 1DC8204A064C5CBC00F61B0E /* lpc10.h */, - 1DC8204B064C5CBC00F61B0E /* lpc10dec.c */, - 1DC8204C064C5CBC00F61B0E /* lpc10enc.c */, - DBAFF4A706471AAE00683BA4 /* UICredits.cpp */, - DBAFF4A806471AAE00683BA4 /* UICredits.h */, - DBAFF49906471A4200683BA4 /* soccerGame.cpp */, - DBAFF49A06471A4200683BA4 /* soccerGame.h */, - DB997D270638AFC1002745B0 /* gameItems.cpp */, - DB997D280638AFC1002745B0 /* quickChat.cpp */, - DB997D290638AFC1002745B0 /* quickChat.h */, - 6656DDCA0635C95C00E30126 /* CTFGame.cpp */, - 6656DDCB0635C95C00E30126 /* CTFGame.h */, - 6656DDCC0635C95C00E30126 /* gameType.cpp */, - 6656DDCD0635C95C00E30126 /* gameType.h */, - 6656DDCE0635C95C00E30126 /* item.cpp */, - 6656DDCF0635C95C00E30126 /* item.h */, - 6656DDD00635C95C00E30126 /* moveObject.cpp */, - 6656DDD10635C95C00E30126 /* moveObject.h */, - 6656DDD20635C95C00E30126 /* sfx.cpp */, - 6656DDD30635C95C00E30126 /* sfx.h */, - 6692C22D0625E7E800D5ADFE /* barrier.cpp */, - 6692C22E0625E7E800D5ADFE /* barrier.h */, - 6692C22F0625E7E800D5ADFE /* game.cpp */, - 6692C2300625E7E800D5ADFE /* game.h */, - 6692C2310625E7E800D5ADFE /* gameLoader.cpp */, - 6692C2320625E7E800D5ADFE /* gameLoader.h */, - 6692C2330625E7E800D5ADFE /* gameObject.cpp */, - 6692C2340625E7E800D5ADFE /* gameObject.h */, - 6692C2350625E7E800D5ADFE /* gridDB.cpp */, - 6692C2360625E7E800D5ADFE /* gridDB.h */, - 6692C2370625E7E800D5ADFE /* teleporter.cpp */, - 6692C2380625E7E800D5ADFE /* teleporter.h */, - 6692C08E06247C2300D5ADFE /* gameConnection.cpp */, - 6692C08F06247C2300D5ADFE /* gameConnection.h */, - 6692C09006247C2300D5ADFE /* gameNetInterface.cpp */, - 6692C09106247C2300D5ADFE /* gameNetInterface.h */, - 6692C09406247C2300D5ADFE /* main.cpp */, - 6692C09506247C2300D5ADFE /* masterConnection.cpp */, - 6692C09606247C2300D5ADFE /* masterConnection.h */, - 6692C09706247C2300D5ADFE /* point.h */, - 6692C09806247C2300D5ADFE /* projectile.cpp */, - 6692C09906247C2300D5ADFE /* projectile.h */, - 6692C09A06247C2300D5ADFE /* ship.cpp */, - 6692C09B06247C2300D5ADFE /* ship.h */, - 6692C09C06247C2300D5ADFE /* sparkManager.cpp */, - 6692C09D06247C2300D5ADFE /* sparkManager.h */, - 6692C09E06247C2300D5ADFE /* SweptEllipsoid.cpp */, - 6692C09F06247C2300D5ADFE /* SweptEllipsoid.h */, - 6692C0A006247C2300D5ADFE /* UI.cpp */, - 6692C0A106247C2300D5ADFE /* UI.h */, - 6692C0A206247C2300D5ADFE /* UIGame.cpp */, - 6692C0A306247C2300D5ADFE /* UIGame.h */, - 6692C0A406247C2300D5ADFE /* UIMenus.cpp */, - 6692C0A506247C2300D5ADFE /* UIMenus.h */, - 6692C0A606247C2300D5ADFE /* UINameEntry.cpp */, - 6692C0A706247C2300D5ADFE /* UINameEntry.h */, - 6692C0A806247C2300D5ADFE /* UIQueryServers.cpp */, - 6692C0A906247C2300D5ADFE /* UIQueryServers.h */, - 6692C18A06247DB900D5ADFE /* glutInclude.h */, - ); - name = ZAP; - sourceTree = ""; - }; - 66BA0EA905FD479700D882FA /* masterclient */ = { - isa = PBXGroup; - children = ( - 66BA0EA305FD478900D882FA /* main.cpp */, - ); - name = masterclient; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 6649E0D305FD01D700B3DD8B /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 6649E1A005FD02BA00B3DD8B /* mycrypt_argchk.h in Headers */, - 6649E1A105FD02BA00B3DD8B /* mycrypt_cfg.h in Headers */, - 6649E1A205FD02BA00B3DD8B /* mycrypt_cipher.h in Headers */, - 6649E1A305FD02BA00B3DD8B /* mycrypt_custom.h in Headers */, - 6649E1A405FD02BA00B3DD8B /* mycrypt_gf.h in Headers */, - 6649E1A505FD02BA00B3DD8B /* mycrypt_hash.h in Headers */, - 6649E1A605FD02BA00B3DD8B /* mycrypt_kr.h in Headers */, - 6649E1A705FD02BA00B3DD8B /* mycrypt_macros.h in Headers */, - 6649E1A805FD02BA00B3DD8B /* mycrypt_misc.h in Headers */, - 6649E1A905FD02BA00B3DD8B /* mycrypt_pk.h in Headers */, - 6649E1AA05FD02BA00B3DD8B /* mycrypt_prng.h in Headers */, - 6649E1AB05FD02BA00B3DD8B /* mycrypt.h in Headers */, - 6649E1C505FD02BA00B3DD8B /* tommath.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6692C08506247BE000D5ADFE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 6692C0AB06247C2300D5ADFE /* gameConnection.h in Headers */, - 6692C0AD06247C2300D5ADFE /* gameNetInterface.h in Headers */, - 6692C0B206247C2300D5ADFE /* masterConnection.h in Headers */, - 6692C0B306247C2300D5ADFE /* point.h in Headers */, - 6692C0B506247C2300D5ADFE /* projectile.h in Headers */, - 6692C0B706247C2300D5ADFE /* ship.h in Headers */, - 6692C0B906247C2300D5ADFE /* sparkManager.h in Headers */, - 6692C0BB06247C2300D5ADFE /* SweptEllipsoid.h in Headers */, - 6692C0BD06247C2300D5ADFE /* UI.h in Headers */, - 6692C0BF06247C2300D5ADFE /* UIGame.h in Headers */, - 6692C0C106247C2300D5ADFE /* UIMenus.h in Headers */, - 6692C0C306247C2300D5ADFE /* UINameEntry.h in Headers */, - 6692C0C506247C2300D5ADFE /* UIQueryServers.h in Headers */, - 6692C18B06247DB900D5ADFE /* glutInclude.h in Headers */, - 6692C23A0625E7E800D5ADFE /* barrier.h in Headers */, - 6692C23C0625E7E800D5ADFE /* game.h in Headers */, - 6692C23E0625E7E800D5ADFE /* gameLoader.h in Headers */, - 6692C2400625E7E800D5ADFE /* gameObject.h in Headers */, - 6692C2420625E7E800D5ADFE /* gridDB.h in Headers */, - 6692C2440625E7E800D5ADFE /* teleporter.h in Headers */, - 6656DDD50635C95C00E30126 /* CTFGame.h in Headers */, - 6656DDD70635C95C00E30126 /* gameType.h in Headers */, - 6656DDD90635C95C00E30126 /* item.h in Headers */, - 6656DDDB0635C95C00E30126 /* moveObject.h in Headers */, - 6656DDDD0635C95C00E30126 /* sfx.h in Headers */, - DB997D2C0638AFC1002745B0 /* quickChat.h in Headers */, - DBAFF49C06471A4200683BA4 /* soccerGame.h in Headers */, - DBAFF4AA06471AAE00683BA4 /* UICredits.h in Headers */, - 1DC8204D064C5CBC00F61B0E /* lpc10.h in Headers */, - 1DC6ED500652D24B00BDEE0B /* gsm.h in Headers */, - 1DC6ED520652D24B00BDEE0B /* voiceCodec.h in Headers */, - 1D8DCBB906557E6D00BC4809 /* controlObjectConnection.h in Headers */, - 1D3E3EEC0666A7EE005D645B /* loadoutSelect.h in Headers */, - 1D3E3EF00666A871005D645B /* UIEditor.h in Headers */, - 1DE1EC7706909AB400D93C76 /* engineeredObjects.h in Headers */, - 1DE1EC7B06909AB400D93C76 /* gameObjectRender.h in Headers */, - 1DE1EC7D06909AB400D93C76 /* huntersGame.h in Headers */, - 1DE1EC8006909AB400D93C76 /* rabbitGame.h in Headers */, - 1DE1EC8206909AB400D93C76 /* UIInstructions.h in Headers */, - 1DE1ED0E06909D0A00D93C76 /* gameWeapons.h in Headers */, - 1D49BDC80691F8E000643C72 /* input.h in Headers */, - 1D3CACCD0694D76300313D6F /* goalZone.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66BA0E5905FD467E00D882FA /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0E7C05FD46F600D882FA /* masterInterface.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66BA0E8605FD473200D882FA /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0EBC05FD47B100D882FA /* masterInterface.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66D85E1605ACBA97008DC9C1 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 66D85E7305ACCB91008DC9C1 /* tnl.h in Headers */, - 66BA0C6605FD107700D882FA /* tnlAssert.h in Headers */, - 66BA0C6705FD107700D882FA /* tnlAsymmetricKey.h in Headers */, - 66BA0C6805FD107700D882FA /* tnlBitSet.h in Headers */, - 66BA0C6905FD107700D882FA /* tnlBitStream.h in Headers */, - 66BA0C6A05FD107700D882FA /* tnlByteBuffer.h in Headers */, - 66BA0C6B05FD107700D882FA /* tnlCertificate.h in Headers */, - 66BA0C6C05FD107700D882FA /* tnlClientPuzzle.h in Headers */, - 66BA0C6D05FD107700D882FA /* tnlConnectionStringTable.h in Headers */, - 66BA0C6E05FD107700D882FA /* tnlDataChunker.h in Headers */, - 66BA0C6F05FD107700D882FA /* tnlEndian.h in Headers */, - 66BA0C7005FD107700D882FA /* tnlEventConnection.h in Headers */, - 66BA0C7105FD107700D882FA /* tnlGhostConnection.h in Headers */, - 66BA0C7205FD107700D882FA /* tnlHuffmanStringProcessor.h in Headers */, - 66BA0C7305FD107700D882FA /* tnlLog.h in Headers */, - 66BA0C7405FD107700D882FA /* tnlNetBase.h in Headers */, - 66BA0C7505FD107700D882FA /* tnlNetConnection.h in Headers */, - 66BA0C7605FD107700D882FA /* tnlNetEvent.h in Headers */, - 66BA0C7705FD107700D882FA /* tnlNetInterface.h in Headers */, - 66BA0C7805FD107700D882FA /* tnlNetObject.h in Headers */, - 66BA0C7905FD107700D882FA /* tnlNetStringTable.h in Headers */, - 66BA0C7A05FD107700D882FA /* tnlNonce.h in Headers */, - 66BA0C7B05FD107700D882FA /* tnlPlatform.h in Headers */, - 66BA0C7C05FD107700D882FA /* tnlRandom.h in Headers */, - 66BA0C7D05FD107700D882FA /* tnlRPC.h in Headers */, - 66BA0C7E05FD107700D882FA /* tnlSymmetricCipher.h in Headers */, - 66BA0C7F05FD107700D882FA /* tnlTypes.h in Headers */, - 66BA0C8005FD107700D882FA /* tnlUDP.h in Headers */, - 66BA0C8105FD107700D882FA /* tnlVector.h in Headers */, - 1DC82049064C5C9000F61B0E /* tnlMethodDispatch.h in Headers */, - 1DC6ED460652D22A00BDEE0B /* tnlJournal.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66D85EDB05ACCC36008DC9C1 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 66D85EF305ACCC8D008DC9C1 /* testGame.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D1107270486CEB800E47090 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 66D85C2205AC8772008DC9C1 /* testGame.h in Headers */, - 66D85C9305AC8DC7008DC9C1 /* MyOpenGLView.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 6649E0D505FD01D700B3DD8B /* libtomcrypt */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99498B10DED559001B3AFF /* Build configuration list for PBXNativeTarget "libtomcrypt" */; - buildPhases = ( - 6649E0D305FD01D700B3DD8B /* Headers */, - 6649E0D405FD01D700B3DD8B /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = libtomcrypt; - productName = libtomcrypt; - productReference = 6649E0D605FD01D700B3DD8B /* liblibtomcrypt.a */; - productType = "com.apple.product-type.library.static"; - }; - 6692C08706247BE000D5ADFE /* ZAP */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99499010DED559001B3AFF /* Build configuration list for PBXNativeTarget "ZAP" */; - buildPhases = ( - 6692C08506247BE000D5ADFE /* Headers */, - 6692C08606247BE000D5ADFE /* Sources */, - 6692C15706247D1800D5ADFE /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = ZAP; - productName = ZAP; - productReference = 6692C08806247BE000D5ADFE /* ZAP */; - productType = "com.apple.product-type.tool"; - }; - 66BA0E5B05FD467E00D882FA /* master */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99498E10DED559001B3AFF /* Build configuration list for PBXNativeTarget "master" */; - buildPhases = ( - 66BA0E5905FD467E00D882FA /* Headers */, - 66BA0E5A05FD467E00D882FA /* Sources */, - 66BA0E6605FD469900D882FA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 66BA0E6105FD468600D882FA /* PBXTargetDependency */, - 66BA0E6305FD468B00D882FA /* PBXTargetDependency */, - ); - name = master; - productName = master; - productReference = 66BA0E5C05FD467E00D882FA /* master */; - productType = "com.apple.product-type.tool"; - }; - 66BA0E8805FD473200D882FA /* masterclient */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99498F10DED559001B3AFF /* Build configuration list for PBXNativeTarget "masterclient" */; - buildPhases = ( - 66BA0E8605FD473200D882FA /* Headers */, - 66BA0E8705FD473200D882FA /* Sources */, - 66BA0E9905FD476D00D882FA /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 66BA0E8E05FD473A00D882FA /* PBXTargetDependency */, - 66BA0E9005FD474000D882FA /* PBXTargetDependency */, - ); - name = masterclient; - productName = masterclient; - productReference = 66BA0E8905FD473200D882FA /* masterclient */; - productType = "com.apple.product-type.tool"; - }; - 66D85E1805ACBA97008DC9C1 /* tnl */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99498A10DED559001B3AFF /* Build configuration list for PBXNativeTarget "tnl" */; - buildPhases = ( - 66D85E1605ACBA97008DC9C1 /* Headers */, - 66D85E1705ACBA97008DC9C1 /* Sources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = tnl; - productName = tnl; - productReference = 66D85E1905ACBA97008DC9C1 /* libtnl.a */; - productType = "com.apple.product-type.library.static"; - }; - 66D85EDD05ACCC36008DC9C1 /* testserver */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99498D10DED559001B3AFF /* Build configuration list for PBXNativeTarget "testserver" */; - buildPhases = ( - 66D85EDB05ACCC36008DC9C1 /* Headers */, - 66D85EDC05ACCC36008DC9C1 /* Sources */, - 66D85F2E05ACCD61008DC9C1 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 66D85EE305ACCC3C008DC9C1 /* PBXTargetDependency */, - 66BA0E9405FD475500D882FA /* PBXTargetDependency */, - ); - name = testserver; - productName = testserver; - productReference = 66D85EDE05ACCC36008DC9C1 /* testserver */; - productType = "com.apple.product-type.tool"; - }; - 8D1107260486CEB800E47090 /* TNLTest */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1D99498C10DED559001B3AFF /* Build configuration list for PBXNativeTarget "TNLTest" */; - buildPhases = ( - 8D1107270486CEB800E47090 /* Headers */, - 8D1107290486CEB800E47090 /* Resources */, - 8D11072C0486CEB800E47090 /* Sources */, - 8D11072E0486CEB800E47090 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 66D85ED905ACCC15008DC9C1 /* PBXTargetDependency */, - 66BA0C3705FD0E5B00D882FA /* PBXTargetDependency */, - ); - name = TNLTest; - productInstallPath = "$(HOME)/Applications"; - productName = TNLTest; - productReference = 8D1107320486CEB800E47090 /* TNLTest.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 29B97313FDCFA39411CA2CEA /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1D99498910DED559001B3AFF /* Build configuration list for PBXProject "tnl" */; - compatibilityVersion = "Xcode 2.4"; - hasScannedForEncodings = 1; - mainGroup = 29B97314FDCFA39411CA2CEA /* TNLTest */; - projectDirPath = ""; - projectRoot = ..; - targets = ( - 8D1107260486CEB800E47090 /* TNLTest */, - 66D85E1805ACBA97008DC9C1 /* tnl */, - 66D85EDD05ACCC36008DC9C1 /* testserver */, - 6649E0D505FD01D700B3DD8B /* libtomcrypt */, - 66BA0E5B05FD467E00D882FA /* master */, - 66BA0E8805FD473200D882FA /* masterclient */, - 6692C08706247BE000D5ADFE /* ZAP */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8D1107290486CEB800E47090 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */, - 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 6649E0D405FD01D700B3DD8B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6649E18705FD02BA00B3DD8B /* aes.c in Sources */, - 6649E18805FD02BA00B3DD8B /* base64.c in Sources */, - 6649E18905FD02BA00B3DD8B /* bits.c in Sources */, - 6649E18A05FD02BA00B3DD8B /* blowfish.c in Sources */, - 6649E18B05FD02BA00B3DD8B /* cast5.c in Sources */, - 6649E18C05FD02BA00B3DD8B /* cbc.c in Sources */, - 6649E18D05FD02BA00B3DD8B /* cfb.c in Sources */, - 6649E18E05FD02BA00B3DD8B /* crypt.c in Sources */, - 6649E18F05FD02BA00B3DD8B /* ctr.c in Sources */, - 6649E19005FD02BA00B3DD8B /* des.c in Sources */, - 6649E19205FD02BA00B3DD8B /* dh.c in Sources */, - 6649E19305FD02BA00B3DD8B /* dsa.c in Sources */, - 6649E19405FD02BA00B3DD8B /* ecb.c in Sources */, - 6649E19605FD02BA00B3DD8B /* ecc.c in Sources */, - 6649E19705FD02BA00B3DD8B /* gf.c in Sources */, - 6649E19805FD02BA00B3DD8B /* hash.c in Sources */, - 6649E19905FD02BA00B3DD8B /* hmac.c in Sources */, - 6649E19A05FD02BA00B3DD8B /* keyring.c in Sources */, - 6649E19B05FD02BA00B3DD8B /* md2.c in Sources */, - 6649E19C05FD02BA00B3DD8B /* md4.c in Sources */, - 6649E19D05FD02BA00B3DD8B /* md5.c in Sources */, - 6649E19E05FD02BA00B3DD8B /* mem.c in Sources */, - 6649E19F05FD02BA00B3DD8B /* mpi.c in Sources */, - 6649E1AC05FD02BA00B3DD8B /* noekeon.c in Sources */, - 6649E1AD05FD02BA00B3DD8B /* ofb.c in Sources */, - 6649E1AE05FD02BA00B3DD8B /* omac.c in Sources */, - 6649E1AF05FD02BA00B3DD8B /* packet.c in Sources */, - 6649E1B005FD02BA00B3DD8B /* prime.c in Sources */, - 6649E1B105FD02BA00B3DD8B /* rc2.c in Sources */, - 6649E1B205FD02BA00B3DD8B /* rc4.c in Sources */, - 6649E1B305FD02BA00B3DD8B /* rc5.c in Sources */, - 6649E1B405FD02BA00B3DD8B /* rc6.c in Sources */, - 6649E1B505FD02BA00B3DD8B /* rmd128.c in Sources */, - 6649E1B605FD02BA00B3DD8B /* rmd160.c in Sources */, - 6649E1B805FD02BA00B3DD8B /* rsa.c in Sources */, - 6649E1B905FD02BA00B3DD8B /* safer_tab.c in Sources */, - 6649E1BA05FD02BA00B3DD8B /* safer.c in Sources */, - 6649E1BB05FD02BA00B3DD8B /* safer+.c in Sources */, - 6649E1BC05FD02BA00B3DD8B /* sha1.c in Sources */, - 6649E1BE05FD02BA00B3DD8B /* sha256.c in Sources */, - 6649E1C005FD02BA00B3DD8B /* sha512.c in Sources */, - 6649E1C105FD02BA00B3DD8B /* skipjack.c in Sources */, - 6649E1C205FD02BA00B3DD8B /* sprng.c in Sources */, - 6649E1C305FD02BA00B3DD8B /* strings.c in Sources */, - 6649E1C405FD02BA00B3DD8B /* tiger.c in Sources */, - 6649E1C705FD02BA00B3DD8B /* twofish.c in Sources */, - 6649E1C805FD02BA00B3DD8B /* xtea.c in Sources */, - 6649E1C905FD02BA00B3DD8B /* yarrow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 6692C08606247BE000D5ADFE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 6692C0AA06247C2300D5ADFE /* gameConnection.cpp in Sources */, - 6692C0AC06247C2300D5ADFE /* gameNetInterface.cpp in Sources */, - 6692C0B006247C2300D5ADFE /* main.cpp in Sources */, - 6692C0B106247C2300D5ADFE /* masterConnection.cpp in Sources */, - 6692C0B406247C2300D5ADFE /* projectile.cpp in Sources */, - 6692C0B606247C2300D5ADFE /* ship.cpp in Sources */, - 6692C0B806247C2300D5ADFE /* sparkManager.cpp in Sources */, - 6692C0BA06247C2300D5ADFE /* SweptEllipsoid.cpp in Sources */, - 6692C0BC06247C2300D5ADFE /* UI.cpp in Sources */, - 6692C0BE06247C2300D5ADFE /* UIGame.cpp in Sources */, - 6692C0C006247C2300D5ADFE /* UIMenus.cpp in Sources */, - 6692C0C206247C2300D5ADFE /* UINameEntry.cpp in Sources */, - 6692C0C406247C2300D5ADFE /* UIQueryServers.cpp in Sources */, - 6692C1FA06247F2000D5ADFE /* masterInterface.cpp in Sources */, - 6692C2390625E7E800D5ADFE /* barrier.cpp in Sources */, - 6692C23B0625E7E800D5ADFE /* game.cpp in Sources */, - 6692C23D0625E7E800D5ADFE /* gameLoader.cpp in Sources */, - 6692C23F0625E7E800D5ADFE /* gameObject.cpp in Sources */, - 6692C2410625E7E800D5ADFE /* gridDB.cpp in Sources */, - 6692C2430625E7E800D5ADFE /* teleporter.cpp in Sources */, - 6656DDD40635C95C00E30126 /* CTFGame.cpp in Sources */, - 6656DDD60635C95C00E30126 /* gameType.cpp in Sources */, - 6656DDD80635C95C00E30126 /* item.cpp in Sources */, - 6656DDDA0635C95C00E30126 /* moveObject.cpp in Sources */, - 6656DDDC0635C95C00E30126 /* sfx.cpp in Sources */, - DB997D2A0638AFC1002745B0 /* gameItems.cpp in Sources */, - DB997D2B0638AFC1002745B0 /* quickChat.cpp in Sources */, - DBAFF49B06471A4200683BA4 /* soccerGame.cpp in Sources */, - DBAFF4A906471AAE00683BA4 /* UICredits.cpp in Sources */, - 1DC8204E064C5CBC00F61B0E /* lpc10dec.c in Sources */, - 1DC8204F064C5CBC00F61B0E /* lpc10enc.c in Sources */, - 1DC6ED4D0652D24B00BDEE0B /* gsm_decode.c in Sources */, - 1DC6ED4E0652D24B00BDEE0B /* gsm_encode.c in Sources */, - 1DC6ED4F0652D24B00BDEE0B /* gsm_state.c in Sources */, - 1DC6ED510652D24B00BDEE0B /* voiceCodec.cpp in Sources */, - 1D8DCBB806557E6D00BC4809 /* controlObjectConnection.cpp in Sources */, - 1D3E3EEB0666A7EE005D645B /* loadoutSelect.cpp in Sources */, - 1D3E3EEF0666A871005D645B /* UIEditor.cpp in Sources */, - 1DE1EC7606909AB400D93C76 /* engineeredObjects.cpp in Sources */, - 1DE1EC7806909AB400D93C76 /* flagItem.cpp in Sources */, - 1DE1EC7906909AB400D93C76 /* footballGame.cpp in Sources */, - 1DE1EC7A06909AB400D93C76 /* gameObjectRender.cpp in Sources */, - 1DE1EC7C06909AB400D93C76 /* huntersGame.cpp in Sources */, - 1DE1EC7E06909AB400D93C76 /* LoadoutZone.cpp in Sources */, - 1DE1EC7F06909AB400D93C76 /* rabbitGame.cpp in Sources */, - 1DE1EC8106909AB400D93C76 /* UIInstructions.cpp in Sources */, - 1DE1ED0D06909D0A00D93C76 /* gameWeapons.cpp in Sources */, - 1DE1EDF50690BA1600D93C76 /* osxInput.cpp in Sources */, - 1D49BDC70691F8E000643C72 /* input.cpp in Sources */, - 1D3CACCC0694D76300313D6F /* goalZone.cpp in Sources */, - 1D3CACCE0694D76300313D6F /* retrieveGame.cpp in Sources */, - 1DD229E3070B4A02000DFF1F /* HTFGame.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66BA0E5A05FD467E00D882FA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0E7A05FD46F600D882FA /* main.cpp in Sources */, - 66BA0E7B05FD46F600D882FA /* masterInterface.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66BA0E8705FD473200D882FA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 66BA0EB905FD47A900D882FA /* masterInterface.cpp in Sources */, - 66BA0EA405FD478900D882FA /* main.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66D85E1705ACBA97008DC9C1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 66D85EA605ACCBBA008DC9C1 /* huffmanStringProcessor.cpp in Sources */, - 66D85EA705ACCBBA008DC9C1 /* assert.cpp in Sources */, - 66D85EA805ACCBBA008DC9C1 /* dataChunker.cpp in Sources */, - 66D85EA905ACCBBA008DC9C1 /* netStringTable.cpp in Sources */, - 66D85EAA05ACCBBA008DC9C1 /* ghostConnection.cpp in Sources */, - 66D85EAC05ACCBBA008DC9C1 /* netConnection.cpp in Sources */, - 66D85EAF05ACCBBA008DC9C1 /* log.cpp in Sources */, - 66D85EB005ACCBBA008DC9C1 /* random.cpp in Sources */, - 66D85EB105ACCBBA008DC9C1 /* netObject.cpp in Sources */, - 66D85EB205ACCBBA008DC9C1 /* connectionStringTable.cpp in Sources */, - 66D85EB305ACCBBA008DC9C1 /* rpc.cpp in Sources */, - 66D85EB405ACCBBA008DC9C1 /* netInterface.cpp in Sources */, - 66D85EB505ACCBBA008DC9C1 /* netBase.cpp in Sources */, - 66D85EB605ACCBBA008DC9C1 /* eventConnection.cpp in Sources */, - 66D85EB705ACCBBA008DC9C1 /* vector.cpp in Sources */, - 66D85EB805ACCBBA008DC9C1 /* bitStream.cpp in Sources */, - 6661401405B3965A00320653 /* udp.cpp in Sources */, - 6661401A05B3966700320653 /* platform.cpp in Sources */, - 66BA0CE405FD17F600D882FA /* asymmetricKey.cpp in Sources */, - 66BA0CE505FD17F600D882FA /* byteBuffer.cpp in Sources */, - 66BA0CE605FD17F600D882FA /* clientPuzzle.cpp in Sources */, - 66BA0CE705FD17F600D882FA /* symmetricCipher.cpp in Sources */, - DB9525E4063610C200B8795E /* certificate.cpp in Sources */, - 1DC82048064C5C9000F61B0E /* tnlMethodDispatch.cpp in Sources */, - 1DC6ED450652D22A00BDEE0B /* journal.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 66D85EDC05ACCC36008DC9C1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 66D85EE705ACCC6A008DC9C1 /* server.cpp in Sources */, - 66D85EF005ACCC8D008DC9C1 /* testGame.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 8D11072C0486CEB800E47090 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 66D85C2105AC8772008DC9C1 /* testGame.cpp in Sources */, - 66D85C2305AC8772008DC9C1 /* testGameRender.cpp in Sources */, - 66D85DB805ACA1F0008DC9C1 /* MyOpenGLView.mm in Sources */, - 6645D4C405ACD81600EFFB5D /* main.mm in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 66BA0C3705FD0E5B00D882FA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6649E0D505FD01D700B3DD8B /* libtomcrypt */; - targetProxy = 66BA0C3605FD0E5B00D882FA /* PBXContainerItemProxy */; - }; - 66BA0E6105FD468600D882FA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 66D85E1805ACBA97008DC9C1 /* tnl */; - targetProxy = 66BA0E6005FD468600D882FA /* PBXContainerItemProxy */; - }; - 66BA0E6305FD468B00D882FA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6649E0D505FD01D700B3DD8B /* libtomcrypt */; - targetProxy = 66BA0E6205FD468B00D882FA /* PBXContainerItemProxy */; - }; - 66BA0E8E05FD473A00D882FA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 66D85E1805ACBA97008DC9C1 /* tnl */; - targetProxy = 66BA0E8D05FD473A00D882FA /* PBXContainerItemProxy */; - }; - 66BA0E9005FD474000D882FA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6649E0D505FD01D700B3DD8B /* libtomcrypt */; - targetProxy = 66BA0E8F05FD474000D882FA /* PBXContainerItemProxy */; - }; - 66BA0E9405FD475500D882FA /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 6649E0D505FD01D700B3DD8B /* libtomcrypt */; - targetProxy = 66BA0E9305FD475500D882FA /* PBXContainerItemProxy */; - }; - 66D85ED905ACCC15008DC9C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 66D85E1805ACBA97008DC9C1 /* tnl */; - targetProxy = 66D85ED805ACCC15008DC9C1 /* PBXContainerItemProxy */; - }; - 66D85EE305ACCC3C008DC9C1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 66D85E1805ACBA97008DC9C1 /* tnl */; - targetProxy = 66D85EE205ACCC3C008DC9C1 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 089C165DFE840E0CC02AAC07 /* English */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; - 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { - isa = PBXVariantGroup; - children = ( - 29B97319FDCFA39411CA2CEA /* English */, - ); - name = MainMenu.nib; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 1D99497110DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Development; - }; - 1D99497210DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Deployment; - }; - 1D99497310DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Default; - }; - 1D99497410DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - DEBUGGING_SYMBOLS = YES; - FRAMEWORK_SEARCH_PATHS = ""; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_ENABLE_TRIGRAPHS = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - 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; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99497510DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - FRAMEWORK_SEARCH_PATHS = ""; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99497610DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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; - }; - name = Default; - }; - 1D99497710DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - 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; - 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"; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99497810DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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"; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99497910DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Default; - }; - 1D99497A10DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - 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; - 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"; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99497B10DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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"; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99497C10DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Default; - }; - 1D99497D10DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - 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; - 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"; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99497E10DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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"; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99497F10DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Default; - }; - 1D99498010DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - 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; - 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"; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99498110DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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"; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99498210DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Default; - }; - 1D99498310DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - 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; - 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"; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99498410DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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"; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99498510DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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"; - }; - name = Default; - }; - 1D99498610DED559001B3AFF /* Development */ = { - isa = XCBuildConfiguration; - 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; - 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; - ZERO_LINK = YES; - }; - name = Development; - }; - 1D99498710DED559001B3AFF /* Deployment */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = YES; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - 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; - ZERO_LINK = NO; - }; - name = Deployment; - }; - 1D99498810DED559001B3AFF /* Default */ = { - isa = XCBuildConfiguration; - 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; - }; - name = Default; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1D99498910DED559001B3AFF /* Build configuration list for PBXProject "tnl" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99497110DED559001B3AFF /* Development */, - 1D99497210DED559001B3AFF /* Deployment */, - 1D99497310DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99498A10DED559001B3AFF /* Build configuration list for PBXNativeTarget "tnl" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99497710DED559001B3AFF /* Development */, - 1D99497810DED559001B3AFF /* Deployment */, - 1D99497910DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99498B10DED559001B3AFF /* Build configuration list for PBXNativeTarget "libtomcrypt" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99497D10DED559001B3AFF /* Development */, - 1D99497E10DED559001B3AFF /* Deployment */, - 1D99497F10DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99498C10DED559001B3AFF /* Build configuration list for PBXNativeTarget "TNLTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99497410DED559001B3AFF /* Development */, - 1D99497510DED559001B3AFF /* Deployment */, - 1D99497610DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99498D10DED559001B3AFF /* Build configuration list for PBXNativeTarget "testserver" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99497A10DED559001B3AFF /* Development */, - 1D99497B10DED559001B3AFF /* Deployment */, - 1D99497C10DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99498E10DED559001B3AFF /* Build configuration list for PBXNativeTarget "master" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99498010DED559001B3AFF /* Development */, - 1D99498110DED559001B3AFF /* Deployment */, - 1D99498210DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99498F10DED559001B3AFF /* Build configuration list for PBXNativeTarget "masterclient" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99498310DED559001B3AFF /* Development */, - 1D99498410DED559001B3AFF /* Deployment */, - 1D99498510DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; - 1D99499010DED559001B3AFF /* Build configuration list for PBXNativeTarget "ZAP" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1D99498610DED559001B3AFF /* Development */, - 1D99498710DED559001B3AFF /* Deployment */, - 1D99498810DED559001B3AFF /* Default */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Default; - }; -/* End XCConfigurationList section */ - }; - rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; -} diff --git a/tnl-1.5.0/tnl/osx/version.plist b/tnl-1.5.0/tnl/osx/version.plist deleted file mode 100644 index a293201..0000000 --- a/tnl-1.5.0/tnl/osx/version.plist +++ /dev/null @@ -1,16 +0,0 @@ - - - - - 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 deleted file mode 100644 index 83ca2eb..0000000 --- a/tnl-1.5.0/tnl/test/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# 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 deleted file mode 100644 index 91a8060..0000000 --- a/tnl-1.5.0/tnl/test/TNLTest.def +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index a38118c4a4bd7c3f2e54c7cebd790fa1d23bbc74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9728 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 diff --git a/tnl-1.5.0/tnl/test/TNLTest.vcproj b/tnl-1.5.0/tnl/test/TNLTest.vcproj deleted file mode 100644 index cd6685a..0000000 --- a/tnl-1.5.0/tnl/test/TNLTest.vcproj +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/test/client.cpp b/tnl-1.5.0/tnl/test/client.cpp deleted file mode 100644 index f706a86..0000000 --- a/tnl-1.5.0/tnl/test/client.cpp +++ /dev/null @@ -1,30 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 deleted file mode 100644 index 85fc01ffe454a59503fee92bb924c8ec58818d71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10240 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 W&W<&#(^0IC=3D80T?R) diff --git a/tnl-1.5.0/tnl/test/mondrian.ico b/tnl-1.5.0/tnl/test/mondrian.ico deleted file mode 100644 index 2310c5d275a87af295d5ea8dc79ea417a5e74c53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 766 zcmZQzU}RuqP*4zH0D%`w3=Con3=A3!3=9ek3=9qoAbA#$6axbjgu*2EGcfFDU|`t4 zA3`zg2Qe8A95}$x(9poZ!0;c882 -#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 deleted file mode 100644 index 4966d33..0000000 --- a/tnl-1.5.0/tnl/test/server.vcproj +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/test/test.rc b/tnl-1.5.0/tnl/test/test.rc deleted file mode 100644 index e3b11b0..0000000 --- a/tnl-1.5.0/tnl/test/test.rc +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 7a9b35a890257ba318ff95f1ee9e8e68d7ff7194..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13312 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*1Oo3?K{^5@29pVu0X(|Ns97i!m@T{2v8F zDg^%i|Nozbfq_ASfq{XQfdL%f>{0s~X0t^fcf(#4{LJSNH!VC-ypmYH8Jd8$XgZQI(aD_k+Lq0=3LkWWdgDXQG zLkU9>LnSOL6Ge+Lu)^~^D81m-^yAvaZwC%DGJ_OJfd~eM0EQxle1jv5C%0aQ*BYd@$A1?4Z0u`Ud$3`q>74CxH%V0*(E5*bPuk{L1>QW*%@4brc` zz{Cj3lOVf67$imrgUW4Cn1R%R@+vw8`31QQ0OfyBIRH}!@-K+3!N9z25SZe1{($j23rOO20I1@273ku1_uTP21f=4 z1}6pv24@Ba1{Vef23H0K1~&!<26qMq1`h@X22TbC1}_E%25$xi1|O)K{1_M*{GseX z1_p*8C>!MdPzDBuFa`#Oa0Uj32nGg*NCpOmCZK0_L~ z>q2JUjKmH05X#h2DNu^mA{~v%40}j z2xiDlnl63!r z+H#<>8e}l#X%JLj@-6 z&fvU`T<+yF6fqPsl!8maRE9i;bZ{;Pm5Id+nGCrMF${SOsSG6y?%>iAJ^lGIq%!0( zfXt|52nXv-VaR7F$C(Rt$jE=7_DTrUQ=t4_0&e-_flEJ7`iGR1kTNujA(bJSp@hMi zAs<{8fqYbg&1`JG$puP{tZV(2UNeF}bP3F*Q6QBLCwx|oZO$cf!V4AE)M)-sJY)_y@u|m4= zpk@@P2?gp1_A#Y1ae;dBf=mpcq8g;K!#aa^flUT4sMO*Fm7ffZ3||FL~47Ch;3@Hrd;2IZUuRplpxJb32KMr zfl>h$ti!;>2&zj#{R3jtKWMz*2P8rn{27uMvKV|BKy4+6-JsF{loRo_IuH(#BP0FG zGcYjZLXB`{$N~2Niy1&|uvCU}oFxrZ0~)2mzy$6~f>H>v{s;9FV8*~oIZ!!Rz>otj zc|rY8NNNLx1xzJ&8r1&;*$c`?AR4 zo|>0hl!(7;0CEUH9189y=QAWSq%fp1q`>Q3NWBJjH(oQ87?>DADn8BC91sd`NVEaoLDj7gMaY)M> zR3AW)z9OcE0Wzq8+|fZVqCk};$UE-fL6=kpJ%$X18ipEBE0w{3!Ii;~!I8m~!I{B~ zL6^aa!5G{e1T`038BD;(E`ZWtkV_&^~9itqx40vd!4C~WeWLLvPJb^KxTVi1K5sKEmo_@`Bx zF*Y$Z1BK06Sl>zlci4bx>K}t5Y+yMGG@J?(P7_@&kdc8Qk&%G`G`EQ^w~v8=;VyKp6J1W9 zk%7SuR6~Fy7#J9k?Q3IZU|7TqnZpE0Bg^G6GB9*v(TBZ{51L7(W<(P=$_DDmIf6%f zGa1SlQW=~X(!leewhSELwJC@`u{8s{I|^Bbg4%XuU`Pawu|j&1A>etp5(Wl_W=Nhw zDWgH{cF=eT!fb5)ZOGg;LJg>wPy!w^1C6hPdP$%@04U5E88{fefF`KHeT=Vg);B1N zo8bqT#mw+sj{!WU!p!g!ECO0{^9#=U4QKs-{R2?nEE6225Yupv znn2`7Lk&IDKx?fKp@KZlM4b==rF~uKIu=kqDgv+L8cyjB)PqJ%ccZx$RPKXjt|7%6 zqy)g8YtzB2VL*8uykKVV_TOpO=E3M=s35m{%()lXm~(?_OVC^wh#t26c=S3FnktB< z1jrcw1I_(@0ad(2+k#&qXxs~i@vEebEX-~YO&c5Vn+mcQhViS!A`6-n1&wW?j&h;& z2~ftkF!RPp?ti~xDq{xEm80}2F~dk`5cZou(~Y3%UC^@IB8FU~DZm(pa`4g*KL*f3 z5m3LJR{bcHbcQlsh#7{XV;ESnFKF<85)%W%IvndO+(2tH7$NOSkapxgp%4>jl?SZk K7^O#I2mk - -#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.getString()); -} - -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 deleted file mode 100644 index d37b8ea..0000000 --- a/tnl-1.5.0/tnl/test/testGame.h +++ /dev/null @@ -1,369 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 4a0ff09..0000000 --- a/tnl-1.5.0/tnl/test/testGameRender.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e359161..0000000 --- a/tnl-1.5.0/tnl/test/testWindow.cpp +++ /dev/null @@ -1,182 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 962f1f90c5313e7ec7939b65b14425d68c8115bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 330982 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 TVHQ-J?FGV}T(g)MW<$jRbDN6k diff --git a/tnl-1.5.0/tnl/tnl.sln b/tnl-1.5.0/tnl/tnl.sln deleted file mode 100644 index ba6e349..0000000 --- a/tnl-1.5.0/tnl/tnl.sln +++ /dev/null @@ -1,134 +0,0 @@ -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 deleted file mode 100644 index 6dad149..0000000 --- a/tnl-1.5.0/tnl/tnl/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# 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 deleted file mode 100644 index a94f13c..0000000 --- a/tnl-1.5.0/tnl/tnl/assert.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3bbba4c..0000000 --- a/tnl-1.5.0/tnl/tnl/asymmetricKey.cpp +++ /dev/null @@ -1,200 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 91429d6..0000000 --- a/tnl-1.5.0/tnl/tnl/bitStream.cpp +++ /dev/null @@ -1,591 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1d6786c..0000000 --- a/tnl-1.5.0/tnl/tnl/byteBuffer.cpp +++ /dev/null @@ -1,154 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index f073c31..0000000 --- a/tnl-1.5.0/tnl/tnl/certificate.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 662f29b..0000000 --- a/tnl-1.5.0/tnl/tnl/clientPuzzle.cpp +++ /dev/null @@ -1,179 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1601893..0000000 --- a/tnl-1.5.0/tnl/tnl/connectionStringTable.cpp +++ /dev/null @@ -1,152 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index dc6919e..0000000 --- a/tnl-1.5.0/tnl/tnl/dataChunker.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index fba2c95..0000000 --- a/tnl-1.5.0/tnl/tnl/eventConnection.cpp +++ /dev/null @@ -1,494 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e944357..0000000 --- a/tnl-1.5.0/tnl/tnl/ghostConnection.cpp +++ /dev/null @@ -1,840 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 47a198c..0000000 --- a/tnl-1.5.0/tnl/tnl/huffmanStringProcessor.cpp +++ /dev/null @@ -1,524 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 976848a..0000000 --- a/tnl-1.5.0/tnl/tnl/journal.cpp +++ /dev/null @@ -1,330 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3f6b7de..0000000 --- a/tnl-1.5.0/tnl/tnl/log.cpp +++ /dev/null @@ -1,110 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 168b230..0000000 --- a/tnl-1.5.0/tnl/tnl/netBase.cpp +++ /dev/null @@ -1,173 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 490e34f..0000000 --- a/tnl-1.5.0/tnl/tnl/netConnection.cpp +++ /dev/null @@ -1,918 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index bad581b..0000000 --- a/tnl-1.5.0/tnl/tnl/netInterface.cpp +++ /dev/null @@ -1,1312 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 412466b..0000000 --- a/tnl-1.5.0/tnl/tnl/netObject.cpp +++ /dev/null @@ -1,268 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index cd59ccb..0000000 --- a/tnl-1.5.0/tnl/tnl/netStringTable.cpp +++ /dev/null @@ -1,441 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index a8d92b9..0000000 --- a/tnl-1.5.0/tnl/tnl/platform.cpp +++ /dev/null @@ -1,488 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 8f4f6f8..0000000 --- a/tnl-1.5.0/tnl/tnl/random.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index f0042c7..0000000 --- a/tnl-1.5.0/tnl/tnl/rpc.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 9938b3c..0000000 --- a/tnl-1.5.0/tnl/tnl/symmetricCipher.cpp +++ /dev/null @@ -1,103 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index febbcde..0000000 --- a/tnl-1.5.0/tnl/tnl/thread.cpp +++ /dev/null @@ -1,300 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 78c4ec1..0000000 --- a/tnl-1.5.0/tnl/tnl/tnl.changelog.txt +++ /dev/null @@ -1,28 +0,0 @@ -// 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 deleted file mode 100644 index 3a8c62c..0000000 --- a/tnl-1.5.0/tnl/tnl/tnl.h +++ /dev/null @@ -1,54 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 57104f3..0000000 --- a/tnl-1.5.0/tnl/tnl/tnl.overview.txt +++ /dev/null @@ -1,539 +0,0 @@ -/* - 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 deleted file mode 100644 index 2122d8cdb0a1f97ae9aecb2e51c3e4051256c915..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7680 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*1Oo3?K{^5@29pg7W|U|NkE>#=yYve-sR< z5cvE5|9=(+1_n?ZvNAA$Dn8BC9 z1sW0sVB1R=DjA%>AyW=@4@fOGti`~@2r8rbNbo->|H8}yu|XIVC!lfwR0e?f$QYFW zLFE7_%0OiR$SzQL!_){Nl?yO2aRvqk2?hoRNd^W6DFy}xX$A%c83qOhSq26MIR*v> zd8i&e1_lNt1_lOw1_lNd1_lOI1_lN-1_lOo1_lNV1_lOA1_lN#1_lOg1_lNls2-Rd zAQ}|rqnP{<@RZ*E;>zsHzDwtPU2(ZDy$_Zyh^0R`gK7z4Rb#3Hr73=w)UwRvR0Ze! zypp2)9B`K7cP^?dE=kN$2udx;FDe0xvA86bB!Z0KitzPO2u{vO%>{FLT{07M^3xSu zQ!-2Pi$DqleDjksb5a$;Q`6%2_-@ ze0@NM@j2&Y79`~-7NsZzW#*-WgxK9v^HPfvb3km$FsLk`!~~FjQ2udduwsZ|$Y984 z$Yn@nh+!yU$YaPsqH)>b$q)jr0dg3U81fk^7=pp&PZ>idLo!1uE=@?{3Jgq)pwtH{ z13)yA6iz0n-FOHp>%x%Aki<~Rkj{_}wmF<3k)ebknIVHAl>r=UP<6N{ko}-A0GUaw z{h;zv1Zp6<{h(4el_8NKo1uUqpCJ=mC*pI51_Ki#sLTY}4Z=`k@lv3=0#xpS6rtM> zs{cSCU%*hpkjaqGkVhaC)EJn+^)IMCA=ZA7S`Y@=4+=XFO(_P|9}Nr)49Vbh2&vW6 z8HyMZ8FCpE7~B{#8FIie8pGfVPFtW_znCGPAr0L22m{x?r3{G-ISdL6!3-q~r3@)x z|0^))G59gKGK4TFFc>iyFc>fxGsG~2F(fmXGsG|?GZZnDFvKtvGZZl-GsG}3Fn|g$ z`nmy>UUL|78PdQmfVl+5A3QFCxDymc$Z?IH{y;I6$B@Dh%#hDe3Jz8LrGOeV|AT4) zV$&Z;?H*{t!)<>hLoT>X!e7Y3(m%*<5JvVJE;gv`hb#a4GNdx(GUS8X!QtTipTdyO z0BVI{H%$kc|3G$wFm_d_qM-I-2vi7^-%G$HUmiI1gTfz@Qy_ULiy@UEnW2Qi8C({C zRDxRRh!V*P8vY==K^ST*UJBG+2DSC@Dk4D=RQ94Pr$h|hEL!qGWj7_}Q>q`77JL~> z8FIkoJ*ebM1ea;033JVX$N{WH4mV zWiVuLVQ^$HXV7IZVK8BEV{m2AWv~Q`fn-7I92s00j2KKAoWMFjECYsG1{a2WhGd3P zaH|27vXIk!07E`QF+(QUWw>f018DjK^$&f1pwmQV*k83+L!CFfoGqN1%QY zvG$8GFfhbHGl)M!5g{1qn~>58q?QBRZ=+_~v}UlUa%$IO2x3SDw?sg_{#1q<21t50 zW-wyVV@P9g0;e=k>(hxLham+e=h;%-Er`006nB79nDZA!7~*IZ*GW1f19N7}CKlYmomzW-&5wFnobF$~hRm!dc&-EN+G$ zU=}mOcRdDhY0S*<6D$H6EBys${f4vtz*&ExEN+JXP!?z;!<`|OArD;hgIc|iybmdN zFkK1pM;L=MgA+qBLo$OexQCJo@4JC~02(a;jp3z0+X@h~Agu`4s8S}l4Gu94k`tU6 za=;^C#SEY}cq&6VR5!7ukO~76xGV*gJs=En2_Xy`w}GjFxGxJl?pMH&18#YN#@`^N z4agNRmDp*}_#3P}N38vd3=9klpvHxQ`^otXi3}+WsSGLbIu}x|fpY>>C3Z@QjPe)R z|B#%4-E3k+ImobInSp^J2U`Dt`nsSI&(U0ioC6`L5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/tnl/tnlAssert.h b/tnl-1.5.0/tnl/tnl/tnlAssert.h deleted file mode 100644 index 46d355d..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlAssert.h +++ /dev/null @@ -1,92 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 8f581cf..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlAsymmetricKey.h +++ /dev/null @@ -1,130 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index ffd29f6..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlBitSet.h +++ /dev/null @@ -1,110 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 00ee140..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlBitStream.h +++ /dev/null @@ -1,405 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 8297e18..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlByteBuffer.h +++ /dev/null @@ -1,208 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index da8eed0..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlCertificate.h +++ /dev/null @@ -1,112 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 45e2fc7..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlClientPuzzle.h +++ /dev/null @@ -1,144 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e47a5be..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlConnectionStringTable.h +++ /dev/null @@ -1,108 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 95f2b47..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlDataChunker.h +++ /dev/null @@ -1,136 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 9b9e776..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlEndian.h +++ /dev/null @@ -1,140 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 7442ec2..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlEventConnection.h +++ /dev/null @@ -1,158 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 41318a2..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlGhostConnection.h +++ /dev/null @@ -1,331 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 31fbe05..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlHuffmanStringProcessor.h +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 4e73947..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlJournal.h +++ /dev/null @@ -1,189 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1ec1c0a..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlLog.h +++ /dev/null @@ -1,134 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c2223b8..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 68053d8..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlMethodDispatch.h +++ /dev/null @@ -1,319 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 0dd42f9..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNetBase.h +++ /dev/null @@ -1,657 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index cd166ea..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNetConnection.h +++ /dev/null @@ -1,599 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 370ea1d..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNetEvent.h +++ /dev/null @@ -1,281 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1e4e611..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNetInterface.h +++ /dev/null @@ -1,386 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 02be77b..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNetObject.h +++ /dev/null @@ -1,421 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3d8228a..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNetStringTable.h +++ /dev/null @@ -1,186 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 834d388..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlNonce.h +++ /dev/null @@ -1,63 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 4385fb5..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlPlatform.h +++ /dev/null @@ -1,128 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d1a2b4a..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlRPC.h +++ /dev/null @@ -1,200 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c015a5a..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlRandom.h +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c3ffe9b..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlString.h +++ /dev/null @@ -1,103 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 0cc453d..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlSymmetricCipher.h +++ /dev/null @@ -1,70 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 9133ba9..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlThread.h +++ /dev/null @@ -1,215 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 398afba..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlTypes.h +++ /dev/null @@ -1,448 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 -# elif __GNUC__ == 4 -# define TNL_GCC_4 -# 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 deleted file mode 100644 index 34294af..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlUDP.h +++ /dev/null @@ -1,194 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1197acc..0000000 --- a/tnl-1.5.0/tnl/tnl/tnlVector.h +++ /dev/null @@ -1,403 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 - -#ifndef _TNL_ASSERT_H_ -#include "tnlAssert.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 deleted file mode 100644 index 91f7a79..0000000 --- a/tnl-1.5.0/tnl/tnl/udp.cpp +++ /dev/null @@ -1,796 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 56f7034..0000000 --- a/tnl-1.5.0/tnl/tnl/vector.cpp +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 77852e0..0000000 --- a/tnl-1.5.0/tnl/zap/CTFGame.cpp +++ /dev/null @@ -1,176 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 38167b8..0000000 --- a/tnl-1.5.0/tnl/zap/CTFGame.h +++ /dev/null @@ -1,66 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 005d987..0000000 --- a/tnl-1.5.0/tnl/zap/HTFGame.cpp +++ /dev/null @@ -1,305 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d077f22..0000000 --- a/tnl-1.5.0/tnl/zap/LoadoutZone.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index b392200..0000000 --- a/tnl-1.5.0/tnl/zap/Makefile +++ /dev/null @@ -1,91 +0,0 @@ -# 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 deleted file mode 100644 index 954966f..0000000 --- a/tnl-1.5.0/tnl/zap/SweptEllipsoid.cpp +++ /dev/null @@ -1,347 +0,0 @@ -// 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 deleted file mode 100644 index 6aee99e..0000000 --- a/tnl-1.5.0/tnl/zap/SweptEllipsoid.h +++ /dev/null @@ -1,43 +0,0 @@ -// 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 deleted file mode 100644 index d40323e..0000000 --- a/tnl-1.5.0/tnl/zap/UI.cpp +++ /dev/null @@ -1,208 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1c22187..0000000 --- a/tnl-1.5.0/tnl/zap/UI.h +++ /dev/null @@ -1,81 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 447bdce..0000000 --- a/tnl-1.5.0/tnl/zap/UICredits.cpp +++ /dev/null @@ -1,181 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 7f659c7..0000000 --- a/tnl-1.5.0/tnl/zap/UICredits.h +++ /dev/null @@ -1,111 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index a3fbd78..0000000 --- a/tnl-1.5.0/tnl/zap/UIEditor.cpp +++ /dev/null @@ -1,1247 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index af9666e..0000000 --- a/tnl-1.5.0/tnl/zap/UIEditor.h +++ /dev/null @@ -1,140 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 250676f..0000000 --- a/tnl-1.5.0/tnl/zap/UIGame.cpp +++ /dev/null @@ -1,834 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 63c146b..0000000 --- a/tnl-1.5.0/tnl/zap/UIGame.h +++ /dev/null @@ -1,159 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 0478e2b..0000000 --- a/tnl-1.5.0/tnl/zap/UIInstructions.cpp +++ /dev/null @@ -1,452 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 7ebe86d..0000000 --- a/tnl-1.5.0/tnl/zap/UIInstructions.h +++ /dev/null @@ -1,55 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 9e33019..0000000 --- a/tnl-1.5.0/tnl/zap/UIMenus.cpp +++ /dev/null @@ -1,548 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index b5c6049..0000000 --- a/tnl-1.5.0/tnl/zap/UIMenus.h +++ /dev/null @@ -1,160 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 77c8206..0000000 --- a/tnl-1.5.0/tnl/zap/UINameEntry.cpp +++ /dev/null @@ -1,192 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 5da380e..0000000 --- a/tnl-1.5.0/tnl/zap/UINameEntry.h +++ /dev/null @@ -1,124 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 936c75f..0000000 --- a/tnl-1.5.0/tnl/zap/UIQueryServers.cpp +++ /dev/null @@ -1,590 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d389cb3..0000000 --- a/tnl-1.5.0/tnl/zap/UIQueryServers.h +++ /dev/null @@ -1,117 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 20ffd6b..0000000 --- a/tnl-1.5.0/tnl/zap/ZAP.rc +++ /dev/null @@ -1,72 +0,0 @@ -// 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 deleted file mode 100644 index d43d525..0000000 --- a/tnl-1.5.0/tnl/zap/ZAP.vcproj +++ /dev/null @@ -1,520 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tnl-1.5.0/tnl/zap/barrier.cpp b/tnl-1.5.0/tnl/zap/barrier.cpp deleted file mode 100644 index fed10d2..0000000 --- a/tnl-1.5.0/tnl/zap/barrier.cpp +++ /dev/null @@ -1,258 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 05d6d06..0000000 --- a/tnl-1.5.0/tnl/zap/barrier.h +++ /dev/null @@ -1,80 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 5d361da..0000000 --- a/tnl-1.5.0/tnl/zap/controlObjectConnection.cpp +++ /dev/null @@ -1,266 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 64d3de9..0000000 --- a/tnl-1.5.0/tnl/zap/controlObjectConnection.h +++ /dev/null @@ -1,105 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index f7e78ed..0000000 --- a/tnl-1.5.0/tnl/zap/engineeredObjects.cpp +++ /dev/null @@ -1,711 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 51934de..0000000 --- a/tnl-1.5.0/tnl/zap/engineeredObjects.h +++ /dev/null @@ -1,163 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c00941a..0000000 --- a/tnl-1.5.0/tnl/zap/flagItem.cpp +++ /dev/null @@ -1,133 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 63476f0..0000000 --- a/tnl-1.5.0/tnl/zap/flagItem.h +++ /dev/null @@ -1,60 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 9517c0d..0000000 --- a/tnl-1.5.0/tnl/zap/footballGame.cpp +++ /dev/null @@ -1,242 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3bc7253..0000000 --- a/tnl-1.5.0/tnl/zap/ftol.h +++ /dev/null @@ -1,35 +0,0 @@ -#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 deleted file mode 100644 index ecedb98..0000000 --- a/tnl-1.5.0/tnl/zap/game.cpp +++ /dev/null @@ -1,773 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index a8dab7f..0000000 --- a/tnl-1.5.0/tnl/zap/game.h +++ /dev/null @@ -1,241 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index ff17045..0000000 --- a/tnl-1.5.0/tnl/zap/gameConnection.cpp +++ /dev/null @@ -1,440 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 68bf356..0000000 --- a/tnl-1.5.0/tnl/zap/gameConnection.h +++ /dev/null @@ -1,131 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 36bbcf4..0000000 --- a/tnl-1.5.0/tnl/zap/gameItems.cpp +++ /dev/null @@ -1,190 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 321456f..0000000 --- a/tnl-1.5.0/tnl/zap/gameLoader.cpp +++ /dev/null @@ -1,191 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 -#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) - { - char path[1024]; - getcwd(path, sizeof(path)); - printf("path = %s\n", path); - 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 deleted file mode 100644 index ea355ae..0000000 --- a/tnl-1.5.0/tnl/zap/gameLoader.h +++ /dev/null @@ -1,44 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 09446ae..0000000 --- a/tnl-1.5.0/tnl/zap/gameNetInterface.cpp +++ /dev/null @@ -1,178 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 054c46a..0000000 --- a/tnl-1.5.0/tnl/zap/gameNetInterface.h +++ /dev/null @@ -1,69 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 2e63953..0000000 --- a/tnl-1.5.0/tnl/zap/gameObject.cpp +++ /dev/null @@ -1,378 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index a32052b..0000000 --- a/tnl-1.5.0/tnl/zap/gameObject.h +++ /dev/null @@ -1,191 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d6480e4..0000000 --- a/tnl-1.5.0/tnl/zap/gameObjectRender.cpp +++ /dev/null @@ -1,635 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 1727023..0000000 --- a/tnl-1.5.0/tnl/zap/gameObjectRender.h +++ /dev/null @@ -1,58 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e7af804..0000000 --- a/tnl-1.5.0/tnl/zap/gameType.cpp +++ /dev/null @@ -1,1073 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 8ffd8ba..0000000 --- a/tnl-1.5.0/tnl/zap/gameType.h +++ /dev/null @@ -1,241 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index f36b66f..0000000 --- a/tnl-1.5.0/tnl/zap/gameWeapons.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index ef5e928..0000000 --- a/tnl-1.5.0/tnl/zap/gameWeapons.h +++ /dev/null @@ -1,120 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 90ec044..0000000 --- a/tnl-1.5.0/tnl/zap/goalZone.cpp +++ /dev/null @@ -1,161 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d3977d8..0000000 --- a/tnl-1.5.0/tnl/zap/goalZone.h +++ /dev/null @@ -1,74 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c6d82a2..0000000 --- a/tnl-1.5.0/tnl/zap/gridDB.cpp +++ /dev/null @@ -1,265 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 989eabe..0000000 --- a/tnl-1.5.0/tnl/zap/gridDB.h +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index dd296cb..0000000 --- a/tnl-1.5.0/tnl/zap/gsm.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 deleted file mode 100644 index 5f9f79b..0000000 --- a/tnl-1.5.0/tnl/zap/gsm_decode.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - 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 deleted file mode 100644 index 2f07762..0000000 --- a/tnl-1.5.0/tnl/zap/gsm_encode.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* - 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 deleted file mode 100644 index 841f3da..0000000 --- a/tnl-1.5.0/tnl/zap/gsm_state.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - 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 deleted file mode 100644 index fce7d43..0000000 --- a/tnl-1.5.0/tnl/zap/huntersGame.cpp +++ /dev/null @@ -1,490 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 0b0e0c5..0000000 --- a/tnl-1.5.0/tnl/zap/huntersGame.h +++ /dev/null @@ -1,146 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 6538f0f..0000000 --- a/tnl-1.5.0/tnl/zap/input.cpp +++ /dev/null @@ -1,466 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e985435..0000000 --- a/tnl-1.5.0/tnl/zap/input.h +++ /dev/null @@ -1,79 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3225154..0000000 --- a/tnl-1.5.0/tnl/zap/item.cpp +++ /dev/null @@ -1,314 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 8d3d1e7..0000000 --- a/tnl-1.5.0/tnl/zap/item.h +++ /dev/null @@ -1,111 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index b88f3d4..0000000 --- a/tnl-1.5.0/tnl/zap/linuxInput.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 5b94249..0000000 --- a/tnl-1.5.0/tnl/zap/loadoutSelect.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index f79d77f..0000000 --- a/tnl-1.5.0/tnl/zap/loadoutSelect.h +++ /dev/null @@ -1,59 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index ee86929..0000000 --- a/tnl-1.5.0/tnl/zap/lpc10.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - 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 deleted file mode 100644 index 0afe281..0000000 --- a/tnl-1.5.0/tnl/zap/lpc10dec.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - 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 deleted file mode 100644 index 8fdd3ad..0000000 --- a/tnl-1.5.0/tnl/zap/lpc10enc.c +++ /dev/null @@ -1,1476 +0,0 @@ -/* - 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 deleted file mode 100644 index da14933..0000000 --- a/tnl-1.5.0/tnl/zap/main.cpp +++ /dev/null @@ -1,751 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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, "/Work/Torque-Network-Library/tnl-1.5.0/tnl/exe/"); - //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 deleted file mode 100644 index c6446cc..0000000 --- a/tnl-1.5.0/tnl/zap/masterConnection.cpp +++ /dev/null @@ -1,220 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3dfe20d..0000000 --- a/tnl-1.5.0/tnl/zap/masterConnection.h +++ /dev/null @@ -1,73 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 65846ed..0000000 --- a/tnl-1.5.0/tnl/zap/move.h +++ /dev/null @@ -1,131 +0,0 @@ -//---------------------------------------------------------------- -// -// 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 deleted file mode 100644 index cab900a..0000000 --- a/tnl-1.5.0/tnl/zap/moveObject.cpp +++ /dev/null @@ -1,425 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e2105c0..0000000 --- a/tnl-1.5.0/tnl/zap/moveObject.h +++ /dev/null @@ -1,95 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index b32bf83..0000000 --- a/tnl-1.5.0/tnl/zap/osxInput.cpp +++ /dev/null @@ -1,348 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 ((CFDictionaryRef) refElement, CFSTR(kIOHIDElementTypeKey)); - CFTypeRef refUsagePage = CFDictionaryGetValue ((CFDictionaryRef) refElement, CFSTR(kIOHIDElementUsagePageKey)); - CFTypeRef refUsage = CFDictionaryGetValue ((CFDictionaryRef) refElement, CFSTR(kIOHIDElementUsageKey)); - bool isButton = false, isAxis = false; - - ControllerElement *theElement = NULL; - if ((refElementType) && (CFNumberGetValue ((CFNumberRef) refElementType, kCFNumberLongType, &elementType))) - { - /* look at types of interest */ - if ((elementType == kIOHIDElementTypeInput_Misc) || (elementType == kIOHIDElementTypeInput_Button) || - (elementType == kIOHIDElementTypeInput_Axis)) - { - if (refUsagePage && CFNumberGetValue ((CFNumberRef) refUsagePage, kCFNumberLongType, &usagePage) && - refUsage && CFNumberGetValue ((CFNumberRef) 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 ((CFArrayRef) refElementTop)}; - /* CountElementsCFArrayHandler called for each array member */ - CFArrayApplyFunction ((CFArrayRef) refElementTop, range, HIDGetElementsCFArrayHandler, NULL); - } - } - } - } - if (theElement) /* add to list */ - { - long number; - CFTypeRef refType; - - refType = CFDictionaryGetValue ((CFDictionaryRef) refElement, CFSTR(kIOHIDElementCookieKey)); - if (refType && CFNumberGetValue ((CFNumberRef) refType, kCFNumberLongType, &number)) - theElement->cookie = (IOHIDElementCookie) number; - refType = CFDictionaryGetValue ((CFDictionaryRef) refElement, CFSTR(kIOHIDElementMinKey)); - if (refType && CFNumberGetValue ((CFNumberRef) refType, kCFNumberLongType, &number)) - theElement->minValue = number; - - refType = CFDictionaryGetValue ((CFDictionaryRef) refElement, CFSTR(kIOHIDElementMaxKey)); - - if (refType && CFNumberGetValue ((CFNumberRef) 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 ((CFStringRef) refCF) + 1; - char * buffer = (char *)malloc (bufferSize); - if (buffer) - { - if (CFStringGetCString ((CFStringRef) refCF, buffer, bufferSize, CFStringGetSystemEncoding ())) - strncpy(gJoystickName, buffer, MaxJoystickNameLen); - free(buffer); - } - } - refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); - long usage, usagePage; - CFNumberGetValue ((CFNumberRef) refCF, kCFNumberLongType, &usagePage); - refCF = CFDictionaryGetValue (hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); - CFNumberGetValue ((CFNumberRef) 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 ((CFArrayRef) refElementTop)}; - /* CountElementsCFArrayHandler called for each array member */ - CFArrayApplyFunction ((CFArrayRef) refElementTop, range, HIDGetElementsCFArrayHandler, NULL); - - IOCFPlugInInterface ** ppPlugInInterface = NULL; - SInt32 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 deleted file mode 100644 index 9ceb97f..0000000 --- a/tnl-1.5.0/tnl/zap/point.h +++ /dev/null @@ -1,177 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 58b358f..0000000 --- a/tnl-1.5.0/tnl/zap/private.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - 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 static 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 deleted file mode 100644 index 7ef581a..0000000 --- a/tnl-1.5.0/tnl/zap/projectile.cpp +++ /dev/null @@ -1,504 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 90ab501..0000000 --- a/tnl-1.5.0/tnl/zap/projectile.h +++ /dev/null @@ -1,132 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 3823c41..0000000 --- a/tnl-1.5.0/tnl/zap/quickChat.cpp +++ /dev/null @@ -1,212 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d29af1a..0000000 --- a/tnl-1.5.0/tnl/zap/quickChat.h +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 808f1e1..0000000 --- a/tnl-1.5.0/tnl/zap/rabbitGame.cpp +++ /dev/null @@ -1,263 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 364c2fa..0000000 --- a/tnl-1.5.0/tnl/zap/rabbitGame.h +++ /dev/null @@ -1,106 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c8599fa..0000000 --- a/tnl-1.5.0/tnl/zap/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{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 deleted file mode 100644 index 5b2c38f..0000000 --- a/tnl-1.5.0/tnl/zap/retrieveGame.cpp +++ /dev/null @@ -1,285 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index cc33652..0000000 --- a/tnl-1.5.0/tnl/zap/sfx.cpp +++ /dev/null @@ -1,954 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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" -#include - -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); - } -} - - -typedef struct /* WAV File-header */ - { - ALubyte Id[4]; - ALsizei Size; - ALubyte Type[4]; - } WAVFileHdr_Struct; - -typedef struct /* WAV Fmt-header */ - { - ALushort Format; - ALushort Channels; - ALuint SamplesPerSec; - ALuint BytesPerSec; - ALushort BlockAlign; - ALushort BitsPerSample; - } WAVFmtHdr_Struct; - -typedef struct /* WAV FmtEx-header */ - { - ALushort Size; - ALushort SamplesPerBlock; - } WAVFmtExHdr_Struct; - -typedef struct /* WAV Smpl-header */ - { - ALuint Manufalimturer; - ALuint Product; - ALuint SamplePeriod; - ALuint Note; - ALuint FineTune; - ALuint SMPTEFormat; - ALuint SMPTEOffest; - ALuint Loops; - ALuint SamplerData; - struct - { - ALuint Identifier; - ALuint Type; - ALuint Start; - ALuint End; - ALuint Frac; - ALuint Count; - } Loop[1]; - } WAVSmplHdr_Struct; - -typedef struct /* WAV Chunk-header */ - { - ALubyte Id[4]; - ALuint Size; - } WAVChunkHdr_Struct; - -//#pragma palimk (pop, alut) /* Default alignment */ - -ALvoid alutLoadWAV(const ALbyte *name,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq) -{ - WAVChunkHdr_Struct ChunkHdr; - WAVFmtExHdr_Struct FmtExHdr; - WAVFileHdr_Struct FileHdr; - WAVSmplHdr_Struct SmplHdr; - WAVFmtHdr_Struct FmtHdr; - FILE *Stream; - - *format=AL_FORMAT_MONO16; - *data=NULL; - *size=0; - *freq=22050; - if (name) - { - Stream=fopen(name,"rb"); - if (Stream) - { - fread(&FileHdr,1,sizeof(WAVFileHdr_Struct),Stream); - FileHdr.Size=((FileHdr.Size+1)&~1)-4; - - while (FileHdr.Size!=0) - { - if (fread(&ChunkHdr,1,sizeof(WAVChunkHdr_Struct),Stream)) - { - if (!memcmp(ChunkHdr.Id,"fmt ",4)) - { - fread(&FmtHdr,1,sizeof(WAVFmtHdr_Struct),Stream); - if (FmtHdr.Format!=0x0001) - { - fread(&FmtExHdr,1,sizeof(WAVFmtExHdr_Struct),Stream); - fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct)-sizeof(WAVFmtExHdr_Struct),SEEK_CUR); - } else fseek(Stream,ChunkHdr.Size-sizeof(WAVFmtHdr_Struct),SEEK_CUR); - *format=(FmtHdr.Channels==1? - (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16): - (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16)); - *freq=FmtHdr.SamplesPerSec; - } - else if (!memcmp(ChunkHdr.Id,"data",4)) - { - if (FmtHdr.Format==0x0001) - { - *size=ChunkHdr.Size; - *data=malloc(ChunkHdr.Size+31); - if (*data) fread(*data,FmtHdr.BlockAlign,ChunkHdr.Size/FmtHdr.BlockAlign,Stream); - memset(((char *)*data)+ChunkHdr.Size,0,31); - } - else if (FmtHdr.Format==0x0011) - { - //IMA ADPCM - } - else if (FmtHdr.Format==0x0055) - { - //MP3 WAVE - } - } - else if (!memcmp(ChunkHdr.Id,"smpl",4)) - { - fread(&SmplHdr,1,sizeof(WAVSmplHdr_Struct),Stream); - fseek(Stream,ChunkHdr.Size-sizeof(WAVSmplHdr_Struct),SEEK_CUR); - } - else fseek(Stream,ChunkHdr.Size,SEEK_CUR); - fseek(Stream,ChunkHdr.Size&1,SEEK_CUR); - FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8); - } - else break; ///BUG - } - fclose(Stream); - } - } -} - -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; -#ifdef TNL_OS_MAC_OSX - gDevice = alcOpenDevice(NULL); -#else - gDevice = alcOpenDevice((ALubyte *) "DirectSound3D"); -#endif - 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 - alutLoadWAV((const ALbyte *) fileBuffer,&format,&data,&size,&freq); - //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); - free(data); - //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 deleted file mode 100644 index 472bff1..0000000 --- a/tnl-1.5.0/tnl/zap/sfx.h +++ /dev/null @@ -1,162 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 5eb04ae..0000000 --- a/tnl-1.5.0/tnl/zap/ship.cpp +++ /dev/null @@ -1,1183 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 9a05d5d..0000000 --- a/tnl-1.5.0/tnl/zap/ship.h +++ /dev/null @@ -1,188 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c02b3e2..0000000 --- a/tnl-1.5.0/tnl/zap/shipItems.h +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index c49a385..0000000 --- a/tnl-1.5.0/tnl/zap/soccerGame.cpp +++ /dev/null @@ -1,208 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index b6943d9..0000000 --- a/tnl-1.5.0/tnl/zap/soccerGame.h +++ /dev/null @@ -1,93 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 01e3be8..0000000 --- a/tnl-1.5.0/tnl/zap/sparkManager.cpp +++ /dev/null @@ -1,340 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 01cce0a..0000000 --- a/tnl-1.5.0/tnl/zap/sparkManager.h +++ /dev/null @@ -1,90 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index d9b2be9..0000000 --- a/tnl-1.5.0/tnl/zap/teleporter.cpp +++ /dev/null @@ -1,194 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 23541ac..0000000 --- a/tnl-1.5.0/tnl/zap/teleporter.h +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 295fb78..0000000 --- a/tnl-1.5.0/tnl/zap/timer.h +++ /dev/null @@ -1,89 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 6a03e87..0000000 --- a/tnl-1.5.0/tnl/zap/voiceCodec.cpp +++ /dev/null @@ -1,205 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 930a4a0..0000000 --- a/tnl-1.5.0/tnl/zap/voiceCodec.h +++ /dev/null @@ -1,126 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 08f9b23..0000000 --- a/tnl-1.5.0/tnl/zap/winJoystick.cpp +++ /dev/null @@ -1,222 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index 6f650ea..0000000 --- a/tnl-1.5.0/tnl/zap/winmain.cpp +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------------------- -// -// 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 deleted file mode 100644 index e9f5b81db93bc337eebe65d89fce0597c761dbf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33927 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 Y_y98l!w*IVhChr94F3v2eL@BX0H@%g#{d8T diff --git a/tnl-_next/core/algorithm_templates.h b/tnl-_next/core/algorithm_templates.h deleted file mode 100755 index 687e319..0000000 --- a/tnl-_next/core/algorithm_templates.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -// if min/max are #define'd, undef them -#undef min -#undef max -template inline type min(type a,type b) { return (a < b)? a: b; } -template inline type max(type a,type b) { return (a > b)? a: b; } - -template inline type clamp(type a,type min,type max) { return (a < min)? min:(a>max)?max: a;} -template inline type clamp_min(type a,type min) { return (a < min)? min: a; } -template inline type clamp_max(type a,type max) { return (a > max)? max: a; } - -template inline bool less(const type &a, const type &b) -{ - return a < b; -} - -template inline void swap(type &a, type &b) -{ - type temp = a; - a = b; - b = temp; -} - -template inline void swap(type *start, type *end, type *dest) -{ - while(start != end) - swap(*start++, *dest++); -} - -namespace internal { - template inline dst_type copy_aux(src_type src,src_type end,dst_type dst,false_type) - { - while (src != end) - *dst++ = *src++; - return dst; - } - - template inline dst_type copy_aux(src_type src,src_type end,dst_type dst,true_type) - { - memcpy(dst, src, (end - src) * sizeof(src_type)); - return dst + (end - src); - } -} // Private - -/// Copy from [src,end) to dst, going forwards. -/// Source and destination may overlap. This function works for all iterators -/// and memcpy is used for real pointers. -template inline dst_ptr_type copy(src_ptr_type src,src_ptr_type end,dst_ptr_type dst) -{ - typedef typename non_qualified_type::value_type>::value_type src_data_type; - typedef typename non_qualified_type::value_type>::value_type dst_data_type; - typename bool_type< - is_pointer::is_true && - is_pointer::is_true && - is_same::is_true && - has_trivial_assign::is_true - >::value_type is_trivial; - return internal::copy_aux(src,end,dst,is_trivial); -} - -template -inline U copy(T src,unsigned int count,U dst) -{ - return copy(src,src + count,dst); -} - -namespace internal { - template - inline void ucopy_is_trivial(src_type src,src_type end,dst_type dst,false_type) - { - while (src != end) - construct(dst++,*src++); - } - - template - inline void ucopy_is_trivial(src_type src,src_type end,dst_type dst,true_type) - { - memcpy(dst, src, (end - src) * sizeof(src_type)); - } -} - -template -inline void uninitialized_copy(src_ptr_type src,src_ptr_type end,dst_ptr_type dst) -{ - typedef typename non_qualified_type::value_type>::value_type src_data_type; - typedef typename non_qualified_type::value_type>::value_type dst_data_type; - typename bool_type< - is_pointer::is_true && - is_pointer::is_true && - is_same::is_true && - has_trivial_assign::is_true - >::value_type is_trivial; - internal::ucopy_is_trivial(src,end,dst,is_trivial); -} - diff --git a/tnl-_next/core/array.h b/tnl-_next/core/array.h deleted file mode 100755 index f9ba87f..0000000 --- a/tnl-_next/core/array.h +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -// Maintain a reserve of half the public size -struct array_half_reserve_policy -{ - inline static uint32 grow_to(uint32 public_size, uint32 array_size) { - return public_size + public_size / 2; - } - inline static uint32 shrink_to(uint32 public_size, uint32 array_size) { - return (public_size < array_size / 2)? - array_size + array_size / 4: array_size; - }; -}; - -template class array -{ -public: - typedef type value_type; - typedef type &reference; - typedef const type &const_reference; - typedef type *iterator; - typedef const type *const_iterator; - - array() - { - _public_size = 0; - _array_size = 0; - _array = 0; - } - - array(const uint32 initial_reserve) - { - _public_size = 0; - _array_size = initial_reserve; - _array = initial_reserve ? (type *) memory_allocate(initial_reserve * sizeof(type)) : 0; - } - - array(const array &p) - { - _public_size = 0; - _array_size = 0; - _array = 0; - *this = p; - } - - ~array() - { - destroy(begin(), end()); - memory_deallocate(_array); - } - - uint32 size() const - { - return _public_size; - } - - uint32 capacity() const - { - return _array_size; - } - - void reserve(uint32 size) - { - if(size > _array_size) - _resize(size); - } - - void resize(uint32 size) - { - if(size > _public_size) - { - if(size > _array_size) - _resize(policy::grow_to(size, _array_size)); - construct(end(), end() + (size - _public_size)); - _public_size = size; - } - else if(size < _public_size) - { - destroy(end() - (_public_size - size), end()); - _public_size = size; - uint32 new_size = policy::shrink_to(size, _array_size); - if(new_size != _array_size) - _resize(new_size); - } - } - - void compact() - { - if(_public_size < _array_size) - _resize(_public_size); - } - - void clear() - { - destroy(begin(), end()); - memory_deallocate(_array); - _public_size = 0; - _array_size = 0; - _array = 0; - } - - bool is_empty() - { - return _public_size == 0; - } - - iterator insert(uint32 index, const type &x) - { - if(_public_size + 1 > _array_size) - { - uint32 new_size = policy::grow_to(_public_size + 1, _array_size); - assert(new_size > _public_size); - type *new_array = (type *) memory_allocate(new_size * sizeof(type)); - uninitialized_copy(_array + index, end(), new_array + index + 1); - destroy(begin(), end()); - memory_deallocate(_array); - _array = new_array; - _array_size = new_size; - } else { - construct(end()); - copy_backwards(_array + index, end(), end() + 1); - _array[index] = x; - } - _public_size++; - return _array + index; - } - - iterator insert(iterator itr, const type &x) - { - return insert(uint32(itr - _array), x); - } - - iterator insert(uint32 index) - { - return insert(index, type()); - } - - iterator insert(iterator itr) - { - return insert(uint32(itr - _array)); - } - - iterator push_front(const type &x) - { - return insert(uint32(0), x); - } - - iterator push_back(const type &x) - { - if(_public_size + 1 > _array_size) - _resize(policy::grow_to(_public_size + 1, _array_size)); - return construct(_array + _public_size++, x); - } - - iterator push_front() - { - return insert(uint32(0)); - } - - iterator push_back() - { - return push_back(type()); - } - - void erase(uint32 index) - { - if(has_trivial_copy::is_true) - { - copy(_array + index + 1, end(), _array + index); - destroy(&last()); - uint32 new_size = policy::shrink_to(--_public_size, _array_size); - assert(new_size >= _public_size); - if(new_size != _array_size) - { - _array = (type *) memory_reallocate(_array, new_size * sizeof(type)); - _array_size = new_size; - } - } - else - { - uint32 new_size = policy::shrink_to(_public_size - 1, _array_size); - if(new_size != _array_size) - { - assert(new_size >= _public_size - 1); - type *new_array = (type *) memory_allocate(new_size * sizeof(type)); - uninitialized_copy(begin(), _array + index, new_array); - uninitialized_copy(_array + index + 1, end(), new_array + index); - destroy(begin(), end()); - memory_deallocate(_array); - _array = new_array; - _array_size = new_size; - } - else - { - copy(_array + index + 1, end(), _array + index); - destroy(&last()); - } - _public_size--; - } - } - - void erase(iterator itr) - { - erase(uint32(itr - _array)); - } - - void erase_unstable(iterator itr) - { - if(itr != end() - 1) - core::swap(*itr, last()); - pop_back(); - } - - void erase_unstable(uint32 index) - { - erase_unstable(&_array[index]); - } - - void pop_front() - { - erase(uint32(0)); - } - - void pop_back() - { - destroy(&last()); - uint32 size = policy::shrink_to(--_public_size, _array_size); - if(size != _array_size) - _resize(size); - } - - iterator begin() - { - return _array; - } - - const_iterator begin() const - { - return _array; - } - - iterator end() - { - return _array + _public_size; - } - - const_iterator end() const - { - return _array + _public_size; - } - - iterator rbegin() - { - return end() - 1; - } - - const_iterator rbegin() const - { - return end() - 1; - } - - iterator rend() - { - return begin() - 1; - } - - const_iterator rend() const - { - return begin() - 1; - } - - type &first() - { - return _array[0]; - } - - const type &first() const - { - return _array[0]; - } - - type &last() - { - return _array[_public_size - 1]; - } - - const type &last() const - { - return _array[_public_size - 1]; - } - - type &operator[](uint32 index) - { - return _array[index]; - } - - const type &operator[](uint32 index) const - { - return _array[index]; - } - - void operator=(const array &p) - { - if(_array_size != p._array_size) - { - destroy(begin(), end()); - memory_deallocate(_array); - _array_size = p._array_size; - _array = (type *) memory_allocate(p._array_size * sizeof(type)); - uninitialized_copy(p.begin(), p.end(), _array); - } - else if(_public_size > p._public_size) - { - destroy(&_array[p._public_size], end()); - copy(p.begin(), p.end(), begin()); - } - else - { - copy(p.begin(), &p[_public_size], begin()); - uninitialized_copy(&p[_public_size], p.end(), end()); - } - _public_size = p._public_size; - } -protected: - uint32 _public_size; - uint32 _array_size; - type *_array; - - void _resize(uint32 size) - { - assert(size >= _public_size); - if(has_trivial_copy::is_true) - _array = (type *) memory_reallocate(_array, size * sizeof(type)); - else - { - type *new_array = (type *) memory_allocate(size * sizeof(type)); - uninitialized_copy(begin(), end(), new_array); - destroy(begin(), end()); - memory_deallocate(_array); - _array = new_array; - } - _array_size = size; - } -}; - -/*template struct container_manipulator > -{ - static type_record *get_key_type() - { - return get_global_type_record(); - } - static type_record *get_value_type() - { - return get_global_type_record(); - } -};*/ diff --git a/tnl-_next/core/assert.h b/tnl-_next/core/assert.h deleted file mode 100755 index 47adbe6..0000000 --- a/tnl-_next/core/assert.h +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -#undef assert -#if defined(INLINE_ASM_STYLE_GCC_X86) -#define ASM_DEBUG_BREAK asm ( "int $3" ); -#elif defined(INLINE_ASM_STYLE_VC_X86) -#define ASM_DEBUG_BREAK __asm { int 3 } -#endif - -#define assert(x) { if(!bool(x)) { printf("ASSERT FAILED: \"%s\"\n", #x); ASM_DEBUG_BREAK } } diff --git a/tnl-_next/core/base_type_declarations.h b/tnl-_next/core/base_type_declarations.h deleted file mode 100755 index 3f45970..0000000 --- a/tnl-_next/core/base_type_declarations.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -typedef char char8; ///< 8 bit character -typedef unsigned short char16; ///< 16 bit character -typedef unsigned int char32; ///< 32 bit character -typedef signed char int8; ///< Signed 8 bit integer -typedef unsigned char uint8; ///< Unsigned 8 bit integer -typedef unsigned char byte; ///< Unsigned 8 bit integer -typedef signed short int16; ///< Signed 16 bit integer -typedef unsigned short uint16; ///< Unsigned 16 bit integer -typedef signed int int32; ///< Signed 32 bit integer -typedef unsigned int uint32; ///< Unsigned 8 bit integer -typedef float float32; ///< 32 bit floating-point value -typedef double float64; ///< 64 bit floating-point value -typedef double float128; ///< 128 bit floating point value -#if defined(COMPILER_VISUALC) - typedef signed _int64 int64; ///< Signed 64 bit integer - typedef unsigned _int64 uint64; ///< Unsigned 64 bit integer - #define CONSTANT_64(a) (a##I64) - #define CONSTANT_U64(a) (a##UI64) -#else - typedef signed long long int64; ///< Signed 64 bit integer - typedef unsigned long long uint64; ///< Unsigned 64 bit integer - #define CONSTANT_64(a) (a##LL) - #define CONSTANT_U64(a) (a##ULL) -#endif - -typedef const char *static_string; ///< Static string type is a string that refers to a static string in the executable. The assumption that functions can make for arguments of this type are that they will not move and will survive for the duration of the program execution. - -struct empty_type {}; ///< "Null" type used by templates - - -const int8 min_value_int8 = -128; ///< Smallest possible value for this type -const int8 max_value_int8 = +127; ///< Largest possible value for this type -const uint8 max_value_uint8 = +255U; ///< Largest possible value for this type - -const int16 min_value_int16 = -32768; ///< Smallest possible value for this type -const int16 max_value_int16 = +32767; ///< Largest possible value for this type -const uint16 max_value_uint16 = +65535U; ///< Largest possible value for this type - -const int32 min_value_int32 = -2147483647L; ///< Smallest possible value for this type -const int32 max_value_int32 = +2147483647L; ///< Largest possible value for this type -const uint32 max_value_uint32 = +4294967295U; ///< Largest possible value for this type - -const int64 min_value_int64 = CONSTANT_64(-9223372036854775807); ///< Smallest possible value for this type -const int64 max_value_int64 = CONSTANT_64(+9223372036854775807); ///< Largest possible value for this type -const uint64 max_value_uint64 = CONSTANT_U64(+18446744073709551615); ///< Largest possible value for this type - -const float32 min_value_float32 = float32(1.175494351e-38F); ///< Smallest possible positive value for this type -const float32 max_value_float32 = float32(3.402823466e+38F); ///< Largest possible value for this type - -template class int_ranged -{ -public: - enum { - max_offset_value = range_max - range_min, - }; - int_ranged() - { - _offset_value = 0; - } - int_ranged(int32 value) - { - _offset_value = value - range_min; - assert(_offset_value <= max_offset_value); - } - operator int32() - { - return _offset_value + range_min; - } -private: - uint32 _offset_value; -}; - -template class enumeration -{ -public: - enumeration() - { - _enum_value = 0; - } - enumeration(uint32 enum_value) - { - assert(enum_value < enum_count); - _enum_value = enum_value; - } - operator uint32() - { - return _enum_value; - } -private: - uint32 _enum_value; -}; \ No newline at end of file diff --git a/tnl-_next/core/base_type_io.h b/tnl-_next/core/base_type_io.h deleted file mode 100755 index 99f1138..0000000 --- a/tnl-_next/core/base_type_io.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -template inline bool write(stream &the_stream, const type &value) -{ - type temp = value; - host_to_little_endian(temp); - return the_stream.write_bytes((byte *) &temp, sizeof(temp)) == sizeof(temp); -} - -template inline bool read(stream &the_stream, type &value) -{ - if(the_stream.read_bytes((byte *) &value, sizeof(type)) != sizeof(type)) - return false; - - host_to_little_endian(value); - return true; -} \ No newline at end of file diff --git a/tnl-_next/core/base_type_traits.h b/tnl-_next/core/base_type_traits.h deleted file mode 100755 index bdadc70..0000000 --- a/tnl-_next/core/base_type_traits.h +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -struct true_type -{ - static const bool is_true = true; -}; - -struct false_type -{ - static const bool is_true = false; -}; - -template struct bool_type -{ - typedef false_type value_type; -}; - -template<> struct bool_type -{ - typedef true_type value_type; -}; - -template struct int_to_type -{ - enum { value = v }; -}; - -template -struct select_type -{ - typedef flag_true_type value_type; -}; - -template -struct select_type -{ - typedef flag_false_type value_type; -}; - -template struct is_same -{ - static const bool is_true = false; -}; - -template struct is_same -{ - static const bool is_true = true; -}; - -#define TYPE_INFO_TEMPLATE(name, type_info_type, type_info_name, default_value) template struct name { static const type_info_type type_info_name = default_value; } - -#define INTEGER_TYPE_INFO_TEMPLATE(name, int_default_value) TYPE_INFO_TEMPLATE(name, int32, value, int_default_value) - -#define TYPE_INFO_PARTIAL_SPEC(name, type_name, type_info_type, type_info_name, value) template<> struct name { static const type_info_type type_info_name = value; } - -#define INTEGER_TYPE_INFO_PARTIAL_SPEC(name, type_name, int_value) TYPE_INFO_PARTIAL_SPEC(name, type_name, int32, value, int_value) - -#define BOOLEAN_TYPE_INFO_TEMPLATE(name, default_is_true) TYPE_INFO_TEMPLATE(name, bool, is_true, default_is_true) - -#define BOOLEAN_TYPE_INFO_PARTIAL_SPEC(name, type_name, bool_is_true) TYPE_INFO_PARTIAL_SPEC(name, type_name, bool, is_true, bool_is_true) - -#define TYPE_INFO_PARTIAL_SPEC1(name, type, spec, type_info_type, type_info_name, value) template struct name { static const type_info_type type_info_name = value; } - -#define BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(name, type, spec, bool_is_true) TYPE_INFO_PARTIAL_SPEC1(name, type, spec, bool, is_true, bool_is_true) - -#define TYPE_INFO_PARTIAL_SPEC2(name, type1, type2, spec, type_info_type, type_info_name, value) template struct name { static const type_info_type type_info_name = value; } - -#define BOOLEAN_TYPE_INFO_PARTIAL_SPEC2(name, type1, type2, spec, bool_is_true) TYPE_INFO_PARTIAL_SPEC2(name, type1, type2, spec, bool, is_true, bool_is_true) - -BOOLEAN_TYPE_INFO_TEMPLATE(is_integral, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, bool, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, int8, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, uint8, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, int16, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, uint16, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, int32, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, uint32, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, int64, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_integral, uint64, true); -template struct is_integral > { static const bool is_true = true; }; -template struct is_integral > { static const bool is_true = true; }; - -BOOLEAN_TYPE_INFO_TEMPLATE(is_signed, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_signed, int8, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_signed, int16, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_signed, int32, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_signed, int64, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_signed, float32, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_signed, float64, true); -template struct is_signed > { static const bool is_true = range_min < 0; }; - -BOOLEAN_TYPE_INFO_TEMPLATE(is_float, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_float, float32, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_float, float64, true); - -template struct integer_range { - static const int32 range_min = 0; - static const uint32 range_size = 0; -}; - -#define INTEGER_RANGE(name, min, size) template<> struct integer_range { static const int32 range_min = min; static const uint32 range_size = size; } - -INTEGER_RANGE(bool, 0, 1); -INTEGER_RANGE(int8, min_value_int8, max_value_uint8); -INTEGER_RANGE(uint8, 0, max_value_uint8); -INTEGER_RANGE(int16, min_value_int16, max_value_uint16); -INTEGER_RANGE(uint16, 0, max_value_uint16); -INTEGER_RANGE(int32, min_value_int32, max_value_uint32); -INTEGER_RANGE(uint32, 0, max_value_uint32); -template struct integer_range > { - static const int32 range_min = min; - static const uint32 range_size = uint32(max - min); -}; -template struct integer_range > { - static const int32 range_min = 0; - static const uint32 range_size = enum_count - 1; -}; - -template struct is_arithmetic -{ - static const bool is_true = is_integral::is_true || is_float::is_true; -}; - -BOOLEAN_TYPE_INFO_TEMPLATE(is_void, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_void, void, true); - -BOOLEAN_TYPE_INFO_TEMPLATE(is_array, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC2(is_array, typename t, size_t n, t[n], true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC2(is_array, typename t, size_t n, const t[n], true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC2(is_array, typename t, size_t n, volatile t[n], true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC2(is_array, typename t, size_t n, const volatile t[n], true); - -BOOLEAN_TYPE_INFO_TEMPLATE(is_reference, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(is_reference, typename t, t&, true); - -BOOLEAN_TYPE_INFO_TEMPLATE(is_member_pointer, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC2(is_member_pointer, typename t, typename u, u t::*, true); - -template struct is_function -{ - typedef uint16 yes; - typedef uint32 no; - - template static yes test(...); - template static no test(u (*)[1]); - static const bool is_true = sizeof(test(0)) == sizeof(yes); - static const bool is_false = !is_true; -}; - -BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(is_function, typename type, type&, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_function, void, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC(is_function, void const, false); - -BOOLEAN_TYPE_INFO_TEMPLATE(is_basic_pointer, false); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(is_basic_pointer, typename t, t*, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(is_basic_pointer, typename t, t* const, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(is_basic_pointer, typename t, t* volatile, true); -BOOLEAN_TYPE_INFO_PARTIAL_SPEC1(is_basic_pointer, typename t, t* const volatile, true); - -template struct is_pointer -{ - static const bool is_true = is_basic_pointer::is_true && !is_member_pointer::is_true; -}; - -namespace internal -{ - template struct is_convertible_aux - { - struct anything { - template anything(const volatile to_type &); - template anything(to_type &); - }; - typedef uint16 yes; - typedef uint32 no; - static yes test(from_type, int); - static no test(anything,...); - }; -} - -template -struct is_convertible -{ - static from_type dummy_make_type(); - static const bool is_true = sizeof(internal::is_convertible_aux::test(dummy_make_type(),0)) - == sizeof(typename internal::is_convertible_aux::yes); -}; - -namespace internal -{ - template struct is_enum_convertible - { - static const bool is_true = false; - }; - template struct is_enum_convertible - { - static const bool is_true = is_convertible::is_true; - }; -} - -template struct is_enum -{ - static const bool is_true = internal::is_enum_convertible::is_true || is_pointer::is_true || - is_function::is_true || is_reference::is_true>::is_true; -}; - -template struct is_scalar -{ - static const bool is_true = is_arithmetic::is_true || - is_enum::is_true || - is_basic_pointer::is_true; -}; - -template struct class_traits -{ - static const bool is_pod = false; - static const bool has_trivial_constructor = false; - static const bool has_trivial_destructor = false; - static const bool has_trivial_assign = false; - static const bool has_trivial_copy = false; -}; - -template struct is_pod -{ - static const bool is_true = is_scalar::is_true || - is_void::is_true || - class_traits::is_pod; -}; - -template struct is_pod : is_pod {}; - -template struct has_trivial_constructor -{ - static const bool is_true = is_pod::is_true || class_traits::has_trivial_constructor; -}; - -template struct has_trivial_destructor -{ - static const bool is_true = is_pod::is_true || class_traits::has_trivial_destructor; -}; - -template struct has_trivial_assign -{ - static const bool is_true = is_pod::is_true || class_traits::has_trivial_assign; -}; - -template struct has_trivial_copy -{ - static const bool is_true = is_pod::is_true || class_traits::has_trivial_copy; -}; - -template struct non_qualified_type -{ - typedef type value_type; -}; - -template -struct enumeration_traits -{ - enum { bit_count = 0, }; -}; - -template -struct type_traits { - typedef typename type::value_type value_type; - typedef typename type::pointer pointer; - typedef typename type::reference reference; -}; - -template -struct type_traits { - typedef type value_type; - typedef type* pointer; - typedef type& reference; -}; - -template -struct type_traits { - typedef type value_type; - typedef type* pointer; - typedef type& reference; -}; - -template struct non_qualified_type { typedef type value_type; }; -template struct non_qualified_type { typedef type value_type; }; -template struct non_qualified_type { typedef type value_type; }; -template struct non_qualified_type { typedef type value_type; }; -template struct non_qualified_type { typedef type value_type; }; -template struct non_qualified_type { typedef type value_type; }; - - diff --git a/tnl-_next/core/base_types.h b/tnl-_next/core/base_types.h deleted file mode 100755 index a183d06..0000000 --- a/tnl-_next/core/base_types.h +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. -// basic type declarations; due to namespace ambiguity errors, these exist in the global namespace. diff --git a/tnl-_next/core/bit_stream.h b/tnl-_next/core/bit_stream.h deleted file mode 100755 index 8b9d439..0000000 --- a/tnl-_next/core/bit_stream.h +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright Mark Frohnmayer and GarageGames. See /license/info.txt in this distribution for licensing terms. - -/// stream is a virtual base class for managing bit-level streaming of data. Subclasses are responsible for refilling the _start and _end -class bit_stream -{ - public: - typedef uint64 bit_position; - - bit_stream(byte *buffer = 0, uint32 buffer_size = 0) { _init(buffer, 0, buffer_size * 8); } - - void set_buffer(byte *buffer, uint32 bit_start, uint32 bit_end) { _init(buffer, bit_start, bit_end); } - - bool is_dirty() {return _is_dirty;} - void raise_error() { _error_detected = true; } - bool was_error_detected() { return _error_detected; } - - virtual bit_position get_bit_position() { return _bit_num; } - virtual void set_bit_position(bit_position pos) { _bit_num = uint32(pos); } - virtual bit_position get_stream_bit_size() { return _bit_end; } - - virtual uint32 get_byte_position() { return _bit_num >> 3; } - virtual void set_byte_position(uint32 byte_pos) { _bit_num = byte_pos << 3; } - virtual uint32 get_stream_byte_size() { return (_bit_end + 7) >> 3; } - - static void copy_bits(byte *dest_ptr, uint32 dest_bit, const byte *source_ptr, uint32 source_bit, uint32 bit_count) { _copy_bits(dest_ptr, dest_bit, source_ptr, source_bit, bit_count); } - - uint32 write_bits(const byte *source_ptr, uint32 source_bit_num, uint32 write_bit_count) { return _write_bits(source_ptr, source_bit_num, write_bit_count); } - uint32 read_bits(byte *dest_ptr, uint32 dest_bit_num, uint32 read_bit_count) { return _read_bits(dest_ptr, dest_bit_num, read_bit_count); } - - uint32 write_bytes(const byte *source_ptr, uint32 write_byte_count) { return _write_bits(source_ptr, 0, write_byte_count << 3) >> 3; } - uint32 read_bytes(byte *dest_ptr, uint32 read_byte_count) { return _read_bits(dest_ptr, 0, read_byte_count << 3) >> 3; } - - uint32 read_integer(uint32 bit_width) { return _read_integer(bit_width); } - void write_integer(uint32 value, uint32 bit_width) { _write_integer(value, bit_width); } - - virtual bool more(uint32 bits_requested) { return false; } - - private: - byte *_base_ptr; - uint32 _bit_num; - uint32 _bit_end; // when _bit_num == _bit_end, no more can be read/written, and the stream will ask for more data. - bool _is_dirty; - bool _error_detected; - - void _init(byte *buffer, uint32 bit_start, uint32 bit_end) - { - _base_ptr = buffer; - _bit_num = bit_start; - _bit_end = bit_end; - _is_dirty = false; - _error_detected = false; - } - - static void _copy_bits(byte *dest_ptr, uint32 dest_bit, const byte *source_ptr, uint32 source_bit, uint32 bit_count) - { - assert(bit_count != 0); // this should be checked by any calling code - dest_ptr += dest_bit >> 3; - source_ptr += source_bit >> 3; - dest_bit &= 7; - source_bit &= 7; - uint32 last_write_bit = dest_bit + bit_count - 1; - byte *last_write_byte = dest_ptr + (last_write_bit >> 3); - - // check if this is byte aligned first: - if(source_bit == dest_bit) - { - // preload the first byte: - byte mask = (1 << source_bit) - 1; - byte buffer = (*dest_ptr & mask) | (*source_ptr++ & ~mask); - - while(dest_ptr != last_write_byte) - { - *dest_ptr++ = buffer; - buffer = *source_ptr++; - } - mask = byte((1 << ((last_write_bit & 7) + 1)) - 1); - *dest_ptr = (buffer & mask) | (*dest_ptr & ~mask); - } - else - { - uint32 slider = *source_ptr++; - uint32 up_shift; - if(source_bit < dest_bit) - { - up_shift = dest_bit - source_bit; - if(dest_bit + bit_count <= 8) - { - byte mask = ((1 << bit_count) - 1) << dest_bit; - *dest_ptr = (*dest_ptr & ~mask) | (byte(slider << up_shift) & mask); - return; - } - // otherwise, lets spit out the first dest byte: - byte mask = (1 << dest_bit) - 1; - *dest_ptr = (*dest_ptr & mask) | ((slider << up_shift) & ~mask); - dest_ptr++; - slider >>= 8 - up_shift; - } - else // source_bit > dest_bit - { - uint32 down_shift = source_bit - dest_bit; - byte mask = (1 << dest_bit) - 1; - slider = (*dest_ptr & mask) | ((slider >> down_shift) & ~mask); - up_shift = 8 - down_shift; - } - while(dest_ptr != last_write_byte) - { - slider |= uint32(*source_ptr++) << up_shift; - *dest_ptr++ = byte(slider); - slider >>= 8; - } - uint32 last_write_bit_in_byte = last_write_bit & 7; - // see if we need to read one more source byte: - if(last_write_bit_in_byte >= up_shift) - slider |= uint32(*source_ptr) << up_shift; - byte mask = byte((1 << (last_write_bit_in_byte + 1)) - 1); - *dest_ptr = (slider & mask) | (*dest_ptr & ~mask); - } - } - - uint32 _write_bits(const byte *source_ptr, uint32 source_bit_num, uint32 write_bit_count) - { - if(!write_bit_count) - return 0; - - uint32 bits_written = 0; - _is_dirty = true; - - for(;;) - { - uint32 bits_remaining = _bit_end - _bit_num; - if(!bits_remaining) - { - if(!more(write_bit_count)) - { - _error_detected = true; - return bits_written; - } - else - bits_remaining = _bit_end - _bit_num; - } - - if(write_bit_count <= bits_remaining) - { - copy_bits(_base_ptr, _bit_num, source_ptr, source_bit_num, write_bit_count); - _bit_num += write_bit_count; - return bits_written + write_bit_count; - } - else - { - copy_bits(_base_ptr,_bit_num, source_ptr, source_bit_num, bits_remaining); - _bit_num += bits_remaining; - source_bit_num += bits_remaining; - bits_written += bits_remaining; - write_bit_count -= bits_remaining; - } - } - } - - uint32 _read_bits(byte *dest_ptr, uint32 dest_bit_num, uint32 read_bit_count) - { - if(!read_bit_count) - return 0; - - uint32 bits_read = 0; - for(;;) - { - uint32 bits_remaining = _bit_end - _bit_num; - if(!bits_remaining) - { - if(!more(read_bit_count)) - { - _error_detected = true; - return bits_read; - } - else - bits_remaining = _bit_end - _bit_num; - } - - if(read_bit_count <= bits_remaining) - { - copy_bits(dest_ptr, dest_bit_num, (const byte *) _base_ptr, _bit_num, read_bit_count); - _bit_num += read_bit_count; - return bits_read + read_bit_count; - } - else - { - copy_bits(dest_ptr, dest_bit_num, (const byte *) _base_ptr, _bit_num, bits_remaining); - _bit_num += bits_remaining; - dest_bit_num += bits_remaining; - bits_read += bits_remaining; - read_bit_count -= bits_remaining; - } - } - } - - uint32 _read_integer(uint32 bit_width) - { - uint32 ret = 0; - _read_bits((byte *) &ret, 0, bit_width); - little_endian_to_host(ret); - return ret; - } - - void _write_integer(uint32 value, uint32 bit_width) - { - host_to_little_endian(value); - _write_bits((byte *) &value, 0, bit_width); - } - -}; - -static void stream_test() -{ - struct internal - { - static void print_bits(const byte *bits_ptr, uint32 bit_start, uint32 bit_count) - { - char *array = new char[bit_count + 1]; - for(uint32 i = 0; i < bit_count; i++) - { - const byte *ptr = bits_ptr + ((i + bit_start) >> 3); - array[i] = "-X"[(*ptr >> ((i + bit_start) & 7)) & 1]; - } - array[bit_count] = 0; - printf("%s\n", array); - delete[] array; - } - static void test_range(int start, int count) - { - const byte bits[] = { 0xFF, 0xAA, 0x55, 0xCC, 0xFF, 0 }; - uint32 bits_size = strlen((const char *) bits); - - printf("Bit buffer copy %d, %d\n", start, count); - internal::print_bits(bits, 0, bits_size * 8); - internal::print_bits(bits, start, count); - byte *buf = new byte[strlen((const char *) bits)]; - printf("0 1 2 3 4 5 6 7 \n"); - printf("0123456701234567012345670123456701234567012345670123456701234567\n"); - for(uint32 i = 0;i < 17; i++) - { - stream::copy_bits(buf, 0, bits, 0, bits_size * 8); - stream::copy_bits(buf, i, bits, start, count); - internal::print_bits(buf, 0, bits_size * 8); - } - } - }; - internal::test_range(0,8); - internal::test_range(12,7); - internal::test_range(12,17); -} \ No newline at end of file diff --git a/tnl-_next/core/byte_stream_fixed.h b/tnl-_next/core/byte_stream_fixed.h deleted file mode 100755 index 3f772b9..0000000 --- a/tnl-_next/core/byte_stream_fixed.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright Mark Frohnmayer and GarageGames. See /license/info.txt in this distribution for licensing terms. - -class byte_stream_fixed -{ -public: - uint32 _position; - uint32 _buffer_size; - byte *_buffer; - - byte_stream_fixed(byte *buffer = 0, uint32 buffer_size = 0) - { - set_buffer(buffer, buffer_size); - } - - void set_position(uint32 byte_pos) - { - _position = byte_pos; - if(_position > _buffer_size) - _position = _buffer_size; - } - - uint32 get_position() - { - return _position; - } - - void set_buffer(byte *buffer, uint32 buffer_size) - { - _buffer = buffer; - _buffer_size = buffer_size; - _position = 0; - } - - uint32 read_bytes(byte *dest_ptr, uint32 read_byte_count) - { - if(read_byte_count + _position > _buffer_size) - read_byte_count = _buffer_size - _position; - - memcpy(dest_ptr, _buffer + _position, read_byte_count); - _position += read_byte_count; - return read_byte_count; - } - - uint32 write_bytes(const byte *src_ptr, uint32 write_byte_count) - { - if(write_byte_count + _position > _buffer_size) - write_byte_count = _buffer_size - _position; - - memcpy(_buffer + _position, src_ptr, write_byte_count); - _position += write_byte_count; - return write_byte_count; - } -}; \ No newline at end of file diff --git a/tnl-_next/core/construct.h b/tnl-_next/core/construct.h deleted file mode 100755 index 5641e3e..0000000 --- a/tnl-_next/core/construct.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -template inline type* construct(type* ptr) -{ - return new((void*)ptr) type; -} - -template inline type* construct(type* ptr,const type& a) -{ - return new((void*)ptr) type(a); -} - -template inline void destroy(type* ptr) -{ - ptr->~type(); -} - -namespace internal { - template inline void construct_aux(type* ptr, type* end, true_type) {} - template inline void construct_aux(type* ptr, type* end, false_type) - { - while (ptr != end) - construct(ptr++); - } -} // Private - -template inline void construct(type* ptr,type* end) -{ - typename bool_type::is_true>::value_type is_trivial; - internal::construct_aux(ptr,end,is_trivial); -} - -template inline void construct(type* ptr,type* end,const type& x) -{ - while (ptr != end) - construct(ptr++,x); -} - -//----------------------------------------------------------------------------- - -namespace internal { - template inline void destroy_aux(type* ptr, type* end, true_type) {} - template inline void destroy_aux(type* ptr, type* end, false_type) - { - while (ptr != end) - (ptr++)->~type(); - } -} // Private - -template inline void destroy(type* ptr,type* end) -{ - typename bool_type::is_true>::value_type is_trivial; - internal::destroy_aux(ptr,end,is_trivial); -} diff --git a/tnl-_next/core/core.h b/tnl-_next/core/core.h deleted file mode 100755 index e9fcacb..0000000 --- a/tnl-_next/core/core.h +++ /dev/null @@ -1,14 +0,0 @@ -#include "core/assert.h" -#include "core/base_type_declarations.h" -#include "core/base_type_traits.h" -#include "core/cpu_endian.h" -#include "core/algorithm_templates.h" -#include "core/memory_functions.h" -#include "core/construct.h" -#include "core/array.h" -#include "core/formatted_string_buffer.h" -#include "core/string.h" -#include "core/byte_stream_fixed.h" -#include "core/base_type_io.h" -#include "core/time.h" -#include "core/utils.h" diff --git a/tnl-_next/core/cpu_endian.h b/tnl-_next/core/cpu_endian.h deleted file mode 100755 index 8a1a260..0000000 --- a/tnl-_next/core/cpu_endian.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -inline void endian_swap(uint16 &value) -{ - value = (value << 8) | (value >> 8); -} - -inline void endian_swap(uint32 &value) -{ - value = ((value << 24) & 0xFF000000) | ((value << 8) & 0xFF0000) | ((value >> 8) & 0xFF00) | ((value >> 24) & 0xFF); -} - -inline void endian_swap(uint64 &value) -{ - uint32 *src_ptr = (uint32 *) &value; - endian_swap(src_ptr[0]); - endian_swap(src_ptr[1]); - uint32 temp = src_ptr[0]; - src_ptr[0] = src_ptr[1]; - src_ptr[1] = temp; -} - -inline void endian_swap(char8) {} -inline void endian_swap(int8) {} -inline void endian_swap(uint8) {} -inline void endian_swap(bool) {} - -inline void endian_swap(int16 &value) { endian_swap(reinterpret_cast(value)); } -inline void endian_swap(int32 &value) { endian_swap(reinterpret_cast(value)); } -inline void endian_swap(float32 &value) { endian_swap(reinterpret_cast(value)); } -inline void endian_swap(int64 &value) { endian_swap(reinterpret_cast(value)); } -inline void endian_swap(float64 &value) { endian_swap(reinterpret_cast(value)); } - -#ifdef LITTLE_ENDIAN -template inline void host_to_little_endian(type& value) { } -template inline void host_to_big_endian(type& value) { endian_swap(value); } -template inline void little_endian_to_host(type& value) { } -template inline void big_endian_to_host(type& value) { endian_swap(value); } -#else -template inline void host_to_little_endian(type& value) { endian_swap(value); } -template inline void host_to_big_endian(type& value) { } -template inline void little_endian_to_host(type& value) { endian_swap(value); } -template inline void big_endian_to_host(type& value) { } -#endif \ No newline at end of file diff --git a/tnl-_next/core/formatted_string_buffer.h b/tnl-_next/core/formatted_string_buffer.h deleted file mode 100755 index 6433515..0000000 --- a/tnl-_next/core/formatted_string_buffer.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -class formatted_string_buffer -{ -public: - formatted_string_buffer() - { - _dynamic_buffer = 0; - _len = 0; - } - - formatted_string_buffer(const char8 *fmt, ...) - { - va_list args; - va_start(args, fmt); - _dynamic_buffer = 0; - format(fmt, args); - } - - formatted_string_buffer(const char8 *fmt, void *args) - { - _dynamic_buffer = 0; - format(fmt, args); - } - - ~formatted_string_buffer() - { - memory_deallocate(_dynamic_buffer); - } - - int32 format( const char8 *fmt, ... ) - { - va_list args; - va_start(args, fmt); - _dynamic_buffer = 0; - - return format(fmt, args); - } - - int32 format(const char8 *fmt, void *args) - { - if(_dynamic_buffer) - { - memory_deallocate(_dynamic_buffer); - _dynamic_buffer = 0; - } - - _len = vsnprintf(_fixed_buffer, sizeof(_fixed_buffer), fmt, (char *) args); - if(_len < sizeof(_fixed_buffer)) - return _len; - - _dynamic_size = sizeof(_fixed_buffer); - for(;;) - { - _dynamic_size *= 2; - _dynamic_buffer = (char8 *) memory_reallocate(_dynamic_buffer, _dynamic_size, false); - _len = vsnprintf(_dynamic_buffer, _dynamic_size, fmt, (char *) args); - if(_len < _dynamic_size) - { - // trim off the remainder of the allocation - memory_reallocate(_dynamic_buffer, _len + 1, true); - return _len; - } - } - } - - bool copy(char8 *buffer, uint32 buffer_size) - { - assert(buffer_size > 0); - if(buffer_size >= size()) - { - memcpy(buffer, c_str(), size()); - return true; - } - else - { - memcpy(buffer, c_str(), buffer_size - 1); - buffer[buffer_size - 1] = 0; - return false; - } - } - - uint32 length() { return _len; }; - - uint32 size() { return _len + 1; }; - - const char8* c_str() - { - return _dynamic_buffer ? _dynamic_buffer : _fixed_buffer; - } - - static int32 format_buffer(char8 *buffer, uint32 buffer_size, const char8 *fmt, ...) - { - va_list args; - va_start(args, fmt); - return format_buffer(buffer, buffer_size, fmt, args); - } - - static int32 format_buffer(char8 *buffer, uint32 buffer_size, const char8 *fmt, void *args) - { - assert(buffer_size > 0); - int32 len = vsnprintf(buffer, buffer_size, fmt, (char *) args); - buffer[buffer_size - 1] = 0; - return len; - } -private: - char8 _fixed_buffer[2048]; // Fixed size buffer - char8* _dynamic_buffer; // Format buffer for strings longer than _fixed_buffer - uint32 _dynamic_size; // Size of dynamic buffer - uint32 _len; // Length of the formatted string -}; diff --git a/tnl-_next/core/memory_functions.h b/tnl-_next/core/memory_functions.h deleted file mode 100755 index 70f3433..0000000 --- a/tnl-_next/core/memory_functions.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. -// simple memory allocation functions for requesting memory from the system. - -void *memory_allocate(size_t size) -{ - return malloc(size); -} - -void memory_deallocate(void *ptr) -{ - free(ptr); -} - -void *memory_reallocate(void *ptr, size_t size, bool keep_contents = true) -{ - if(!keep_contents || !ptr) - { - free(ptr); - return malloc(size); - } - return realloc(ptr, size); -} \ No newline at end of file diff --git a/tnl-_next/core/string.h b/tnl-_next/core/string.h deleted file mode 100755 index f974c40..0000000 --- a/tnl-_next/core/string.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -class string -{ - struct string_record - { - uint32 ref_count; - uint32 len; - char data[1]; - }; - - static string_record *_get_null_string_record() - { - static string_record null_string = { 0x7FFFFFFF, 0, 0 }; - return &null_string; - } - - string_record *_string_record; - void _dec_ref() - { - if(!--_string_record->ref_count) - memory_deallocate(_string_record); - } -public: - string() - { - _string_record = _get_null_string_record(); - _string_record->ref_count++; - } - - ~string() - { - _dec_ref(); - } - string(const char *string_data) - { - _string_record = _get_null_string_record(); - _string_record->ref_count++; - set(string_data); - } - string(const string &the_string) - { - _string_record = the_string._string_record; - _string_record->ref_count++; - } - - string& operator=(const string &the_string) - { - _dec_ref(); - _string_record = the_string._string_record; - _string_record->ref_count++; - return *this; - } - void set(const char *string_data) - { - uint32 len = strlen(string_data); - set(string_data, len); - } - - void set(const char *string_data, uint32 len) - { - _dec_ref(); - _string_record = (string_record *) memory_allocate(sizeof(string_record) + len); - _string_record->len = len; - _string_record->ref_count = 1; - memcpy(_string_record->data, string_data, len); - _string_record->data[len] = 0; - } - operator const char *() - { - return _string_record->data; - } - const char *c_str() - { - return _string_record->data; - } -}; - -string format_string(const char *fmt, ...) -{ - formatted_string_buffer buf; - - va_list args; - va_start(args, fmt); - uint32 len = buf.format(fmt, args); - - string return_value; - return_value.set(buf.c_str(), len); - - return return_value; -} \ No newline at end of file diff --git a/tnl-_next/core/time.h b/tnl-_next/core/time.h deleted file mode 100755 index 9ec32be..0000000 --- a/tnl-_next/core/time.h +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -#define ONE_DAY int64(86400000) -#define ONE_HOUR int64( 3600000) -#define ONE_MINUTE int64( 60000) -#define ONE_SECOND int64( 1000) -#define ONE_MILLISECOND int64( 1) - -#define UNIX_TIME_TO_INT64(t) ((int64(t) + int64(62135683200)) * ONE_SECOND) - -static int8 _DaysInMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static int8 _DaysInMonthLeap[13]= {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -static int32 _DayNumber[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; -static int32 _DayNumberLeap[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}; - -/// Time, broken out into time/date -struct date_and_time { - int32 year; ///< current year - int32 month; ///< Month (0-11; 0=january) - int32 day; ///< Day of year (0-365) - int32 hour; ///< Hours after midnight (0-23) - int32 minute; ///< Minutes after hour (0-59) - int32 second; ///< seconds after minute (0-59) - int32 millisecond; ///< Milliseconds after second (0-999) -}; - -/// time values are defined as a 64-bit number of milliseconds since 12:00 AM, January 1, 0000 -class time -{ - int64 _time; - - bool _is_leap_year(int32 year) const - { - return ((year & 3) == 0) && ( ((year % 100) != 0) || ((year % 400) == 0) ); - } - - int32 _days_in_month(int32 month, int32 year) const - { - if (_is_leap_year(year)) - return _DaysInMonthLeap[month]; - else - return _DaysInMonth[month]; - } -public: - /// Empty constructor. - time() {} - - /// Constructs the time from a 64-bit millisecond value. - time(int64 time) - { - _time = time; - } - - /// Constructs the time from specified values. - time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second, int32 millisecond) - { - set(year, month, day, hour, minute, second, millisecond); - } - - /// Constructs the time from the specified DateTime. - time(const date_and_time &date_time) - { - set(date_time); - } - - /// Sets the time from the specified date_and_time. - inline void set(const date_and_time &date_time) - { - set(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.minute, date_time.second, date_time.millisecond); - } - - /// Sets the time from specified values. - void set(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second, int32 millisecond) - { - second += millisecond / 1000; - millisecond %= 1000; - minute += second / 60; - second %= 60; - hour += minute / 60; - minute %= 60; - int32 carry_days = hour / 24; - hour %= 24; - - bool leap_year = _is_leap_year(year); - - year -= 1; // all the next operations need (year-1) so do it ahead of time - int32 gregorian = 365 * year // number of days since the epoch - + (year/4) // add julian leap year days - - (year/100) // subtract century leap years - + (year/400) // add gregorian 400 year leap adjustment - + ((367*month-362)/12) // days in prior months - + day // add days - + carry_days; // add days from time overflow/underflow - - // make days in this year adjustment if leap year - if (leap_year) { - if (month > 2) - gregorian -= 1; - } - else - if (month > 2) - gregorian -= 2; - - _time = int64(gregorian) * ONE_DAY; - _time += int64((hour * ONE_HOUR) + - (minute * ONE_MINUTE) + - (second * ONE_SECOND) + - millisecond); - } - - - /// Gets the date and time values from the time. - inline void get(date_and_time &dt) const - { - get_date(dt.year, dt.month, dt.day); - get_time(dt.hour, dt.minute, dt.second, dt.millisecond); - } - - /// Gets the date. - void get_date(int32 &year, int32 &month, int32 &day) const - { - int32 gregorian = (int32)(_time / ONE_DAY); - - int32 prior = gregorian - 1; // prior days - int32 years400 = prior / 146097L; // number of 400 year cycles - int32 days400 = prior % 146097L; // days NOT in years400 - int32 years100 = days400 / 36524L; // number 100 year cycles not checked - int32 days100 = days400 % 36524L; // days NOT already included - int32 years4 = days100 / 1461L; // number 4 year cycles not checked - int32 days4 = days100 % 1461L; // days NOT already included - int32 year1 = days4 / 365L; // number years not already checked - int32 day1 = days4 % 365L; // days NOT already included - - year = (400 * years400) + (100 * years100) + (4 * years4) + year1; - - // December 31 of leap year - if (years100 == 4 || year1 == 4) - day = 366; - else - { - year += 1; - day = day1 + 1; - } - - int32 *day_number; - if (_is_leap_year(year)) - day_number = _DayNumberLeap; - else - day_number = _DayNumber; - - // find month and day in month given computed year and day number, - month = 0; - while(day >= day_number[month+1]) - month++; - - day -= day_number[month]; - } - - /// Gets the time since midnight from the Time. - void get_time(int32 &hour, int32 &minute, int32 &second, int32 &millisecond) const - { - // extract time - int32 time = int32(_time % ONE_DAY); - hour = time / int32(ONE_HOUR); - time -= hour * int32(ONE_HOUR); - - minute = time / int32(ONE_MINUTE); - time -= minute * int32(ONE_MINUTE); - - second = time / int32(ONE_SECOND); - time -= second * int32(ONE_SECOND); - - millisecond = time; - } - - /// Gets the total millisecond count. - int64 get_milliseconds() - { - return _time; - } - - inline const time& operator=(const int64 the_time) - { - _time = the_time; - return *this; - } - - inline time operator+(const time &the_time) const - { - return time(_time + the_time._time); - } - - inline time operator-(const time &the_time) const - { - return time(_time - the_time._time); - } - - inline const time& operator+=(const time the_time) - { - _time += the_time._time; - return *this; - } - - inline const time& operator-=(const time the_time) - { - _time -= the_time._time; - return *this; - } - - inline bool operator==(const time &the_time) const - { - return (_time == the_time._time); - } - - inline bool operator!=(const time &the_time) const - { - return (_time != the_time._time); - } - inline bool operator<(const time &the_time) const - { - return (_time < the_time._time); - } - inline bool operator>(const time &the_time) const - { - return (_time > the_time._time); - } - inline bool operator<=(const time &the_time) const - { - return (_time <= the_time._time); - } - inline bool operator>=(const time &the_time) const - { - return (_time >= the_time._time); - } - -#ifdef PLATFORM_WIN32 - static int64 win32_file_time_to_milliseconds(FILETIME &ft) - { - ULARGE_INTEGER lt; - lt.LowPart = ft.dwLowDateTime; - lt.HighPart = ft.dwHighDateTime; - - // FILETIME is a number of 100-nanosecond intervals since January 1, 1601 (UTC). - // re-base it to January 1, 0000 - return lt.QuadPart / 10000 + int64(50491209600) * ONE_SECOND; - } - - class win32_multimedia_timer - { - uint32 resolution; - uint32 last_timer_time; - int64 system_time; - public: - win32_multimedia_timer() - { - TIMECAPS tc; - timeGetDevCaps(&tc, sizeof(tc)); - resolution = max(uint32(tc.wPeriodMin), uint32(1)); - timeBeginPeriod(resolution); - last_timer_time = timeGetTime(); - FILETIME ft; - GetSystemTimeAsFileTime(&ft); - system_time = win32_file_time_to_milliseconds(ft); - } - - ~win32_multimedia_timer() - { - timeEndPeriod(resolution); - } - - int64 get_current() - { - uint32 current = timeGetTime(); - system_time += current - last_timer_time; - last_timer_time = current; - return system_time; - } - }; - - - /// Returns the current time. - static time get_current() - { - static win32_multimedia_timer the_timer; - time current_time = the_timer.get_current(); - - return current_time; - } -#endif -}; - diff --git a/tnl-_next/core/utils.h b/tnl-_next/core/utils.h deleted file mode 100755 index fd958e3..0000000 --- a/tnl-_next/core/utils.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright GarageGames. See /license/info.txt in this distribution for licensing terms. - -#if 0 - -void output_debug_string(); -void debug_break(); -void exit(int code); -void alert_ok(const char *window_title, const char *message); -void sleep(uint32 millisecond_count); - -#elif defined(PLATFORM_WIN32) - -void output_debug_string(const char *string) -{ - OutputDebugStringA(string); -} - -void debug_break() -{ - DebugBreak(); -} - -void exit(int code) -{ - ExitProcess(code); -} - -void alert_ok(const char *window_title, const char *message) -{ - ShowCursor(true); - MessageBoxA(NULL, message, window_title, MB_ICONINFORMATION | MB_SETFOREGROUND | MB_TASKMODAL | MB_OK); -} - -void sleep(uint32 millisecond_count) -{ - Sleep(millisecond_count); -} - -#elif defined(PLATFORM_MAC_OSX) - -#elif defined(PLATFORM_LINUX) - -#endif \ No newline at end of file diff --git a/tnl-_next/crypto/asymmetric_key.h b/tnl-_next/crypto/asymmetric_key.h deleted file mode 100755 index cde5f56..0000000 --- a/tnl-_next/crypto/asymmetric_key.h +++ /dev/null @@ -1,245 +0,0 @@ -#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 - -class AsymmetricKey : public Object -{ -enum { - StaticCryptoBufferSize = 2048, -}; - - /// 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 U8 *bufferPtr, U32 bufferSize) - { - U8 staticCryptoBuffer[StaticCryptoBufferSize]; - mIsValid = false; - - crypto_key *theKey = (crypto_key *) MemoryAllocate(sizeof(crypto_key)); - mHasPrivateKey = bufferPtr[0] == KeyTypePrivate; - - 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); - mPrivateKey = new ByteBuffer((U8 *) bufferPtr, bufferSize); - } - else - { - mPublicKey = new ByteBuffer((U8 *) bufferPtr, bufferSize); - } - mIsValid = true; - } - - - - /// 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(dataPtr, bufferSize); - } - - /// Constructs an AsymmetricKey from a ByteBuffer. - AsymmetricKey(const ByteBuffer &theBuffer) : mKeyData(NULL) - { - load(theBuffer.getBuffer(), theBuffer.getBufferSize()); - } - - /// Constructs an AsymmetricKey by reading it from a BitStream. - AsymmetricKey(BitStream *theStream) - { - ByteBufferPtr theBuffer; - read(*theStream, &theBuffer); - load(theBuffer->getBuffer(), theBuffer->getBufferSize()); - } - - /// Generates a new asymmetric key of keySize bytes - AsymmetricKey(U32 keySize) - { - U8 staticCryptoBuffer[StaticCryptoBufferSize]; - mIsValid = false; - - int descriptorIndex = register_prng ( &yarrow_desc ); - crypto_key *theKey = (crypto_key *) MemoryAllocate(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); - - 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); - - mHasPrivateKey = true; - mIsValid = true; - } - - - - /// Destructor for the AsymmetricKey. - ~AsymmetricKey() - { - if(mKeyData) - { - crypto_free((crypto_key *) mKeyData); - MemoryDeallocate(mKeyData); - } - } - - - - /// 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) - { - if(publicKey->getKeySize() != getKeySize() || !mHasPrivateKey) - return NULL; - - U8 hash[32]; - unsigned long outLen = sizeof(staticCryptoBuffer); - U8 staticCryptoBuffer[StaticCryptoBufferSize]; - - 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); - - return new ByteBuffer(hash, 32); - } - - /// 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 U8 *buffer, U32 bufferSize) - { - int descriptorIndex = register_prng ( &yarrow_desc ); - - U8 hash[32]; - hash_state hashState; - U8 staticCryptoBuffer[StaticCryptoBufferSize]; - - sha256_init(&hashState); - sha256_process(&hashState, buffer, bufferSize); - 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); - } - - - /// Returns true if the private key associated with this AsymmetricKey - /// signed theByteBuffer with theSignature. - bool verifySignature(const U8 *signedBytes, U32 signedByteSize, const ByteBuffer &theSignature) - { - U8 hash[32]; - hash_state hashState; - - sha256_init(&hashState); - sha256_process(&hashState, signedBytes, signedBytesSize); - sha256_done(&hashState, hash); - - int stat; - - ecc_verify_hash(theSignature.getBuffer(), theSignature.getBufferSize(), hash, 32, &stat, (crypto_key *) mKeyData); - return stat != 0; - } - - -}; - -typedef RefPtr AsymmetricKeyPtr; - diff --git a/tnl-_next/crypto/certificate.h b/tnl-_next/crypto/certificate.h deleted file mode 100755 index c8cf524..0000000 --- a/tnl-_next/crypto/certificate.h +++ /dev/null @@ -1,150 +0,0 @@ -/// 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 Object -{ -protected: - ByteBufferPtr mCertificateData; ///< The full certificate data - 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) - { - ByteBufferPtr theData = new ByteBuffer(dataPtr, dataSize); - setCertificateData(theData); - } - - Certificate(ByteBufferPtr &buffer) - { - setCertificateData(buffer); - } - - Certificate(BitStream *stream) - { - ByteBufferPtr theBuffer; - read(*stream, &theBuffer); - setCertificateData(theBuffer); - } - Certificate(const ByteBufferPtr payload, RefPtr publicKey, RefPtr theCAPrivateKey) - { - mIsValid = false; - mSignatureByteSize = 0; - - if(payload->getBufferSize() > MaxPayloadSize || !publicKey->isValid()) - return; - - ByteBufferPtr thePublicKey = publicKey->getPublicKey(); - BitStream packet; - - write(packet, payload); - write(packet, thePublicKey); - mSignatureByteSize = packet.getBytePosition(); - packet.setBytePosition(mSignatureByteSize); - - mSignature = theCAPrivateKey->hashAndSign(packet.getBuffer(), packet.getBytePosition()); - write(packet, mSignature); - - mCertificateData = new ByteBuffer(packet.getBuffer(), packet.getBytePosition()); - } - - - /// Parses this certificate into the payload, public key, identiy, certificate authority and signature - void parse() - { - BitStream aStream(mCertificateData->getBuffer(), mCertificateData->getBufferSize()); - read(aStream, &mPayload); - - mPublicKey = new AsymmetricKey(&aStream); - - mSignatureByteSize = aStream.getBytePosition(); - - // advance the bit stream to the next byte: - aStream.setBytePosition(aStream.getBytePosition()); - - read(aStream, &mSignature); - - if(aStream.isValid() && mCertificateData->getBufferSize() == aStream.getBytePosition() && mPublicKey->isValid()) - mIsValid = true; - } - - /// Sets the full certificate from a ByteBuffer, and parses it. - void setCertificateData(ByteBufferPtr &theBuffer) - { - mCertificateData = theBuffer; - mSignatureByteSize = 0; - mIsValid = false; - parse(); - } - - /// Returns a ByteBufferPtr to the full certificate data - ByteBufferPtr getCertificateData() - { - return mCertificateData; - } - /// Returns a ByteBufferPtr to the full certificate data - const ByteBufferPtr getCertificateData() const - { - return mCertificateData; - } - - /// 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) - { - if(!mIsValid) - return false; - - return signatoryPublicKey->verifySignature(mCertificateData->getBuffer(), mSignatureByteSize, *mSignature); - } - - /// Returns the public key from the certificate - RefPtr getPublicKey() { return mPublicKey; } - - /// Returns the certificate payload - ByteBufferPtr getPayload() { return mPayload; } -}; - -inline void read(BitStream &str, Certificate *theCertificate) -{ - ByteBufferPtr theBuffer; - read(str, &theBuffer); - theCertificate->setCertificateData(theBuffer); -} - -inline void write(BitStream &str, const Certificate &theCertificate) -{ - write(str, theCertificate.getCertificateData()); -} - -inline void read(BitStream &str, RefPtr *theCertificate) -{ - read(str, theCertificate->getPointer()); -} - -inline void write(BitStream &str, const RefPtr &theCertificate) -{ - write(str, *theCertificate.getPointer()); -} diff --git a/tnl-_next/crypto/crypto.h b/tnl-_next/crypto/crypto.h deleted file mode 100755 index f6ba3ef..0000000 --- a/tnl-_next/crypto/crypto.h +++ /dev/null @@ -1,8 +0,0 @@ -/// crypto files - -#include "random_generator.h" -#include "symmetric_cipher.h" -//#include "asymmetric_key.h" -//#include "certificate.h" - - diff --git a/tnl-_next/crypto/random_generator.h b/tnl-_next/crypto/random_generator.h deleted file mode 100755 index c988f40..0000000 --- a/tnl-_next/crypto/random_generator.h +++ /dev/null @@ -1,63 +0,0 @@ -/// The Random class encapsulates a cryptographically secure -/// pseudo random number generator (PRNG). Internally the Random class -/// uses the Yarrow PRNG algorithm. -class random_generator -{ - prng_state _random_state; - uint32 _entropy_added; - - random_generator() - { - yarrow_start(&_random_state); - yarrow_ready(&_random_state); - _entropy_added = 0; - } - prng_state *get_state() - { - return &_random_state; - } - - /// Adds random "seed" data to the random number generator - void add_entropy(const uint8 *random_data, uint32 data_len) - { - yarrow_add_entropy(random_data, data_len, &_random_state); - _entropy_added += data_len; - if(_entropy_added >= 16) - { - yarrow_ready(&_random_state); - _entropy_added = 0; - } - } - - void random_buffer(uint8 *out_buffer, uint32 buffer_size) - { - yarrow_read(out_buffer, buffer_size, &_random_state); - } - - uint32 random_integer() - { - uint8 buffer[4]; - random_buffer(buffer, sizeof(buffer)); - return (uint32(buffer[0]) << 24) | (uint32(buffer[1]) << 16) | (uint32(buffer[2]) << 8) | uint32(buffer[3]); - } - - uint32 random_in_range(uint32 range_start, uint32 range_end) - { - assert(range_start <= range_end); - return (random_integer() % (range_end - range_start + 1)) + range_start; - } - - float32 random_unit_float() - { - return float32( float64(random_integer()) / float64(max_value_uint32) ); - } - - bool random_bool() - { - uint8 buffer; - random_buffer(&buffer, sizeof(buffer)); - - return buffer & 1; - } -}; - diff --git a/tnl-_next/crypto/symmetric_cipher.h b/tnl-_next/crypto/symmetric_cipher.h deleted file mode 100755 index eb45e81..0000000 --- a/tnl-_next/crypto/symmetric_cipher.h +++ /dev/null @@ -1,101 +0,0 @@ -/// Class for symmetric encryption of data across a connection. Internally it uses -/// the libtomcrypt AES algorithm to encrypt the data. - -class symmetric_cipher -{ - public: - enum { - block_size = 16, - key_size = 16, - }; - private: - struct key - { - uint32 e_k[64], d_k[64]; - int n_r; - }; - uint32 _counter[block_size >> 2]; - uint32 _init_vector[block_size]; - uint8 _pad[block_size]; - key _symmetric_key; - uint32 _pad_len; - public: - symmetric_cipher(const uint8 symmetric_key[key_size], const uint8 init_vector[block_size]) - { - rijndael_setup(symmetric_key, key_size, 0, (symmetric_key *) &_symmetric_key); - memcpy(_init_vector, init_vector, block_size); - memcpy(_counter, init_vector, block_size); - rijndael_ecb_encrypt((uint8 *) _counter, _pad, (symmetric_key *) &_symmetric_key); - _pad_len = 0; - } - - symmetric_cipher(const ByteBuffer *theByteBuffer) - { - if(theByteBuffer->getBufferSize() != key_size * 2) - { - uint8 buffer[key_size]; - memset(buffer, 0, key_size); - rijndael_setup(buffer, key_size, 0, (symmetric_key *) &_symmetric_key); - memcpy(_init_vector, buffer, block_size); - } - else - { - rijndael_setup(theByteBuffer->getBuffer(), key_size, 0, (symmetric_key *) &_symmetric_key); - memcpy(_init_vector, theByteBuffer->getBuffer() + key_size, block_size); - } - memcpy(_counter, _init_vector, block_size); - rijndael_ecb_encrypt((uint8 *) _counter, _pad, (symmetric_key *) &_symmetric_key); - _pad_len = 0; - } - - - void setupCounter(uint32 counterValue1, uint32 counterValue2, uint32 counterValue3, uint32 counterValue4) - { - for(uint32 i = 0; i < 4; i++) - { - _counter[i] = _init_vector[i]; - littleEndianToHost(_counter[i]); - } - _counter[0] += counterValue1; - _counter[1] += counterValue2; - _counter[2] += counterValue3; - _counter[3] += counterValue4; - - for(uint32 i = 0; i < 4; i++) - hostToLittleEndian(_counter[i]); - - rijndael_ecb_encrypt((uint8 *) _counter, _pad, (symmetric_key *) &_symmetric_key); - _pad_len = 0; - } - - void encrypt(const uint8 *plainText, uint8 *cipherText, uint32 len) - { - while(len-- > 0) - { - if(_pad_len == block_size) - { - // we've reached the end of the pad, so compute a new pad - rijndael_ecb_encrypt(_pad, _pad, (symmetric_key *) &_symmetric_key); - _pad_len = 0; - } - uint8 encryptedChar = *plainText++ ^ _pad[_pad_len]; - _pad[_pad_len++] = *cipherText++ = encryptedChar; - } - } - - - void decrypt(const uint8 *cipherText, uint8 *plainText, uint32 len) - { - while(len-- > 0) - { - if(_pad_len == block_size) - { - rijndael_ecb_encrypt(_pad, _pad, (symmetric_key *) &_symmetric_key); - _pad_len = 0; - } - uint8 encryptedChar = *cipherText++; - *plainText++ = encryptedChar ^ _pad[_pad_len]; - _pad[_pad_len++] = encryptedChar; - } - } -}; diff --git a/tnl-_next/libtomcrypt-1.17/Debug/BuildLog.htm b/tnl-_next/libtomcrypt-1.17/Debug/BuildLog.htm deleted file mode 100755 index c5a2a885dd1c5524371654525116cddf42d49cce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73034 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 Zug{PKKKry1e7=l6c%(0vA&0?^0RUDR9p?Z5 diff --git a/tnl-_next/libtomcrypt-1.17/Debug/vc90.idb b/tnl-_next/libtomcrypt-1.17/Debug/vc90.idb deleted file mode 100755 index 5a0e5364399bb2f37c3092185104ead35412bf83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 691200 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 |+T8?1|5pMtXk$yS1O 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

~m#pNEKS9>|TL$$k(G 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