diff --git a/source/etcpak/AUTHORS.txt b/source/etcpak/AUTHORS.txt deleted file mode 100644 index 73892f5fd..000000000 --- a/source/etcpak/AUTHORS.txt +++ /dev/null @@ -1,2 +0,0 @@ -Bartosz Taudul -Daniel Jungmann diff --git a/source/etcpak/LICENSE.txt b/source/etcpak/LICENSE.txt deleted file mode 100644 index 2254f9ece..000000000 --- a/source/etcpak/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2013, Bartosz Taudul -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/source/etcpak/include/ProcessRGB.h b/source/etcpak/include/ProcessRGB.h deleted file mode 100644 index 00b036d51..000000000 --- a/source/etcpak/include/ProcessRGB.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PROCESSRGB_H_ -#define PROCESSRGB_H_ - -#if !defined __cplusplus || __cplusplus < 201103L -# include -#else -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -uint64_t ProcessRGB( const uint8_t * src ); -uint64_t ProcessRGB_ETC2( const uint8_t * src ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/etcpak/src/Math.hpp b/source/etcpak/src/Math.hpp deleted file mode 100644 index 3945605f5..000000000 --- a/source/etcpak/src/Math.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef DARKRL__MATH_HPP__ -#define DARKRL__MATH_HPP__ - -#if defined __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wunused-parameter" -#endif -#include -#if defined __GNUC__ -# pragma GCC diagnostic pop -#endif - -#include "Types.hpp" - -template -inline T AlignPOT( T val ) -{ - if( val == 0 ) return 1; - val--; - for( unsigned int i=1; i> i; - } - return val + 1; -} - -inline int CountSetBits( uint32 val ) -{ - val -= ( val >> 1 ) & 0x55555555; - val = ( ( val >> 2 ) & 0x33333333 ) + ( val & 0x33333333 ); - val = ( ( val >> 4 ) + val ) & 0x0f0f0f0f; - val += val >> 8; - val += val >> 16; - return val & 0x0000003f; -} - -inline int CountLeadingZeros( uint32 val ) -{ - val |= val >> 1; - val |= val >> 2; - val |= val >> 4; - val |= val >> 8; - val |= val >> 16; - return 32 - CountSetBits( val ); -} - -inline float sRGB2linear( float v ) -{ - const float a = 0.055f; - if( v <= 0.04045f ) - { - return v / 12.92f; - } - else - { - return pow( ( v + a ) / ( 1 + a ), 2.4f ); - } -} - -inline float linear2sRGB( float v ) -{ - const float a = 0.055f; - if( v <= 0.0031308f ) - { - return 12.92f * v; - } - else - { - return ( 1 + a ) * pow( v, 1/2.4f ) - a; - } -} - -template -inline T SmoothStep( T x ) -{ - return x*x*(3-2*x); -} - -inline uint8 clampu8( int32 val ) -{ - return std::min( std::max( 0, val ), 255 ); -} - -template -inline T sq( T val ) -{ - return val * val; -} - -static inline int mul8bit( int a, int b ) -{ - int t = a*b + 128; - return ( t + ( t >> 8 ) ) >> 8; -} - -#endif diff --git a/source/etcpak/src/ProcessCommon.hpp b/source/etcpak/src/ProcessCommon.hpp deleted file mode 100644 index da2c43ecf..000000000 --- a/source/etcpak/src/ProcessCommon.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef PROCESSCOMMON_HPP__ -#define PROCESSCOMMON_HPP__ - -#include -#include - -#include "Types.hpp" - -template -static size_t GetLeastError( const T* err, size_t num ) -{ - size_t idx = 0; - for( size_t i=1; i> 24 ) | - ( ( d & 0x000000FF00000000 ) << 24 ) | - ( ( d & 0x00FF000000000000 ) >> 8 ) | - ( ( d & 0x0000FF0000000000 ) << 8 ); -} - -template -static uint64 EncodeSelectors( uint64 d, const T terr[2][8], const S tsel[16][8], const uint32* id ) -{ - size_t tidx[2]; - tidx[0] = GetLeastError( terr[0], 8 ); - tidx[1] = GetLeastError( terr[1], 8 ); - - d |= tidx[0] << 26; - d |= tidx[1] << 29; - for( int i=0; i<16; i++ ) - { - uint64 t = tsel[i][tidx[id[i]%2]]; - d |= ( t & 0x1 ) << ( i + 32 ); - d |= ( t & 0x2 ) << ( i + 47 ); - } - - return d; -} - -#endif diff --git a/source/etcpak/src/ProcessRGB.cpp b/source/etcpak/src/ProcessRGB.cpp deleted file mode 100644 index b4669d64a..000000000 --- a/source/etcpak/src/ProcessRGB.cpp +++ /dev/null @@ -1,470 +0,0 @@ -#include -#include - -#include "Math.hpp" -#include "ProcessCommon.hpp" -#include "ProcessRGB.h" -#include "Tables.hpp" -#include "Types.hpp" -#include "Vector.hpp" - -namespace -{ - -static inline uint32 byteswap(uint32 l) -{ - return ((l >> 8u) & 0xff00u) | ((l & 0xff00u) << 8u) | (l << 24u) | (l >> 24u); -} - -template -struct simple_array -{ - simple_array() - { - memset(data, 0, sizeof(data)); - } - - T operator [](size_t i) const - { - return data[i]; - } - T & operator [](size_t i) - { - return data[i]; - } - -protected: - T data[size]; -}; - -typedef simple_array v4i; - -void Average( const uint8* data, v4i* a ) -{ - uint32 r[4]; - uint32 g[4]; - uint32 b[4]; - - memset(r, 0, sizeof(r)); - memset(g, 0, sizeof(g)); - memset(b, 0, sizeof(b)); - - for( int j=0; j<4; j++ ) - { - for( int i=0; i<4; i++ ) - { - int index = (j & 2) + (i >> 1); - r[index] += *data++; - g[index] += *data++; - b[index] += *data++; - data++; - } - } - - a[0][0] = uint16( (r[2] + r[3] + 4) / 8 ); - a[0][1] = uint16( (g[2] + g[3] + 4) / 8 ); - a[0][2] = uint16( (b[2] + b[3] + 4) / 8 ); - a[0][3] = 0; - a[1][0] = uint16( (r[0] + r[1] + 4) / 8 ); - a[1][1] = uint16( (g[0] + g[1] + 4) / 8 ); - a[1][2] = uint16( (b[0] + b[1] + 4) / 8 ); - a[1][3] = 0; - a[2][0] = uint16( (r[1] + r[3] + 4) / 8 ); - a[2][1] = uint16( (g[1] + g[3] + 4) / 8 ); - a[2][2] = uint16( (b[1] + b[3] + 4) / 8 ); - a[2][3] = 0; - a[3][0] = uint16( (r[0] + r[2] + 4) / 8 ); - a[3][1] = uint16( (g[0] + g[2] + 4) / 8 ); - a[3][2] = uint16( (b[0] + b[2] + 4) / 8 ); - a[3][3] = 0; -} - -void CalcErrorBlock( const uint8* data, uint err[4][4] ) -{ - uint terr[4][4]; - - memset(terr, 0, 16 * sizeof(uint)); - - for( int j=0; j<4; j++ ) - { - for( int i=0; i<4; i++ ) - { - int index = (j & 2) + (i >> 1); - uint d = *data++; - terr[index][0] += d; - d = *data++; - terr[index][1] += d; - d = *data++; - terr[index][2] += d; - data++; - } - } - - for( int i=0; i<3; i++ ) - { - err[0][i] = terr[2][i] + terr[3][i]; - err[1][i] = terr[0][i] + terr[1][i]; - err[2][i] = terr[1][i] + terr[3][i]; - err[3][i] = terr[0][i] + terr[2][i]; - } - for( int i=0; i<4; i++ ) - { - err[i][3] = 0; - } -} - -uint CalcError( const uint block[4], const v4i& average ) -{ - uint err = 0x3FFFFFFF; // Big value to prevent negative values, but small enough to prevent overflow - err -= block[0] * 2 * average[0]; - err -= block[1] * 2 * average[1]; - err -= block[2] * 2 * average[2]; - err += 8 * ( sq( average[0] ) + sq( average[1] ) + sq( average[2] ) ); - return err; -} - -void ProcessAverages( v4i* a ) -{ - for( int i=0; i<2; i++ ) - { - for( int j=0; j<3; j++ ) - { - int32 c1 = mul8bit( a[i*2+1][j], 31 ); - int32 c2 = mul8bit( a[i*2][j], 31 ); - - int32 diff = c2 - c1; - if( diff > 3 ) diff = 3; - else if( diff < -4 ) diff = -4; - - int32 co = c1 + diff; - - a[5+i*2][j] = ( c1 << 3 ) | ( c1 >> 2 ); - a[4+i*2][j] = ( co << 3 ) | ( co >> 2 ); - } - } - - for( int i=0; i<4; i++ ) - { - a[i][0] = g_avg2[mul8bit( a[i][0], 15 )]; - a[i][1] = g_avg2[mul8bit( a[i][1], 15 )]; - a[i][2] = g_avg2[mul8bit( a[i][2], 15 )]; - } -} - -void EncodeAverages( uint64& _d, const v4i* a, size_t idx ) -{ - auto d = _d; - d |= ( idx << 24 ); - size_t base = idx << 1; - - if( ( idx & 0x2 ) == 0 ) - { - for( int i=0; i<3; i++ ) - { - d |= uint64( a[base+0][i] >> 4 ) << ( i*8 ); - d |= uint64( a[base+1][i] >> 4 ) << ( i*8 + 4 ); - } - } - else - { - for( int i=0; i<3; i++ ) - { - d |= uint64( a[base+1][i] & 0xF8 ) << ( i*8 ); - int32 c = ( ( a[base+0][i] & 0xF8 ) - ( a[base+1][i] & 0xF8 ) ) >> 3; - c &= ~0xFFFFFFF8; - d |= ((uint64)c) << ( i*8 ); - } - } - _d = d; -} - -uint64 CheckSolid( const uint8* src ) -{ - const uint8* ptr = src + 4; - for( int i=1; i<16; i++ ) - { - if( memcmp( src, ptr, 4 ) != 0 ) - { - return 0; - } - ptr += 4; - } - - return 0x02000000 | - ( uint( src[0] & 0xF8 ) ) | - ( uint( src[1] & 0xF8 ) << 8 ) | - ( uint( src[2] & 0xF8 ) << 16 ); -} - -void PrepareAverages( v4i a[8], const uint8* src, uint err[4] ) -{ - Average( src, a ); - ProcessAverages( a ); - - uint errblock[4][4]; - CalcErrorBlock( src, errblock ); - - for( int i=0; i<4; i++ ) - { - err[i/2] += CalcError( errblock[i], a[i] ); - err[2+i/2] += CalcError( errblock[i], a[i+4] ); - } -} - -void FindBestFit( uint64 terr[2][8], uint16 tsel[16][8], v4i a[8], const uint32* id, const uint8* data ) -{ - for( size_t i=0; i<16; i++ ) - { - uint16* sel = tsel[i]; - uint bid = id[i]; - uint64* ter = terr[bid%2]; - - uint8 r = *data++; - uint8 g = *data++; - uint8 b = *data++; - data++; - - int dr = a[bid][0] - r; - int dg = a[bid][1] - g; - int db = a[bid][2] - b; - - int pix = dr * 77 + dg * 151 + db * 28; - - for( int t=0; t<8; t++ ) - { - const int64* tab = g_table256[t]; - uint idx = 0; - uint64 err = sq( tab[0] + pix ); - for( int j=1; j<4; j++ ) - { - uint64 local = sq( tab[j] + pix ); - if( local < err ) - { - err = local; - idx = j; - } - } - *sel++ = idx; - *ter++ += err; - } - } -} - -uint8_t convert6(float f) -{ - int i = (std::min(std::max(static_cast(f), 0), 1023) - 15) >> 1; - return (i + 11 - ((i + 11) >> 7) - ((i + 4) >> 7)) >> 3; -} - -uint8_t convert7(float f) -{ - int i = (std::min(std::max(static_cast(f), 0), 1023) - 15) >> 1; - return (i + 9 - ((i + 9) >> 8) - ((i + 6) >> 8)) >> 2; -} - -std::pair Planar(const uint8* src) -{ - int32 r = 0; - int32 g = 0; - int32 b = 0; - - for (int i = 0; i < 16; ++i) - { - r += src[i * 4 + 0]; - g += src[i * 4 + 1]; - b += src[i * 4 + 2]; - } - - int32 difRyz = 0; - int32 difGyz = 0; - int32 difByz = 0; - int32 difRxz = 0; - int32 difGxz = 0; - int32 difBxz = 0; - - const int32 scaling[] = { -255, -85, 85, 255 }; - - for (int i = 0; i < 16; ++i) - { - int32 difR = (static_cast(src[i * 4 + 0]) << 4) - r; - int32 difG = (static_cast(src[i * 4 + 1]) << 4) - g; - int32 difB = (static_cast(src[i * 4 + 2]) << 4) - b; - - difRyz += difR * scaling[i % 4]; - difGyz += difG * scaling[i % 4]; - difByz += difB * scaling[i % 4]; - - difRxz += difR * scaling[i / 4]; - difGxz += difG * scaling[i / 4]; - difBxz += difB * scaling[i / 4]; - } - - const float scale = -4.0f / ((255 * 255 * 8.0f + 85 * 85 * 8.0f) * 16.0f); - - float aR = difRxz * scale; - float aG = difGxz * scale; - float aB = difBxz * scale; - - float bR = difRyz * scale; - float bG = difGyz * scale; - float bB = difByz * scale; - - float dR = r * (4.0f / 16.0f); - float dG = g * (4.0f / 16.0f); - float dB = b * (4.0f / 16.0f); - - // calculating the three colors RGBO, RGBH, and RGBV. RGB = df - af * x - bf * y; - float cofR = fma(aR, 255.0f, fma(bR, 255.0f, dR)); - float cofG = fma(aG, 255.0f, fma(bG, 255.0f, dG)); - float cofB = fma(aB, 255.0f, fma(bB, 255.0f, dB)); - float chfR = fma(aR, -425.0f, fma(bR, 255.0f, dR)); - float chfG = fma(aG, -425.0f, fma(bG, 255.0f, dG)); - float chfB = fma(aB, -425.0f, fma(bB, 255.0f, dB)); - float cvfR = fma(aR, 255.0f, fma(bR, -425.0f, dR)); - float cvfG = fma(aG, 255.0f, fma(bG, -425.0f, dG)); - float cvfB = fma(aB, 255.0f, fma(bB, -425.0f, dB)); - - // convert to r6g7b6 - int32 coR = convert6(cofR); - int32 coG = convert7(cofG); - int32 coB = convert6(cofB); - int32 chR = convert6(chfR); - int32 chG = convert7(chfG); - int32 chB = convert6(chfB); - int32 cvR = convert6(cvfR); - int32 cvG = convert7(cvfG); - int32 cvB = convert6(cvfB); - - // Error calculation - auto ro0 = coR; - auto go0 = coG; - auto bo0 = coB; - auto ro1 = (ro0 >> 4) | (ro0 << 2); - auto go1 = (go0 >> 6) | (go0 << 1); - auto bo1 = (bo0 >> 4) | (bo0 << 2); - auto ro2 = (ro1 << 2) + 2; - auto go2 = (go1 << 2) + 2; - auto bo2 = (bo1 << 2) + 2; - - auto rh0 = chR; - auto gh0 = chG; - auto bh0 = chB; - auto rh1 = (rh0 >> 4) | (rh0 << 2); - auto gh1 = (gh0 >> 6) | (gh0 << 1); - auto bh1 = (bh0 >> 4) | (bh0 << 2); - - auto rh2 = rh1 - ro1; - auto gh2 = gh1 - go1; - auto bh2 = bh1 - bo1; - - auto rv0 = cvR; - auto gv0 = cvG; - auto bv0 = cvB; - auto rv1 = (rv0 >> 4) | (rv0 << 2); - auto gv1 = (gv0 >> 6) | (gv0 << 1); - auto bv1 = (bv0 >> 4) | (bv0 << 2); - - auto rv2 = rv1 - ro1; - auto gv2 = gv1 - go1; - auto bv2 = bv1 - bo1; - - uint64 error = 0; - - for (int i = 0; i < 16; ++i) - { - int32 cR = clampu8((rh2 * (i / 4) + rv2 * (i % 4) + ro2) >> 2); - int32 cG = clampu8((gh2 * (i / 4) + gv2 * (i % 4) + go2) >> 2); - int32 cB = clampu8((bh2 * (i / 4) + bv2 * (i % 4) + bo2) >> 2); - - int32 difR = static_cast(src[i * 4 + 0]) - cR; - int32 difG = static_cast(src[i * 4 + 1]) - cG; - int32 difB = static_cast(src[i * 4 + 2]) - cB; - - int32 dif = difR * 38 + difG * 76 + difB * 14; - - error += dif * dif; - } - - /**/ - uint32 rgbv = cvB | (cvG << 6) | (cvR << 13); - uint32 rgbh = chB | (chG << 6) | (chR << 13); - uint32 hi = rgbv | ((rgbh & 0x1FFF) << 19); - uint32 lo = (chR & 0x1) | 0x2 | ((chR << 1) & 0x7C); - lo |= ((coB & 0x07) << 7) | ((coB & 0x18) << 8) | ((coB & 0x20) << 11); - lo |= ((coG & 0x3F) << 17) | ((coG & 0x40) << 18); - lo |= coR << 25; - - const auto idx = (coR & 0x20) | ((coG & 0x20) >> 1) | ((coB & 0x1E) >> 1); - - lo |= g_flags[idx]; - - uint64 result = static_cast(byteswap(lo)); - result |= static_cast(static_cast(byteswap(hi))) << 32; - - return std::make_pair(result, error); -} - -template -uint64 EncodeSelectors( uint64 d, const T terr[2][8], const S tsel[16][8], const uint32* id, const uint64 value, const uint64 error) -{ - size_t tidx[2]; - tidx[0] = GetLeastError( terr[0], 8 ); - tidx[1] = GetLeastError( terr[1], 8 ); - - if ((terr[0][tidx[0]] + terr[1][tidx[1]]) >= error) - { - return value; - } - - d |= tidx[0] << 26; - d |= tidx[1] << 29; - for( int i=0; i<16; i++ ) - { - uint64 t = tsel[i][tidx[id[i]%2]]; - d |= ( t & 0x1 ) << ( i + 32 ); - d |= ( t & 0x2 ) << ( i + 47 ); - } - - return FixByteOrder(d); -} -} - -uint64 ProcessRGB( const uint8* src ) -{ - uint64 d = CheckSolid( src ); - if( d != 0 ) return d; - - v4i a[8]; - uint err[4] = {}; - PrepareAverages( a, src, err ); - size_t idx = GetLeastError( err, 4 ); - EncodeAverages( d, a, idx ); - - uint64 terr[2][8] = {}; - uint16 tsel[16][8]; - auto id = g_id[idx]; - FindBestFit( terr, tsel, a, id, src ); - - return FixByteOrder( EncodeSelectors( d, terr, tsel, id ) ); -} - -uint64 ProcessRGB_ETC2( const uint8* src ) -{ - auto result = Planar( src ); - - uint64 d = 0; - - v4i a[8]; - uint err[4] = {}; - PrepareAverages( a, src, err ); - size_t idx = GetLeastError( err, 4 ); - EncodeAverages( d, a, idx ); - - uint64 terr[2][8] = {}; - uint16 tsel[16][8]; - auto id = g_id[idx]; - FindBestFit( terr, tsel, a, id, src ); - - return EncodeSelectors( d, terr, tsel, id, result.first, result.second ); -} - diff --git a/source/etcpak/src/Tables.cpp b/source/etcpak/src/Tables.cpp deleted file mode 100644 index 5b05288fb..000000000 --- a/source/etcpak/src/Tables.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "Tables.hpp" - -const int32 g_table[8][4] = { - { 2, 8, -2, -8 }, - { 5, 17, -5, -17 }, - { 9, 29, -9, -29 }, - { 13, 42, -13, -42 }, - { 18, 60, -18, -60 }, - { 24, 80, -24, -80 }, - { 33, 106, -33, -106 }, - { 47, 183, -47, -183 } -}; - -const int64 g_table256[8][4] = { - { 2*256, 8*256, -2*256, -8*256 }, - { 5*256, 17*256, -5*256, -17*256 }, - { 9*256, 29*256, -9*256, -29*256 }, - { 13*256, 42*256, -13*256, -42*256 }, - { 18*256, 60*256, -18*256, -60*256 }, - { 24*256, 80*256, -24*256, -80*256 }, - { 33*256, 106*256, -33*256, -106*256 }, - { 47*256, 183*256, -47*256, -183*256 } -}; - -const uint32 g_id[4][16] = { - { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2 }, - { 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4 }, - { 7, 7, 6, 6, 7, 7, 6, 6, 7, 7, 6, 6, 7, 7, 6, 6 } -}; - -const uint32 g_avg2[16] = { - 0x00, - 0x11, - 0x22, - 0x33, - 0x44, - 0x55, - 0x66, - 0x77, - 0x88, - 0x99, - 0xAA, - 0xBB, - 0xCC, - 0xDD, - 0xEE, - 0xFF -}; - -const uint32 g_flags[64] = { - 0x80800402, 0x80800402, 0x80800402, 0x80800402, - 0x80800402, 0x80800402, 0x80800402, 0x8080E002, - 0x80800402, 0x80800402, 0x8080E002, 0x8080E002, - 0x80800402, 0x8080E002, 0x8080E002, 0x8080E002, - 0x80000402, 0x80000402, 0x80000402, 0x80000402, - 0x80000402, 0x80000402, 0x80000402, 0x8000E002, - 0x80000402, 0x80000402, 0x8000E002, 0x8000E002, - 0x80000402, 0x8000E002, 0x8000E002, 0x8000E002, - 0x00800402, 0x00800402, 0x00800402, 0x00800402, - 0x00800402, 0x00800402, 0x00800402, 0x0080E002, - 0x00800402, 0x00800402, 0x0080E002, 0x0080E002, - 0x00800402, 0x0080E002, 0x0080E002, 0x0080E002, - 0x00000402, 0x00000402, 0x00000402, 0x00000402, - 0x00000402, 0x00000402, 0x00000402, 0x0000E002, - 0x00000402, 0x00000402, 0x0000E002, 0x0000E002, - 0x00000402, 0x0000E002, 0x0000E002, 0x0000E002 -}; diff --git a/source/etcpak/src/Tables.hpp b/source/etcpak/src/Tables.hpp deleted file mode 100644 index 46f5a36da..000000000 --- a/source/etcpak/src/Tables.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef TABLES_HPP__ -#define TABLES_HPP__ - -#include "Types.hpp" - -extern const int32 g_table[8][4]; -extern const int64 g_table256[8][4]; - -extern const uint32 g_id[4][16]; - -extern const uint32 g_avg2[16]; - -extern const uint32 g_flags[64]; - -#endif diff --git a/source/etcpak/src/Types.hpp b/source/etcpak/src/Types.hpp deleted file mode 100644 index c1971c77c..000000000 --- a/source/etcpak/src/Types.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DARKRL__TYPES_HPP__ -#define DARKRL__TYPES_HPP__ - -#if __cplusplus < 201103L -# include -#else -# include -#endif - -typedef int8_t int8; -typedef uint8_t uint8; -typedef int16_t int16; -typedef uint16_t uint16; -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; - -typedef unsigned int uint; - -#endif diff --git a/source/etcpak/src/Vector.hpp b/source/etcpak/src/Vector.hpp deleted file mode 100644 index 97fb2470a..000000000 --- a/source/etcpak/src/Vector.hpp +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef DARKRL__VECTOR_HPP__ -#define DARKRL__VECTOR_HPP__ - -#include -#include -#include - -#include "Math.hpp" -#include "Types.hpp" - -template -struct Vector2 -{ - Vector2() : x( 0 ), y( 0 ) {} - Vector2( T v ) : x( v ), y( v ) {} - Vector2( T _x, T _y ) : x( _x ), y( _y ) {} - - bool operator==( const Vector2& rhs ) const { return x == rhs.x && y == rhs.y; } - bool operator!=( const Vector2& rhs ) const { return !( *this == rhs ); } - - Vector2& operator+=( const Vector2& rhs ) - { - x += rhs.x; - y += rhs.y; - return *this; - } - Vector2& operator-=( const Vector2& rhs ) - { - x -= rhs.x; - y -= rhs.y; - return *this; - } - Vector2& operator*=( const Vector2& rhs ) - { - x *= rhs.x; - y *= rhs.y; - return *this; - } - - T x, y; -}; - -template -Vector2 operator+( const Vector2& lhs, const Vector2& rhs ) -{ - return Vector2( lhs.x + rhs.x, lhs.y + rhs.y ); -} - -template -Vector2 operator-( const Vector2& lhs, const Vector2& rhs ) -{ - return Vector2( lhs.x - rhs.x, lhs.y - rhs.y ); -} - -template -Vector2 operator*( const Vector2& lhs, const float& rhs ) -{ - return Vector2( lhs.x * rhs, lhs.y * rhs ); -} - -template -Vector2 operator/( const Vector2& lhs, const T& rhs ) -{ - return Vector2( lhs.x / rhs, lhs.y / rhs ); -} - - -typedef Vector2 v2i; -typedef Vector2 v2f; - - -template -struct Vector3 -{ - Vector3() : x( 0 ), y( 0 ), z( 0 ) {} - Vector3( T v ) : x( v ), y( v ), z( v ) {} - Vector3( T _x, T _y, T _z ) : x( _x ), y( _y ), z( _z ) {} - template - Vector3( const Vector3& v ) : x( T( v.x ) ), y( T( v.y ) ), z( T( v.z ) ) {} - - T Luminance() const { return T( x * 0.3f + y * 0.59f + z * 0.11f ); } - void Clamp() - { - x = std::min( T(1), std::max( T(0), x ) ); - y = std::min( T(1), std::max( T(0), y ) ); - z = std::min( T(1), std::max( T(0), z ) ); - } - - bool operator==( const Vector3& rhs ) const { return x == rhs.x && y == rhs.y && z == rhs.z; } - bool operator!=( const Vector2& rhs ) const { return !( *this == rhs ); } - - T& operator[]( uint idx ) { assert( idx < 3 ); return ((T*)this)[idx]; } - const T& operator[]( uint idx ) const { assert( idx < 3 ); return ((T*)this)[idx]; } - - Vector3 operator+=( const Vector3& rhs ) - { - x += rhs.x; - y += rhs.y; - z += rhs.z; - return *this; - } - - Vector3 operator*=( const Vector3& rhs ) - { - x *= rhs.x; - y *= rhs.y; - z *= rhs.z; - return *this; - } - - Vector3 operator*=( const float& rhs ) - { - x *= rhs; - y *= rhs; - z *= rhs; - return *this; - } - - T x, y, z; - T padding; -}; - -template -Vector3 operator+( const Vector3& lhs, const Vector3& rhs ) -{ - return Vector3( lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z ); -} - -template -Vector3 operator-( const Vector3& lhs, const Vector3& rhs ) -{ - return Vector3( lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z ); -} - -template -Vector3 operator*( const Vector3& lhs, const Vector3& rhs ) -{ - return Vector3( lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z ); -} - -template -Vector3 operator*( const Vector3& lhs, const float& rhs ) -{ - return Vector3( T( lhs.x * rhs ), T( lhs.y * rhs ), T( lhs.z * rhs ) ); -} - -template -Vector3 operator/( const Vector3& lhs, const T& rhs ) -{ - return Vector3( lhs.x / rhs, lhs.y / rhs, lhs.z / rhs ); -} - -template -bool operator<( const Vector3& lhs, const Vector3& rhs ) -{ - return lhs.Luminance() < rhs.Luminance(); -} - -typedef Vector3 v3i; -typedef Vector3 v3f; -typedef Vector3 v3b; - - -static inline v3b v3f_to_v3b( const v3f& v ) -{ - return v3b( uint8( std::min( 1.f, v.x ) * 255 ), uint8( std::min( 1.f, v.y ) * 255 ), uint8( std::min( 1.f, v.z ) * 255 ) ); -} - -template -Vector3 Mix( const Vector3& v1, const Vector3& v2, float amount ) -{ - return v1 + ( v2 - v1 ) * amount; -} - -template<> -inline v3b Mix( const v3b& v1, const v3b& v2, float amount ) -{ - return v3b( v3f( v1 ) + ( v3f( v2 ) - v3f( v1 ) ) * amount ); -} - -template -Vector3 Desaturate( const Vector3& v ) -{ - T l = v.Luminance(); - return Vector3( l, l, l ); -} - -template -Vector3 Desaturate( const Vector3& v, float mul ) -{ - T l = T( v.Luminance() * mul ); - return Vector3( l, l, l ); -} - -template -Vector3 pow( const Vector3& base, float exponent ) -{ - return Vector3( - pow( base.x, exponent ), - pow( base.y, exponent ), - pow( base.z, exponent ) ); -} - -template -Vector3 sRGB2linear( const Vector3& v ) -{ - return Vector3( - sRGB2linear( v.x ), - sRGB2linear( v.y ), - sRGB2linear( v.z ) ); -} - -template -Vector3 linear2sRGB( const Vector3& v ) -{ - return Vector3( - linear2sRGB( v.x ), - linear2sRGB( v.y ), - linear2sRGB( v.z ) ); -} - -#endif diff --git a/source/kenbuild/buildlic.txt b/source/kenbuild/buildlic.txt deleted file mode 100644 index 3a3985bb6..000000000 --- a/source/kenbuild/buildlic.txt +++ /dev/null @@ -1,71 +0,0 @@ -BUILD SOURCE CODE LICENSE TERMS: 06/20/2000 - -[1] I give you permission to make modifications to my Build source and - distribute it, BUT: - -[2] Any derivative works based on my Build source may be distributed ONLY - through the INTERNET. - -[3] Distribution of any derivative works MUST be done completely FREE of - charge - no commercial exploitation whatsoever. - -[4] Anything you distribute which uses a part of my Build Engine source - code MUST include: - - [A] The following message somewhere in the archive: - - // "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman - // Ken Silverman's official web site: "http://www.advsys.net/ken" - // See the included license file "BUILDLIC.TXT" for license info. - - [B] This text file "BUILDLIC.TXT" along with it. - - [C] Any source files that you modify must include this message as well: - - // This file has been modified from Ken Silverman's original release - -[5] The use of the Build Engine for commercial purposes will require an - appropriate license arrangement with me. Contact information is - on my web site. - -[6] I take no responsibility for damage to your system. - -[7] Technical support: Before contacting me with questions, please read - and do ALL of the following! - - [A] Look through ALL of my text files. There are 7 of them (including this - one). I like to think that I wrote them for a reason. You will find - many of your answers in the history section of BUILD.TXT and - BUILD2.TXT (they're located inside SRC.ZIP). - - [B] If that doesn't satisfy you, then try going to: - - "http://www.advsys.net/ken/buildsrc" - - where I will maintain a Build Source Code FAQ (or perhaps I might - just provide a link to a good FAQ). - - [C] I am willing to respond to questions, but ONLY if they come at a rate - that I can handle. - - PLEASE TRY TO AVOID ASKING DUPLICATE QUESTIONS! - - As my line of defense, I will post my current policy about - answering Build source questions (right below the E-mail address - on my web site.) You can check there to see if I'm getting - overloaded with questions or not. - - If I'm too busy, it might say something like this: - - I'm too busy to answer Build source questions right now. - Sorry, but don't expect a reply from me any time soon. - - If I'm open for Build source questions, please state your question - clearly and don't include any unsolicited attachments unless - they're really small (like less than 50k). Assume that I have - a 28.8k modem. Also, don't leave out important details just - to make your question appear shorter - making me guess what - you're asking doesn't save me time! - ----------------------------------------------------------------------------- --Ken S. (official web site: http://www.advsys.net/ken) diff --git a/source/kenbuild/rsrc/build.bmp b/source/kenbuild/rsrc/build.bmp deleted file mode 100644 index 6800c5365..000000000 Binary files a/source/kenbuild/rsrc/build.bmp and /dev/null differ diff --git a/source/kenbuild/rsrc/build.xcf b/source/kenbuild/rsrc/build.xcf deleted file mode 100644 index a1ddd6d4e..000000000 Binary files a/source/kenbuild/rsrc/build.xcf and /dev/null differ diff --git a/source/kenbuild/rsrc/build_icon.c b/source/kenbuild/rsrc/build_icon.c deleted file mode 100644 index 16ca3e1f8..000000000 --- a/source/kenbuild/rsrc/build_icon.c +++ /dev/null @@ -1,2350 +0,0 @@ -/* GIMP RGBA C-Source image dump (build_icon.c) */ - -#include "sdl_inc.h" -#include "sdlappicon.h" - -static Uint8 sdlappicon_pixels[] = { - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0hgg\7\230\227\2274\316\316\316v\335\335\335" - "\267\327\327\327\321~\177\203\235\200\201\206+\217\217\221\3\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0baa\10\231\231\2310\314" - "\314\314p\335\334\334\261\344\343\343\353\361\360\360\377\354\352\352\377" - "\347\345\345\377\347\345\345\377\204\205\211\364\204\205\212\371\217\220" - "\223\304\220\220\222f\220\220\222\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0CCC\7\233\233\233,\313" - "\312\312l\334\334\334\255\345\344\344\345\360\356\356\376\354\353\353\377" - "\350\346\346\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\341\337\337\375~\177\203\360\244\245\251\377\302\303\305\374\221" - "\221\223\377\220\220\222\222\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0,,,\5\233\233\233)\310\310\310g\333\333\333\250\346\345\345\341" - "\356\355\355\375\355\353\353\377\350\346\346\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\335\333\333\372z{\200\366ifh\377iee\374" - "\220\220\222\377\220\220\222\313\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\7\7\2\221\221" - "\221%\306\306\306b\333\333\333\243\345\344\344\337\356\355\355\374\356\354" - "\354\377\351\347\347\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\327\325\325\370yz\177\364vtu\377urr\376\220\220\222\377\220\220\222\271" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1" - "~}}\40\305\305\305]\334\334\334\236\343\343\343\335\356\355\355\373\356\355" - "\355\377\351\347\347\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\311\307" - "\310\364|}\202\371\260\261\263\377\263\264\266\372\220\220\222\377\220\220" - "\222\244\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0a``\31\302\302\302X\334\333" - "\333\231\342\342\342\332\360\357\357\373\356\355\355\377\351\347\347\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\300\277\300\357~\177\204\377_[[\377rpp\376" - "\220\220\222\377\220\220\222\216\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0???\2rrr\27\276\276\276S\332\332\332\224" - "\342\341\341\325\360\357\357\375\357\356\356\377\351\350\350\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\345\343\343\377\326\324" - "\324\377\322\321\321\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\270\266\267\353~\177\204\377roo\377}{|\373\220\220\222\377" - "\220\220\222x\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\30\30\30\1\205\204\204" - "\25\273\273\273O\331\331\331\220\343\342\342\317\355\354\354\373\360\357" - "\357\377\352\350\350\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\340\336\336\377\276\274\274\377\221\220\220\377YXX\377///\377\24" - "\24\24\377\240\237\237\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\253\252\254\355\202\203\210\377\302\304\306\377\250\250" - "\252\376\220\220\222\377\220\220\222c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\6\6\6\1\207\207\207\24\271\271" - "\271J\331\330\330\213\343\343\343\312\353\352\352\370\361\357\357\377\353" - "\351\351\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\346\344\344\377\331" - "\327\327\377\256\255\255\377{zz\377KKK\377***\377\17\17\17\377\31\31\31\377" - "\14\14\14\377\14\14\14\377\4\4\4\377\234\232\232\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\244\243\245\355zz\177\377ZU" - "T\377\177}\177\374\220\220\222\377\220\220\222M\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0vuu\22\270\270\270E\330\330\330\206\343\342" - "\342\306\353\353\353\364\361\360\360\377\353\352\352\377\350\346\346\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\345\343\343\377\317\315\315\377\240\237\237\377" - "kjj\377@@@\377\"\"\"\377\17\17\17\377\30\30\30\377\12\12\12\377\16\16\16" - "\377\0\0\0\377\14\14\14\377\0\0\0\377\12\12\12\377\3\3\3\377\272\271\271" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\231" - "\231\233\352|}\201\377kgg\377\205\204\206\376\220\220\222\377\220\220\222" - "7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\\\\\\\16\266\266\266A\327\327\327\201\342\342\342" - "\302\355\354\354\361\361\360\360\377\354\352\352\377\350\346\346\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\343\341\341\377\304\302\302\377\226\250\225\377hhg\377" - ";;;\377\26\26\26\377\24\24\24\377\21\21\21\377\12\12\12\377\11\11\11\377" - "\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\4\4\4\377\25\25\25\377\16" - "\16\16\377\31\31\31\377\16\16\16\377\324\322\322\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\215\215\220\355\217\220\224" - "\377\305\306\310\374\231\232\234\375\220\220\222\377\220\220\222\"\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""888\11\261\261" - "\261<\326\326\326|\342\342\342\275\354\354\354\360\361\360\360\376\354\353" - "\353\377\350\346\346\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\337\335\335\377\267\265" - "\265\377\205\204\204\377MMM\377000\377\22\22\22\377\32A\32\377')'\377&&&" - "\377\3\3\3\377\12\12\12\377\2\2\2\377\5\5\5\377\7\7\7\377\10\10\10\377\26" - "\26\26\377\17\17\17\377\31\31\31\377\13\13\13\377\17\17\17\377\0\0\0\377" - "\14\14\14\377\0\0\0\377\324\322\322\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\346\344\344\377\207\207\213\353rqt\377]XW\376\214\213\215\376" - "\220\220\222\376\220\220\222\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\32\32\32\5" - "\246\245\2457\324\324\324w\342\342\342\270\353\352\352\360\361\360\360\376" - "\355\353\353\377\350\346\346\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\332\330\330\377" - "\250\247\247\377vuu\377@@@\377\37\37\37\377\17\17\17\377\27\27\27\377\11" - "\11\11\377\15\15\15\377\0\0\0\377\13\13\13\377\0\0\0\377\22\22\22\377\37" - "\37\37\377---\377\26\26\26\377\25\25\25\377\21\21\21\377\14\14\14\377\11" - "\11\11\377\2\2\2\377\12\12\12\377\0\0\0\377\14\15\14\377\1\1\1\377\33\33" - "\33\377888\377\340\336\336\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\343\341\341\376\177\177\203\351|{~\377spo\376\216\216\217\377\220\220" - "\222\360\220\220\222\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0rrr\5\240\237\2372\324\323\323s\342\342\342\263\351" - "\350\350\360\363\362\362\377\355\354\354\377\350\346\346\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\344" - "\342\342\377\320\316\316\377\231\230\230\377fff\377433\377\27\27\27\377\17" - "\17\17\377\26\26\26\377\6\6\6\377\13\13\13\377\0\0\0\377\13\13\13\377\0\0" - "\0\377\14\14\14\377\6\6\6\377\27\27\27\377\16\16\16\377\27\27\27\377\15\15" - "\15\377\20\20\20\377\26\26\26\377&&&\377\22\22\22\377\7\12\7\377\5\6\5\377" - "\6\6\6\377\14\14\14\377\16)\16\377-R-\377---\377&&&\377+++\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\340\336\336\373yz~\361" - "\233\234\237\377\275\276\300\372\222\222\224\377\220\220\222\335\220\220" - "\222\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0qqq\7\241\241\241-\322\322" - "\322m\342\342\342\256\350\350\350\352\363\362\362\377\356\355\355\377\351" - "\347\347\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\336\334\334\377\272\270\270\377\214\212\212\377YXX\377" - "+**\377\25\25\25\377\16\16\16\377\24\24\24\377\4\4\4\377\12\12\12\377\0\0" - "\0\377\12\12\12\377\0\0\0\377\15\15\15\377\11\11\11\377\27\27\27\377\16\16" - "\16\377\26\26\26\377\11\11\11\377\14\14\14\377\0\0\0\377\13\13\13\377\0\0" - "\0\377\13\13\13\377\0\0\0\377\16\16\16\377\32\32\32\3771_1\377\17\34\17\377" - "\26\26\26\377\14\14\14\377\16\20\16\377\30\31\30\377\0\0\0\377\15\15\15\377" - "'''\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\332" - "\330\330\371xy~\357hfg\377b^]\377\220\220\222\377\220\220\222\312\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0RRR\6\244\244\244*\321\320\320i\341\341\341\252\351\351\351\344\362" - "\362\362\376\357\355\355\377\351\347\347\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\346\344\344\377\327\325\325\377\253" - "\250\250\377\207||\377_OG\377/E\40\377\20\20\20\377\22\22\22\377\20\20\20" - "\377\4\4\4\377\12\12\12\377\0\0\0\377\12\12\12\377\1\1\1\377\17\17\17\377" - "\14\14\14\377\27\27\27\377\16\16\16\377\24\24\24\377\5\5\5\377\13\13\13\377" - "\0\0\0\377\13\13\13\377\0\0\0\377\13\13\13\377\2\2\2\377\22\22\22\377\15" - "\15\15\377\30\30\30\377\16\16\16\377\33\33\33\377\37\37\37\377\17\22\17\377" - "\1\1\1\377\13\13\13\377\1\1\1\377\26\26\26\377\17\17\17\377\4\4\4\377\25" - "\25\25\377baa\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\314\312\313\363|}\202\363zyz\377wtt\373\220\220\222\377\220\220" - "\222\264\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0///\4\245" - "\244\244&\316\316\316d\341\341\341\245\352\351\351\340\361\360\360\375\357" - "\356\356\377\352\350\350\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\344\342\342\377\314\314\312\377\241\240\231\377~oo\377" - "V==\3779\36\36\377'\15\15\377%\23\23\377\13\11\7\377\11\20\11\377\5\5\5\377" - "\4\4\4\377\11\11\11\377\4\4\4\377\22\22\22\377\15\15\15\377\26\26\26\377" - "\15\15\15\377\22\22\22\377\2\2\2\377\13\13\13\377\0\0\0\377\13\13\13\377" - "\0\0\0\377\13\13\13\377\5\5\5\377\25\25\25\377\17\17\17\377\30\30\30\377" - "\14\14\14\377\21\21\21\377\1\1\1\377\13\13\13\377\14\14\14\377!!!\377\1\1" - "\1\377\14\14\14\377\3\3\3\377\23\23\23\377\16\16\16\377***\377\24\24\24\377" - "\14\14\14\377\17\17\17\377]\\\\\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\304\303\303\355~\177\204\376\256\257\262\377\264" - "\265\266\374\220\220\222\377\220\220\222\237\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\21\21" - "\21\2\236\235\235#\315\315\315_\341\341\341\240\351\351\351\335\360\360\360" - "\374\360\357\357\377\352\350\350\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\341\337\337\377\300\276\276\377\217\216\216" - "\377XWW\377766\377\25#\23\377$&\15\377\36\21\21\377\10\5\5\377\12\12\12\377" - "\0\0\0\377\12\12\12\377\2\2\2\377\16\16\16\377\22\22\22\377\20\20\20\377" - "\26\26\26\377\13\13\13\377\16\16\16\377\0\0\0\377\12\12\12\377\0\0\0\377" - "\13\13\13\377\0\0\0\377\15\15\15\377\12\12\12\377\26\26\26\377\16\16\16\377" - "\27\27\27\377\12\12\12\377\14\14\14\377\2\2\2\377\11\11\11\377\0\0\0\377" - "\13\13\13\377\0\0\0\377\40\40\40\377\30\30\30\377\27\27\27\377\16\16\16\377" - "\30\30\30\377\14\14\14\377\21\21\21\377\1\1\1\377###\377\2\2\2\377\3\3\3" - "\377\12\12\12\377onn\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\274\272\273\346~\177\204\377`\\\\\377pmm\374\220\220\222" - "\377\220\220\222\211\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\214\214\214\36\314\313\313Z\341\340\340\233\350\350" - "\350\333\361\360\360\372\360\357\357\377\353\351\351\377\347\346\346\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\335\333\333\377\264\262" - "\262\377|{{\377POO\377)))\377\22\22\22\377\24\24\24\377\10\10\10\377\13\13" - "\13\377\5\5\5\377\5\5\5\377\11\11\11\377\2\2\2\377\21\21\21\377\15\15\15" - "\377\25\25\25\377\17\17\17\377\16\16\16\377\13\13\13\377\1\1\1\377\12\12" - "\12\377\0\0\0\377\12\12\12\377\1\1\1\377\21\21\21\377\14\14\14\377\26\26" - "\26\377\17\17\17\377\22\22\22\377\11\11\12\377\12\12\12\377\1\1\1\377\12" - "\12\12\377\2\2\2\377\11\11\11\377\5\5\5\377\15\15\15\377\16\16\16\377\31" - "\31\31\377%%%\377\35\35\35\377\7\7\7\377\15\15\15\377\0\0\0\377\14\14\14" - "\377\0\0\0\377\14\14\14\377\0\0\0\377%%%\377\5\5\5\377\21\21\21\377\25\25" - "\25\377\230\227\227\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\257\256\260\347\177\200\204\377\207\205\206\377\207\206\207" - "\377\220\220\222\377\220\220\222t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "tss\30\312\311\311V\340\340\340\226\350\347\347\327\362\362\362\372\361\360" - "\360\377\353\351\351\377\347\346\346\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\327\325\325\377\244\242\242\377qpp\377???\377\36\36\36\377" - "\25\25\25\377\14\14\14\377\15\15\15\377\10\10\10\377\2\2\2\377\11\11\11\377" - "\0\0\0\377\15\15\15\377\21\21\21\377\17\17\17\377\25\25\25\377\13\13\13\377" - "\15\15\15\377\1\1\1\377\12\12\12\377\5\5\5\377\5\5\5\377\16\12\12\377\30" - "\5\4\377\35""3\16\377\15\15\15\377\26\26\26\377\15\15\15\377\21\21\22\377" - "\25\25\33\377;;L\377WWr\377ww\232\377ss\226\37799J\377\10\10\11\377\23\23" - "\23\377\21\21\21\377\24\24\24\377\24\24\24\377\14\14\14\377\14\14\14\377" - "\40\40\40\377\4\4\4\377\13\13\13\377\0\0\0\377\13\13\13\377\0\0\0\377\20" - "\20\20\377\15\15\15\377\30\30\30\377\17\17\17\377///\377\12\12\12\377\11" - "\11\11\377\5\5\5\377\225\223\223\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\247\247\250\352\200\201\205\377\247\247\251" - "\377\241\241\243\374\220\220\222\377\220\220\222^\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\27\27\27" - "\2\314\314\314\210\345\345\345\330\363\362\362\374\362\360\360\377\354\352" - "\352\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\344\342\342\377" - "\313\312\312\377\231\224\224\377p^^\377Q77\377*:\22\377\15\17\14\377\22\22" - "\22\377\10\10\10\377\4\4\4\377\11\11\11\377\2\2\2\377\10\10\10\377\17\17" - "\17\377\15\15\15\377\25\25\25\377\16\16\16\377\20\20\20\377\12\12\12\377" - "\0\0\0\377\11\11\11\377\0\2\0\377\12\21\10\377\21\3\3\377*\17\17\377.\22" - "\22\377*\17\17\377+\24\24\377\32\13\11\377!\26\12\377\0\0\0\377\30\30\35" - "\377SSo\377qq\224\377\206\206\260\377\214\214\267\377\213\213\265\377\213" - "\213\266\377\216\216\270\377\217\217\272\377DDT\377\5\5\5\377\6\6\6\377\5" - "\5\5\377\11\11\11\377\20\20\20\377\35\35\35\377\4\4\4\377\7\7\7\377\24\24" - "\24\377\20\20\20\377\27\27\27\377\17\17\17\377\24\24\24\377\2\2\2\377\14" - "\14\14\377\0\0\0\377&&&\377\0\0\0\377\12\12\12\377\3\3\3\377\256\254\254" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\234" - "\234\236\344{{\200\377ZUT\377|{|\377\220\220\222\377\220\220\222H\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0rqq3\353\352\352\377\350\346\346\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\346\344\344" - "\377\335\334\333\377\275\273\273\377\207\206\206\377djQ\377=$$\377*\21\21" - "\377(\22\22\377\23\13\13\377\7\7\7\377\10\10\10\377\0\0\0\377\11\11\11\377" - "\12\12\12\377\14\14\14\377\24\24\24\377\20\20\20\377\20\20\20\377\15\15\15" - "\377\0\0\0\377\11\11\11\377\2\2\2\377\7\7\7\377\12\12\12\377\6\6\6\377\24" - "\24\24\377\21\33\13\3774#\15\377\37\21\22\377\21\21\23\377))3\377\17\17\23" - "\377\16\12\12\377\16\0\0\377\36\12\12\377\2\2\2\377,,6\377dd\206\377xx\237" - "\377\216\216\272\377\217\217\275\377\213\213\267\377\227\227\307\377\233" - "\233\314\377\234\234\314\377\203\203\252\377\4\4\5\377\12\12\12\377\7\7\7" - "\377\31E\31\377,1,\377\30\30\30\377\17\17\17\377\21\21\21\377\6\6\6\377\3" - "\3\3\377\11\11\11\377\0\0\0\377\14\14\14\377\0\0\0\377\16\16\16\377\7\7\7" - "\377...\377\17\17\17\377\31\31\31\377\17\17\17\377\316\314\314\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\221\221\224\347" - "\203\203\210\377\220\217\217\377\215\214\216\377\220\220\222\377\220\220" - "\2223\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\234\232\232S\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\345\343\343\377\323\322\322\377\256\255\255\377xww\377M" - "LL\3770Q/\377\20\20\20\377\16\16\16\377\14\32\13\377\3\3\3\377\5\5\5\377" - "\10\10\10\377\6\6\6\377\13\13\13\377\23\23\23\377\15\15\15\377\23\23\23\377" - "\21\21\21\377\2\2\2\377\11\11\11\377\6\6\6\377\3\3\3\377\11\11\11\377\4\4" - "\4\377\22\22\22\377\21\21\21\377\21\21\21\377\24\24\24\377\15\15\17\377#" - "#,\377\34\20\24\377'\27\34\377]\\{\377~~\245\377\216\216\273\377%$-\377\"" - "\22\22\377\22\15\15\377$\24\24\377\14\14\14\377//;\377ii\213\377\224\224" - "\302\377oo\221\37744D\377\"\"+\377==P\377\210\210\262\377\235\235\316\377" - "\240\240\321\377\31\31\35\377\26\26\26\377\12\12\12\377\14\30\14\377\13\13" - "\13\377&&&\377\27\27\27\377\15\15\15\377\1\1\1\377\7\7\7\377\17\17\17\377" - "\17\17\17\377\27\27\27\377\17\17\17\377\27\27\27\377\10\10\10\377%%%\377" - "\0\0\0\377\15\15\15\377\0\0\0\377\315\313\313\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\346\344\344\377\212\212\215\347\204\205\211\377" - "\245\245\246\375\226\226\230\375\220\220\222\377\220\220\222\35\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\253\251\251i\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\343\341\341\377\310\307\307\377\230\227\227\377nmm\377999\377\32" - "\32\32\377\22\22\22\377\17\17\17\377\33\33\33\377\12\14\12\377\6\6\6\377" - "\2\2\2\377\14\14\14\377\16\16\16\377\16\16\16\377\23\23\23\377\20\20\20\377" - "\10\10\10\377\11\11\11\377\2\2\2\377\6\6\6\377\10\24\10\377\2\2\2\377\20" - "\20\20\377\22\22\22\377\16\16\16\377\24\24\24\377\14\14\15\377\37\37%\377" - "\34\34!\377\10\10\12\377VVq\377vv\233\377\217\217\273\377<,7\377-)2\377d" - "d\206\377\201\201\252\377\214\214\270\377&\30\36\377\16\12\12\377\13\2\2" - "\377\24\11\11\377\4\4\4\377\14\14\16\377dd\203\377\230\230\306\377@@O\377" - "\17\17\17\377\27\27\27\377\15\15\15\377WWq\377\234\234\315\377\224\224\301" - "\377\12\12\15\377\13\13\13\377\0\0\0\377\14\14\14\377\4\4\4\377\23\23\23" - "\377\25\25\25\377///\377(((\377\30\30\30\377\12\12\12\377\5\5\5\377\10\10" - "\10\377\2\2\2\377\12\12\12\377\1\1\1\377$$$\377\0\0\0\377\16\16\16\377\35" - "\35\35\377\341\337\337\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\345\343\343\376\177\200\203\342sru\377YTS\377\211\211\212\377\220\220\222" - "\371\220\220\222\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\265\264\264\200\347\345\345\377\347\345" - "\345\377\306\304\304\377a``\377100\377\22\22\22\377\22\22\22\377\17\17\17" - "\377\4\4\4\377\6\6\6\377\15\15\15\377\30\30\30\377\13\13\13\377\22\22\22" - "\377\22\22\22\377\14\14\14\377\17\17\17\377\12\12\12\377\0\0\0\377\10\10" - "\10\377\10\7\7\377\11\2\2\377\40\15\15\377(\17\17\377*\17\17\377*+\14\377" - "\14\14\15\377\25\25\27\377\12\12\12\377\0\0\0\377CCW\377jj\215\377\216\216" - "\273\377II\\\377\27\27\34\377dd\205\377}}\245\377\216\216\273\3775#*\377" - "$#-\377jj\214\377\227\227\306\377XRh\377\16\5\6\377\12\12\12\377\26\10\10" - "\377\30\21\21\377\24\24\24\377\20\20\20\377uu\230\377\224\224\302\377//:" - "\377\0\0\0\377\13\13\13\377\0\0\0\37777D\377\233\233\313\377\253\253\340" - "\37755D\377\27\27\27\377\16\16\16\377\27\27\27\377\13\13\13\377\20\20\20" - "\377\1\1\1\377\13\13\13\377\5\5\5\377$$$\377\37\37\37\377\15\33\15\377\5" - "\14\5\377\11\11\11\377\21\21\21\377\21\21\21\377---\377\17\17\17\377\27\27" - "\27\377$$$\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\343\341\341\375xy}\351\210\210\213\377\214\212\212\377\217\217\220\377" - "\220\220\222\351\220\220\222\10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\275\275\236\347\345\345" - "\377\347\345\345\377nmm\377\14\14\14\377\10\10\10\377\1\1\1\377\7\7\7\377" - "\13\13\13\377\16\16\16\377\26\26\26\377\40\40\40\377\21\21\21\377\6\6\6\377" - "\11\11\11\377\10\10\10\377\0\0\0\377\10\10\10\377\13\13\13\377\12\22\10\377" - "&'\14\377+\22\22\377\35\14\14\377\24\16\16\377\12\12\12\377#\24\32\377VN" - "f\377vv\233\377hh\210\377\15\15\16\377\13\13\13\377WWs\377ss\231\377\222" - "\222\300\377;;K\377\24\24\33\377ff\207\377\225\225\303\377SSl\377!\15\17" - "\377\4\4\4\377kk\214\377\226\226\303\3776B.\377\17\17\17\377\23\23\23\377" - "\36\15\15\377\12\6\6\377\11\11\11\377\2\2\2\377||\244\377\215\215\272\377" - "\"\"*\377\6\6\6\377\25\25\25\377\16\16\16\377KK]\377\226\226\304\377\245" - "\245\331\377\35\35&\377\13\13\13\377\0\0\0\377\13\13\13\377\0\0\0\377\13" - "\13\13\377\0\0\0\377\14\14\14\377\7\7\7\377\27\27\27\377\27\27\27\3770S0" - "\377\20\33\20\377\22\22\22\377\7\7\7\377\14\14\14\377\32\32\32\377\0\0\0" - "\377\15\15\15\377&&&\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\335\333\333\373wx|\350\215\215\220\377\246\246\247\370\222" - "\222\224\376\220\220\222\331\220\220\222\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\303\301\301\260" - "\347\345\345\377\347\345\345\377NNN\377\15\15\15\377\21\21\21\377\15\15\15" - "\377\21\21\21\377\17\17\17\377\22\22\22\377\20\20\20\377\10\10\10\377\10" - "\10\10\377\1\1\1\377\16\16\16\377\23\23\23\377\15\15\15\377\22\22\22\377" - "\23\23\23\377\35\33\40\377Q=L\377WWp\37788I\377\25\25\32\377\22\11\11\377" - "5/=\377ff\211\377\211\211\264\377``~\377\21\21\21\377\5\5\5\377QQk\377\215" - "\215\271\377kk\215\377\24\24\30\377\2\2\3\377aa}\377\227\227\305\377--8\377" - "'\23\23\377\15\15\16\377yy\236\377\217\217\272\377$\33\36\377\20\4\4\377" - "\6\6\6\377\33\10\10\377\4\3\3\377\20\20\20\377\21\21\22\377\210\210\263\377" - "\212\212\264\377\"\"'\377\7\7\7\377\14\14\14\377\0\0\0\377SSj\377\232\232" - "\311\377\213\213\270\377\12\12\15\377\13\13\13\377\2\2\2\377\24\24\24\377" - "\16\16\16\377\30\30\30\377\17\17\17\377\27\27\27\377\7\7\7\377\32\32\32\377" - "\27\27\27\377\13\13\13\377\1\1\1\377\12\12\12\377\2\2\2\377\25\25\25\377" - "\17\17\17\377\3\3\3\377\26\26\26\377[ZZ\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\317\315\315\363|}\202\354jgi\377`\\[\377" - "\220\220\222\377\220\220\222\306\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\307\307\317" - "\347\345\345\377\346\344\344\377HGG\377\14\14\14\377\10\10\10\377\4\4\4\377" - "\4\5\4\377\22\34\22\377\30\30\30\377\13\13\13\377\22\22\22\377\23\23\23\377" - "\15\15\15\377\12\12\12\377\11\11\11\37766F\377WWr\377||\243\377\216\216\271" - "\377\214\214\267\377\213\213\266\377\221\221\275\377qn\220\377\36\22\22\377" - "..=\377wv\234\377\221\221\276\377((5\377\11\11\11\377\3\3\3\37799H\377\230" - "\230\307\377II]\377\25\25\25\377\17\17\17\377pp\221\377\223\223\300\377\27" - "\27\36\377\35\12\12\377\3\3\3\377\202\202\253\377\206\206\260\377\31\31\33" - "\377$\21\21\377\25\20\20\377(\24\24\377\15\15\15\377\17\17\17\377\13\13\17" - "\377\216\216\273\377\202\202\253\377\22\22\24\377\0\0\0\377\12\12\12\377" - "\1\1\1\377ff\203\377\244\244\326\377]]x\377\16\16\16\377\30\30\30\377\15" - "\15\15\377\15\15\15\377\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\25" - "\25\25\377\31\31\31\377\0\0\0\377\15\15\15\377\10\10\10\377\30\30\30\377" - "\17\17\17\377+++\377\24\24\24\377\15\15\15\377\17\17\17\377VUU\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\310\306\306\352" - "~\177\204\373\213\212\214\377\212\211\212\371\220\220\222\377\220\220\222" - "\260\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\314\312\312\346\347\345\345\377\343\341\341" - "\377\"!!\377\24\25\24\377\26.\26\377\21\21\21\377\15\24\15\377%5%\377\36" - "\36\36\377\3\3\3\377\6\6\6\377\10\10\10\377\4\4\4\377\5\5\5\377\21\21\22" - "\377]]{\377ss\230\377\210\210\262\377\211\211\263\377\204\204\255\377\231" - "\231\310\377\231\231\311\377\235\233\314\377\27\27\33\377\11\6\10\377\220" - "\207\260\377||\240\377\16\16\16\377\24\24\24\377\21\21\21\377KK`\377\231" - "\231\312\37733C\377\11\11\11\377\5\5\6\377ww\233\377\211\211\263\377\26\26" - "\32\377'\24\24\377\32\25\27\377\215\213\267\377~~\245\377\17\17\17\377\12" - "\11\11\377\26\1\1\377\40\12\12\377\0\0\0\377\12\12\12\377\25\25\34\377\222" - "\222\277\377zz\240\377\31\31\32\377\17\17\17\377\26\26\26\377\40\40'\377" - "\223\223\277\377\250\250\335\377@@T\377\1\1\1\377\12\12\12\377\3\3\3\377" - "\11\11\11\377\0\0\0\377\14\14\14\377\10\10\10\377---\377\24\24\24\377\31" - "\31\31\377\16\16\16\377\30\30\30\377\7\7\7\377\15\15\15\377\0\0\0\377$$$" - "\377\2\2\2\377\2\2\2\377\12\12\12\377ccc\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\300\277\277\341~\177\204\377\230\230" - "\232\377\246\246\247\373\220\220\222\377\220\220\222\232\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\32\31\31\13\326\325\325\365\347\345\345\377\340\336\336\377322\377\30\31" - "\30\377\27!\27\377\7\7\7\377\2\2\2\377\6\6\6\377\23\23\23\377!!!\377\24\24" - "\24\377\23\23\23\377\21\21\21\377\15\15\15\377\25\25\30\377aa\201\377\216" - "\216\272\377NNe\3777*6\377\24\24\32\377TTk\377\235\235\316\377\233\233\314" - "\377\34\34\37\377\32\22\25\377\227\222\300\377ll\213\377\1\1\1\377\10\10" - "\10\377\7\7\7\377TTn\377\230\230\310\377..9\377\25\25\25\377\26\26\27\377" - "\202\202\251\377\201\201\251\377\12\12\14\377\37\12\12\377!\21\27\377\220" - "\220\274\377ss\227\377\11\7\7\377\24\12\12\377\35\6\5\377*8\16\377\16\16" - "\16\377\26\26\26\377--9\377\222\222\300\377kk\215\377\13\13\13\377\3\3\3" - "\377$$-\377vv\233\377\234\234\315\377\223\223\301\377\20\20\23\377\6\6\6" - "\377\22\22\22\377\21\21\21\377\24\24\24\377\20\20\20\377!!!\377\40\40\40" - "\377\16\16\16\377\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377" - "\14\14\14\377\0\0\0\377&&&\377\6\6\6\377\17\17\17\377\26\26\26\377\221\220" - "\220\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\264\263\264\340~\177\204\377a]]\377mjj\377\220\220\222\377\220\220\222\205" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0MLL!\342\340\340\374\347\345\345\377\315\313\313\377\5\5" - "\5\377\4\4\4\377\31\31\31\377\20\20\20\377\17\17\17\377\17\17\17\377\21\21" - "\21\377\16\16\16\377\25\25\25\377\35\35\35\377\11\14\11\377\1\1\1\377\11" - "\11\12\377PPg\377\206\206\260\377\35\35\40\377#\22\22\377\17\17\17\377RR" - "h\377\243\243\325\377\\Up\377\11\11\11\377\36\22\27\377\230\227\306\377`" - "`z\377\15\15\15\377\23\23\23\377\24\24\24\377gg\206\377\226\226\304\377\32" - "\32!\377\11\11\11\377\21\21\23\377\210\210\262\377vv\233\377\4\10\4\377." - "\34\12\3778#-\377\222\222\277\377rj\211\377)\17\17\377&\24\24\3771+5\377" - "KXa\377\27\27\37\377\13\13\13\37722B\377\221\221\275\377ss\227\377YYt\377" - "ss\227\377\215\215\267\377\226\226\304\377\240\240\323\377MMa\377\22\22\22" - "\377\16\16\16\377\13\13\13\377\7\7\7\377\5\5\5\377\30\30\30\377\24\24\24" - "\377\1\1\1\377\13\13\13\377\0\0\0\377\15\15\15\377\6\6\6\377\25\25\25\377" - "\17\17\17\377\30\30\30\377\17\17\17\377...\377\11\11\11\377\12\12\12\377" - "\6\6\6\377\216\215\215\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\253\252\254\345\177\200\205\377\225\224\225\377\217\216" - "\217\377\220\220\222\377\220\220\222o\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0zyy3\344\342\342\376" - "\347\345\345\377\303\301\301\377\21\21\21\377\20\20\20\377\30\30\30\377\12" - "\12\12\377\6\6\6\377\1\1\1\377\10\10\10\377\11\11\11\377\6\6\6\377\30\30" - "\30\377$E$\377\16\20\16\377\20\20\20\377\\\\w\377{{\241\377&&0\377I>P\377" - "\\\\x\377\224\224\301\377ss\224\377\36\30\34\377\"\23\23\3776*3\377\230\230" - "\310\377OOd\377\5\5\5\377\5\5\5\377\11\11\11\377pp\224\377\224\224\303\377" - "\20\20\24\377\14\14\14\377!!&\377\217\217\273\377ll\216\377\15\27\15\377" - "\30\40\16\37741?\377\222\222\277\377ZZt\377\5\5\7\377\33\33!\377ww\234\377" - "\216\216\273\377\36\36'\377++4\377\201\201\252\377\221\221\276\377\235\235" - "\320\377\247\247\333\377\245\245\331\377\243\243\325\377\241\241\324\377" - "``~\377\14\14\15\377\2\2\2\377\7\7\7\377\4\4\4\377\14\34\11\377\34\37\34" - "\377\25\25\25\377\16\16\16\377\21\21\21\377\25\25\25\377\20\20\20\377\26" - "\26\26\377\11\11\11\377\17\17\17\377\0\0\0\377\14\14\14\377\0\0\0\377%%%" - "\377\0\0\0\377\12\12\12\377\3\3\3\377\254\252\252\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\240\237\241\336\177\177\204" - "\377\232\231\233\377\233\233\234\372\220\220\222\377\220\220\222Y\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\234\233\233R\346\344\344\377\347\345\345\377\245\244\244\377\10" - "\10\10\377\12\12\12\377\16\16\16\377\15\15\15\377\21\21\21\377\14\14\14\377" - "\23\23\23\377\22\22\22\377\14\14\14\377\32\32\32\377\11\12\11\377\5\5\5\377" - "\3\3\3\377cc\203\377\211\211\265\377\226\226\304\377\227\227\304\377\225" - "\225\302\377\227\227\305\377ss\224\377\20\20\24\377\26\10\10\377B0?\377\225" - "\225\303\377==N\377\7\7\7\377\13\13\13\377\30\30\32\377\206\206\256\377\224" - "\224\301\377\27\27\31\377\14\14\14\377''/\377\221\221\277\377]]{\377\4\4" - "\5\377\16\16\21\377PPi\377\220\220\275\377\212\212\265\377\223\223\302\377" - "\243\243\326\377\235\235\316\377\234\234\315\377!!(\377;;I\377\212\212\264" - "\377\236\236\317\377\245\245\327\377\240\240\321\377\226\226\304\377\200" - "\202\252\377OOf\377\20\13\15\377\32\22\22\377\14\14\14\377\26\26\26\377\26" - "\20\20\377I2\31\377(,(\377###\377\5\5\5\377\11\11\11\377\3\3\3\377\2\2\2" - "\377\11\11\11\377\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\3\3\3\377" - ",,,\377\15\15\15\377\31\31\31\377\17\17\17\377\307\305\305\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\225\224\227\340|}\201" - "\377ZUT\377{yz\377\220\220\222\377\220\220\222D\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\251\250\250" - "g\347\345\345\377\347\345\345\377\217\216\216\377\22\22\22\377\31\31\31\377" - "\22\22\22\377\15\15\15\377\11\11\11\377\1\1\1\377\7\7\7\377\17\17\17\377" - "\30\30\30\377\17\17\17\377\23\23\23\377\22\22\22\377\16\16\17\377tt\227\377" - "\226\226\305\377\225\225\303\377\216\214\266\377\215\215\270\377\236\236" - "\317\377\242\242\324\377H>P\377(\16\16\377[\\X\377\226\226\303\377TTk\377" - "\22\22\22\377\6\6\6\37777F\377\235\235\316\377\205\205\257\377\12\12\13\377" - "\5\5\7\377XXq\377\220\220\275\377\232\232\312\37788F\37733>\377\213\213\265" - "\377\230\230\310\377\242\242\325\377\245\245\331\377\246\246\332\377\251" - "\251\336\377\237\237\317\377\21\21\26\377/0=\377UVq\377QPh\377LBR\377K2;" - "\377[/3\377k++\377\21055\377\252AA\377g..\377\3\3\3\377\14\14\14\377>\11" - "\11\377\23\15\15\377\0\0\0\377\27\27\27\377\37\37\37\377\35\35\35\377\1\1" - "\1\377\11\11\11\377\22\22\22\377\20\20\20\377\27\27\27\377\17\17\17\377\30" - "\30\30\377\14\14\14\377)))\377\1\1\1\377\15\15\15\377\0\0\0\377\306\304\304" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\215" - "\215\220\342\202\203\210\377\224\222\223\377\216\216\217\375\220\220\222" - "\377\220\220\222.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\267\265\265\204\347\345\345\377\347\345" - "\345\377vuu\377\7\7\7\377\24\24\24\377\4\4\4\377\14\14\14\377\21\21\21\377" - "\17\17\17\377\32\32\32\377\36\36\36\377\16\16\16\377\4\4\4\377\10\10\10\377" - "\7\7\7\377\5\5\7\377\202\202\252\377tt\225\377$)-\37764\33\377=%,\377yt\230" - "\377\246\246\331\377ca}\377\6\5\5\377JLa\377\224\224\303\377vv\233\377,," - "8\377CCY\377\206\206\260\377\244\244\327\377MMc\377\25\25\25\377\35\35\"" - "\377\216\216\273\377\235\235\316\377\256\256\344\377((3\37700?\377\202\202" - "\253\377\223\223\301\377\210\212\263\377op\222\377ZZt\377CCV\37722=\377I" - "!\"\377j**\3771\35\35\377[('\377\17700\377\21755\377\234::\377\246==\377" - "\265CC\377\307KK\377Q$$\377\0\0\0\3776\14\14\377\30\4\4\377\20\20\20\377" - "\15\15\15\377\30\30\30\377\17\17\17\377###\377***\377###\377\6\6\6\377\4" - "\4\4\377\10\10\10\377\2\2\2\377\12\12\12\377\0\0\0\377%%%\377\0\0\0\377\15" - "\15\15\377\26\26\26\377\342\340\340\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\177\200\203\333\202\203\207\377\237\236\240" - "\373\226\226\230\373\220\220\222\376\220\220\222\32\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\275" - "\275\236\347\345\345\377\347\345\345\377]\\\\\377\22\22\22\377\40\40\40\377" - "\14\14\14\377\15\15\15\377\11\11\11\377\23\23\23\377\15\15\15\377\10\10\10" - "\377\10\10\10\377\3\3\3\377\20\20\20\377\23\23\23\377\30\30\34\377\214\214" - "\267\377SSj\377\7\11\7\377\10\17\10\377%%.\377\207\207\261\377\245\245\330" - "\377::J\377\2\2\2\377<>\377b&&\377,\20\20\377" - "\20511\377\246??\377*\21\21\377\7\7\7\377\7\4\4\377\20000\377\240;;\377$" - "\30\30\377k**\377\23299\377\\$$\3774\34\34\377\33\15\15\377\25\20\20\377" - "\3\1\1\377\25\14\14\377;\11\11\377\13\13\13\377\0\0\0\377\13\13\13\377\0" - "\0\0\377\15\15\15\377\5\5\5\377\25\25\25\377\17\17\17\377\30\30\30\377\17" - "\17\17\377(E(\377\16\27\16\377\17\17\17\377\5\5\5\377\13\13\13\377\33\33" - "\33\377\0\0\0\377\15\15\15\377\33\32\32\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\337\335\335\376vw{\340\210\210\214\377\221" - "\217\220\372\217\217\221\376\220\220\222\345\220\220\222\7\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\311\307\307\324\347\345\345\377\345\343\343\377+++\377\21\21\21\377\40" - "\40\40\377\20\20\20\377\14\17\14\377\31$\31\377\40\40\40\377\3\3\3\377\7" - "\7\7\377\10\10\10\377\3\3\3\377\10\10\10\377\20\20\21\377qq\225\377\222\222" - "\277\377\241\241\325\377\247\247\333\377\245\245\331\377\243\243\326\377" - "\227\227\306\37711@\377\10\10\10\377\0\0\0\377\11\11\11\377#\37&\377VNc\377" - ":9G\377%$,\377G')\377\20122\377\22388\377\246??\377\235<<\377%\21\21\377" - "\12\11\11\377v--\377\21644\377\272EE\377M\35\35\377;\27\27\377\23188\377" - "\334SS\377\227;;\377\26\25\25\377\27\21\21\377\22377\377\242<<\377\31\22" - "\22\377y..\377\244==\377!\14\14\377\13\13\13\377\2\1\1\377\14\13\13\377\0" - "\11\0\377:(\20\377\14\11\11\377\26\26\26\377\16\16\16\377\30\30\30\377\16" - "\16\16\377\26\26\26\377\11\11\11\377\17\17\17\377\0\0\0\377\14\14\14\377" - "\0\0\0\377###\377\1\1\1\377\12\12\12\377\2\2\2\377\25\25\25\377\20\20\20" - "\377\3\3\3\377\23\23\23\377QPP\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\321\317\317\365|}\202\343\213\213\216\377\245\245" - "\246\372\222\222\224\376\220\220\222\326\220\220\222\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\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2\316" - "\314\314\345\347\345\345\377\344\342\342\377!!!\377\6\6\6\377\27\27\27\377" - "\6\6\6\377\2\2\2\377\10\10\10\377\17\17\17\377\"\"\"\377\35\35\35\377\23" - "\23\23\377\20\20\20\377\15\15\15\377\24\24\27\377\200\200\247\377\233\233" - "\314\377\235\235\315\377\217\220\274\377xy\236\377``}\377+\40&\377-\24\25" - "\377\30\25\25\377\15\15\15\377\26\25\25\377\21155\377x-,\377\15\14\14\377" - "1\23\23\377\23399\377\246>>\377\265DD\377\276FF\377\331QQ\377\20211\377\24" - "\21\21\377j**\377\257AA\377\22499\377!\26\26\377R##\377\252@@\377\351XX\377" - "\322OO\3770\30\30\377\22\7\7\377\236::\377\232:9\377\20\37\14\377\20422\377" - "\241==\377c%%\377r--\377\22266\377F!!\377\26\"\26\377%0\35\377\6\6\6\377" - "\14\14\14\377\1\1\1\377\12\12\12\377\0\0\0\377\13\13\13\377\0\0\0\377\14" - "\14\14\377\0\0\0\377\14\14\14\377\3\3\3\377)))\377\14\14\14\377\27\27\27" - "\377\20\20\20\377)))\377\25\25\25\377\15\15\15\377\23\23\23\377RQQ\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\313\312\312" - "\351~\177\204\366kik\377_ZZ\377\220\220\222\377\220\220\222\301\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0""222\22\332\330\330\365\347\345\345\377\327\325\325\377\12\12\12\377" - "\15\15\15\377\37\37\37\377\22\22\22\377\16\16\16\377\17\17\17\377\16\16\16" - "\377\10\10\10\377\16\16\16\377\40\40\40\377\13\16\13\377\2\2\2\377\20\17" - "\21\377F=M\377O9E\377^4;\377m02\377\21366\377;\34\34\377m++\377\22788\377" - ";\33\33\377\2\2\2\377\15\11\11\377\21233\377m))\377\15\12\12\377\21022\377" - "\253@@\377\231<<\377d))\377v11\377\353YY\377\261CC\377\22\20\20\3778\25\25" - "\377\266DD\377^\"\"\377\12\12\12\377\\!!\377\266EE\377\344VV\377\350WW\377" - "n00\377)\25\25\377\247>>\377\224?:\377/G)\377\21666\377\253@@\377\272EE\377" - "\273FF\377\305II\3772\22\22\377\25\25\25\377!!!\377\1\1\1\377\13\13\13\377" - "\3\3\3\377\13\13\13\377\10\10\10\377\25\25\25\377\16\16\16\377\30\30\30\377" - "\17\17\17\377\31\31\31\377\14\14\14\377)))\377\3\3\3\377\15\15\15\377\0\0" - "\0\377###\377\3\3\3\377\1\1\1\377\13\13\13\377baa\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\305\303\303\333~\177\204\377" - "\222\222\225\377\224\223\224\377\220\220\222\377\220\220\222\253\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0^]]\"\340\336\336\373\347\345\345\377\312\310\310\377\16\16\16\377" - "\7\7\7\377\24\24\24\377\10\10\10\377\5\5\5\377\3\3\3\377\10\10\10\377\13" - "\13\13\377\12\12\12\377\27\27\27\3777B!\377\30\21\16\3770\34\34\377\2011" - "1\377\22176\377\243<<\377\261AA\377\300HH\377)\20\20\377m))\377\266DD\377" - "\235<<\377\21\20\20\377\37\24\24\377\237<<\377n,,\377G$$\377\241<<\377\220" - "55\377\33\17\17\377\0\0\0\377\17\13\13\377\21255\3774\23\23\377\12\12\12" - "\377D\31\31\377\270EE\377W%%\377\24\24\24\377q,,\377\271EE\377\232;;\377" - "\340SS\377\302II\377:\26\26\377\270EE\377\21599\3772''\377\22488\377\274" - "FF\377\275GG\377\267DD\377\236::\377(\30\30\377\33\33\33\377&&&\377\25\25" - "\25\377\26\26\26\377\22\22\22\377\22\22\22\377\12\12\12\377\13\13\13\377" - "\1\1\1\377\13\13\13\377\0\0\0\377\14\14\14\377\0\0\0\377%%%\377\0\0\0\377" - "\14\14\14\377\0\0\0\377%%%\377\6\6\6\377\15\15\15\377\27\27\27\377\212\211" - "\211\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\271\267\270\331~\177\204\377\216\215\217\377\233\232\234\370\220\220\222" - "\377\220\220\222\225\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210\207\2079\343\341\341\376\347\345" - "\345\377\264\262\262\377\10\10\10\377\11\11\11\377\31\31\31\377\22\22\22" - "\377\21\21\21\377\15\15\15\377\23\23\23\377\17\17\17\377\10\10\10\377\32" - "\32\32\377\16\12\12\377?\13\13\3770\25\25\377\20200\377\240<<\377\240==\377" - "\223;;\377r..\377\34\23\23\377\20644\377\326QQ\377\321OO\377&\24\24\377!" - "\15\15\377\251??\377Z\"\"\377O\40\40\377\252??\377G\33\33\377\16\16\16\377" - "5\26\26\377K\37\37\377&\33\33\377\15\15\15\377\25\25\25\377Z%%\377\272FF" - "\377B\33\33\377\6\6\6\377{--\377\261BB\3778\32\32\377\274EE\377\301HH\377" - "\21544\377\315LL\377y//\3775\"\"\377\241<<\377\237<<\377:\37\37\377&\30\30" - "\377\33\24\24\377\37\37\37\377\11\11\11\377\5\5\5\377\33\33\33\377\6\6\6" - "\377\7\7\7\377\4\4\4\377\7\7\7\377888\377@@@\377kkk\377\"\"\"\377\22\22\22" - "\377\15\15\15\377...\377\17\17\17\377\31\31\31\377\17\17\17\377///\377\13" - "\13\13\377\12\12\12\377\7\7\7\377\207\206\206\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\260\257\260\337~\177\204\377b^_" - "\377lhh\377\220\220\222\377\220\220\222\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\236\234\234U\347" - "\345\345\377\347\345\345\377\226\225\225\377\22\22\22\377\24\24\24\377\15" - "\15\15\377\7\7\7\377\7\7\7\377\1\1\1\377\7\7\7\377\21\21\21\377\25\25\25" - "\377\15\15\15\377\22\22\22\377-\22\22\377e##\377\233::\3775\31\31\377\17" - "\11\11\377\13\11\11\377\4\4\4\377\15\7\7\377\22777\377\334SS\377\354YY\377" - "h,,\3776\27\27\377\260AA\377R&&\377c**\377\253@@\377*\25\25\377\34\24\24" - "\377\22066\377\22366\377\230;;\377\13\4\4\377\12\12\12\377c$$\377\272FF\377" - "4\27\27\377\6\5\5\377\21233\377\255@@\377%\33\33\377q//\377\271DD\377\310" - "JJ\377\343UU\377i))\3777\33\33\377\242<<\377y--\377\10\10\10\377\4\3\3\377" - "\21\16\16\377!\27\27\377\34\20\20\377\2\2\2\377!!!\377\6\6\6\377\21\21\21" - "\377\17\17\17\377\36\36\36\377ttt\377iii\377fff\377$$$\377\22\22\22\377\4" - "\4\4\377!!!\377\0\0\0\377\14\14\14\377\0\0\0\377%%%\377\0\0\0\377\11\11\11" - "\377\3\3\3\377\252\250\250\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\244\243\245\327~\177\204\377\227\226\230\377\222\221" - "\222\373\220\220\222\377\220\220\222j\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\253\251\251i\347\345" - "\345\377\347\345\345\377\215\214\214\377\7\7\7\377\23\23\23\377\11\11\11" - "\377\17\17\17\377\22\22\22\377\16\16\16\377\36\36\36\377\35\35\35\377\15" - "\15\15\377\11\11\11\377\11\11\11\377\7\7\7\377e\"\"\377\234;;\377!\20\20" - "\377\35\13\13\377&\24\24\377\20\20\20\377\37\23\23\377\245==\377\251??\377" - "\333RR\377\276II\377M\36\36\377\273FF\377>\33\33\377k''\377\254??\377\25" - "\10\10\377\26\15\15\377\20300\377\250??\377\321NN\377;\32\32\377\25\25\25" - "\377x//\377\270EE\377/\34\34\377\22\16\16\377\233::\377\251??\377\22\15\15" - "\377+\20\20\377\254@@\377\324OO\377\350XX\377V##\377C\34\34\377\241;;\377" - "\21766\377t..\377\20100\377\227::\377\264CC\377w55\377\17\17\17\377%%%\377" - "\17\17\17\377\20\20\20\377\1\1\1\377\13\13\13\377\11\11\11\377\11\11\11\377" - "\3\3\3\377\2\2\2\377\12\12\12\377\6\6\6\377\36\36\36\377\0\0\0\377\15\15" - "\15\377\4\4\4\377,,,\377\15\15\15\377\31\31\31\377\17\17\17\377\301\277\277" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\231" - "\230\233\331~\177\204\377\224\223\224\376\231\231\232\370\220\220\222\377" - "\220\220\222U\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\271\267\267\212\347\345\345\377\347\345\345" - "\377edd\377\22\22\22\377\37\37\37\377\11\11\11\377\13\13\13\377\10\10\10" - "\377\25\25\25\377\14\14\14\377\10\10\10\377\10\10\10\377\6\6\6\377\20\20" - "\20\377\22\22\22\377a((\377\243==\377\251@@\377\267DD\377`%%\377\12\12\12" - "\377#\17\17\377\255@@\377Z$$\377\247??\377\277GG\377\21444\377\313KK\377" - "5\34\34\377|..\377\251??\377\37\24\24\377\23\23\23\377#\30\30\377\250@@\377" - "\343UU\377O\36\36\377\12\11\11\377\21022\377\264CC\377\36\20\20\377\16\5" - "\5\377\250>>\377\236;;\377\15\13\13\377\7\6\6\377\227==\377\323OO\377\346" - "WW\377N&&\377X''\377\250>>\377\303II\377\274GG\377\273FF\377\302II\377\320" - "MM\377`))\377\0\0\0\377\17\17\17\377\24\24\24\377\13\13\13\377\0\0\0\377" - "\13\13\13\377\1\1\1\377\15\15\15\377\11\11\11\377\20\20\20\377\24\24\24\377" - "\31\31\31\377%%%\377\17\17\17\377\30\30\30\377\13\13\13\377+++\377\3\3\3" - "\377\15\15\15\377\0\0\0\377\277\275\275\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\220\220\222\334}~\202\377ZUT\377ywx\377" - "\220\220\222\377\220\220\222?\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\275\275\236\347\345\345" - "\377\347\345\345\377XXX\377\7\7\7\377\27\27\27\377\5\5\5\377\15\16\15\377" - "\35""9\35\377\27\27\27\377\15\15\15\377\23\23\23\377\22\22\22\377\10\10\10" - "\377\13\13\13\377\11\11\11\377j((\377\264CC\377\304JJ\377\310JJ\377B\30\30" - "\377\13\13\13\377B$$\377\257AA\377M$$\377[((\377\271EE\377\314LL\377\327" - "QQ\377*\30\30\377\21655\377\304JJ\377H\35\35\377\6\5\5\377;\31\31\377\274" - "FF\377\325PP\377#\16\16\377B\35\35\377\241<<\377\320NN\377\20555\377(\26" - "\26\377\270EE\377\22599\377\25\25\25\377\15\15\15\377D\36\36\377\336TT\377" - "\345WW\3775\31\31\377d&&\377\256@@\377\302HH\377\265CC\377\245??\377\226" - "88\377|--\377/\31\31\377\10\10\10\377\24\24\24\377###\377\27\27\27\377\16" - "\16\16\377\30\30\30\377\16\16\16\377\25\25\25\377\10\10\10\377\14\14\14\377" - "\3\3\3\377\22\22\22\377\22\22\22\377\2\2\2\377\12\12\12\377\0\0\0\377%%%" - "\377\0\0\0\377\14\14\14\377\15\15\15\377\335\333\333\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\202\202\206\324\202\203" - "\207\377\231\230\231\375\220\217\221\373\220\220\222\377\220\220\222)\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\305\304\304\273\347\345\345\377\347\345\345\377888\377\22\22" - "\22\377\40\40\40\377\14\14\14\377\10\11\10\377\27\34\27\377\7\7\7\377\0\0" - "\0\377\10\10\10\377\10\10\10\377\1\1\1\377\10\10\10\377\17\17\17\377\204" - "44\377\242??\377R''\3778\33\33\377\30\23\23\377\27\27\27\377N&&\377\266D" - "D\3779\33\33\377\33\12\12\377\251??\377\332RR\377\317ON\377\31\32\16\377" - "\21444\377\316MM\377\276HH\377\22266\377\266DD\377\336SS\377\21766\377\23" - "\22\22\377\21088\377\300GG\377\354YY\377{//\3770\21\21\377\306II\377x--\377" - "\10\10\10\377\6\6\6\377\37\22\22\377\242>?\377{--\377\33\21\21\3775\30\30" - "\377D##\377D**\377/\37\37\377*\"\"\377\34\31\31\377\17\16\16\377\25\25\25" - "\377\7\7\7\377\16\16\16\377\26\26\26\377\16\16\16\377\0\0\0\377\13\13\13" - "\377\0\0\0\377\13\13\13\377\0\0\0\377\15\15\15\377\10\10\10\377#9#\377\16" - "\33\16\377\17\17\17\377\24\24\24\377\22\22\22\377---\377\17\17\17\377\31" - "\31\31\377\35\35\35\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377yz~\331\201\202\206\377\236\236\237\374\226\226" - "\230\373\220\220\222\372\220\220\222\31\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\311\307\307\324\347" - "\345\345\377\347\345\345\377!!!\377\7\7\7\377\27\27\27\377\5\5\5\377\7\7" - "\7\377\32\32\32\377\21\21\21\377\14\14\14\377\22\22\22\377\23\23\23\377\17" - "\17\17\377\17\17\17\377\35\32\32\377\22399\377z55\377\15\15\15\377\5\4\4" - "\377\16\10\10\377\37\32\32\377S\37\37\377\270EE\377;''\377\12\11\11\377\216" - "::\377\333RR\377\304NL\377%@!\377x00\377\341TT\377\332QQ\377\316MM\377\334" - "RR\377\265DD\377$\20\20\377\11\10\10\377\20423\377\252??\377\246=>\377@\31" - "\31\377$\17\17\377d1/\377I1+\377A5'\377XF2\377x`E\377\210iI\377oW=\377\25" - "\24\24\377\7\7\7\377\15\15\15\377\25\25\25\377\35\35\35\377\5\5\5\377\13" - "\13\13\377\0\0\0\377\13\13\13\377\0\0\0\377\13\13\13\377\6\16\6\377)@)\377" - "$$$\377222\377,,,\377444\377---\377333\377%%%\377\33""4\33\377\12\22\12\377" - "\13\13\13\377\6\6\6\377\13\13\13\377\33\33\33\377\0\0\0\377\15\15\15\377" - "\31\31\31\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\337\335\335\377xy}\331uux\377YTS\377\206\205\207\377\220\220\222\357" - "\220\220\222\17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\15\15\15\6\321\317\317\346\347\345\345\377\336\335" - "\335\377!!!\377\20\20\20\377\40\40\40\377\22\22\22\377\24\24\24\377\23\23" - "\23\377\11\11\11\377\5\5\5\377\11\11\11\377\10\10\10\377\5\5\5\377\3\3\3" - "\377\"\33\33\377\23088\377\22599\377\20466\377\21655\377\255@@\377R$$\377" - "p--\377\276GG\3772&&\377\4\4\4\377F\37\37\377\346WW\377\251@@\377\33\33\33" - "\377\33\13\13\377\235<<\377\255@A\377\21534\377q++\377@.+\377F@9\377>2&\377" - "`D2\377vY@\377\203eE\377\225tP\377\241|T\377\247\201W\377\243}R\377\247\200" - "S\377\232uM\377\224pI\377\217mG\377rW9\377\13\13\13\377\0\0\0\377\13\13\13" - "\377\7\21\7\377'<'\377\12\12\12\377\27\27\27\377\16\16\16\377\27\27\27\377" - "\16\16\16\377\30\30\30\377\15\27\15\377\26*\26\377\10\10\10\377\16\16\16" - "\377\1\1\1\377\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\13\13\13\377" - "\1\1\1\377\11\11\11\377\3\3\3\377\24\24\24\377\22\22\22\377\0\0\0\377\16" - "\16\16\377EEE\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\323\321\321\366|}\202\333\213\214\220\377\235\234\235\377\220\220" - "\222\377\220\220\222\343\220\220\222\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0GFF\26\334\332\332\365\347" - "\345\345\377\320\317\317\377\6\6\6\377\3\3\3\377\26\26\26\377\7\7\7\377\16" - "\16\16\377\12\12\12\377;;;\377bbb\377[[[\377\23\23\23\377\22\22\22\377\24" - "\24\24\3771\"\"\377\251>>\377\307KK\377\301II\377\304JJ\377\314LL\3776\24" - "\24\377}..\377\22566\377\35\30\30\377\12\12\12\377\30\16\15\377|86\377K)" - "#\377I>2\377RA.\377nT;\377\203eG\377\217pL\377\236|T\377\251\203X\377\245" - "~T\377\233vM\377\233vM\377\250\200T\377\242{Q\377\256\205W\377\255\204W\377" - "\262\210Y\377\270\215\\\377\271\215\\\377\272\216]\377\315\234f\377\236y" - "O\377lT9\377\27\27\27\377\16\16\16\377\27\27\27\377\15\26\15\377\17!\17\377" - "\5\5\5\377\12\12\12\377\0\0\0\377\13\13\13\377\0\0\0\377\13\13\13\377\1\1" - "\1\377\12\12\12\377\0\0\0\377\13\13\13\377\0\0\0\377\14\14\14\377\1\1\1\377" - "\16\16\16\377\6\6\6\377\25\25\25\377\16\16\16\377\30\30\30\377\20\20\20\377" - "(((\377\30\30\30\377\17\17\17\377\30\30\30\377ONN\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\317\315\315\353}~\203\355\204" - "\204\207\377\226\225\226\370\221\221\223\376\220\220\222\322\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0poo#\336\334\334\373\347\345\345\377\303\302\302\377\20\20\20\377\17" - "\17\17\377\35\35\35\377\23\23\23\377\35\35\35\377\20\20\20\377///\377333" - "\377\32\32\32\377\10\10\10\377\10\10\10\377\21\21\21\377*\23\23\377\2237" - "7\377\22677\377\20366\377k,,\377Z++\377\33\24\24\377W=/\377nQ:\377\200dF" - "\377\223sO\377\234xQ\377\244\200V\377\245~S\377\250\200T\377\242|Q\377\231" - "tL\377\203dA\377\230tK\377\240zO\377\257\205W\377\225rJ\377\236yO\377\261" - "\207X\377\260\206W\377\261\207Y\377\275\217^\377\270\214\\\377\264\211Z\377" - "\300\223`\377\273\217]\377\276\221_\377\265\212Z\377\231tL\377U@*\377\12" - "\12\12\377\0\0\0\377\13\13\13\377\2\2\2\377\11\11\11\377\3\3\3\377\10\10" - "\10\377\2\2\2\377\12\12\12\377\3\3\3\377\21\21\21\377\14\14\14\377\26\26" - "\26\377\20\20\20\377\27\27\27\377\17\17\17\377\30\30\30\377\16\16\16\377" - "\26\26\26\377\11\11\11\377\17\17\17\377\1\1\1\377\14\14\14\377\0\0\0\377" - "!!!\377\5\5\5\377\0\0\0\377\14\14\14\377`__\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\311\307\307\331}~\203\372ljl\377]XX" - "\377\220\220\222\377\220\220\222\274\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\216\214\214?\344\342" - "\342\377\347\345\345\377\235\234\234\377\12\12\12\377\10\10\10\377\17\17" - "\17\377\7\7\7\377\26\26\26\377\1\1\1\377\10\10\10\377\11\11\11\377\5\5\5" - "\377\17\17\17\377\24\24\24\377\34\34\34\377\24\22\22\377\34\26\26\377\22" - "\20\20\377\33\32\32\377\36\35\35\377\15\15\15\377\14\13\11\377\221nH\377" - "\256\205V\377\233vM\377\237yO\377\230tL\377\244}R\377\261\206X\377\263\210" - "Y\377\255\203V\377\315\234f\377\201c@\377\242{P\377\255\203V\377\267\213" - "[\377\206fB\377\276\220^\377\227sK\377\265\211Z\377\251\201U\377\245~R\377" - "\244}R\377\203dA\377\243}Q\377\213jE\377\235xN\377\225qJ\377\242{P\377D4" - "\"\377\16\16\16\377\7\7\7\377\25\24\24\377\24\22\21\377\37\31\30\377%\35" - "\32\377\35\26\26\377\22\22\22\377\22\22\22\377\15\15\15\377\20\20\20\377" - "\11\11\11\377\7\7\7\377\3\3\3\377\10\10\10\377\0\0\0\377\13\13\13\377\0\0" - "\0\377\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\15\15\15\377\5\5\5\377" - "!>!\377\5\11\5\377\7\7\7\377\23\23\23\377\202\201\201\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\275\274\274\325~\177\204" - "\374\223\223\226\377\231\230\231\371\220\220\222\377\220\220\222\246\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\234\233\233U\347\345\345\377\347\345\345\377\230\227\227\377" - "\13\13\13\377\26\26\26\377\22\22\22\377\23\23\23\377!!!\377\15\15\15\377" - "\22\22\22\377\21\21\21\377\12\12\12\377\12\12\12\377\26\26\26\377\10\10\10" - "\377\3\3\3\377\10\10\10\377\5\5\5\377\4\4\4\377$4$\377\11\11\11\377\27\24" - "\21\377\222oI\377\302\224`\377\233vM\377\300\222`\377~`>\377\271\215]\377" - "\255\204V\377\266\212Z\377\250\200T\377\262\210Y\377z]=\377\233vM\377\250" - "\200S\377\244|Q\377\236xN\377\230tK\377\220nH\377\251\201T\377\242|Q\377" - "\242}S\377\245\201W\377\233xQ\377\222rO\377\207gH\377\201`E\377wT=\377yQ" - "=\377L($\377tSP\377\207E6\377\231L=\377\242M>\377\260QB\377\242TB\377/\21" - "\21\377\7\7\7\377\3\3\3\377\6\6\6\377\5\5\5\377\10\10\10\377\3\3\3\377\10" - "\10\10\377\20\20\20\377\25\25\25\377$$$\377$$$\377222\377---\377555\377." - "..\377555\377)))\377!D!\377\14\17\14\377\16\16\16\377\15\15\15\377\202\201" - "\201\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\264\263\264\331~\177\204\376\211\210\212\377\231\230\231\370\220\220\222" - "\377\220\220\222\221\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\256\255\255o\347\345\345\377\347\345" - "\345\377poo\377\16\16\16\377\31\31\31\377\3\3\3\377\7\7\7\377\27\30\27\377" - "\3\3\3\377\5\5\5\377\15\15\15\377\24\24\24\377\34\36\34\377\35""6\35\377" - "\21\21\21\377\15\15\15\377\23\23\23\377\22\22\22\377\15\16\15\377\22*\22" - "\377\17\17\17\377\36\30\21\377\227tK\377\300\222_\377\210hD\377\231uM\377" - "w[;\377\226rK\377\236yO\377\252\201T\377\241zP\377\240zP\377\240{R\377\241" - "}T\377\231wQ\377\220pM\377\200cE\377\201jQ\377xaF\377lJ7\377^7.\377K'#\377" - ":!\36\377+\24\22\377\252bI\377\246K=\377\254L@\377\247G=\377\243C;\377{," - "+\377\310\177u\377\22153\377\22144\377\22144\377\22034\377u-+\377\"\34\34" - "\377)))\377***\377111\377---\377433\3772..\377///\377&&&\377\37\37\37\377" - "\26\26\26\377\11\11\11\377\17\17\17\377\1\1\1\377\14\14\14\377\0\0\0\377" - "\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\11\11\11\377\3\3\3\377\236" - "\234\234\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\250\247\251\321~\177\204\377c``\377jff\377\220\220\222\377\220\220\222" - "{\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\272\270\270\214\347\345\345\377\347\345\345\377___\377\12" - "\12\12\377\35\35\35\377\13\13\13\377\21\22\21\377!B!\377)))\377&&&\377%%" - "%\377\34\34\34\377\14\15\14\377\12\24\12\377\11\11\11\377\0\0\0\377\10\10" - "\10\377\10\10\10\377\0\0\0\377\10\10\10\377\10\10\10\377(\36\24\377\250\200" - "T\377\247\200U\377\237|S\377\231xR\377\214nK\377\177cE\377w`G\377raN\377" - "\200iO\377{_B\377k91\377S$\"\3770\25\22\377\17\17\16\377xwv\377\273\236\223" - "\377\230ZM\377\21083\377\177//\377z--\377X\"\37\377T#\36\377\251OB\377\204" - "//\377\21212\377\21311\377\21422\377~-.\377\270hO\377\21523\377\22044\377" - "\21533\377\21322\377_%#\377\23\21\21\377\23\23\23\377\4\4\4\377\14\14\14" - "\377\1\1\1\377.\20\20\377k''\377\12\12\12\377\1\1\1\377\10\10\10\377\4\4" - "\4\377\2\2\2\377\12\12\12\377\0\0\0\377\13\13\13\377\0\0\0\377\14\14\14\377" - "\2\2\2\377\22\22\22\377\12\12\12\377\27\27\27\377\17\17\17\377\271\270\270" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\235" - "\234\237\322~\177\204\377\252\253\255\377\241\241\242\377\220\220\222\377" - "\220\220\222f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\277\276\276\240\347\345\345\377\347\345\345" - "\377EEE\377\20\20\20\377\33\33\33\377\4\4\4\377\6\6\6\377\10\10\10\377\7" - "\7\7\377\1\1\1\377\10\10\10\377\10\10\10\377\1\1\1\377\10\10\10\377\13\13" - "\13\377\12\12\12\377\22\21\21\377\27\24\25\377\24\16\17\377\24\24\24\377" - "\26\25\25\377K,&\377u@:\377{C@\377\202LK\377\205VV\377G!$\377\12\10\10\377" - "fff\377\315\302\272\377\234[K\377\210=6\377\1770/\377y,,\377Y\37\37\377y" - "aX\377\270\232\232\377u,+\377z,,\377y,,\377}-.\377\200..\377g%%\377\241Q" - "L\377\227PJ\377\202//\377\205//\377z--\377q*)\377\21533\377\256[H\377\220" - "44\377\21744\377e$$\3770\21\21\377\34\20\17\377\0\0\0\377\13\13\13\377\0" - "\0\0\377\13\13\13\377\0\0\0\377j&&\377r++\377\16\16\16\377\11\11\11\377\25" - "\25\25\377\21\21\21\377\24\24\24\377\24\24\24\377\20\20\20\377\30\30\30\377" - "\17\17\17\377\30\30\30\377\16\16\16\377\24\24\24\377\5\5\5\377\16\16\16\377" - "\1\1\1\377\270\267\267\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\224\223\226\326~\177\204\377}{|\377\213\212\213\366\220" - "\220\222\377\220\220\222P\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\306\304\304\301\347\345\345\377" - "\347\345\345\377(((\377\10\10\10\377\30\30\30\377\7\7\7\377\13\13\13\377" - "\22\22\22\377\22\22\22\377\14\14\14\377\23\23\23\377\23\23\23\377\15\15\15" - "\377\22\22\22\377$\36\32\377\217QE\377\250[I\377\274kU\377\213WL\377\7\7" - "\7\377I$!\377\316\231\211\377\265\216\216\377\251\201\201\377\223kk\377\204" - "SS\377j))\3777$\40\377\312\270\265\377\177=7\377w++\377y,,\377y,,\377y,," - "\377`\"\"\377\254iN\377\203=7\377{--\377p))\377\2015/\377\201//\377\202/" - "/\377g&&\377\300ZK\377\21574\377\21633\377y++\3774\23\23\377\22\14\7\377" - "\234N@\377\246D?\377\22455\377\22255\377L\37\35\377\14\13\13\377\27\27\27" - "\377\17\17\17\377\27\27\27\377\16\16\16\377\30\30\30\377\20\17\17\377\233" - "<<\377N!\40\377\25\25\25\377\6\6\6\377\14\14\14\377\1\1\1\377\12\12\12\377" - "\2\2\2\377\2\2\2\377\12\12\12\377\2\2\2\377\12\12\12\377\0\0\0\377\14\14" - "\14\377\0\0\0\377\14\14\14\377\10\7\7\377\336\335\335\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\205\206\211\315~\177\204" - "\377[VU\377wuv\377\220\220\222\377\220\220\222:\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\312\310\310" - "\324\347\345\345\377\341\337\337\377)((\377\21\21\21\377\40\40\40\377\16" - "\16\16\377\7\7\7\377\10\10\10\377\10\10\10\377\2\2\2\377\5\5\5\377\10\10" - "\10\377\3\3\3\377\6\6\6\377b3,\377\266|n\377\213G:\377\200;4\377[10\377(" - "((\377\205JG\377\217E8\377w**\377w**\377y,,\377w++\377k''\377}<2\377\230" - "SB\377x,,\377n))\377{0-\377\20120\377y,,\377Y\37\37\377\301{v\377\202--\377" - "\200..\377g&%\377\254OA\377\21111\377\21211\377m('\377\277kS\377\21522\377" - "\22044\377l''\377\40\27\27\377\24\20\20\377\262ti\377\230;:\377\22777\377" - "\21755\377D\33\33\3777\26\25\377\30\17\17\377\0\0\0\377\13\13\13\377\0\0" - "\0\377\13\13\13\377\25\10\10\377\274FF\377\32\12\11\377\13\13\13\377\0\0" - "\0\377\13\13\13\377\0\0\0\377\16\16\16\377\7\7\7\377\22\22\22\377\34\34\34" - "\377'''\377666\377777\377EEE\377???\377FFF\377EEE\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377|}\201\322\202" - "\203\210\377\273\274\275\377\235\235\237\376\220\220\222\376\220\220\222" - "&\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0+**\12\324\322\322\351\347\345\345\377\324\322\322\377\11\11\11\377" - "\3\4\3\377\27\36\27\377\16\16\16\377\17\17\17\377\32\32\32\377###\377&&&" - "\377'''\377+++\377***\377(''\377\252XL\377\224<7\377\203//\377|--\377A\35" - "\35\377\5\4\4\377\255VI\377\205:3\377x,,\377k('\377\207B6\377x,,\377b$$\377" - "\254NB\377\206;4\377y,,\377c#$\377\271aL\377\20341\377\202//\377c\"\"\377" - "\274o^\377\21211\377\21111\377t.+\377\256PC\377\22144\377\21522\377x++\377" - "\275PG\377\22355\377\22355\377n+'\377S&\36\377[!\37\377\312tk\377\240<<\377" - "\247??\377\243JA\377\310^M\377\230>8\377\35\22\22\377\5\5\5\377\26\26\26" - "\377\25\25\25\377(((\377G\40\40\377\304MM\377>99\377BBB\377===\377EEE\377" - "<<<\377BBB\377777\377777\377(((\377\40\40\40\377\23\23\23\377\7\7\7\377\16" - "\16\16\377\0\0\0\377\15\15\15\377\27\27\27\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\340\336\336\376z{\177\322||\200\377" - "vrs\373\214\213\214\371\220\220\222\366\220\220\222\30\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0XWW\26\332" - "\330\330\366\347\345\345\377\314\313\313\377\25\25\25\377\14\22\14\377!7" - "!\377$$$\377\33\33\33\377\23\23\23\377\17\17\17\377\11\11\11\377\1\1\1\377" - "\10\10\10\377\10\10\10\377\25\10\10\377\310hS\377\21543\377\21122\377\201" - "//\3773\30\30\377\13\5\5\377\266SF\377\20220\377|--\377~76\377\235]W\377" - "{--\377a\"#\377\272eO\377\200..\377\204//\377f$$\377\266od\377\21422\377" - "\20500\377\20541\377\252NA\377\22044\377\20611\377\20430\377\21171\377m(" - "(\377b##\377\22064\377\257E@\377\22566\377\23188\377\263LB\377\302XI\377" - "\235@:\377\274OE\377\256CC\377\260DD\377\263EE\377\267EE\377k)*\377A<<\377" - "555\377777\377'''\377%%%\377\20322\377\262DD\377\6\4\4\377\14\14\14\377\0" - "\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\13\13\13\377\0\0\0" - "\377\11\11\11\377\3\3\3\377\3\3\3\377\12\12\12\377\0\0\0\377\15\15\15\377" - ";::\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\325" - "\323\323\367|}\202\323vvz\377YTS\377\205\203\205\377\220\220\222\356\220" - "\220\222\13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0yxx&\337\335\335\375\347\345\345\377\245\243\243\377\7" - "\7\7\377\1\1\1\377\7\7\7\377\7\7\7\377\6\6\6\377\2\2\2\377\10\10\10\377\12" - "\12\12\377\7\7\7\377\20\20\20\377\22\22\22\377S'#\377\265]K\377\21243\377" - "\232G<\377\21111\3770\33\33\377/\31\27\377\301`W\377\21322\377\202..\377" - "\230D?\377\227KE\377\21322\377j%%\377\265_K\377\21733\377\20600\377z,,\377" - "\264OD\377\22144\377{,,\377\231@8\377\236=:\377\22455\377\200..\377A\33\33" - "\377\30\20\20\377\31\24\24\377#\32\32\377\247]J\377\240=<\377\241<<\377\243" - "==\377\246>>\377\22177\377\246E>\377\275RI\377\260DD\377\260DD\377\255BB" - "\377\253AA\377P\36\35\377\14\12\12\377\1\1\1\377\12\12\12\377\0\0\0\377\23" - "\16\16\377\306KK\377\21133\377\1\0\0\377\13\13\13\377\0\0\0\377\15\15\15" - "\377\5\5\5\377\22\22\22\377\13\13\13\377\27\27\27\377\15\15\15\377\30\30" - "\30\377\20\20\20\377\24\24\24\377\25\25\25\377\17\17\17\377\32\32\32\377" - "LKK\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\322" - "\320\320\355|}\202\344\222\223\227\377\272\273\275\372\224\225\226\375\220" - "\220\222\342\220\220\222\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\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\214\213\213C\346\344\344\377\347\345\345" - "\377\240\237\237\377\22\22\22\377\15\15\15\377\21\21\21\377\23\23\23\377" - "\22\22\22\377\15\15\15\377\22\22\22\377\20\20\20\377\7\7\7\377\12\12\12\377" - "\13\12\12\377\211I@\377\242GA\377\215<6\377\242MA\377\21122\377\34\17\17" - "\377U%*\377\262ng\377\22144\377y++\377\255WF\377\21633\377\21222\377y,-\377" - "\254I@\377\22456\377\202//\377\21554\377\243><\377\22666\377n''\377\253e" - "^\377\232><\377\22666\377v**\377d%$\377r**\377\2020/\377k'&\377\310ul\377" - "\244>>\377\256CC\377\247??\377\232::\377w++\377\272YK\377\271TK\377\260D" - "D\377\254BB\377d%%\377K\37\37\377*\25\23\377\23\22\23\377\17\17\17\377\25" - "\25\25\377\17\17\17\377B\"\"\377\355YY\377w00\377\20\20\20\377\30\30\30\377" - "\16\16\16\377\26\26\26\377\13\13\13\377\22\22\22\377\5\5\5\377\16\16\16\377" - "\1\1\1\377\14\14\14\377\0\0\0\377\10\10\10\377\4\4\4\377\0\0\0\377\14\14" - "\14\377]\\\\\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\314\313\313\332}~\203\362zy|\377~{{\373\220\220\222\376\220\220" - "\222\315\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\235\234\234V\347\345\345\377\347\345\345\377|{{" - "\377\10\10\10\377\5\5\5\377\3\3\3\377\7\7\7\377\10\10\10\377\2\2\2\377\6" - "\6\6\377\10\10\10\377\6\6\6\377\16\16\16\377(\34\33\377\310`T\377\241>>\377" - "\235H>\377\240H?\377\20722\3773,,\377\221H?\377\243D=\377\22355\377w++\377" - "\273VH\377\22355\377~--\377\236TM\377\241GC\377\22677\377q((\377\257_R\377" - "\237><\377\23288\377h&&\377\302`_\377\245??\377\244==\377x3.\377\306VN\377" - "\276GG\377\273HG\377\2012.\377\311UK\377\253AA\377\257CC\377r((\3775\26\26" - "\377?\37\35\377\320]O\377\264FE\377\261DD\377\23199\377.\24\24\377\17\16" - "\16\377\13\12\12\377\11\11\11\377\7\7\7\377\6\6\6\377\4\3\3\377~53\377\372" - "f_\377d$$\377\3\3\3\377\10\10\10\377\1\1\1\377\13\13\13\377\0\0\0\377\14" - "\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\12\12" - "\12\377\2\2\2\377\1\1\1\377\14\14\14\377vuu\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\301\277\300\323~\177\204\366mkn\377" - "[WV\377\220\217\221\377\220\220\222\267\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\261\260\260v\347\345" - "\345\377\347\345\345\377rqq\377%%%\377(((\377%%%\377***\377***\377(((\377" - "(((\377+++\377(((\377\35\35\35\377f82\377\316iU\377\251@@\377\250QD\377\237" - "B=\377\201//\377\21\13\13\377\247G>\377\23299\377\22666\377z,,\377\271[J" - "\377\22667\377v**\377\266a]\377\236??\377\237;;\377n''\377\275j[\377\241" - "=<\377\244>>\377y.,\377\277eQ\377\254AA\377\247??\377\216F9\377\253AA\377" - "\257DD\377\235;;\377\21474\377\276PI\377\260DD\377\255BB\377c##\377\23\6" - "\6\3770\30\30\377\303nU\377\260CC\377\262DD\377\21333\377\30\16\16\377\3" - "\3\3\377\10\10\10\377\3\3\3\377\7\7\7\377\3\3\3\377\24\10\10\377\315_S\377" - "\365{a\377W!!\377\10\10\10\377\13\13\13\377\13\13\13\377\23\23\23\377\16" - "\16\16\377\31\31\31\377\17\17\17\377\31\31\31\377\17\17\17\377\31\31\31\377" - "\17\17\17\377\31\31\31\377\20\20\20\377\24\24\24\377\25\25\25\377\200\177" - "\177\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\270\267\270\325~\177\204\373\240\241\244\377\260\260\261\376\220\220\222" - "\377\220\220\222\242\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\272\270\270\214\347\345\345\377\347" - "\345\345\377RRR\377\14\14\14\377\11\11\11\377\1\1\1\377\6\6\6\377\10\10\10" - "\377\6\6\6\377\2\2\2\377\10\10\10\377\10\10\10\377\1\1\1\377\216H>\377\266" - "TJ\377\241==\377\257SD\377\237=;\377\20000\377.\37\34\377\310o`\377\247>" - ">\377\236;;\377\223B<\377\264VK\377\240<<\377u**\377\302QG\377\251@@\377" - "\244>>\377u-+\377\273^L\377\260DD\377\237<<\377\21374\377\276[M\377\260D" - "D\377\241==\377~9/\377\255CB\377\260DD\377\21666\377\240MA\377\273XM\377" - "\260DD\377\246??\377c\"\"\377]!!\377g,*\377\312eS\377\266EE\377\271EE\377" - "v,,\377\36\27\27\377\17\17\17\377\27\27\27\377\20\20\20\377\26\26\26\377" - "\21\21\21\377X##\377\364\207k\377\365ua\377T##\377\23\23\23\377\14\14\14" - "\377\14\14\14\377\11\11\11\377\1\1\1\377\14\14\14\377\0\0\0\377\14\14\14" - "\377\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\0\0\0\377\11\11\11\377" - "\3\3\3\377\233\232\232\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\255\254\255\312~\177\204\377yxz\377\202\200\201\365\220" - "\220\222\377\220\220\222\214\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\301\277\277\247\347\345\345" - "\377\347\345\345\377322\377\15\15\15\377\17\17\17\377\14\14\14\377\20\20" - "\20\377\23\23\23\377\22\22\22\377\15\15\15\377\23\23\23\377\23\23\23\377" - "\34\23\22\377\313^Q\377\262FE\377\22699\377\301WJ\377\253AA\377p++\377=\35" - "\34\377\316hZ\377\257CC\377\232::\377\252_]\377\251LK\377\252AA\377u+*\377" - "\300RH\377\257CC\377\244>>\377\2002/\377\271TH\377\260DD\377\21133\377\230" - "97\377\270IF\377\260DD\377\21344\377\253j`\377\261GF\377\260DD\377~0/\377" - "\301[L\377\266NH\377\260DD\377\234;;\377]!!\377\30\22\22\377\212D8\377\320" - "UN\377\276GG\377\273FF\377d$$\377#\24\23\377\12\4\3\377\13\13\13\377\0\0" - "\0\377\13\13\13\377\12\4\4\377\264BB\377\362\276\240\377\363{i\377Y\37\37" - "\377\13\13\13\377\1\1\1\377\7\7\7\377\4\4\4\377\3\3\3\377\11\11\11\377\0" - "\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\1\1\1\377\17\17\17\377\4\4\4" - "\377\20\20\20\377\11\11\11\377\261\260\260\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\242\241\243\313~\177\204\377ebc\377" - "hed\377\220\220\222\377\220\220\222v\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\306\305\305\303\347" - "\345\345\377\344\342\342\377211\377\14\14\14\377\13\13\13\377\7\7\7\377\3" - "\3\3\377\7\7\7\377\10\10\10\377\1\1\1\377\6\6\6\377\10\10\10\377G\34\32\377" - "\317nh\377\257CC\377\21565\377\303eR\377\260DD\377c''\377e/,\377\273\\M\377" - "\260DD\377\260HC\377\305RK\377\260DD\377\240==\377\20141\377\310eT\377\260" - "DD\377\230::\377\216>6\377\273SJ\377\260DD\377m((\377\312]O\377\264EE\377" - "\260DD\377x,,\377\307^P\377\257DD\377\256CC\377s**\377\320nX\377\261CD\377" - "\263DD\377\21443\377\20230\377f''\377\303ZL\377\304II\377\300GG\377\300L" - "H\377\277kS\377\274jP\377-\21\17\377\13\13\13\377\1\1\1\377\15\14\14\377" - "M\35\35\377\357`\\\377\364\324\273\377\372\206k\377y/0\377\26\26\26\377\16" - "\16\16\377\27\27\27\377\21\21\21\377\24\24\24\377\24\24\24\377\17\17\17\377" - "\31\31\31\377\20\20\20\377\30\30\30\377\16\16\16\377\30\30\30\377\14\14\14" - "\377\24\24\24\377\11\11\11\377\270\266\266\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\227\227\231\316~\177\204\377\263\264" - "\266\377\254\255\256\375\220\220\222\377\220\220\222a\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\5\5\2\314" - "\312\312\325\347\345\345\377\330\326\326\377\15\15\15\377\5\5\5\377\11\11" - "\11\377\13\13\13\377\10\10\10\377\16\16\16\377\21\21\21\377\16\16\16\377" - "\17\17\17\377\23\23\23\377\224FA\377\274RO\377\256BB\377\221=<\377\271e_" - "\377\260DD\377U&&\377\243LC\377\265RH\377\260DD\377\260DD\377\260DD\377\257" - "CC\377t+,\377\247JB\377\272OH\377\260DD\377x,,\377\274PF\377\265GE\377\260" - "CC\377m%&\377\321\177s\377\260CC\377\262DD\377\21484\377\302\\N\377\260D" - "D\377\253AA\377x,+\377\316jV\377\265CC\377\271EE\377\303NJ\377\321\\O\377" - "\21052\377\334\207{\377\275FF\377\304II\377\314NL\377\323[R\377\224>9\377" - "\35\16\16\377\27\27\27\377\16\16\16\377,\35\35\377\303JK\377\372\224}\377" - "\361\346\331\377\374\204e\377\256AA\377\27\20\20\377\1\1\1\377\13\13\13\377" - "\1\1\1\377\11\11\11\377\2\2\2\377\2\2\2\377\12\12\12\377\2\2\2\377\12\12" - "\12\377\0\0\0\377\14\14\14\377\0\0\0\377\14\14\14\377\2\2\2\377\334\332\332" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\211" - "\211\214\307~\177\204\377pmn\377\202\201\201\366\220\220\222\377\220\220" - "\222K\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0@??\14\324\323\323\354\347\345\345\377\324\322\322\377\31\31" - "\31\377\15\15\15\377\21\21\21\377\17\17\17\377\10\10\10\377\10\10\10\377" - "\12\12\12\377\7\7\7\377\3\3\3\377\23\15\14\377\305c`\377\263HG\377\237;;" - "\377\242UP\377\265dd\377\257DD\377I\36\36\377\275GG\377\263EE\377\260DD\377" - "\250@@\377\232::\377o*.\377&\20\21\377\267fQ\377\257CC\377\262DD\377n'(\377" - "\313xm\377\261BB\377\252@@\377\2030/\377\320]Q\377\267FF\377\272FF\377\310" - "RK\377\273LG\377\266DD\377\250??\377\21132\377\314UL\377\276GG\377\277GG" - "\377\277GG\377\267DD\377\234=:\377\333gY\377\317LM\377\321NN\377\321MM\377" - "\331QQ\377o*'\377\6\2\2\377\13\13\13\377\15\4\4\377\241=<\377\367\203m\377" - "\363\344\331\377\362\357\353\377\372\230y\377\354ZY\377P\"\"\377\0\0\0\377" - "\14\14\14\377\0\0\0\377\13\13\13\377\1\1\1\377\6\6\6\377\7\7\7\377\5\5\5" - "\377\14\14\14\377\6\6\6\377\23\23\23\377\13\13\13\377\27\27\27\377\17\17" - "\17\377\346\344\344\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\200\200\204\313~\177\204\377[WV\377ust\377\220\220\222\377\220" - "\220\2226\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0fee\24\330\326\326\367\347\345\345\377\257\255\255\377\7" - "\7\7\377\1\1\1\377\10\10\10\377\10\10\10\377\5\5\5\377\3\3\3\377\11\11\11" - "\377\12\12\12\377\7\7\7\377F#\"\377\322^U\377\261CC\377\261_Z\377\325xa\377" - "\260KK\377\255BB\377a&'\377\326aU\377\261DD\377\252AA\377C\30\30\377\"\20" - "\20\377\25\16\24\377%\30\27\377\306WM\377\267DD\377\267EE\377\232;9\377\315" - "`T\377\271DE\377\240<<\377\217;4\377\273JF\377\274GG\377\274GG\377\272EE" - "\377\275GG\377\277HH\377\22577\377\257KB\377\314PM\377\277HH\377\272EE\377" - "\264CC\377\23399\377\245A=\377\256C@\377\244<<\377\23599\377\22677\377\222" - "66\377J\32\32\377\23\6\6\377:\32\32\377\247=>\377\370xd\377\364\332\306\377" - "\371\371\371\377\367\367\367\377\367\301\235\377\371v^\377\317MM\377P!!\377" - "\37\32\32\377\20\20\20\377\30\30\30\377\20\20\20\377\27\27\27\377\20\20\20" - "\377\23\23\23\377\20\20\20\377\12\12\12\377\21\21\21\377\4\4\4\377\17\17" - "\17\377\26\26\26\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\341\337\337\376|}\201\313\201\202\207\377\301\302\304\375\241" - "\242\243\371\220\220\222\373\220\220\222#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0xww+\341\337\337\376\347" - "\345\345\377\247\246\246\377\22\22\22\377\15\15\15\377\22\22\22\377\22\22" - "\22\377\22\22\22\377\15\15\15\377\21\21\21\377\20\20\20\377\7\7\7\377\220" - "JG\377\302ff\377\265DD\377\262DD\377\260CC\377\262DD\377\252AA\377}--\377" - "\317yn\377\263CC\377\233::\377\23\6\6\377\11\11\11\377\5\5\5\377D\35\33\377" - "\313UL\377\275FF\377\300HH\377\312LL\377\302II\377\276GG\377r**\377t.+\377" - "\261FB\377\301HH\377\303II\377\277GG\377\21133\377|..\377d##\377\232E<\377" - "w,+\377t**\377m&&\377m&&\377v++\377\22577\377\203//\377\21122\377\22034\377" - "\23176\377\246><\377\267HC\377\304VL\377\344oh\377\370\234\205\377\363\337" - "\324\377\367\367\367\377\374\374\374\377\370\370\370\377\363\336\306\377" - "\373\253w\377\373\214k\377\353h[\377\245B?\377W\37\37\377L22\377:::\377A" - "AA\377BBB\377HHH\377III\377NNN\377RRR\377VVV\377[[[\377\202\201\201\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\330\326\326" - "\370|}\201\313||\201\377urr\375\212\211\213\372\220\220\222\366\220\220\222" - "\23\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\211\210\210C\347\345\345\377\347\345\345\377\214\212\212\377\7" - "\7\7\377\4\4\4\377\4\4\4\377\10\10\10\377\10\10\10\377\1\1\1\377\7\7\7\377" - "\10\10\10\377\13\6\5\377\277WK\377\273GG\377\274GG\377\270EE\377\270DE\377" - "\272FF\377\251??\377\223;6\377\307VK\377\271EE\377\21232\377\25\20\17\377" - "\24\24\24\377\23\23\23\377H!\37\377\303YK\377\304II\377\302II\377\303II\377" - "\303II\377\243<<\377/\23\23\377%\22\22\377_!!\377y,,\377z,,\377m''\377u*" - "*\377\21433\377\245<=\377\275FE\377\313NL\377\324RP\377\334VR\377\351]X\377" - "\357m`\377\362rb\377\366xe\377\366}h\377\367\207t\377\365\252\236\377\365" - "\264\245\377\362\300\257\377\360\330\277\377\364\354\343\377\367\371\371" - "\377\372\372\372\377\374\374\374\377\374\374\374\377\374\374\374\377\365" - "\365\364\377\361\354\346\377\370\312\232\377\373\240q\377\365i]\377\353\\" - "[\377\266MK\377ZTO\377[TM\377]TK\377`TG\377cTD\377fTA\377kT=\377nT:\377^" - "TI\377\215\215\215\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\325\323\323\357{|\200\333xx|\377ZUT\377\203\202\203\377\220" - "\220\222\357\220\220\222\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\241\240\240[\347\345\345\377\347\345\345" - "\377srr\377\22\22\22\377\22\22\22\377\15\15\15\377\23\23\23\377\23\23\23" - "\377\17\17\17\377\20\20\20\377\23\23\23\3778\34\33\377\331fZ\377\304II\377" - "\253@A\377n+,\377\274JE\377\275FF\377\241;;\377\243C<\377\277IH\377\277G" - "G\377l//\377'''\377///\377333\377D14\377\207;5\377\273FF\377\307KK\377\304" - "HH\377\23389\377h*(\377\204DC\377\226@@\377\260BB\377\270DD\377\300FG\377" - "\325SP\377\346_V\377\367h]\377\363}f\377\372\224m\377\373\235n\377\373\241" - "p\377\374\245r\377\374\252t\377\371\310\221\377\364\335\301\377\360\345\325" - "\377\360\350\332\377\360\354\343\377\365\367\367\377\364\365\365\377\362" - "\345\332\377\365\362\362\377\365\363\360\377\367\370\370\377\373\373\373" - "\377\374\374\374\377\374\374\374\377\372\372\372\377\362\357\352\377\355" - "\275\252\377\357|h\377\313TG\377\247F'\377\224D\21\377\246S\7\377\244T\4" - "\377\246T\2\377\247T\1\377\250T\0\377\250T\0\377\250T\0\377\250T\0\377\250" - "T\0\377mT:\377\225\225\225\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\317\315\315\335|}\202\350\220\221\225\377\274\275\276" - "\375\225\226\227\375\220\220\222\336\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\263\261\261z\347\345" - "\345\377\347\345\345\377wvv\377...\377222\377222\377999\377===\377???\377" - "CCC\377HHH\377\225NK\377\321c_\377\305JJ\377\217>>\377vRT\377\326TP\377\303" - "II\377\237;;\377\264^K\377\304LJ\377\301HH\377e:8\377[UN\377]TK\377\\RH\377" - "`QD\377R-&\377c$$\377t,)\377\203E5\377\236ZD\377\326gU\377\342YU\377\344" - "VU\377\350ZW\377\363i\\\377\366{a\377\354\236n\377\363\254s\377\365\257u" - "\377\372\252t\377\372\247s\377\371\243q\377\372\241p\377\367\234n\377\361" - "\210j\377\354\201g\377\347~k\377\337\203\203\377\334}}\377\325tt\377\322" - "nn\377\314gg\377\321`\\\377\364xm\377\372\230{\377\364\320\275\377\364\363" - "\362\377\372\372\372\377\371\372\372\377\360\342\325\377\356\222~\377\343" - "[V\377\220B;\377}K%\377\206T!\377\202T&\377\177T)\377|T+\377xT/\377uT3\377" - "sT5\377oT9\377kT<\377iT?\377fTB\377XTP\377\250\250\250\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\304\303\303\324~\177\204" - "\357yx{\377vss\367\220\220\221\376\220\220\222\310\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\272\270" - "\270\215\347\345\345\377\347\345\345\377trr\377hSS\377gRR\377dRR\377iSS\377" - "cSS\377\\SS\377]TT\377}NL\377\306fX\377\320NN\377\311LL\377\214GF\377\230" - "QP\377\330VQ\377\306JJ\377\22677\377\305`P\377\307KK\377\270DD\377W+\27\377" - "h6\4\377h4\4\377|;\15\377\223K'\377\300YC\377\324gU\377\325v[\377\315WP\377" - "\344_X\377\340^T\377\353jX\377\366m]\377\371{^\377\371}`\377\367\204c\377" - "\366\212f\377\366|e\377\353k^\377\341[U\377\306OK\377\261HD\377\247TQ\377" - "\221NL\377qAA\377f?@\377c@@\377_AA\377\\BA\377ZCC\377XEE\377UEE\377\\II\377" - "\201BB\377\344VV\377\366qd\377\361\306\240\377\356\355\354\377\356\347\340" - "\377\363\224v\377\335TR\377sBB\377TSS\377UUU\377VVV\377WWW\377YYY\377ZZZ" - "\377[[[\377]]]\377___\377___\377___\377aaa\377bbb\377aaa\377\266\265\265" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\275" - "\273\274\321~\177\204\367onp\377ZUT\377\217\217\221\377\220\220\222\263\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\303\301\301\255\347\345\345\377\345\343\343\377unn\377\277" - "<<\377\240@@\377\224CC\377\222CC\377\202II\377\244??\377fPP\377\255DD\377" - "\332lZ\377\322NN\377\311KJ\377pCA\377\236SP\377\330VQ\377\314LL\377\2177" - "6\377\313nc\377\307JJ\377\22066\377^=9\377zN;\377\265ZC\377\316hQ\377\323" - "pY\377\320\\Q\377\331OP\377\333QQ\377\346WV\377\343cU\377\351nW\377\360l" - "Z\377\361`[\377\347_V\377\344VV\377\326PP\377\274NN\377\220AA\377qEE\377" - "oTT\377^QQ\377WQQ\377_^^\377```\377```\377aaa\377aaa\377bbb\377bbb\377bb" - "b\377bbb\377bbb\377ccc\377caa\377\211EE\377\361ZZ\377\370\237w\377\366\326" - "\263\377\366\253\212\377\347[V\377\206DD\377a__\377bbb\377ccc\377aaa\377" - "___\377___\377^^^\377[[[\377ZZZ\377ZZZ\377YYY\377WWW\377WWW\377VVV\377VV" - "V\377\274\273\273\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\262\260\261\304~\177\204\376\243\245\250\377\277\300\302\374" - "\220\220\222\377\220\220\222\235\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\307\305\305\302\347\345" - "\345\377\334\332\332\377a``\377XQQ\377VRR\377VSS\377UTT\377UTT\377XTT\377" - "WWW\377\226VT\377\332gX\377\325OO\377\256GG\377_[[\377\244h]\377\325XQ\377" - "\317MM\377\21374\377\250QF\377r)*\377\22798\377\273aO\377\313cR\377\305a" - "P\377\263DB\377\310JJ\377\326OO\377\336SS\377\344VV\377\346YW\377\343aU\377" - "\343^U\377\343UU\377\313LL\377\235<<\377wAA\377V<<\377[WW\377][[\377[[[\377" - "ZZZ\377YYY\377XXX\377WWW\377VVV\377VVV\377UUU\377UUU\377UUU\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377S;;\377\333QR\377\373\203g\377\366\273\222" - "\377\360d[\377\264HH\377VPP\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377UUU\377\317\315\315" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\247" - "\246\247\304~\177\204\377qoq\377vss\367\220\220\222\377\220\220\222\207\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0!\40\40\4\316\314\314\332\347\345\345\377\327\326\326\377ddd\377``" - "`\377```\377```\377```\377___\377^^^\377`]]\377\305m\\\377\326SQ\377\325" - "OO\377\215BC\377VVV\377\260sh\377\322SP\377\250>>\377m''\377\230:8\377\314" - "gS\377\272XH\377\241M@\377\236;;\377\260CC\377\301HH\377\314LL\377\320MM" - "\377\327PP\377\336SS\377\334QR\377\333QQ\377\271DE\377z55\377X==\377SNN\377" - "SRR\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377NFF\377" - "\301JK\377\374\204g\377\372\234r\377\343UT\377lAA\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377YYY\377\322\321\321\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\234\233\235\306~\177\204\377gde\377gdc\376\220\220" - "\222\377\220\220\222r\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0QQQ\12\323\321\321\357\347\345\345\377\311\310" - "\310\377XXX\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377fYT\377\333i_\377" - "\330PP\377\327OO\377gEG\377UTT\377\265vp\377{..\377\21654\377\314ZO\377\266" - "dL\377\212=5\377\20400\377\22144\377\241<<\377\254BB\377\261CC\377\275GG" - "\377\306II\377\315LL\377\313KK\377\277GG\377{22\377O<<\377OLL\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "SNN\377\274JJ\377\374\213i\377\371qb\377\256EE\377RKK\377TTT\377TTT\377T" - "TT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377```\377\331\327\327\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\215\215\217\277~\177\204\377\264\265\270" - "\377\261\262\264\371\220\220\222\377\220\220\222\\\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0baa\25\331\327" - "\327\372\347\345\345\377\271\270\270\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377\220]V\377\334nb\377\330PP\377\304IJ\377RFH\377USS\377\242" - "L\\\377\266NF\377\272aM\377\212C8\377{.-\377|..\377\20300\377\21633\377\224" - "66\377\234::\377\243==\377\255BB\377\261CC\377\265CC\377\21566\377Z::\377" - "MHH\377SSS\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377NKK\377\265GG\377\374|a\377\361][\377l>>\377" - "TSS\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377fff\377\344\343\343\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\204\204\207\304~\177" - "\204\377qnn\377\200~~\365\220\220\222\377\220\220\222F\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0qpp0\344\342" - "\342\377\347\345\345\377\262\261\261\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377VTS\377\276lY\377\330XS\377\327PP\377\237BB\377WLM\377\220SO\377\306" - "dQ\377\235M>\377{/.\377x+,\377y,,\377z--\377\177//\377\20511\377\21633\377" - "\22355\377\23188\377\234::\377\234::\377_.(\377A=7\377SSS\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377USS\377\302UT\377\374m`\377\305LL\377TJJ\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377lll\377\346\344\344\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\341\337\337\376~\177\203\303~\177\204\377]YY\377" - "tqr\377\220\220\222\376\220\220\2222\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\211\210\210C\347\345\345\377" - "\347\345\345\377\231\230\230\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "aSQ\377\333zl\377\330PP\377\256??\377p))\377\265PJ\377\260dL\377\17751\377" - "y,,\377y,,\377r**\377t++\377z--\377}..\377\20100\377\21011\377\22044\377" - "\22044\377\21222\377T0*\377GGD\377SSS\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377WSS\377\306QQ\377\373_`\377\214FE\377SSS\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377|{{\377\346\344\344\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\333\331\331\371{|\200\303\201\202\207\377\300\301\303\376\244" - "\244\246\372\220\220\222\373\220\220\222\37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\246\245\245b\347\345\345" - "\377\347\345\345\377\223\222\222\377TTT\377TTT\377TTT\377TTT\377TTT\377T" - "TT\377\204XT\377\335c\\\377\244<<\377\2030/\377\304bQ\377\224O>\377t,+\377" - "u++\377x,,\377u++\377s**\377t**\377x,,\377}..\377\200//\377\20511\377\210" - "22\377~0.\377?3'\377NPN\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377WQQ\377\307NN\377\350XX\377]DB\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377\211\211\211\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\330\326\326\362zz\177\321||\201\377okk\373\210\207\210" - "\372\220\220\222\370\220\220\222\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\263\261\261z\347\345\345\377\347" - "\345\345\377zzz\377TTT\377TTT\377TTT\377TTT\377TTT\377UTT\377\265g]\377\231" - "GD\377\233?:\377\303eP\377z:1\377m()\377o))\377t**\377r**\377u**\377p))\377" - "s**\377v++\377y,,\377~//\377~//\377}/.\377F5+\377PQP\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377^QQ\377\334UU\377\256CC\377SNN\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377\220\217\217\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\321\317\317\342{|\201" - "\333xx}\377YTT\377\201\200\201\377\220\220\222\357\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\274\272" - "\272\222\347\345\345\377\346\344\344\377rrr\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377_UR\377\217B8\377\243D?\377\253WF\377m+)\377g((\377i((\377j((\377" - "j((\377q**\377m((\377o))\377r**\377s**\377w,,\377t++\377y,,\377H*#\377LN" - "L\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377kRR\377" - "\347WW\377\201DD\377RRR\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "\244\243\243\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\307\305\305\325~\177\204\347\220\221\226\377\312\314\316\374\232" - "\232\234\376\220\220\222\331\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\303\301\301\261\347\345\345" - "\377\337\335\335\377hgg\377TTT\377TTT\377TTT\377TTT\377TTT\377iMK\377\262" - "ND\377\230WB\377c&%\377h((\377h((\377h((\377h((\377h((\377m))\377k((\377" - "n))\377n))\377r**\377r**\377x,,\377Z)$\377DHB\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377uRR\377\332SS\377T>>\377T" - "TT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377\256\255\255\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\300\277\277" - "\320~\177\204\361vux\377iee\372\215\215\217\376\220\220\222\304\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1" - "\1\1\1\307\306\306\304\347\345\345\377\333\331\331\377[ZZ\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377\233_Q\377\201H9\377U\40!\377T\36\37\377Z!#\377[\"%" - "\377[#&\377]#&\377]''\377_))\377]((\377`))\377d**\377c))\377h++\377c))\377" - "G=9\377SSS\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TSS\377\204GG\377\254GG\377UQQ\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377\267\266\266\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\266\265\266\277~\177\204\373rqt\377]XW\375\216\216" - "\220\377\220\220\222\256\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""988\3\315\314\314\341\347\345\345\377\320" - "\316\316\377ZZZ\377TTT\377TTT\377TTT\377TTT\377TTT\377c]S\377CDC\377L?E\377" - "JJ\377K=J\377QKO\377TQQ\377TQQ\377TQQ\377TQQ\377TQ" - "Q\377TQQ\377TQQ\377SSS\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TRR\377\233AA\377{66\377SSS\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377UUU\377\312\311\311\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\254\253\254\275~\177\204\377\241" - "\243\246\377\301\302\304\373\221\221\223\377\220\220\222\230\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0YXX\7" - "\321\317\317\363\347\345\345\377\276\275\275\377UUU\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377WRR\377\260" - "FF\377fEE\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377YYY\377" - "\317\316\316\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\240\240\241\276~\177\204\377qpr\377qnn\364\220\220\222\377\220\220" - "\222\203\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0ONN\30\334\332\332\375\347\345\345\377\272\271\271\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377[RR\377\212@@\377]MM\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377___\377\325\323\323\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\221\221\223\270~\177\204\377rpr\377njj\377\220\220" - "\222\377\220\220\222m\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0dcc/\346\344\344\377\347\345\345\377\240\237" - "\237\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377T" - "TT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT" - "\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377ddd\377\342\340\340\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\210\210\213\275~\177\204\377\262\264" - "\267\377\273\274\276\376\220\220\222\377\220\220\222W\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0~}}<\347\345" - "\345\377\347\345\345\377\236\235\235\377```\377```\377aaa\377```\377```\377" - "aaa\377```\377```\377aaa\377```\377aaa\377aaa\377aaa\377aaa\377aaa\377aa" - "a\377aaa\377aaa\377```\377```\377___\377^^^\377^^^\377]]]\377\\\\\\\377[" - "[[\377ZZZ\377YYY\377XXX\377WWW\377VVV\377VVV\377UUU\377UUU\377UUU\377UUU" - "\377UUU\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377" - "TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377TTT\377iii\377\343\341\341" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\342\340\340\376\200" - "\201\204\273~\177\204\377b^^\377olm\372\220\220\222\377\220\220\222B\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\232\231\231S\347\345\345\377\347\345\345\377\203\202\202\377eWE\377" - "c_P\377]e[\377\\e]\377[aY\377^XM\377^TJ\377[WP\377XZV\377XXT\377WXU\377W" - "VS\377WTQ\377VTR\377VTR\377UTS\377UUU\377TUU\377UUU\377UUU\377VVU\377WWV" - "\377WWW\377XXX\377YYY\377ccc\377[[[\377\\\\\\\377]]]\377^^^\377___\377``" - "`\377```\377aaa\377aaa\377aaa\377aaa\377aaa\377bbb\377bbb\377bbb\377bbb\377" - "bbb\377bbb\377bbb\377bbb\377bbb\377ccc\377ccc\377bbb\377ccc\377ccc\377cc" - "c\377ddd\377ccc\377bbb\377bbb\377ccc\377ddd\377ddd\377ccc\377bbb\377bbb\377" - "bbb\377ccc\377ccc\377aaa\377```\377___\377___\377^^^\377]]]\377\\\\\\\377" - "ZZZ\377YYY\377{{{\377\345\343\343\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\335\333\333\372{{\177\273~\177\204\377tqr\377{yy\377\220\220" - "\222\377\220\220\222,\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\253\252\252j\347\345\345\377\347\345\345\377" - "xwv\377\177\204X\377\212\200J\377\205\215Z\377\210\211T\377\201\231k\377" - "\233g\40\377\211\213U\377\216\200E\377\200\235p\377\210\214W\377\210\211" - "T\377\222s4\377\220u8\377\205\207U\377\206\203P\377\213u=\377\177\211]\377" - "|\213b\377{\210_\377\224U\24\377\222T\25\377\220T\27\377\216T\31\377\214" - "T\34\377fTA\377^^]\377\217t9\377\227|9\377\214k2\377\220w:\377\222\177A\377" - "\211r<\377\201g9\377yZ4\377w[7\377tY9\377u`>\377mT;\377kT=\377pcG\377pfJ" - "\377ldK\377eYH\377gbN\377bZL\377b]O\377_[P\377[TM\377YTN\377XTO\377YVQ\377" - "XVR\377VTR\377UTS\377UTS\377UUT\377UTT\377TTT\377TTT\377TTT\377TTT\377TT" - "T\377TTT\377UUU\377UUU\377VVV\377VVV\377WWW\377XXX\377YYY\377[[[\377[[[\377" - "\\\\\\\377\\\\\\\377^^^\377\214\213\213\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\333\331\331\364xy}\307\177\200\205\377\276" - "\300\302\376\252\253\255\375\220\220\222\376\220\220\222\27\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\262\260" - "\260v\347\345\345\377\342\340\340\377tss\377[YW\377ZXT\377[WR\377[VP\377" - "\\WO\377]UL\377[]V\377`WK\377aXK\377`^Q\377c^N\377g[H\377h^J\377gdQ\377e" - "m[\377mcI\377ljQ\377njO\377plP\377\177T)\377\202T&\377\204T#\377\207T\40" - "\377\212T\36\377dUE\377_^[\377\241~0\377\247z'\377\241i\34\377\265\215+\377" - "\275\231/\377\266\206#\377\256t\31\377\266\177\35\377\301\223%\377\300\216" - "!\377\274\203\33\377\254b\11\377\246T\2\377\312\233$\377\307\224\40\377\316" - "\242'\377\273{\23\377\317\244)\377\301\211\33\377\310\230#\377\305\224\"" - "\377\247Y\6\377\300\216!\377\277\216\"\377\272\206\40\377\265\177\35\377" - "\255s\31\377\243c\23\377\243f\26\377\267\220,\377\252z$\377\246y%\377\263" - "\2267\377\266\237<\377\261\231;\377\242\2012\377\213X\40\377\214^%\377\217" - "g+\377\215g-\377\211f/\377\207f2\377}T+\377{T-\377xT/\377uT2\377sT4\377r" - "T6\377]TJ\377\213\212\212\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\322\320\320\347z{\200\316{|\200\377[VU\376|z{\373\220" - "\220\222\374\220\220\222\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\271\270\270\213\347\345\345\377\345\343" - "\343\377\311\307\307\377\302\300\300\377\305\303\303\377\305\304\304\377" - "\301\300\300\377\272\271\271\377\264\263\263\377\253\252\252\377\243\242" - "\242\377\246\245\245\377\244\243\243\377\237\237\237\377\230\230\230\377" - "\222\221\221\377\210\210\210\377\201\200\200\377\203\203\203\377\200\200" - "\200\377}}}\377xxx\377sss\377lkk\377fff\377fff\377ccc\377ccc\377eee\377^" - "^^\377\\\\[\377ZYY\377XXW\377XWU\377WVT\377WUS\377XUQ\377YUP\377ZUN\377[" - "UM\377]UK\377^TI\377bWI\377eYH\377hZF\377hVA\377n]B\377sbB\377s]=\377{h@" - "\377tU4\377\202k<\377\206n;\377\210m8\377\211j5\377\214k2\377\211_(\377\221" - "i,\377\233z2\377\236z/\377\224`\37\377\250\204.\377\264\2276\377\251}&\377" - "\263\211)\377\237^\23\377\253s\33\377\272\214%\377\302\227)\377\300\221$" - "\377\275\211\37\377\255e\14\377\246T\2\377\246T\1\377\247T\1\377\250T\0\377" - "\250T\0\377jT>\377\237\236\236\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\311\307\310\331~\177\204\334}~\202\377okk\376\204" - "\203\204\376\220\220\222\352\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\300\277\277\243\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\346\344\344\377\345\343\343\377\343\341\341\377\341" - "\337\337\377\340\336\336\377\341\337\337\377\340\337\337\377\337\336\336" - "\377\332\331\331\377\324\323\323\377\316\314\314\377\314\312\312\377\313" - "\311\311\377\311\310\310\377\310\306\306\377\302\301\301\377\273\272\272" - "\377\262\261\261\377\256\255\255\377\253\252\252\377\250\247\247\377\246" - "\245\245\377\241\240\240\377\231\230\230\377\220\217\217\377\212\212\212" - "\377\207\207\207\377\205\204\204\377\203\202\202\377\177~~\377www\377ooo" - "\377jjj\377ggg\377eee\377ddd\377bbb\377___\377\\\\\\\377ZZZ\377XXX\377VV" - "V\377VVV\377UUU\377UTT\377UTS\377UTS\377WVS\377XVR\377XTP\377YUO\377[TM\377" - "\\TL\377]TK\377_TI\377bTF\377dTC\377XTP\377\253\252\252\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\303\302\302\320~\177\204" - "\351\212\213\217\377\304\305\307\370\235\235\237\374\220\220\222\324\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\303\302\302\262\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\346\344\344\377\345\343\343\377\344\342\342\377\343" - "\341\341\377\343\341\341\377\343\341\341\377\343\341\341\377\341\337\337" - "\377\333\331\331\377\322\321\321\377\320\317\317\377\317\316\316\377\316" - "\315\315\377\315\314\314\377\313\311\311\377\302\301\301\377\265\264\264" - "\377\262\262\262\377\260\257\257\377\255\254\254\377\254\253\253\377\251" - "\250\250\377\233\233\233\377\221\221\221\377\217\216\216\377\214\214\214" - "\377\211\211\211\377\210\207\207\377\205\205\205\377\306\304\304\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\273\271\272" - "\274~\177\204\366tsw\377[VU\375\211\210\212\376\220\220\222\277\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\306\305\305\303\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\262\260\261\266~\177" - "\204\377zz}\377jff\366\215\215\217\376\220\220\222\251\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\312" - "\311\311\335\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\245\244\246\266~\177\204\377" - "\235\236\241\377\307\311\313\375\222\222\224\377\220\220\222\223\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\314\312\312\355\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\226\225\227\260" - "~\177\204\377kij\377`\\[\371\217\217\221\377\220\220\222~\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\274\273\273\276\345\343\343\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\214\214\216\266~\177\204" - "\377{z|\377vss\377\220\220\222\377\220\220\222h\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0LLL\13\231" - "\231\232Z\255\255\260\263\265\265\270\357\272\271\274\366\274\273\276\370" - "\300\277\301\375\304\303\304\374\307\305\306\372\314\313\313\375\322\320" - "\321\377\325\324\324\375\327\325\325\374\333\331\331\375\341\337\337\377" - "\346\344\344\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\344\342\342\376\202\203\206\263~\177\204\377\250\251\254\377\265" - "\266\270\371\220\220\222\377\220\220\222S\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\275\276\303\1\275\276\303\33\275\276\3036\275\276\303D\275\276\303Q\275" - "\276\303^\274\275\302l\267\270\275y\263\264\271\206\261\262\266\223\263\264" - "\270\237\261\261\266\255\256\256\262\273\253\253\257\306\254\254\260\317" - "\257\257\262\331\263\263\266\347\266\266\271\360\271\270\273\365\272\272" - "\274\367\274\274\276\372\300\277\301\373\302\302\303\366\304\303\304\365" - "\306\305\306\370\312\311\311\372\317\316\316\367\322\320\321\366\323\321" - "\321\371\330\326\326\375\340\336\336\377\346\344\344\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345" - "\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377" - "\347\345\345\377\347\345\345\377\347\345\345\377\340\336\336\373zz~\262~" - "\177\204\377b^_\377mij\373\220\220\222\377\220\220\222=\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\275\276\303\1\275" - "\276\303\5\275\276\303\10\275\276\303\13\275\276\303\17\275\276\303\32\275" - "\276\303'\275\276\3034\275\276\303B\275\276\303O\274\275\302\\\270\271\276" - "h\265\266\273t\265\266\272\201\265\266\273\220\260\261\265\232\244\244\250" - "\335\240\241\245\371\243\243\247\371\246\247\252\373\253\253\256\374\260" - "\260\263\371\264\264\266\371\266\266\270\373\270\267\271\374\273\273\274" - "\371\276\275\277\371\277\276\277\374\300\277\300\374\304\303\304\372\310" - "\306\307\372\312\311\311\374\315\314\314\375\326\325\325\375\340\336\336" - "\377\346\344\344\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\336\334\334\367wx|\306~\177\204\377xuv\376|z{\372\220\220\222" - "\377\220\220\222!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\224\225\232L\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\225\226\233\377\225\226\233\377\226\227\234\377\230\231\236\377\232" - "\233\240\377\234\235\242\377\236\237\244\377\240\241\246\377\241\242\247" - "\377\243\244\251\376\244\245\252\377\244\245\251\377\236\237\244\373\232" - "\233\237\372\231\231\235\375\233\233\237\374\235\236\242\371\242\243\246" - "\372\250\250\253\376\254\254\257\374\257\256\261\371\260\260\262\371\264" - "\263\265\375\270\267\271\370\271\270\271\364\271\267\271\366\273\272\273" - "\375\303\302\302\372\307\305\305\375\314\313\313\367\325\323\323\373\336" - "\334\334\377\345\343\343\377\346\344\344\377\346\344\344\377\346\344\344" - "\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347" - "\345\345\377\347\345\345\377\347\345\345\377\347\345\345\377\347\345\345" - "\377\347\345\345\377\312\310\310\332}~\203\333\177\200\205\377\277\301\303" - "\371\246\247\251\372\220\220\222\331\220\220\222\3\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224\225\232\1\224\225\232\306\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\226\227\234\377\245\245\250\371\235\236\242\372\234\235" - "\242\377\236\237\244\377\240\241\246\377\237\240\245\377\225\226\232\363" - "\240\241\246\227\227\230\235}\221\222\226}\216\216\222\210\217\217\223\234" - "\224\224\227\254\234\234\237\261\243\243\246\274\244\243\246\321\245\244" - "\247\340\253\252\255\337\260\257\261\342\261\260\261\352\260\260\261\356" - "\266\265\266\352\276\274\275\350\275\273\274\325\211\211\214\263~\177\204" - "\376~\177\204\377\206\206\212\337\220\220\222\327\220\220\222;\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224\225\232" - "D\224\225\232\376\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\226\227\233\377\244\244\247\370" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\215\216" - "\222\366\214\214\221\250\225\226\233\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\275\276\303\4\275\276\303\16\266\267\274\34" - "\264\265\272(\257\260\265-\244\245\252:\233\234\241P\227\230\235a\234\235" - "\242l\216\217\223`\220\220\2220\220\220\222\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224\225\232\2\224\225" - "\232\306\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\241\241\244\375\231\232" - "\236\371\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\207\207\213\353\225\226\233=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224\225\232" - "V\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\225\226\233\377\245\245\250\367" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\215\216" - "\222\367\214\215\221\260\225\226\233\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\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224\225\232" - "\11\224\225\232\343\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\243\244\246\374" - "\230\230\235\371\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\206\207\213\353\225\226\2337\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224" - "\225\232\210\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\227\230\235\377\244" - "\245\247\366\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\212\213\220\365\216\217\224\245\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224" - "\225\2321\224\225\232\375\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\247\247" - "\251\371\225\226\233\374\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\376\206\207\213\351\225\226\233'\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\224" - "\225\232\4\224\225\232\326\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\236\236" - "\242\375\237\237\243\366\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\207\210\214\356\222\223\230\211\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\224\225\232\224\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\225\226" - "\233\377\250\250\252\366\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\222\223\227\374\207\210\214\327\225\226\233\17\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\324\324\326\6\316\316\320\21\307\310\312\34\301\301" - "\304/\272\273\276F\263\264\267\\\255\256\261r\247\250\253e\230\231\236v\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\247\247\251\372\227" - "\227\234\370\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\205\206\212\353\225\226\233a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\11\376\376\376" - "\26\376\376\376%\377\377\3779\377\377\377P\375\375\375f\367\367\367|\360" - "\360\361\222\351\352\353\251\343\343\344\277\334\334\336\325\325\326\330" - "\345\317\317\321\361\310\311\313\375\301\302\304\377\267\270\273\374\255" - "\255\261\373\242\243\246\376\227\227\233\370\215\216\222\375\222\223\230" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\235\235\241\374\241\241\244" - "\366\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\215" - "\216\222\365\213\214\220\267\225\226\233\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\1\377\377\377\14\377\377\377\35\377" - "\377\377.\377\377\377C\377\377\377Z\377\377\377p\377\377\377\206\377\377" - "\377\234\377\377\377\263\377\377\377\311\377\377\377\337\377\377\377\354" - "\377\377\377\365\377\377\377\375\377\377\377\377\377\377\377\377\371\371" - "\371\367\350\350\351\364\331\331\332\372\306\306\310\362\266\266\271\370" - "\247\247\252\367\230\231\234\364\215\216\222\374\200\201\206\365yz~\373t" - "uz\375qrw\374pqv\377pqv\377pqv\377\211\212\217\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\225\226\233\376\251\251\253\363\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\206\206\212\350" - "\225\226\233'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\374\374\2\377\377\377\222" - "\377\377\377\323\377\377\377\351\377\377\377\363\377\377\377\371\377\377" - "\377\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\371\362\362" - "\363\327\316\317\320\327\257\260\262\341\215\215\221\335|}\201\362vw|\374" - "rsw\373pqv\376pqv\377pqv\377pqv\377pqv\377pqv\377pqv\377pqv\377pqv\377pq" - "v\377pqv\377pqv\377pqv\376\200\201\206\375\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377" - "\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225" - "\232\377\224\225\232\377\250\250\252\365\225\226\233\372\224\225\232\377" - "\224\225\232\377\223\224\231\363\222\223\230\363\207\207\214\351\213\214" - "\221\240\205\206\213[\205\206\213F\205\206\2132\205\206\213\40\205\206\213" - "\17\205\206\213\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\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\313\313\313\5\310\310\310\316\316\316\316\353\324\324\324\352\333\333\333" - "\352\341\341\341\357\353\352\352\352\357\357\357\362\370\370\370\355\376" - "\376\376\362\377\377\377\376\377\377\377\377\377\377\377\377\377\377\377" - "\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\374\374" - "\374\374\374\367\367\367\357\346\346\347\353\322\322\323\362\274\275\277" - "\354\253\254\257\365\231\231\235\356\214\215\221\366}~\202\362qrv\365bcg" - "\367TUX\365MNQ\331FGJ\272==@\232./1z\26\26\27\\335sFFH\226SSV\266]]`\324" - "cdh\364ffj\376mnr\377\200\201\205\377\220\221\226\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224" - "\225\232\377\224\225\232\377\224\225\232\377\224\225\232\377\224\225\232" - "\373\222\223\230\354\220\221\226\362\216\217\224\353\222\223\227\354\214" - "\215\222\351\210\211\216\357\206\207\214\356\205\206\213\374\205\206\213" - "\375\205\206\213\377\205\206\213\377\205\206\213\377\205\206\213\377\205" - "\206\213\376\205\206\213\374\205\206\213\371\205\206\213\361\207\210\215" - "\320\222\222\226\277\237\237\242<\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\262\262\262\272\262\262\262\376\262\262\262\376\262\262\262\376\262\262" - "\262\376\275\275\275\377\262\262\262\376\262\262\262\376\262\262\262\375" - "\264\264\264\361\274\274\274\356\303\303\303\366\314\314\314\356\323\323" - "\323\367\335\335\335\362\345\345\345\364\355\355\355\367\370\370\370\362" - "\374\374\374\375\375\375\375\375\371\371\371\376\362\363\363\377\354\354" - "\355\377\345\345\346\377\337\337\340\377\330\330\332\377\321\322\324\377" - "\306\307\311\370\302\302\305\333\275\276\301\276\267\270\273\243\260\261" - "\264\210\252\253\256m\243\244\250S\235\235\2418\226\227\233\35\217\220\225" - "\11\211\212\217\4\214\215\222\1\224\225\232\24nnr4CCER557sCCF\220QRU\261" - "[[_\317ccg\357ffj\371uuy\376\213\214\221\377\223\224\231\370\221\222\227" - "\362\217\220\225\364\215\216\223\363\213\214\221\361\211\212\217\363\206" - "\207\214\357\205\206\213\367\205\206\213\377\205\206\213\377\205\206\213" - "\377\205\206\213\377\205\206\213\377\205\206\213\377\205\206\213\377\205" - "\206\213\376\206\207\213\376\207\210\214\371\213\214\220\365\221\221\225" - "\366\226\227\231\365\234\234\237\364\242\242\244\364\250\251\251\362\257" - "\257\257\364\262\262\262\376\262\262\262\376\261\261\261\251\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\247\247\247\40\246\246\246f\244\244\244\252" - "\243\243\243\332\242\242\242\357\266\265\265\371\242\242\242\376\242\242" - "\242\376\242\242\242\376\242\242\242\376\242\242\242\376\242\242\242\376" - "\242\242\242\376\242\242\242\376\242\242\242\376\242\242\242\376\242\242" - "\242\376\242\242\242\376\243\243\243\374\252\252\252\364\261\261\261\372" - "\270\270\270\366\276\276\276\367\302\302\302\373\306\306\307\365\307\307" - "\310\375\310\311\312\367\307\310\311\374\303\303\306\376\275\276\301\375" - "\267\270\273\377\261\261\264\377\252\253\256\377\243\244\250\377\235\235" - "\241\377\226\227\233\377\217\220\225\370\211\212\217\342\205\206\213\313" - "\205\206\213\261\205\206\213\227\205\206\213|\205\206\213a\205\206\213G\205" - "\206\213K\205\206\213k\205\206\213\215\205\206\213\302z{\200\367z{\200\376" - "\205\206\212\377\205\206\213\377\205\206\213\377\205\206\213\377\205\206" - "\213\377\205\206\213\377\205\206\213\377\205\206\213\377\205\206\213\375" - "\206\207\214\376\210\211\215\367\214\214\220\374\217\217\222\366\223\223" - "\225\373\226\227\230\366\233\233\234\372\236\236\237\366\241\241\241\376" - "\242\242\242\376\242\242\242\376\242\242\242\376\242\242\242\376\242\242" - "\242\376\242\242\242\376\242\242\242\376\242\242\242\376\242\242\242\376" - "\242\242\242\357\236\236\236\22\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\230\230\230\11\235\235\235\36\230\230\2305\227\227" - "\227S\226\226\226q\225\225\225\216\224\224\224\254\223\223\223\312\222\222" - "\222\344\222\222\222\362\222\222\222\375\222\222\222\376\222\222\222\376" - "\222\222\222\376\222\222\222\376\222\222\222\376\222\222\222\376\222\222" - "\222\376\222\222\222\376\222\222\222\376\222\222\222\376\222\222\222\376" - "\222\222\222\376\222\222\222\376\224\224\224\373\226\227\227\372\230\231" - "\231\375\232\232\233\370\232\232\234\376\231\232\234\372\227\227\232\374" - "\224\224\227\375\217\220\224\373\211\212\217\377\205\206\213\375\205\206" - "\213\377\205\206\213\377\205\206\213\377\205\206\213\377\205\206\213\377" - "\205\206\213\377\205\206\213\377\205\206\213\377\205\206\213\377\205\206" - "\213\377\205\206\213\377\205\206\213\376\205\206\213\377\206\206\213\373" - "\207\207\213\376\210\210\213\372\211\212\214\376\213\213\215\371\215\215" - "\217\375\217\217\220\371\221\221\221\376\222\222\222\376\222\222\222\376" - "\222\222\222\376\222\222\222\376\222\222\222\376\222\222\222\376\222\222" - "\222\376\222\222\222\376\222\222\222\376\222\222\222\375\222\222\222\360" - "\222\222\222\336\224\224\224\275\225\225\225\233\226\226\226y\226\226\226" - "W\230\230\2306\230\230\230\32\231\231\231\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\210\210\210\3\210\210\210\23\210\210\210&\207" - "\207\207B\206\206\206`\205\205\205~\204\204\204\233\203\203\203\271\202\202" - "\202\326\202\202\202\351\201\201\201\372\201\201\201\376\201\201\201\376" - "\201\201\201\376\201\201\201\376\201\201\201\376\201\201\201\376\201\201" - "\201\376\201\201\201\376\201\201\201\376\201\201\201\376\201\201\201\376" - "\201\201\201\376\201\201\201\376\201\201\201\376\222\222\222\376\207\207" - "\210\374\200\201\201\376\200\201\202\375\200\201\203\375\201\201\204\376" - "\201\202\205\375\202\203\206\377\202\203\207\377\201\202\205\376\201\201" - "\204\376\200\201\202\375\200\201\202\375\200\201\201\375\201\201\201\376" - "\201\201\201\376\201\201\201\376\201\201\201\376\201\201\201\376\201\201" - "\201\376\201\201\201\376\201\201\201\376\201\201\201\376\201\201\201\376" - "\201\201\201\376\201\201\201\375{{{\365rrs\361lmm\320mnn\250ttty~~~K\210" - "\210\210'\210\210\210\21\210\210\210\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0yy" - "y\1yyy\13yyy\30www2vvvOuuumttt\213sss\250rrr\306qqq\337qqq\364ppp\376ppp" - "\376ppp\376ppp\376ppp\376ppp\376\222\221\221\376\200\200\200\376ppp\376p" - "pp\376ppp\376ppp\376ppp\376ppp\376ppp\376ppp\376ppp\376ppp\376ppp\376ppp" - "\376ppp\376ppp\376ppp\376ppp\376ppp\376kkk\366aab\364STU\352FGH\346<<>\306" - "124\236\"#&o\25\26\31B\5\6\12\32\3\4\10\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0iii\5iii\15ggg!fff?eee\\" - "dddzccc\230bbb\265yyy\321ffg\347ZZZ\373\\\\\\\376```\376```\376```\376``" - "`\376```\376```\376```\376___\376XXX\372OOP\370CDE\357;<=\341346\273()+\242" - "\25\26\31\205\13\14\17q\4\5\11X\3\4\10""3\3\4\10\22\3\4\10\4\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0ZZZ\1YYY\5::;\12\34\35\40""0\35\36\40U,-/|11" - "3\221013\257/01\301**,\257\34\35\40\240\14\15\21\200\7\10\13`\4\5\11>\3\4" - "\10\33\3\4\10\6\3\4\10\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\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", -}; - -struct sdlappicon sdlappicon = { - 128, 128, - sdlappicon_pixels -}; diff --git a/source/kenbuild/rsrc/build_icon.icns b/source/kenbuild/rsrc/build_icon.icns deleted file mode 100644 index 9240c31d5..000000000 Binary files a/source/kenbuild/rsrc/build_icon.icns and /dev/null differ diff --git a/source/kenbuild/rsrc/build_icon.ico b/source/kenbuild/rsrc/build_icon.ico deleted file mode 100644 index 63ae6a308..000000000 Binary files a/source/kenbuild/rsrc/build_icon.ico and /dev/null differ diff --git a/source/kenbuild/rsrc/build_icon.png b/source/kenbuild/rsrc/build_icon.png deleted file mode 100644 index c9a043e28..000000000 Binary files a/source/kenbuild/rsrc/build_icon.png and /dev/null differ diff --git a/source/kenbuild/rsrc/build_icon.xcf b/source/kenbuild/rsrc/build_icon.xcf deleted file mode 100644 index 5f807a76e..000000000 Binary files a/source/kenbuild/rsrc/build_icon.xcf and /dev/null differ diff --git a/source/kenbuild/rsrc/buildres.rc b/source/kenbuild/rsrc/buildres.rc deleted file mode 100644 index 925d236dd..000000000 --- a/source/kenbuild/rsrc/buildres.rc +++ /dev/null @@ -1,71 +0,0 @@ -#define NEED_COMMCTRL_H -#include "windows_inc.h" -#include "startwin.editor.h" - -RSRC_ICON ICON "build_icon.ico" -RSRC_BMP BITMAP "build.bmp" - -WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200 -STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU -CAPTION "Startup" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 32, 32 - CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170 - CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14 - CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14 - - CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32 -END - -WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD -CAPTION "Dialog" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "&2D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 8, 50, 8 - CONTROL "", IDC2DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 6, 80, 56 - CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 148, 8, 49, 10 - CONTROL "&3D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 24, 50, 8 - CONTROL "", IDC3DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 22, 80, 56 - CONTROL "&Always show configuration on start", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8 -END - -#define FILEVER 1,9,9,9 -#define PRODUCTVER 1,9,9,9 -#define STRFILEVER "2.0.0devel\0" -#define STRPRODUCTVER "2.0.0devel\0" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION FILEVER - PRODUCTVERSION PRODUCTVER - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x3L -#else - FILEFLAGS 0x2L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "Mapster32 for KenBuild" - VALUE "FileVersion", STRFILEVER - VALUE "InternalName", "Mapster32" - VALUE "LegalCopyright", "Copyright © 2015 EDuke32 Developers, 2000, 2003 Ken Silverman" - VALUE "OriginalFilename", "ekenbuild-editor.exe" - VALUE "ProductName", "Mapster32" - VALUE "ProductVersion", STRPRODUCTVER - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -1 24 "manifest.build.xml" diff --git a/source/kenbuild/rsrc/game.bmp b/source/kenbuild/rsrc/game.bmp deleted file mode 100644 index 1b00a3ad0..000000000 Binary files a/source/kenbuild/rsrc/game.bmp and /dev/null differ diff --git a/source/kenbuild/rsrc/game.xcf b/source/kenbuild/rsrc/game.xcf deleted file mode 100644 index fadc54b2d..000000000 Binary files a/source/kenbuild/rsrc/game.xcf and /dev/null differ diff --git a/source/kenbuild/rsrc/game32_icon.c b/source/kenbuild/rsrc/game32_icon.c deleted file mode 100644 index aa71e7fe1..000000000 --- a/source/kenbuild/rsrc/game32_icon.c +++ /dev/null @@ -1,167 +0,0 @@ -/* GIMP RGBA C-Source image dump (game_icon.c) */ - -#include "sdl_inc.h" -#include "sdlappicon.h" - -static Uint8 sdlappicon_pixels[] = { - "z_A\377\\J6\377\\J6\377\206t`\377\214zf\377\214zf\377\214zf\377\214zf\377" - "\214zf\377\214zf\377\214zf\377\214zf\377\214zf\377\214zf\377\214zf\377\214" - "zf\377\214zf\377\214zf\377\214zf\377\214zf\377\214zf\377\214zf\377\214zf" - "\377\214zf\377\214zf\377\214zf\377\214zf\377\214zf\377\206t`\377\\J6\377" - "\\J6\377z_A\377\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377fM3\377fM3\377t" - "tt\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377ttt\377fM3\377fM3\377\\J6\377\\J6\377fM3\377" - "fM3\377ttt\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377ttt\377fM3\377fM3\377\\J6\377\\J6\377" - "\40\40\40\377\40\40\40\377\\\\\\\377@@@\377\200\200\200\377ddd\377hhh\377" - "hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hh" - "h\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377ddd\377|||\377@@@\377\\\\" - "\\\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40\40\40\377\40\40\40\377" - "lll\377hhh\377\200\200\200\377hhh\377\200\200\200\377\200\200\200\377\200" - "\200\200\377lll\377jjj\377rrr\377lll\377lll\377vvv\377bbb\377lll\377\200" - "\200\200\377lll\377hhh\377ttt\377\200\200\200\377\200\200\200\377\200\200" - "\200\377ppp\377xxx\377hhh\377lll\377\40\40\40\377\40\40\40\377\\J6\377\\" - "J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200\377h" - "hh\377\200\200\200\377\200\200\200\377\200\200\200\377lll\377jjj\377rrr\377" - "jjj\377jjj\377\200\200\200\377lll\377lll\377\200\200\200\377lll\377|||\377" - "lll\377\200\200\200\377\200\200\200\377\200\200\200\377ppp\377xxx\377\200" - "\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40\40\40\377" - "\40\40\40\377ttt\377\200\200\200\377\200\200\200\377hhh\377\200\200\200\377" - "\200\200\200\377\200\200\200\377vvv\377lll\377|||\377ppp\377ppp\377vvv\377" - "lll\377vvv\377lll\377vvv\377lll\377~~~\377\200\200\200\377\200\200\200\377" - "\200\200\200\377ppp\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40" - "\40\377\\J6\377\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377" - "\200\200\200\377ddd\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377" - "hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hh" - "h\377ddd\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6" - "\377\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200" - "\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377ppp\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\" - "J6\377\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200" - "\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377ppp\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\" - "J6\377\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200" - "\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377ppp\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\" - "J6\377\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200" - "\377ddd\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377" - "hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377ddd\377xx" - "x\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40" - "\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200\377hhh\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377ppp\377" - "xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377" - "\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200\377hhh\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "ppp\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377\\" - "J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200\377h" - "hh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377ppp\377xxx\377\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377" - "\\J6\377\40\40\40\377\40\40\40\377ttt\377\200\200\200\377\200\200\200\377" - "lll\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hh" - "h\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377xxx\377" - "\200\200\200\377ttt\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40\40\40" - "\377\40\40\40\377ttt\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377ttt\377\40\40\40\377\40\40" - "\40\377\\J6\377\\J6\377\40\40\40\377\40\40\40\377fff\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377fff\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40\40\40\377\40" - "\40\40\377<<<\377fff\377ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377" - "ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377ttt\377tt" - "t\377ttt\377ttt\377ttt\377ttt\377fff\377<<<\377\40\40\40\377\40\40\40\377" - "\\J6\377\\J6\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\\J6\377\\J6\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377$$0\377>>>\377HHH\377DDD\377DDD\377" - "FFF\377LLL\377HHH\377HHH\377JJJ\377LLL\377LLL\377LLL\377LLL\377JJJ\377@@" - "@\377444\377444\377444\377444\377,,,\377\40\40\40\377\40\40\40\377\\J6\377" - "\\J6\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377<<<\377rrr\377ppp\377VVV\377PPP\377RRR\377jjj\377" - "xxx\377vvv\377ttt\377zzz\377|||\377xxx\377xxx\377zzz\377rrr\377PPP\377HH" - "H\377HHH\377HHH\377FFF\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377DDD\377lll\377lll\377000\377\40\40\40\377\40\40\40\377TTT\377" - "xxx\377ttt\377ttt\377xxx\377|||\377\200\200\200\377\200\200\200\377zzz\377" - "ttt\377PPP\377HHH\377HHH\377HHH\377HHH\377\40\40\40\377\40\40\40\377\\J6" - "\377\\J6\377(((\377```\377hhh\377ttt\377NNN\377VVV\377\40\40\40\377DDD\377" - "hhh\377lll\377000\377\40\40\40\377\40\40\40\377TTT\377vvv\377vvv\377vvv\377" - "|||\377xxx\377|||\377|||\377~~~\377vvv\377PPP\377HHH\377HHH\377HHH\377HH" - "H\377\40\40\40\377\40\40\40\377\\J6\377\\J6\377```\377\250\250\250\377~~" - "~\377\250\250\250\377lll\377|||\377\40\40\40\377DDD\377jjj\377lll\377000" - "\377\40\40\40\377\40\40\40\377TTT\377ttt\377xxx\377xxx\377~~~\377|||\377" - "xxx\377xxx\377\202\202\202\377|||\377PPP\377HHH\377HHH\377HHH\377HHH\377" - "\40\40\40\377\40\40\40\377\\J6\377\\J6\377|||\377\200\200\200\377@@@\377" - "\250\250\250\377\240\240\240\377|||\377\40\40\40\377FFF\377vvv\377rrr\377" - "000\377\40\40\40\377\40\40\40\377TTT\377vvv\377zzz\377xxx\377~~~\377|||\377" - "xxx\377|||\377\214\214\214\377~~~\377PPP\377HHH\377HHH\377HHH\377HHH\377" - "\"\"\"\377:0%\377\\J6\377\\J6\377```\377\250\250\250\377~~~\377\250\250\250" - "\377lll\377|||\377\40\40\40\377HHH\377xxx\377rrr\377000\377\40\40\40\377" - "\40\40\40\377XXX\377\200\200\200\377\200\200\200\377\200\200\200\377\210" - "\210\210\377\206\206\206\377~~~\377zzz\377\204\204\204\377ttt\377PPP\377" - "HHH\377HHH\377HHH\377HHH\3770+%\377T@*\377hQ8\377tX:\3770,(\377```\377hh" - "h\377ttt\377NNN\377VVV\377\40\40\40\377HHH\377xxx\377ppp\377000\377\40\40" - "\40\377\40\40\40\377XXX\377|||\377zzz\377xxx\377\202\202\202\377\200\200" - "\200\377\200\200\200\377|||\377\202\202\202\377ttt\377PPP\377HHH\377HHH\377" - "HHH\377HHH\377$$$\377L9&\377\\J6\377\230tL\377fM3\377($\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377($\40\377`VL\377ttt\377ppp\377XXX" - "\377XXX\377\\\\\\\377ttt\377|||\377ppp\377xxx\377|||\377xxx\377|||\377\206" - "\206\206\377\202\202\202\377xxx\377PPP\377HHH\377HHH\377HHH\377FFF\377\40" - "\40\40\377\40\40\40\377\\J6\377\230tL\377\230tL\377tX:\377\\J6\377\\J6\377" - "\\J6\377\\J6\377tX:\377\216sU\377\200nZ\377\204r^\377\204r^\377\212xd\377" - "\216|h\377\222\200l\377\214zf\377\210vb\377\210vb\377\210vb\377\210vb\377" - "\212xd\377\220~j\377\214zf\377\210vb\377tbN\377p^J\377p^J\377p^J\377jXD\377" - "\\J6\377\\J6\377z_A\377", -}; - -struct sdlappicon sdlappicon = { - 32, 32, - sdlappicon_pixels -}; diff --git a/source/kenbuild/rsrc/game_icon.c b/source/kenbuild/rsrc/game_icon.c deleted file mode 100644 index f4a2425e0..000000000 --- a/source/kenbuild/rsrc/game_icon.c +++ /dev/null @@ -1,687 +0,0 @@ -/* GIMP RGBA C-Source image dump (game_icon.c) */ - -#include "sdl_inc.h" -#include "sdlappicon.h" - -static Uint8 sdlappicon_pixels[] = { - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230t" - "L\0\40\40\40\377@0\40\377`H0\377`H0\377@0\40\377hhh\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377@0\40" - "\377`H0\377`H0\377@0\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377`H0" - "\377\230tL\0\230tL\0`H0\377hhh\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377hhh\377`H0\377\230tL\0\230tL\0`H" - "0\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377`H0\377\230tL\0\230tL\0`H" - "0\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377hhh\377`H0\377\230tL\0\230tL\0`H0\377\40\40\40\377\230" - "tL\0\230tL\0\40\40\40\377@0\40\377`H0\377`H0\377@0\40\377hhh\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "hhh\377@0\40\377`H0\377`H0\377@0\40\377\40\40\40\377\230tL\0\230tL\0\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377```\377" - "@@@\377```\377\200\200\200\377\200\200\200\377```\377```\377```\377```\377" - "```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377" - "```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377\200\200\200\377\200\200\200\377```\377" - "@@@\377```\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377hhh\377@@@\377\40\40\40\377@@@\377\200\200\200\377\200" - "\200\200\377```\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377" - "ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377pp" - "p\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377" - "ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377```\377pp" - "p\377\200\200\200\377@@@\377\40\40\40\377@@@\377hhh\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377```\377@@@\377" - "```\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377XXX\377XXX\377XXX\377ppp\377\200\200\200\377XXX\377\200" - "\200\200\377\200\200\200\377XXX\377\200\200\200\377XXX\377XXX\377XXX\377" - "\200\200\200\377XXX\377\200\200\200\377\200\200\200\377\200\200\200\377X" - "XX\377XXX\377XXX\377xxx\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377```\377ppp\377\200\200\200\377```\377@@@\377```\377hhh\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230t" - "L\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377XXX\377\200\200" - "\200\377xxx\377XXX\377\200\200\200\377XXX\377\200\200\200\377\200\200\200" - "\377XXX\377\200\200\200\377\200\200\200\377XXX\377\200\200\200\377\200\200" - "\200\377XXX\377\200\200\200\377\200\200\200\377\200\200\200\377XXX\377\200" - "\200\200\377ppp\377XXX\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377XXX\377XXX\377XXX\377ppp\377\200\200\200\377XXX\377\200\200\200" - "\377\200\200\200\377XXX\377\200\200\200\377\200\200\200\377XXX\377\200\200" - "\200\377\200\200\200\377XXX\377\200\200\200\377\200\200\200\377\200\200\200" - "\377XXX\377\200\200\200\377\200\200\200\377XXX\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377XXX\377\200\200\200\377xxx\377XXX\377" - "\200\200\200\377XXX\377xxx\377xxx\377XXX\377\200\200\200\377\200\200\200" - "\377XXX\377\200\200\200\377\200\200\200\377XXX\377\200\200\200\377\200\200" - "\200\377\200\200\200\377XXX\377\200\200\200\377ppp\377XXX\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377p" - "pp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377XXX\377XXX\377XXX\377ppp\377" - "\200\200\200\377hhh\377XXX\377XXX\377hhh\377\200\200\200\377XXX\377XXX\377" - "XXX\377\200\200\200\377XXX\377XXX\377XXX\377\200\200\200\377XXX\377XXX\377" - "XXX\377xxx\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377" - "ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377h" - "hh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230" - "tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377`" - "``\377```\377```\377```\377```\377```\377```\377```\377```\377```\377```" - "\377```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377" - "```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377```\377```\377```\377ppp\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "```\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377pp" - "p\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377" - "ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377pp" - "p\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377```\377ppp\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230t" - "L\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377" - "ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377h" - "hh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230" - "tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377p" - "pp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377" - "```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377" - "```\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377```\377ppp\377ppp\377ppp\377ppp\377ppp\377" - "ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377pp" - "p\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377" - "ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377pp" - "p\377ppp\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230" - "tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377p" - "pp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377ppp\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230t" - "L\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377```\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377```\377ppp\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377```\377```\377" - "```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377" - "```\377```\377```\377```\377```\377```\377```\377```\377```\377```\377``" - "`\377```\377```\377```\377```\377```\377```\377ppp\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377p" - "pp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp" - "\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377" - "ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377ppp\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377hhh\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230t" - "L\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200" - "\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377hhh\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377hhh\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377```\377xxx\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377xxx\377```\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377PPP\377ppp\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377ppp\377PPP\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377888\377```\377ppp\377xxx\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377\200\200\200\377\200\200\200\377xxx\377ppp\377```\377888\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0" - "\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377888\377PPP\377```\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh" - "\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377" - "hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hh" - "h\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377" - "hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377hhh\377```\377PPP\377888\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0" - "\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\37700`" - "\377PPP\377hhh\377ppp\377ppp\377hhh\377hhh\377hhh\377hhh\377hhh\377ppp\377" - "xxx\377xxx\377ppp\377ppp\377ppp\377ppp\377ppp\377xxx\377xxx\377xxx\377xx" - "x\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377ppp\377hhh\377XXX\377HHH\377" - "HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377@@@\377000\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377PPP\377hhh" - "\377xxx\377xxx\377ppp\377hhh\377```\377```\377```\377```\377hhh\377ppp\377" - "xxx\377xxx\377xxx\377xxx\377xxx\377ppp\377xxx\377xxx\377xxx\377xxx\377xx" - "x\377xxx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377xxx\377hhh\377XX" - "X\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377@@@\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230t" - "L\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377```\377" - "ppp\377xxx\377ppp\377hhh\377PPP\377@@@\377@@@\377@@@\377@@@\377@@@\377PP" - "P\377ppp\377xxx\377xxx\377xxx\377ppp\377ppp\377xxx\377xxx\377\200\200\200" - "\377\200\200\200\377\200\200\200\377xxx\377xxx\377xxx\377xxx\377xxx\377x" - "xx\377xxx\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH" - "\377HHH\377HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377hhh\377ppp\377ppp\377ppp\377hhh\377@@@\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377@@@\377hhh\377xxx\377xxx\377" - "xxx\377ppp\377ppp\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377xxx\377x" - "xx\377xxx\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH" - "\377HHH\377HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377hhh\377hhh\377hhh\377ppp\377hhh\377@@@\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377@@@\377hhh\377xxx\377xxx\377" - "xxx\377ppp\377ppp\377xxx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377xxx\377x" - "xx\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH" - "\377HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377\40\40\40\377@@@\377@@@\377" - "@@@\377@@@\377@@@\377@@@\377\40\40\40\377@@@\377@@@\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377hhh\377hhh\377hhh\377ppp\377hhh\377@@@\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377@@@\377" - "hhh\377xxx\377xxx\377xxx\377ppp\377ppp\377xxx\377xxx\377xxx\377xxx\377xx" - "x\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200" - "\200\200\377xxx\377xxx\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377" - "HHH\377HHH\377HHH\377HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377\40\40\40\377@@@\377hhh" - "\377\230\230\230\377\230\230\230\377\210\210\210\377\270\270\270\377\230" - "\230\230\377@@@\377\230\230\230\377\270\270\270\377@@@\377\40\40\40\377\40" - "\40\40\377\40\40\40\377hhh\377hhh\377hhh\377ppp\377hhh\377@@@\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377@@@\377hhh\377pp" - "p\377xxx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377" - "xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377" - "\200\200\200\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377" - "HHH\377HHH\377HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\230tL\0\230tL\0\40\40\40\377@@@\377hhh\377\230\230\230\377" - "\270\270\270\377\270\270\270\377\230\230\230\377\270\270\270\377\230\230" - "\230\377@@@\377\230\230\230\377\270\270\270\377@@@\377\40\40\40\377\40\40" - "\40\377\40\40\40\377hhh\377hhh\377hhh\377ppp\377hhh\377@@@\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377@@@\377hhh\377ppp\377" - "xxx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377\200\200" - "\200\377xxx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377" - "\200\200\200\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377" - "HHH\377HHH\377HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\230tL\0\230tL\0\40\40\40\377@@@\377\230\230\230\377\270\270" - "\270\377\230\230\230\377hhh\377@@@\377\270\270\270\377\230\230\230\377@@" - "@\377\230\230\230\377\270\270\270\377@@@\377\40\40\40\377\40\40\40\377\40" - "\40\40\377hhh\377hhh\377ppp\377ppp\377hhh\377@@@\377\40\40\40\377\40\40\40" - "\377\40\40\40\377\40\40\40\377\40\40\40\377@@@\377hhh\377ppp\377xxx\377x" - "xx\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377xxx\377" - "xxx\377xxx\377xxx\377xxx\377\200\200\200\377\210\210\210\377\210\210\210" - "\377xxx\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377" - "HHH\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\230tL\0\230tL\0\40\40\40\377@@@\377\270\270\270\377\230\230\230\377hhh\377" - "@@@\377@@@\377\270\270\270\377\230\230\230\377\250\250\250\377\230\230\230" - "\377\270\270\270\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377hhh\377" - "ppp\377xxx\377xxx\377hhh\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377@@@\377hhh\377ppp\377xxx\377xxx\377xxx\377xxx\377" - "xxx\377xxx\377\200\200\200\377\200\200\200\377xxx\377xxx\377xxx\377xxx\377" - "\200\200\200\377\210\210\210\377\220\220\220\377\210\210\210\377xxx\377X" - "XX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230" - "tL\0\40\40\40\377@@@\377\270\270\270\377\230\230\230\377hhh\377@@@\377@@" - "@\377\270\270\270\377\230\230\230\377\250\250\250\377\230\230\230\377\270" - "\270\270\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377ppp\377xxx\377" - "xxx\377xxx\377ppp\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377@@@\377hhh\377xxx\377xxx\377xxx\377\200\200\200\377x" - "xx\377xxx\377\200\200\200\377\200\200\200\377\200\200\200\377xxx\377xxx\377" - "xxx\377xxx\377\200\200\200\377\210\210\210\377\220\220\220\377\210\210\210" - "\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377" - "HHH\377\40\40\40\377(((\377XD,\377P<(\377\40\40\40\377\230tL\0\230tL\0\40" - "\40\40\377@@@\377\230\230\230\377\270\270\270\377\230\230\230\377hhh\377" - "@@@\377\270\270\270\377\230\230\230\377@@@\377\230\230\230\377\270\270\270" - "\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377ppp\377xxx\377xxx\377x" - "xx\377ppp\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377@@@\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377" - "\200\200\200\377\200\200\200\377\200\200\200\377\210\210\210\377\210\210" - "\210\377\210\210\210\377\200\200\200\377\200\200\200\377xxx\377xxx\377\200" - "\200\200\377\210\210\210\377\210\210\210\377\200\200\200\377ppp\377XXX\377" - "HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377\40\40\40" - "\377(((\377XD,\377P<(\377\40\40\40\377\230tL\0\230tL\0\40\40\40\377@@@\377" - "hhh\377\230\230\230\377\270\270\270\377\270\270\270\377\230\230\230\377\270" - "\270\270\377\230\230\230\377@@@\377\230\230\230\377\270\270\270\377@@@\377" - "\40\40\40\377\40\40\40\377\40\40\40\377ppp\377xxx\377xxx\377xxx\377hhh\377" - "@@@\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "@@@\377ppp\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\210\210\210\377\210\210\210\377\210" - "\210\210\377\210\210\210\377\200\200\200\377\200\200\200\377xxx\377xxx\377" - "\200\200\200\377\200\200\200\377xxx\377hhh\377XXX\377HHH\377HHH\377HHH\377" - "HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377\40\40\40\377XD,\377XD,\377P<(" - "\377P<(\377\230tL\0\230tL\0@0\40\377\40\40\40\377@@@\377hhh\377\230\230\230" - "\377\230\230\230\377\210\210\210\377\270\270\270\377\230\230\230\377@@@\377" - "\230\230\230\377\270\270\270\377@@@\377\40\40\40\377\40\40\40\377\40\40\40" - "\377ppp\377xxx\377xxx\377xxx\377hhh\377@@@\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377@@@\377ppp\377\200\200\200\377\200" - "\200\200\377\200\200\200\377xxx\377xxx\377xxx\377\200\200\200\377\210\210" - "\210\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377" - "xxx\377xxx\377\200\200\200\377\200\200\200\377xxx\377hhh\377XXX\377HHH\377" - "HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377\40\40\40\377000" - "\377XD,\377P<(\377\40\40\40\377\230tL\0\230tL\0`H0\377@0\40\377\40\40\40" - "\377@@@\377@@@\377@@@\377@@@\377@@@\377@@@\377\40\40\40\377@@@\377@@@\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377ppp\377xxx\377xxx\377" - "xxx\377hhh\377@@@\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377@@@\377ppp\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377\200" - "\200\200\377\200\200\200\377\200\200\200\377\200\200\200\377\200\200\200" - "\377\200\200\200\377\200\200\200\377\200\200\200\377\210\210\210\377\200" - "\200\200\377\200\200\200\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HH" - "H\377HHH\377HHH\377HHH\377HHH\377\40\40\40\377\40\40\40\377H4$\377@0\40\377" - "\40\40\40\377\230tL\0\230tL\0\230tL\0`H0\377@0\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377@0\40\377" - "ppp\377xxx\377xxx\377xxx\377hhh\377PPP\377@@@\377@@@\377@@@\377@@@\377@@" - "@\377PPP\377xxx\377\200\200\200\377xxx\377ppp\377ppp\377xxx\377xxx\377\200" - "\200\200\377xxx\377xxx\377xxx\377xxx\377\200\200\200\377\200\200\200\377" - "\210\210\210\377\210\210\210\377\200\200\200\377\200\200\200\377ppp\377X" - "XX\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377HHH\377\40" - "\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\230tL\0\230" - "tL\0\230tL\0\230tL\0`H0\377@0\40\377\40\40\40\377\40\40\40\377\40\40\40\377" - "\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40" - "\377\40\40\40\377@0\40\377`H0\377ppp\377ppp\377ppp\377ppp\377ppp\377hhh\377" - "hhh\377ppp\377ppp\377xxx\377xxx\377\200\200\200\377\210\210\210\377\200\200" - "\200\377xxx\377ppp\377ppp\377xxx\377xxx\377\200\200\200\377xxx\377xxx\377" - "xxx\377xxx\377\200\200\200\377\210\210\210\377\210\210\210\377\200\200\200" - "\377\200\200\200\377\200\200\200\377ppp\377XXX\377HHH\377HHH\377HHH\377H" - "HH\377HHH\377HHH\377HHH\377HHH\377@@@\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0" - "`H0\377@0\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\40\40\40\377\40\40\40\377@0\40\377`H0\377\230tL\0pp" - "p\377hhh\377hhh\377ppp\377ppp\377ppp\377ppp\377xxx\377\200\200\200\377\200" - "\200\200\377\210\210\210\377\210\210\210\377\220\220\220\377\210\210\210" - "\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377xxx\377" - "\200\200\200\377\210\210\210\377\210\210\210\377\200\200\200\377\200\200" - "\200\377\200\200\200\377ppp\377XXX\377HHH\377HHH\377HHH\377HHH\377HHH\377" - "HHH\377HHH\377HHH\377000\377\40\40\40\377\40\40\40\377\40\40\40\377\40\40" - "\40\377\40\40\40\377\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230tL\0\230" - "tL\0\230tL\0\230tL\0\230tL\0\230tL\0", -}; - -struct sdlappicon sdlappicon = { - 64, 64, - sdlappicon_pixels -}; diff --git a/source/kenbuild/rsrc/game_icon.ico b/source/kenbuild/rsrc/game_icon.ico deleted file mode 100644 index 30eeebe17..000000000 Binary files a/source/kenbuild/rsrc/game_icon.ico and /dev/null differ diff --git a/source/kenbuild/rsrc/game_icon.png b/source/kenbuild/rsrc/game_icon.png deleted file mode 100644 index a814fd268..000000000 Binary files a/source/kenbuild/rsrc/game_icon.png and /dev/null differ diff --git a/source/kenbuild/rsrc/gameres.rc b/source/kenbuild/rsrc/gameres.rc deleted file mode 100644 index d832eab47..000000000 --- a/source/kenbuild/rsrc/gameres.rc +++ /dev/null @@ -1,69 +0,0 @@ -#define NEED_COMMCTRL_H -#include "windows_inc.h" -#include "startwin.game.h" - -RSRC_ICON ICON "game_icon.ico" -RSRC_BMP BITMAP "game.bmp" - -WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200 -STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU -CAPTION "Startup" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 32, 32 - CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170 - CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14 - CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14 - - CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32 -END - -WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD -CAPTION "Dialog" -FONT 8, "MS Shell Dlg" -BEGIN - CONTROL "&Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 8, 50, 8 - CONTROL "", IDC3DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 6, 80, 56 - CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 148, 8, 49, 10 - CONTROL "&Always show configuration on start", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8 -END - -#define FILEVER 1,9,9,9 -#define PRODUCTVER 1,9,9,9 -#define STRFILEVER "2.0.0devel\0" -#define STRPRODUCTVER "2.0.0devel\0" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION FILEVER - PRODUCTVERSION PRODUCTVER - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x3L -#else - FILEFLAGS 0x2L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "KenBuild" - VALUE "FileVersion", STRFILEVER - VALUE "InternalName", "KenBuild" - VALUE "LegalCopyright", "Copyright © 2015 EDuke32 Developers, 2000, 2003 Ken Silverman" - VALUE "OriginalFilename", "ekenbuild.exe" - VALUE "ProductName", "KenBuild" - VALUE "ProductVersion", STRPRODUCTVER - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -1 24 "manifest.game.xml" diff --git a/source/kenbuild/rsrc/manifest.build.xml b/source/kenbuild/rsrc/manifest.build.xml deleted file mode 100644 index 8ac5fcb72..000000000 --- a/source/kenbuild/rsrc/manifest.build.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - true - - - - Mapster32 for KenBuild - - - - - - - - - - - - - - - - - - - - diff --git a/source/kenbuild/rsrc/manifest.game.xml b/source/kenbuild/rsrc/manifest.game.xml deleted file mode 100644 index a841fabe6..000000000 --- a/source/kenbuild/rsrc/manifest.game.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - true - - - - KenBuild - - - - - - - - - - - - - - - - - - - - diff --git a/source/kenbuild/src/StartupWinController.game.mm b/source/kenbuild/src/StartupWinController.game.mm deleted file mode 100644 index aac6583b8..000000000 --- a/source/kenbuild/src/StartupWinController.game.mm +++ /dev/null @@ -1,312 +0,0 @@ -#import - -#include "compat.h" -#include "baselayer.h" -#include "build.h" - -static struct -{ - int fullscreen; - int xdim3d, ydim3d, bpp3d; - int forcesetup; -} settings; - -@interface StartupWinController : NSWindowController -{ - NSMutableArray *modeslist3d; - - IBOutlet NSButton *alwaysShowButton; - IBOutlet NSButton *fullscreenButton; - IBOutlet NSTextView *messagesView; - IBOutlet NSTabView *tabView; - IBOutlet NSPopUpButton *videoMode3DPUButton; - - IBOutlet NSButton *cancelButton; - IBOutlet NSButton *startButton; -} - -- (void)dealloc; -- (void)populateVideoModes:(BOOL)firstTime; - -- (IBAction)alwaysShowClicked:(id)sender; -- (IBAction)fullscreenClicked:(id)sender; - -- (IBAction)cancel:(id)sender; -- (IBAction)start:(id)sender; - -- (void)setupRunMode; -- (void)setupMessagesMode; -- (void)putsMessage:(NSString *)str; -- (void)setTitle:(NSString *)str; -@end - -@implementation StartupWinController - -- (void)dealloc -{ - [modeslist3d release]; - [super dealloc]; -} - -- (void)populateVideoModes:(BOOL)firstTime -{ - int i, mode3d, fullscreen = ([fullscreenButton state] == NSOnState); - int idx3d = -1; - int xdim = 0, ydim = 0, bpp = 0; - - if (firstTime) - { - xdim = settings.xdim3d; - ydim = settings.ydim3d; - bpp = settings.bpp3d; - } - else - { - mode3d = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue]; - if (mode3d >= 0) - { - xdim = validmode[mode3d].xdim; - ydim = validmode[mode3d].ydim; - bpp = validmode[mode3d].bpp; - } - } - - mode3d = checkvideomode(&xdim, &ydim, bpp, fullscreen, 1); - if (mode3d < 0) - { - int i, cd[] = { 32, 24, 16, 15, 8, 0 }; - for (i=0; cd[i]; ) { if (cd[i] >= bpp) i++; else break; } - for (; cd[i]; i++) - { - mode3d = checkvideomode(&xdim, &ydim, cd[i], fullscreen, 1); - if (mode3d < 0) continue; - break; - } - } - - [modeslist3d release]; - [videoMode3DPUButton removeAllItems]; - - modeslist3d = [[NSMutableArray alloc] init]; - - for (i = 0; i < validmodecnt; i++) - { - if (fullscreen == validmode[i].fs) - { - if (i == mode3d) idx3d = [modeslist3d count]; - [modeslist3d addObject:[NSNumber numberWithInt:i]]; - [videoMode3DPUButton addItemWithTitle:[NSString stringWithFormat:@"%d %C %d %d-bpp", - validmode[i].xdim, 0xd7, validmode[i].ydim, validmode[i].bpp]]; - } - } - - if (idx3d >= 0) [videoMode3DPUButton selectItemAtIndex:idx3d]; -} - -- (IBAction)alwaysShowClicked:(id)sender -{ - UNREFERENCED_PARAMETER(sender); -} - -- (IBAction)fullscreenClicked:(id)sender -{ - [self populateVideoModes:NO]; - - UNREFERENCED_PARAMETER(sender); -} - -- (IBAction)cancel:(id)sender -{ - [NSApp abortModal]; - - UNREFERENCED_PARAMETER(sender); -} - -- (IBAction)start:(id)sender -{ - int mode = [[modeslist3d objectAtIndex:[videoMode3DPUButton indexOfSelectedItem]] intValue]; - if (mode >= 0) - { - settings.xdim3d = validmode[mode].xdim; - settings.ydim3d = validmode[mode].ydim; - settings.bpp3d = validmode[mode].bpp; - settings.fullscreen = validmode[mode].fs; - } - - settings.forcesetup = [alwaysShowButton state] == NSOnState; - - [NSApp stopModal]; - - UNREFERENCED_PARAMETER(sender); -} - -- (void)setupRunMode -{ - getvalidmodes(); - - [fullscreenButton setState: (settings.fullscreen ? NSOnState : NSOffState)]; - [alwaysShowButton setState: (settings.forcesetup ? NSOnState : NSOffState)]; - [self populateVideoModes:YES]; - - // enable all the controls on the Configuration page - NSEnumerator *enumerator = [[[[tabView tabViewItemAtIndex:0] view] subviews] objectEnumerator]; - NSControl *control; - while (control = [enumerator nextObject]) [control setEnabled:true]; - - [cancelButton setEnabled:true]; - [startButton setEnabled:true]; - - [tabView selectTabViewItemAtIndex:0]; - [NSCursor unhide]; // Why should I need to do this? -} - -- (void)setupMessagesMode -{ - [tabView selectTabViewItemAtIndex:1]; - - // disable all the controls on the Configuration page except "always show", so the - // user can enable it if they want to while waiting for something else to happen - NSEnumerator *enumerator = [[[[tabView tabViewItemAtIndex:0] view] subviews] objectEnumerator]; - NSControl *control; - while (control = [enumerator nextObject]) - { - if (control == alwaysShowButton) continue; - [control setEnabled:false]; - } - - [cancelButton setEnabled:false]; - [startButton setEnabled:false]; -} - -- (void)putsMessage:(NSString *)str -{ - NSRange end; - NSTextStorage *text = [messagesView textStorage]; - BOOL shouldAutoScroll; - - shouldAutoScroll = ((int)NSMaxY([messagesView bounds]) == (int)NSMaxY([messagesView visibleRect])); - - end.location = [text length]; - end.length = 0; - - [text beginEditing]; - [messagesView replaceCharactersInRange:end withString:str]; - [text endEditing]; - - if (shouldAutoScroll) - { - end.location = [text length]; - end.length = 0; - [messagesView scrollRangeToVisible:end]; - } -} - -- (void)setTitle:(NSString *)str -{ - [[self window] setTitle:str]; -} - -@end - -static StartupWinController *startwin = nil; - -int startwin_open(void) -{ - if (startwin != nil) return 1; - - startwin = [[StartupWinController alloc] initWithWindowNibName:@"startwin.game"]; - if (startwin == nil) return -1; - - [startwin setupMessagesMode]; - [startwin showWindow:nil]; - - return 0; -} - -int startwin_close(void) -{ - if (startwin == nil) return 1; - - [startwin close]; - [startwin release]; - startwin = nil; - - return 0; -} - -int startwin_puts(const char *s) -{ - NSString *ns; - - if (!s) return -1; - if (startwin == nil) return 1; - - ns = [[NSString alloc] initWithUTF8String:s]; - [startwin putsMessage:ns]; - [ns release]; - - return 0; -} - -int startwin_settitle(const char *s) -{ - NSString *ns; - - if (!s) return -1; - if (startwin == nil) return 1; - - ns = [[NSString alloc] initWithUTF8String:s]; - [startwin setTitle:ns]; - [ns release]; - - return 0; -} - -int startwin_idle(void *v) -{ - if (startwin) [[startwin window] displayIfNeeded]; - UNREFERENCED_PARAMETER(v); - return 0; -} - -extern int xdimgame, ydimgame, bppgame, forcesetup; - -int startwin_run(void) -{ - int retval; - - if (startwin == nil) return 0; - - settings.fullscreen = fullscreen; - settings.xdim3d = xdimgame; - settings.ydim3d = ydimgame; - settings.bpp3d = bppgame; - settings.forcesetup = forcesetup; - - [startwin setupRunMode]; - - switch ([NSApp runModalForWindow:[startwin window]]) - { -#ifdef MAC_OS_X_VERSION_10_9 - case NSModalResponseStop: retval = 1; break; - case NSModalResponseAbort: retval = 0; break; -#else - case NSRunStoppedResponse: retval = 1; break; - case NSRunAbortedResponse: retval = 0; break; -#endif - default: retval = -1; - } - - [startwin setupMessagesMode]; - - if (retval) - { - fullscreen = settings.fullscreen; - xdimgame = settings.xdim3d; - ydimgame = settings.ydim3d; - bppgame = settings.bpp3d; - forcesetup = settings.forcesetup; - } - - return retval; -} diff --git a/source/kenbuild/src/bstub.cpp b/source/kenbuild/src/bstub.cpp deleted file mode 100644 index 53600eada..000000000 --- a/source/kenbuild/src/bstub.cpp +++ /dev/null @@ -1,720 +0,0 @@ -// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman -// Ken Silverman's official web site: "http://www.advsys.net/ken" -// See the included license file "BUILDLIC.TXT" for license info. -// -// This file has been modified from Ken Silverman's original release -// by Jonathon Fowler (jf@jonof.id.au) - -#include "compat.h" -#include "build.h" -#include "editor.h" -#include "pragmas.h" -#include "baselayer.h" -#include "names.h" -#include "osd.h" -#include "cache1d.h" -#include "common.h" -#include "m32script.h" - -#include "common_game.h" - -const char *AppProperName = "KenBuild Editor"; -const char *AppTechnicalName = "ekenbuild-editor"; - -#if defined(_WIN32) -#define DEFAULT_GAME_EXEC "ekenbuild.exe" -#define DEFAULT_GAME_LOCAL_EXEC "ekenbuild.exe" -#else -#define DEFAULT_GAME_EXEC "ekenbuild" -#define DEFAULT_GAME_LOCAL_EXEC "./ekenbuild" -#endif - -const char *DefaultGameExec = DEFAULT_GAME_EXEC; -const char *DefaultGameLocalExec = DEFAULT_GAME_LOCAL_EXEC; - -#define SETUPFILENAME "ekenbuild-editor.cfg" -const char *defaultsetupfilename = SETUPFILENAME; -char setupfilename[BMAX_PATH] = SETUPFILENAME; - -static char tempbuf[256]; - -#define NUMOPTIONS 9 -char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0,0}; -unsigned char default_buildkeys[NUMBUILDKEYS] = -{ - 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, - 0x1e,0x2c,0xd1,0xc9,0x33,0x34, - 0x9c,0x1c,0xd,0xc,0xf,0x45 -}; - - - - - -//static int hang = 0; -//static int rollangle = 0; - -//Detecting 2D / 3D mode: -// qsetmode is 200 in 3D mode -// qsetmode is 350/480 in 2D mode -// -//You can read these variables when F5-F8 is pressed in 3D mode only: -// -// If (searchstat == 0) WALL searchsector=sector, searchwall=wall -// If (searchstat == 1) CEILING searchsector=sector -// If (searchstat == 2) FLOOR searchsector=sector -// If (searchstat == 3) SPRITE searchsector=sector, searchwall=sprite -// If (searchstat == 4) MASKED WALL searchsector=sector, searchwall=wall -// -// searchsector is the sector of the selected item for all 5 searchstat's -// -// searchwall is undefined if searchstat is 1 or 2 -// searchwall is the wall if searchstat = 0 or 4 -// searchwall is the sprite if searchstat = 3 (Yeah, I know - it says wall, -// but trust me, it's the sprite number) - -int averagefps; -#define AVERAGEFRAMES 32 -static unsigned int frameval[AVERAGEFRAMES]; -static int framecnt = 0; - -int nextvoxid = 0; - - -const char *ExtGetVer(void) -{ - return s_buildRev; -} - -int32_t ExtPreInit(int32_t argc,char const * const * argv) -{ - UNREFERENCED_PARAMETER(argc); - UNREFERENCED_PARAMETER(argv); - - OSD_SetLogFile("ekenbuild-editor.log"); - OSD_SetVersion(AppProperName,0,2); - initprintf("%s %s\n", AppProperName, s_buildRev); - PrintBuildInfo(); - - return 0; -} - -int32_t ExtInit(void) -{ - int rv = 0; - - /*printf("------------------------------------------------------------------------------\n"); - printf(" BUILD.EXE copyright(c) 1996 by Ken Silverman. You are granted the\n"); - printf(" right to use this software for your personal use only. This is a\n"); - printf(" special version to be used with \"Happy Fun KenBuild\" and may not work\n"); - printf(" properly with other Build engine games. Please refer to license.doc\n"); - printf(" for distribution rights\n"); - printf("------------------------------------------------------------------------------\n"); - getch(); - */ - - bpp = 8; - if (loadsetup(setupfilename) < 0) buildputs("Configuration file not found, using defaults.\n"), rv = 1; - Bmemcpy(buildkeys, default_buildkeys, NUMBUILDKEYS); //Trick to make build use setup.dat keys - if (option[4] > 0) option[4] = 0; - - kensplayerheight = 32; - zmode = 0; - -#ifdef _WIN32 -// allowtaskswitching(0); -#endif - return rv; -} - -int32_t ExtPostStartupWindow(void) -{ - int i; - - initgroupfile(G_GrpFile()); - - //You can load your own palette lookup tables here if you just - //copy the right code! - for (i=0; i<256; i++) - tempbuf[i] = ((i+32)&255); //remap colors for screwy palette sectors - makepalookup(16,tempbuf,0,0,0,1); - - if (initengine()) - { - initprintf("There was a problem initializing the engine.\n"); - return -1; - } - - Ken_InitMultiPsky(); - - tiletovox[PLAYER] = nextvoxid++; - tiletovox[BROWNMONSTER] = nextvoxid++; - - return 0; -} - -void ExtPostInit(void) -{ - fillemptylookups(); -} - -void ExtUnInit(void) -{ - uninitgroupfile(); - writesetup(setupfilename); -} - -//static int daviewingrange, daaspect, horizval1, horizval2; -void ExtPreCheckKeys(void) -{ - int /*cosang, sinang, dx, dy, mindx,*/ i, j, k; - - if (keystatus[0x3e]) //F4 - screen re-size - { - keystatus[0x3e] = 0; - - //cycle through all vesa modes, then screen-buffer mode - if (keystatus[0x2a]|keystatus[0x36]) - { - setgamemode(!fullscreen, xdim, ydim, bpp); - } - else - { - - //cycle through all modes - j=-1; - - // work out a mask to select the mode - for (i=0; i 0) - { - if (!in3dmode()) - printmessage16("%s", getmessage); - if (totalclock > getmessagetimeoff) - getmessageleng = 0; - } - -#if 0 - if (keystatus[0x2a]|keystatus[0x36]) - { - if (keystatus[0xcf]) hang = max(hang-1,-182); - if (keystatus[0xc7]) hang = min(hang+1,182); - } - else - { - if (keystatus[0xcf]) hang = max(hang-8,-182); - if (keystatus[0xc7]) hang = min(hang+8,182); - } - if (keystatus[0x4c]) { hang = 0; horiz = 100; } - if (hang != 0) - { - walock[4094] = 255; - - // JBF 20031117: scale each dimension by a factor of 1.2, and work out - // the aspect of the screen. Anywhere you see 'i' below was the value - // '200' before I changed it. NOTE: This whole trick crashes in resolutions - // above 800x600. I'm not sure why, and fixing it is not something I intend - // to do in a real big hurry. - dx = (xdim + (xdim >> 3) + (xdim >> 4) + (xdim >> 6)) & (~7); - dy = (ydim + (ydim >> 3) + (ydim >> 4) + (ydim >> 6)) & (~7); - i = scale(320,ydim,xdim); - - if (waloff[4094] == 0) allocache(&waloff[4094],/*240L*384L*/ dx*dy,&walock[4094]); - setviewtotile(4094,/*240L,384L*/ dy,dx); - - cosang = sintable[(hang+512)&2047]; - sinang = sintable[hang&2047]; - - dx = dmulscale1(320,cosang,i,sinang); mindx = dx; - dy = dmulscale1(-i,cosang,320,sinang); - horizval1 = dy*(320>>1)/dx-1; - - dx = dmulscale1(320,cosang,-i,sinang); mindx = min(dx,mindx); - dy = dmulscale1(i,cosang,320,sinang); - horizval2 = dy*(320>>1)/dx+1; - - daviewingrange = divscale30(xdim>>1, mindx-16); - daaspect = scale(daviewingrange,scale(320,tilesiz[4094].x,tilesiz[4094].y),horizval2+6-horizval1); - setaspect(daviewingrange,scale(daaspect,ydim*320,xdim*i)); - horiz = 100-divscale15(horizval1+horizval2,daviewingrange); - } -#endif -} - -#define MAXVOXMIPS 5 -extern intptr_t voxoff[][MAXVOXMIPS]; -void ExtAnalyzeSprites(int32_t ourx, int32_t oury, int32_t oura, int32_t smoothr) -{ - int i, *longptr; - uspritetype *tspr; - - UNREFERENCED_PARAMETER(ourx); - UNREFERENCED_PARAMETER(oury); - UNREFERENCED_PARAMETER(oura); - UNREFERENCED_PARAMETER(smoothr); - - for (i=0,tspr=&tsprite[0]; ipicnum] >= 0) - { - switch (tspr->picnum) - { - case PLAYER: - if (!voxoff[tiletovox[PLAYER]][0]) - { - if (qloadkvx(tiletovox[PLAYER],"voxel000.kvx")) - { - tiletovox[PLAYER] = -1; - break; - } - } - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - longptr = (int *)voxoff[tiletovox[PLAYER]][0]; - tspr->xrepeat = scale(tspr->xrepeat,56,longptr[2]); - tspr->yrepeat = scale(tspr->yrepeat,56,longptr[2]); - tspr->shade -= 6; - break; - case BROWNMONSTER: - if (!voxoff[tiletovox[BROWNMONSTER]][0]) - { - if (qloadkvx(tiletovox[BROWNMONSTER],"voxel001.kvx")) - { - tiletovox[BROWNMONSTER] = -1; - break; - } - } - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - break; - } - } - - tspr->shade += 6; - if (sector[tspr->sectnum].ceilingstat&1) - tspr->shade += sector[tspr->sectnum].ceilingshade; - else - tspr->shade += sector[tspr->sectnum].floorshade; - } -} - -void ExtCheckKeys(void) -{ - int i; //, p, y, dx, dy, cosang, sinang, bufplc, tsizy, tsizyup15; - int j; - - if (qsetmode == 200) //In 3D mode - { -#if 0 - if (hang != 0) - { - bufplc = waloff[4094]+(mulscale16(horiz-100,xdimenscale)+(tilesiz[4094].x>>1))*tilesiz[4094].y; - setviewback(); - cosang = sintable[(hang+512)&2047]; - sinang = sintable[hang&2047]; - dx = dmulscale1(xdim,cosang,ydim,sinang); - dy = dmulscale1(-ydim,cosang,xdim,sinang); - - begindrawing(); - tsizy = tilesiz[4094].y; - tsizyup15 = (tsizy<<15); - dx = mulscale14(dx,daviewingrange); - dy = mulscale14(dy,daaspect); - sinang = mulscale14(sinang,daviewingrange); - cosang = mulscale14(cosang,daaspect); - p = ylookup[windowxy1.y]+frameplace+windowxy2.x+1; - for (y=windowxy1.y; y<=windowxy2.y; y++) - { - i = divscale16(tsizyup15,dx); - stretchhline(0,(xdim>>1)*i+tsizyup15,xdim>>2,i,mulscale32(i,dy)*tsizy+bufplc,p); - dx -= sinang; dy += cosang; p += ylookup[1]; - } - walock[4094] = 1; - - Bsprintf(tempbuf,"%d",(hang*180)>>10); - printext256(0L,8L,31,-1,tempbuf,1); - enddrawing(); - } -#endif - if (keystatus[0xa]) setaspect(viewingrange+(viewingrange>>8),yxaspect+(yxaspect>>8)); - if (keystatus[0xb]) setaspect(viewingrange-(viewingrange>>8),yxaspect-(yxaspect>>8)); - if (keystatus[0xc]) setaspect(viewingrange,yxaspect-(yxaspect>>8)); - if (keystatus[0xd]) setaspect(viewingrange,yxaspect+(yxaspect>>8)); - //if (keystatus[0x38]) setrollangle(rollangle+=((keystatus[0x2a]|keystatus[0x36])*6+2)); - //if (keystatus[0xb8]) setrollangle(rollangle-=((keystatus[0x2a]|keystatus[0x36])*6+2)); - //if (keystatus[0x1d]|keystatus[0x9d]) setrollangle(rollangle=0); - - begindrawing(); - - i = frameval[framecnt&(AVERAGEFRAMES-1)]; - j = frameval[framecnt&(AVERAGEFRAMES-1)] = getticks(); framecnt++; - if (i != j) averagefps = (averagefps*3 + (AVERAGEFRAMES*1000)/(j-i))>>2; - Bsprintf((char *)tempbuf,"%d",averagefps); - printext256(0L,0L,31,-1,(char *)tempbuf,1); - - enddrawing(); - editinput(); - } - else - { - } -} - -void ExtCleanUp(void) -{ -} - -void ExtPreLoadMap(void) -{ -} - - -void ExtSetupMapFilename(const char *mapname) -{ - UNREFERENCED_PARAMETER(mapname); -} - -void ExtLoadMap(const char *mapname) -{ - UNREFERENCED_PARAMETER(mapname); -} - -int32_t ExtPreSaveMap(void) -{ - return 0; -} - -void ExtSaveMap(const char *mapname) -{ - UNREFERENCED_PARAMETER(mapname); -} - -const char *ExtGetSectorCaption(short sectnum) -{ - if ((sector[sectnum].lotag|sector[sectnum].hitag) == 0) - { - tempbuf[0] = 0; - } - else - { - Bsprintf((char *)tempbuf,"%hu,%hu",(unsigned short)sector[sectnum].hitag, - (unsigned short)sector[sectnum].lotag); - } - return (char *)tempbuf; -} - -const char *ExtGetWallCaption(short wallnum) -{ - if ((wall[wallnum].lotag|wall[wallnum].hitag) == 0) - { - tempbuf[0] = 0; - } - else - { - Bsprintf((char *)tempbuf,"%hu,%hu",(unsigned short)wall[wallnum].hitag, - (unsigned short)wall[wallnum].lotag); - } - return (char *)tempbuf; -} - -const char *ExtGetSpriteCaption(short spritenum) -{ - if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0) - { - tempbuf[0] = 0; - } - else - { - Bsprintf((char *)tempbuf,"%hu,%hu",(unsigned short)sprite[spritenum].hitag, - (unsigned short)sprite[spritenum].lotag); - } - return (char *)tempbuf; -} - -//printext16 parameters: -//printext16(int xpos, int ypos, short col, short backcol, -// char name[82], char fontsize) -// xpos 0-639 (top left) -// ypos 0-479 (top left) -// col 0-15 -// backcol 0-15, -1 is transparent background -// name -// fontsize 0=8*8, 1=3*5 - -//drawline16 parameters: -// drawline16(int x1, int y1, int x2, int y2, char col) -// x1, x2 0-639 -// y1, y2 0-143 (status bar is 144 high, origin is top-left of STATUS BAR) -// col 0-15 - -void ExtShowSectorData(short sectnum) //F5 -{ - int i; - if (qsetmode == 200) //In 3D mode - { - } - else - { - begindrawing(); - clearmidstatbar16(); //Clear middle of status bar - - Bsprintf((char *)tempbuf,"Sector %d",sectnum); - printext16(8,ydim16+32,11,-1,(char *)tempbuf,0); - - printext16(8,ydim16+48,11,-1,"8*8 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",0); - printext16(8,ydim16+56,11,-1,"3*5 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",1); - - i=ydim16; ydim16=ydim; - drawline16(320,i+68,344,i+80,4); //Draw house - drawline16(344,i+80,344,i+116,4); - drawline16(344,i+116,296,i+116,4); - drawline16(296,i+116,296,i+80,4); - drawline16(296,i+80,320,i+68,4); - ydim16=i; - enddrawing(); - } -} - -void ExtShowWallData(short wallnum) //F6 -{ - if (qsetmode == 200) //In 3D mode - { - } - else - { - begindrawing(); - clearmidstatbar16(); //Clear middle of status bar - - Bsprintf((char *)tempbuf,"Wall %d",wallnum); - printext16(8,ydim16+32,11,-1,(char *)tempbuf,0); - enddrawing(); - } -} - -void ExtShowSpriteData(short spritenum) //F6 -{ - if (qsetmode == 200) //In 3D mode - { - } - else - { - begindrawing(); - clearmidstatbar16(); //Clear middle of status bar - - Bsprintf((char *)tempbuf,"Sprite %d",spritenum); - printext16(8,ydim16+32,11,-1,(char *)tempbuf,0); - enddrawing(); - } -} - -void ExtEditSectorData(short sectnum) //F7 -{ - short nickdata; - - if (qsetmode == 200) //In 3D mode - { - //Ceiling - if (searchstat == 1) - sector[searchsector].ceilingpicnum++; //Just a stupid example - - //Floor - if (searchstat == 2) - sector[searchsector].floorshade++; //Just a stupid example - } - else //In 2D mode - { - Bsprintf((char *)tempbuf,"Sector (%d) Nick's variable: ",sectnum); - nickdata = 0; - nickdata = getnumber16((char *)tempbuf,nickdata,65536L,0); - - printmessage16(" "); //Clear message box (top right of status bar) - ExtShowSectorData(sectnum); - } -} - -void ExtEditWallData(short wallnum) //F8 -{ - short nickdata; - - if (qsetmode == 200) //In 3D mode - { - } - else - { - Bsprintf((char *)tempbuf,"Wall (%d) Nick's variable: ",wallnum); - nickdata = 0; - nickdata = getnumber16((char *)tempbuf,nickdata,65536L,0); - - printmessage16(" "); //Clear message box (top right of status bar) - ExtShowWallData(wallnum); - } -} - -void ExtEditSpriteData(short spritenum) //F8 -{ - short nickdata; - - if (qsetmode == 200) //In 3D mode - { - } - else - { - Bsprintf((char *)tempbuf,"Sprite (%d) Nick's variable: ",spritenum); - nickdata = 0; - nickdata = getnumber16((char *)tempbuf,nickdata,65536L,0); - printmessage16(" "); - - printmessage16(" "); //Clear message box (top right of status bar) - ExtShowSpriteData(spritenum); - } -} - -void faketimerhandler(void) -{ - sampletimer(); -} - -void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); } -void G_Polymer_UnInit(void) { } -void SetGamePalette(int32_t j) { UNREFERENCED_PARAMETER(j); } - -int32_t AmbienceToggle, MixRate, ParentalLock; - -int32_t taglab_linktags(int32_t spritep, int32_t num) -{ - int32_t link = 0; - - g_iReturnVar = link; - VM_OnEvent(EVENT_LINKTAGS, spritep ? num : -1); - link = g_iReturnVar; - - return link; -} - -int32_t taglab_getnextfreetag(int32_t *duetoptr) -{ - int32_t i, nextfreetag=1; - int32_t obj = -1; - - for (i=0; i 0) - { - keystatus[j] = 0; - k = j-1; - if (k == 10) k = 0; - n = (danum*10)+k; - if (n < maxnumber) danum = n; - } - if (keystatus[0xe] > 0) // backspace - { - danum /= 10; - keystatus[0xe] = 0; - } - if (keystatus[0x1c] == 1) //L. enter - { - oldnum = danum; - keystatus[0x1c] = 2; - asksave = 1; - } - } - keystatus[0x1c] = 0; - keystatus[0x1] = 0; - return((short)oldnum); -} -*/ - -/* - * vim:ts=4: - */ diff --git a/source/kenbuild/src/common.cpp b/source/kenbuild/src/common.cpp deleted file mode 100644 index e5bef574a..000000000 --- a/source/kenbuild/src/common.cpp +++ /dev/null @@ -1,45 +0,0 @@ - -#include "compat.h" -#include "build.h" - -#include "names.h" -#include "common_game.h" - -static const char *defaultgrpfilename = "stuff.dat"; -static const char *defaultdeffilename = "kenbuild.def"; - -const char *G_DefaultGrpFile(void) -{ - return defaultgrpfilename; -} -const char *G_GrpFile(void) -{ - return defaultgrpfilename; -} - -const char *G_DefaultDefFile(void) -{ - return defaultdeffilename; -} -const char *G_DefFile(void) -{ - return defaultdeffilename; -} - -void Ken_InitMultiPsky(void) -{ - // default - psky_t * const defaultsky = E_DefinePsky(DEFAULTPSKY); - defaultsky->lognumtiles = 1; - defaultsky->horizfrac = 65536; - - // DAYSKY - psky_t * const daysky = E_DefinePsky(DAYSKY); - daysky->lognumtiles = 1; - daysky->horizfrac = 65536; - - // NIGHTSKY - psky_t * const nightsky = E_DefinePsky(NIGHTSKY); - nightsky->lognumtiles = 3; - nightsky->horizfrac = 65536; -} diff --git a/source/kenbuild/src/common_game.h b/source/kenbuild/src/common_game.h deleted file mode 100644 index 6cd6ef23d..000000000 --- a/source/kenbuild/src/common_game.h +++ /dev/null @@ -1,7 +0,0 @@ - -#include "compat.h" - -extern const char *G_DefaultGrpFile(void); -extern const char *G_GrpFile(void); - -extern void Ken_InitMultiPsky(void); diff --git a/source/kenbuild/src/config.cpp b/source/kenbuild/src/config.cpp deleted file mode 100644 index 31e23cf00..000000000 --- a/source/kenbuild/src/config.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// Evil and Nasty Configuration File Reader for KenBuild -// by Jonathon Fowler - -#include "compat.h" -#include "build.h" -#include "editor.h" -#include "osd.h" - -#ifdef RENDERTYPEWIN -#include "winlayer.h" -#endif -#include "baselayer.h" - -#if defined RENDERTYPESDL && defined SDL_TARGET && SDL_TARGET > 1 -# include "sdl_inc.h" -#endif - -static void Ken_SetDefaults() -{ -#if defined RENDERTYPESDL && SDL_MAJOR_VERSION > 1 - uint32_t inited = SDL_WasInit(SDL_INIT_VIDEO); - if (inited == 0) - SDL_Init(SDL_INIT_VIDEO); - else if (!(inited & SDL_INIT_VIDEO)) - SDL_InitSubSystem(SDL_INIT_VIDEO); - - SDL_DisplayMode dm; - if (SDL_GetDesktopDisplayMode(0, &dm) == 0) - { - xdimgame = xdim2d = dm.w; - ydimgame = ydim2d = dm.h; - } - else -#endif - { - xdimgame = xdim2d = 1024; - ydimgame = ydim2d = 768; - } -} - -static int vesares[13][2] = {{320,200},{360,200},{320,240},{360,240},{320,400}, - {360,400},{640,350},{640,400},{640,480},{800,600}, - {1024,768},{1280,1024},{1600,1200}}; - -static int readconfig(BFILE *fp, const char *key, char *value, unsigned len) -{ - char buf[1000], *k, *v, *eq; - int x=0; - - if (len < 1) return 0; - - Brewind(fp); - - while (1) - { - if (!Bfgets(buf, 1000, fp)) return 0; - - if (buf[0] == ';') continue; - - eq = Bstrchr(buf, '='); - if (!eq) continue; - - k = buf; - v = eq+1; - - while (*k == ' ' || *k == '\t') k++; - *(eq--) = 0; - while ((*eq == ' ' || *eq == '\t') && eq>=k) *(eq--) = 0; - - if (Bstrcasecmp(k, key)) continue; - - while (*v == ' ' || *k == '\t') v++; - eq = v + Bstrlen(v)-1; - - while ((*eq == ' ' || *eq == '\t' || *eq == '\r' || *eq == '\n') && eq>=v) *(eq--) = 0; - - value[--len] = 0; - do value[x] = v[x]; while (v[x++] != 0 && len-- > 0); - - return x-1; - } -} - -extern short brightness; -extern int fullscreen; -extern unsigned char option[8]; -extern unsigned char keys[NUMBUILDKEYS]; -double msens; - -/* - * SETUP.DAT - * 0 = video mode (0:chained 1:vesa 2:screen buffered 3/4/5:tseng/paradise/s3 6:red-blue) - * 1 = sound (0:none) - * 2 = music (0:none) - * 3 = input (0:keyboard 1:+mouse) - * 4 = multiplayer (0:single 1-4:com 5-11:ipx) - * 5&0xf0 = com speed - * 5&0x0f = com irq - * 6&0xf0 = chained y-res - * 6&0x0f = chained x-res or vesa mode - * 7&0xf0 = sound samplerate - * 7&0x01 = sound quality - * 7&0x02 = 8/16 bit - * 7&0x04 = mono/stereo - * - * bytes 8 to 26 are key settings: - * 0 = Forward (0xc8) - * 1 = Backward (0xd0) - * 2 = Turn left (0xcb) - * 3 = Turn right (0xcd) - * 4 = Run (0x2a) - * 5 = Strafe (0x9d) - * 6 = Fire (0x1d) - * 7 = Use (0x39) - * 8 = Stand high (0x1e) - * 9 = Stand low (0x2c) - * 10 = Look up (0xd1) - * 11 = Look down (0xc9) - * 12 = Strafe left (0x33) - * 13 = Strafe right (0x34) - * 14 = 2D/3D switch (0x9c) - * 15 = View cycle (0x1c) - * 16 = 2D Zoom in (0xd) - * 17 = 2D Zoom out (0xc) - * 18 = Chat (0xf) - */ - -int Ken_loadsetup(const char *fn) -{ - Ken_SetDefaults(); - - BFILE *fp; -#define VL 32 - char val[VL]; - int i; - - if ((fp = Bfopen(fn, "rt")) == NULL) return -1; - - if (readconfig(fp, "forcesetup", val, VL) > 0) { if (Batoi(val) != 0) forcesetup = 1; else forcesetup = 0; } - if (readconfig(fp, "fullscreen", val, VL) > 0) { if (Batoi(val) != 0) fullscreen = 1; else fullscreen = 0; } - if (readconfig(fp, "resolution", val, VL) > 0) - { - i = Batoi(val) & 0x0f; - if ((unsigned)i<13) { xdimgame = xdim2d = vesares[i][0]; ydimgame = ydim2d = vesares[i][1]; } - } - if (readconfig(fp, "xdim", val, VL) > 0) xdimgame = xdim2d = Batoi(val); - if (readconfig(fp, "ydim", val, VL) > 0) ydimgame = xdim2d = Batoi(val); - if (readconfig(fp, "samplerate", val, VL) > 0) option[7] = (Batoi(val) & 0x0f) << 4; - if (readconfig(fp, "music", val, VL) > 0) { if (Batoi(val) != 0) option[2] = 1; else option[2] = 0; } - if (readconfig(fp, "mouse", val, VL) > 0) { if (Batoi(val) != 0) option[3] = 1; else option[3] = 0; } - if (readconfig(fp, "bpp", val, VL) > 0) bppgame = Batoi(val); - if (readconfig(fp, "renderer", val, VL) > 0) { i = Batoi(val); setrendermode(i); } - if (readconfig(fp, "brightness", val, VL) > 0) brightness = min(max(Batoi(val),0),15); - -#ifdef RENDERTYPEWIN - if (readconfig(fp, "maxrefreshfreq", val, VL) > 0) maxrefreshfreq = Batoi(val); -#endif - - option[0] = 1; // vesa all the way... - option[1] = 1; // sound all the way... - option[4] = 0; // no multiplayer - option[5] = 0; - - if (readconfig(fp, "keyforward", val, VL) > 0) keys[0] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keybackward", val, VL) > 0) keys[1] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyturnleft", val, VL) > 0) keys[2] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyturnright", val, VL) > 0) keys[3] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyrun", val, VL) > 0) keys[4] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystrafe", val, VL) > 0) keys[5] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyfire", val, VL) > 0) keys[6] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyuse", val, VL) > 0) keys[7] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystandhigh", val, VL) > 0) keys[8] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystandlow", val, VL) > 0) keys[9] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keylookup", val, VL) > 0) keys[10] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keylookdown", val, VL) > 0) keys[11] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystrafeleft", val, VL) > 0) keys[12] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystraferight", val, VL) > 0) keys[13] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "key2dmode", val, VL) > 0) keys[14] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyviewcycle", val, VL) > 0) keys[15] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "key2dzoomin", val, VL) > 0) keys[16] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "key2dzoomout", val, VL) > 0) keys[17] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keychat", val, VL) > 0) keys[18] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyconsole", val, VL) > 0) { keys[19] = Bstrtol(val, NULL, 16); OSD_CaptureKey(keys[19]); } - - if (readconfig(fp, "mousesensitivity", val, VL) > 0) msens = Bstrtod(val, NULL); - - Bfclose(fp); - - return 0; -} - -int Ken_writesetup(const char *fn) -{ - BFILE *fp; - - fp = Bfopen(fn,"wt"); - if (!fp) return -1; - - Bfprintf(fp, - "; Always show configuration options on startup\n" - "; 0 - No\n" - "; 1 - Yes\n" - "forcesetup = %d\n" - "\n" - "; Video mode selection\n" - "; 0 - Windowed\n" - "; 1 - Fullscreen\n" - "fullscreen = %d\n" - "\n" - "; Video resolution\n" - "xdim = %d\n" - "ydim = %d\n" - "\n" - "; 3D-mode colour depth\n" - "bpp = %d\n" - "\n" -#ifdef USE_OPENGL - "; OpenGL mode options\n" - "glusetexcache = %d\n" - "\n" -#endif -#ifdef RENDERTYPEWIN - "; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n" - "maxrefreshfreq = %d\n" - "\n" -#endif - "; 3D mode brightness setting\n" - "; 0 - lowest\n" - "; 15 - highest\n" - "brightness = %d\n" - "\n" - "; Sound sample frequency\n" - "; 0 - 6 KHz\n" - "; 1 - 8 KHz\n" - "; 2 - 11.025 KHz\n" - "; 3 - 16 KHz\n" - "; 4 - 22.05 KHz\n" - "; 5 - 32 KHz\n" - "; 6 - 44.1 KHz\n" - "samplerate = %d\n" - "\n" - "; Music playback\n" - "; 0 - Off\n" - "; 1 - On\n" - "music = %d\n" - "\n" - "; Enable mouse\n" - "; 0 - No\n" - "; 1 - Yes\n" - "mouse = %d\n" - "\n" - "; Mouse sensitivity\n" - "mousesensitivity = %g\n" - "\n" - "; Key Settings\n" - "; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n" - "; +---------------------------------------------------------------------------------------------+\n" - "; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 |\n" - "; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL |\n" - "; | |\n" - "; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A |\n" - "; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- |\n" - "; | |\n" - "; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E |\n" - "; |TAB Q W E R T Y U I O P [ ] \\ DEL END PGDN KP7 KP8 KP9 KP+ |\n" - "; | |\n" - "; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D |\n" - "; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C |\n" - "; | KPENTER|\n" - "; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 |\n" - "; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 |\n" - "; | |\n" - "; | 1D 38 39 B8 9D CB D0 CD 52 53 |\n" - "; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. |\n" - "; +---------------------------------------------------------------------------------------------+\n" - "\n" - "keyforward = %X\n" - "keybackward = %X\n" - "keyturnleft = %X\n" - "keyturnright = %X\n" - "keyrun = %X\n" - "keystrafe = %X\n" - "keyfire = %X\n" - "keyuse = %X\n" - "keystandhigh = %X\n" - "keystandlow = %X\n" - "keylookup = %X\n" - "keylookdown = %X\n" - "keystrafeleft = %X\n" - "keystraferight = %X\n" - "key2dmode = %X\n" - "keyviewcycle = %X\n" - "key2dzoomin = %X\n" - "key2dzoomout = %X\n" - "keychat = %X\n" - "keyconsole = %X\n" - "\n", - - forcesetup, fullscreen, xdimgame, ydimgame, bppgame, -#ifdef USE_OPENGL - glusetexcache, -#endif -#ifdef RENDERTYPEWIN - maxrefreshfreq, -#endif - brightness, option[7]>>4, option[2], - option[3], msens, - keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], - keys[6], keys[7], keys[8], keys[9], keys[10], keys[11], - keys[12], keys[13], keys[14], keys[15], keys[16], keys[17], - keys[18], keys[19] - ); - - Bfclose(fp); - - return 0; -} diff --git a/source/kenbuild/src/game.cpp b/source/kenbuild/src/game.cpp deleted file mode 100644 index 1cb211f20..000000000 --- a/source/kenbuild/src/game.cpp +++ /dev/null @@ -1,6428 +0,0 @@ -// Ken Silverman's official web site: "http://www.advsys.net/ken" -// See the included license file "BUILDLIC.TXT" for license info. -// -// This file has been modified from Ken Silverman's original release -// by Jonathon Fowler (jf@jonof.id.au) - -#include "compat.h" -#include "build.h" -#include "names.h" -#include "pragmas.h" -#include "cache1d.h" -#include "game.h" -#include "osd.h" -#include "mmulti.h" -#include "common.h" - -#include "renderlayer.h" - -#include "common_game.h" - -const char *AppProperName = "KenBuild"; -const char *AppTechnicalName = "ekenbuild"; - -#define SETUPFILENAME "ekenbuild.cfg" -char setupfilename[BMAX_PATH] = SETUPFILENAME; - -#define TIMERINTSPERSECOND 140 //280 -#define MOVESPERSECOND 40 -#define TICSPERFRAME 3 -#define MOVEFIFOSIZ 256 -#define EYEHEIGHT (32<<8) //Normally (32<<8), (51<<8) to make mirrors happy - -#define TILE_TILT (MAXTILES-2) - - -static int32_t setsprite_eyeheight(int16_t spritenum, const vec3_t *pos) ATTRIBUTE((nonnull(2))); -static int32_t setsprite_eyeheight(int16_t spritenum, const vec3_t *pos) -{ - vec3_t eyepos = *pos; - eyepos.z += EYEHEIGHT; - return setsprite(spritenum, &eyepos); -} - - -// declared in sound.c -void initsb(char,char,int,char,char,char,char); -void uninitsb(void); -void setears(int,int,int,int); -void wsayfollow(char const *,int,int,int *,int *,char); -void wsay(char const *,int,int,int); -void loadwaves(void); -void loadsong(char const *); -void musicon(void); -void musicoff(void); -void refreshaudio(void); - -// declared in config.c -int Ken_loadsetup(const char *); -int Ken_writesetup(const char *); - -/*************************************************************************** - KEN'S TAG DEFINITIONS: (Please define your own tags for your games) - - sector[?].lotag = 0 Normal sector - sector[?].lotag = 1 If you are on a sector with this tag, then all sectors - with same hi tag as this are operated. Once. - sector[?].lotag = 2 Same as sector[?].tag = 1 but this is retriggable. - sector[?].lotag = 3 A really stupid sector that really does nothing now. - sector[?].lotag = 4 A sector where you are put closer to the floor - (such as the slime in DOOM1.DAT) - sector[?].lotag = 5 A really stupid sector that really does nothing now. - sector[?].lotag = 6 A normal door - instead of pressing D, you tag the - sector with a 6. The reason I make you edit doors - this way is so that can program the doors - yourself. - sector[?].lotag = 7 A door the goes down to open. - sector[?].lotag = 8 A door that opens horizontally in the middle. - sector[?].lotag = 9 A sliding door that opens vertically in the middle. - -Example of the advantages of not using BSP tree. - sector[?].lotag = 10 A warping sector with floor and walls that shade. - sector[?].lotag = 11 A sector with all walls that do X-panning. - sector[?].lotag = 12 A sector with walls using the dragging function. - sector[?].lotag = 13 A sector with some swinging doors in it. - sector[?].lotag = 14 A revolving door sector. - sector[?].lotag = 15 A subway track. - sector[?].lotag = 16 A true double-sliding door. - - wall[?].lotag = 0 Normal wall - wall[?].lotag = 1 Y-panning wall - wall[?].lotag = 2 Switch - If you flip it, then all sectors with same hi - tag as this are operated. - wall[?].lotag = 3 Marked wall to detemine starting dir. (sector tag 12) - wall[?].lotag = 4 Mark on the shorter wall closest to the pivot point - of a swinging door. (sector tag 13) - wall[?].lotag = 5 Mark where a subway should stop. (sector tag 15) - wall[?].lotag = 6 Mark for true double-sliding doors (sector tag 16) - wall[?].lotag = 7 Water fountain - wall[?].lotag = 8 Bouncy wall! - - sprite[?].lotag = 0 Normal sprite - sprite[?].lotag = 1 If you press space bar on an AL, and the AL is tagged - with a 1, he will turn evil. - sprite[?].lotag = 2 When this sprite is operated, a bomb is shot at its - position. - sprite[?].lotag = 3 Rotating sprite. - sprite[?].lotag = 4 Sprite switch. - sprite[?].lotag = 5 Basketball hoop score. - - KEN'S STATUS DEFINITIONS: (Please define your own statuses for your games) - status = 0 Inactive sprite - status = 1 Active monster sprite - status = 2 Monster that becomes active only when it sees you - status = 3 Smoke on the wall for chainguns - status = 4 Splashing sprites (When you shoot slime) - status = 5 Explosion! - status = 6 Travelling bullet - status = 7 Bomb sprial-out explosion - status = 8 Player! - status = 9 EVILALGRAVE shrinking list - status = 10 EVILAL list - status = 11 Sprite respawning list - status = 12 Sprite which does not respawn (Andy's addition) - status = MAXSTATUS Non-existent sprite (this will be true for your - code also) -**************************************************************************/ - -typedef struct -{ - signed char fvel, svel, avel; - short bits; -} input; - -static int screentilt = 0, oscreentilt = 0; - - -static int fvel, svel, avel; -static int fvel2, svel2, avel2; - -#define NUMOPTIONS 8 -#define NUMGAMEKEYS 19 -char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0}; -unsigned char keys[NUMGAMEKEYS] = -{ - 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, - 0x1e,0x2c,0xd1,0xc9,0x33,0x34, - 0x9c,0x1c,0xd,0xc,0xf -}; -int xdimgame = 320, ydimgame = 200, bppgame = 8, xdim2d = 640, ydim2d = 480; // JBF 20050318: config.c expects to find these -int forcesetup = 1; - -static int digihz[8] = {6000,8000,11025,16000,22050,32000,44100,48000}; - -static char frame2draw[MAXPLAYERS]; -static int frameskipcnt[MAXPLAYERS]; - -#define LAVASIZ 128 -#define LAVALOGSIZ 7 -#define LAVAMAXDROPS 32 -static char lavabakpic[(LAVASIZ+4)*(LAVASIZ+4)], lavainc[LAVASIZ]; -static int lavanumdrops, lavanumframes; -static int lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS]; -static int lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS]; -static int lavaradx[24][96], lavarady[24][96], lavaradcnt[32]; - -//Shared player variables -static vec3_t pos[MAXPLAYERS]; -static int horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS]; -static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS]; -static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS]; -static int lastchaingun[MAXPLAYERS]; -static int health[MAXPLAYERS], flytime[MAXPLAYERS]; -static short oflags[MAXPLAYERS]; -static short numbombs[MAXPLAYERS]; -static short numgrabbers[MAXPLAYERS]; // Andy did this -static short nummissiles[MAXPLAYERS]; // Andy did this -static char dimensionmode[MAXPLAYERS]; -static char revolvedoorstat[MAXPLAYERS]; -static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS]; -static int revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS]; - -static int nummoves; -// Bug: NUMSTATS used to be equal to the greatest tag number, -// so that the last statrate[] entry was random memory junk -// because stats 0-NUMSTATS required NUMSTATS+1 bytes. -Andy -#define NUMSTATS 13 -static signed char statrate[NUMSTATS] = {-1,0,-1,0,0,0,1,3,0,3,15,-1,-1}; - -//Input structures -static char networkmode; //0 is 2(n-1) mode, 1 is n(n-1) mode -static int locselectedgun, locselectedgun2; -static input loc, oloc, loc2; -static input ffsync[MAXPLAYERS], osync[MAXPLAYERS], ssync[MAXPLAYERS]; -//Input faketimerhandler -> movethings fifo -static int movefifoplc, movefifoend[MAXPLAYERS]; -static input baksync[MOVEFIFOSIZ][MAXPLAYERS]; -//Game recording variables -static int reccnt, recstat = 1; -static input recsync[16384][2]; - -//static int myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1; -static signed char otherlag[MAXPLAYERS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; -static int averagelag[MAXPLAYERS] = {512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}; - -static int fakemovefifoplc; -static vec3_t my, omy; -static int myzvel; -static int myhoriz, omyhoriz; -static short myang, omyang, mycursectnum; -static vec3_t mybak[MOVEFIFOSIZ]; -static int myhorizbak[MOVEFIFOSIZ]; -static short myangbak[MOVEFIFOSIZ]; - -//GAME.C sync state variables -static char syncstat, syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ]; -static int syncvaltottail, syncvalhead, othersyncvalhead, syncvaltail; - -static char detailmode = 0, ready2send = 0; -static int ototalclock = 0, gotlastpacketclock = 0, smoothratio; -static vec3_t opos[MAXPLAYERS]; -static int ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS]; -static short oang[MAXPLAYERS]; - -static vec3_t osprite[MAXSPRITES]; - -#define MAXINTERPOLATIONS 1024 -static int numinterpolations = 0, startofdynamicinterpolations = 0; -static int oldipos[MAXINTERPOLATIONS]; -static int bakipos[MAXINTERPOLATIONS]; -static int *curipos[MAXINTERPOLATIONS]; - -// extern int cachecount; - -static char playerreadyflag[MAXPLAYERS]; - -//Miscellaneous variables -static unsigned char packbuf[MAXXDIM]; -static char tempbuf[MAXXDIM]; -static char boardfilename[BMAX_PATH]; -static short tempshort[MAXSECTORS]; -static short screenpeek = 0, oldmousebstatus = 0; -short brightness = 0; -static short screensize, screensizeflag = 0; -static short neartagsector, neartagwall, neartagsprite; -static int lockclock, neartagdist, neartaghitdist; -extern int pageoffset, ydim16; -static int globhiz, globloz, globhihit, globlohit; - -//Over the shoulder mode variables -static int cameradist = -1, cameraang = 0, cameraclock = 0; - -//Board animation variables -#define MAXMIRRORS 64 -static short mirrorwall[MAXMIRRORS], mirrorsector[MAXMIRRORS], mirrorcnt; -static short floormirrorsector[64], floormirrorcnt; -static short turnspritelist[16], turnspritecnt; -static short warpsectorlist[64], warpsectorcnt; -static short xpanningsectorlist[16], xpanningsectorcnt; -static short ypanningwalllist[64], ypanningwallcnt; -static short floorpanninglist[64], floorpanningcnt; -static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt; -static int dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16]; -static short swingcnt, swingwall[32][5], swingsector[32]; -static short swingangopen[32], swingangclosed[32], swingangopendir[32]; -static short swingang[32], swinganginc[32]; -static int swingx[32][8], swingy[32][8]; -static short revolvesector[4], revolveang[4], revolvecnt; -static int revolvex[4][16], revolvey[4][16]; -static int revolvepivotx[4], revolvepivoty[4]; -static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt; -static int subwaystop[4][8], subwaystopcnt[4]; -static int subwaytrackx1[4], subwaytracky1[4]; -static int subwaytrackx2[4], subwaytracky2[4]; -static int subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4]; -static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS]; -static short slimesoundcnt[MAXPLAYERS]; - -//Variables that let you type messages to other player -static char getmessage[162], getmessageleng; -static int getmessagetimeoff; -static char typemessage[162], typemessageleng = 0, typemode = 0; -#if 0 -static char scantoasc[128] = -{ - 0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0, - 'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s', - 'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v', - 'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0, - 0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1', - '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,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 char scantoascwithshift[128] = -{ - 0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0, - 'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S', - 'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V', - 'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0, - 0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1', - '2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -}; -#endif - -//These variables are for animating x, y, or z-coordinates of sectors, -//walls, or sprites (They are NOT to be used for changing the [].picnum's) -//See the setanimation(), and getanimategoal() functions for more details. -#define MAXANIMATES 512 -static int *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; -static int animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0; - -#if defined USE_OPENGL -//These parameters are in exact order of sprite structure in BUILD.H -#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ - clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ - xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ - { \ - spritetype *spr2; \ - newspriteindex2 = insertsprite(sectnum2,statnum2); \ - spr2 = &sprite[newspriteindex2]; \ - spr2->x = x2; spr2->y = y2; spr2->z = z2; \ - spr2->cstat = cstat2; spr2->shade = shade2; \ - spr2->pal = pal2; spr2->clipdist = clipdist2; \ - spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ - spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ - spr2->picnum = picnum2; spr2->ang = ang2; \ - spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ - spr2->owner = owner2; \ - spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ - copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ - show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ - if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ - show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ - clearbufbyte(&spriteext[newspriteindex2], sizeof(spriteext_t), 0); \ - } -#else -#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ - clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ - xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ - { \ - spritetype *spr2; \ - newspriteindex2 = insertsprite(sectnum2,statnum2); \ - spr2 = &sprite[newspriteindex2]; \ - spr2->x = x2; spr2->y = y2; spr2->z = z2; \ - spr2->cstat = cstat2; spr2->shade = shade2; \ - spr2->pal = pal2; spr2->clipdist = clipdist2; \ - spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ - spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ - spr2->picnum = picnum2; spr2->ang = ang2; \ - spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ - spr2->owner = owner2; \ - spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ - copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ - show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ - if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ - show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ - } -#endif - -int nextvoxid = 0; - -int osdcmd_restartvid(const osdfuncparm_t *parm) -{ - UNREFERENCED_PARAMETER(parm); - - resetvideomode(); - if (setgamemode(fullscreen,xdim,ydim,bpp)) - buildputs("restartvid: Reset failed...\n"); - - return OSDCMD_OK; -} - -static int osdcmd_vidmode(const osdfuncparm_t *parm) -{ - int newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen; - - if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP; - - switch (parm->numparms) - { - case 1: // bpp switch - newbpp = Batol(parm->parms[0]); - break; - case 2: // res switch - newx = Batol(parm->parms[0]); - newy = Batol(parm->parms[1]); - break; - case 3: // res & bpp switch - case 4: - newx = Batol(parm->parms[0]); - newy = Batol(parm->parms[1]); - newbpp = Batol(parm->parms[2]); - if (parm->numparms == 4) - newfullscreen = (Batol(parm->parms[3]) != 0); - break; - } - - if (setgamemode(newfullscreen,newx,newy,newbpp)) - buildputs("vidmode: Mode change failed!\n"); - screensize = xdim+1; - return OSDCMD_OK; -} - -static int osdcmd_map(const osdfuncparm_t *parm) -{ - int i; - char *dot, namebuf[BMAX_PATH+1]; - - if (parm->numparms != 1) return OSDCMD_SHOWHELP; - - strncpy(namebuf, parm->parms[0], BMAX_PATH); - namebuf[BMAX_PATH] = 0; - dot = strrchr(namebuf, '.'); - if ((!dot || Bstrcasecmp(dot, ".map")) && strlen(namebuf) <= BMAX_PATH-4) - { - strcat(namebuf, ".map"); - } - - prepareboard(namebuf); - - screenpeek = myconnectindex; - reccnt = 0; - for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i); - - waitforeverybody(); - totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0; - - ready2send = 1; - drawscreen(screenpeek,65536L); - - return OSDCMD_OK; -} - -static void Ken_UninitAll(void) -{ - sendlogoff(); //Signing off - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); -} - -static void Ken_FatalEngineError(void) -{ - buildprintf("There was a problem initialising the engine: %s.\n", engineerrstr); -} - -int32_t app_main(int32_t argc, char const * const * argv) -{ -#if defined STARTUP_SETUP_WINDOW - int cmdsetup = 0; -#endif - int i, j, k /*, l, fil, waitplayers, x1, y1, x2, y2*/; - int /*other, packleng,*/ netparm; - - OSD_SetLogFile("ekenbuild.log"); - - OSD_SetFunctions( - NULL, NULL, NULL, NULL, NULL, - COMMON_clearbackground, - BGetTime, - NULL - ); - - OSD_SetParameters(0,2, 0,0, 4,0, 0, 0, 0); // TODO: Add error and red palookup IDs. - - initprintf("%s %s\n", AppProperName, s_buildRev); - PrintBuildInfo(); - -#ifdef USE_OPENGL - OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid); - OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode); - OSD_RegisterFunction("map", "map [filename]: load a map", osdcmd_map); -#endif - - wm_setapptitle(AppProperName); - - Bstrcpy(boardfilename, "nukeland.map"); - j = 0; netparm = argc; - for (i=1; i= 2); - - loadpics("tiles000.art",1048576); //Load artwork - if (!qloadkvx(nextvoxid,"voxel000.kvx")) - tiletovox[PLAYER] = nextvoxid++; - if (!qloadkvx(nextvoxid,"voxel001.kvx")) - tiletovox[BROWNMONSTER] = nextvoxid++; - if (!loaddefinitionsfile(G_DefFile())) buildputs("Definitions file loaded.\n"); - - if (E_PostInit()) - { - Ken_UninitAll(); - Ken_FatalEngineError(); - return -1; - } - - //Here's an example of TRUE ornamented walls - //The allocatepermanenttile should be called right after loadpics - //Since it resets the tile cache for each call. - if (allocatepermanenttile(SLIME,128,128) == 0) //If enough memory - { - buildputs("Not enough memory for slime!\n"); - exit(0); - } - if (allocatepermanenttile(MAXTILES-1,64,64) != 0) //If enough memory - { - //My face with an explosion written over it - copytilepiece(KENPICTURE,0,0,64,64,MAXTILES-1,0,0); - copytilepiece(EXPLOSION,0,0,64,64,MAXTILES-1,0,0); - } - - initlava(); - - for (j=0; j<256; j++) - tempbuf[j] = ((j+32)&255); //remap colors for screwy palette sectors - makepalookup(16,tempbuf,0,0,0,1); - - for (j=0; j<256; j++) tempbuf[j] = j; - makepalookup(17,tempbuf,96,96,96,1); - - for (j=0; j<256; j++) tempbuf[j] = j; //(j&31)+32; - makepalookup(18,tempbuf,32,32,192,1); - - fillemptylookups(); - - prepareboard(boardfilename); //Load board - - initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1); - //if (Bstrcmp(boardfilename,"klab.map") == 0) - // loadsong("klabsong.kdm"); - //else - loadsong("neatsong.kdm"); - musicon(); - -#if 0 - if (option[4] > 0) - { - x1 = ((xdim-screensize)>>1); - x2 = x1+screensize-1; - y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - y2 = y1 + scale(screensize,ydim-32,xdim)-1; - - drawtilebackground(/*0L,0L,*/ BACKGROUND,8,x1,y1,x2,y2,0); - - sendlogon(); - - if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3; - while (numplayers < waitplayers) - { - sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers); - printext256(68L,84L,31,0,tempbuf,0); - nextpage(); - - if (getpacket(&other,packbuf) > 0) - if (packbuf[0] == 255) - keystatus[1] = 1; - - if (handleevents()) - { - if (quitevent) - { - keystatus[1] = 1; - quitevent = 0; - } - } - - if (keystatus[1]) - { - Ken_UninitAll(); - return 0; - } - } - screenpeek = myconnectindex; - - if (numplayers <= 3) - networkmode = 1; - else - networkmode = 0; - - j = 1; - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - if (myconnectindex == i) break; - j++; - } - sprintf(getmessage,"Player %ld",j); - if (networkmode == 0) - { - if (j == 1) Bstrcat(getmessage," (Master)"); - else Bstrcat(getmessage," (Slave)"); - } - else - Bstrcat(getmessage," (Even)"); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = totalclock+120; - } -#endif - screenpeek = myconnectindex; - reccnt = 0; - for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i); - - waitforeverybody(); - totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0; - - ready2send = 1; - drawscreen(screenpeek,65536L); - - while (!keystatus[1]) //Main loop starts here - { - if (handleevents()) - { - if (quitevent) - { - keystatus[1] = 1; - quitevent = 0; - } - } - - refreshaudio(); - OSD_DispatchQueued(); - - // backslash (useful only with KDM) -// if (keystatus[0x2b]) { keystatus[0x2b] = 0; preparesndbuf(); } - - if ((networkmode == 1) || (myconnectindex != connecthead)) - while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); - - getpackets(); - - if (typemode == 0) //if normal game keys active - { - if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0) //Sh.Sh.R (replay) - { - keystatus[0x13] = 0; - playback(); - } - - if (keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) //Load game - { - keystatus[0x26] = 0; - loadgame(); - drawstatusbar(screenpeek); // Andy did this - } - - if (keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) //Save game - { - keystatus[0x1f] = 0; - savegame(); - } - } - - if ((networkmode == 0) || (option[4] == 0)) - { - while (movefifoplc != movefifoend[0]) domovethings(); - } - else - { - j = connecthead; - if (j == myconnectindex) j = connectpoint2[j]; - averagelag[j] = ((averagelag[j]*7+(((movefifoend[myconnectindex]-movefifoend[j]+otherlag[j]+2)&255)<<8))>>3); - j = max(averagelag[j]>>9,1); - while (((movefifoend[myconnectindex]-movefifoplc)&(MOVEFIFOSIZ-1)) > j) - { - for (i=connecthead; i>=0; i=connectpoint2[i]) - if (movefifoplc == movefifoend[i]) break; - if (i >= 0) break; - if (myconnectindex != connecthead) - { - k = ((movefifoend[myconnectindex]-movefifoend[connecthead]-otherlag[connecthead]+128)&255); - if (k > 128+1) ototalclock++; - if (k < 128-1) ototalclock--; - } - domovethings(); - } - } - i = ((int32_t) totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND)); - - drawscreen(screenpeek,i); - } - - Ken_UninitAll(); - - return 0; -} - -void operatesector(short dasector) -{ - //Door code - int i, j, /*k, s, nexti, good, cnt,*/ datag; - int /*dax, day,*/ daz, dax2, day2, /*daz2,*/ centx, centy; - short startwall, endwall, wallfind[2]; - - datag = sector[dasector].lotag; - - startwall = sector[dasector].wallptr; - endwall = startwall + sector[dasector].wallnum; - centx = 0L, centy = 0L; - for (i=startwall; i= 0) //If door already moving, reverse its direction - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].floorz; - - if (animategoal[i] == daz) - animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; - else - animategoal[i] = daz; - animatevel[i] = 0; - } - else //else insert the door's ceiling on the animation list - { - if (sector[dasector].ceilingz == sector[dasector].floorz) - daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; - else - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].floorz; - } - if ((j = setanimation(§or[dasector].ceilingz,daz,6L,6L)) >= 0) - wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); - } - } - //Simple door that moves down - if ((datag == 7) || (datag == 8)) //If the sector in front's elevator - { - i = getanimationgoal(§or[dasector].floorz); - if (i >= 0) //If elevator already moving, reverse its direction - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].ceilingz; - - if (animategoal[i] == daz) - animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; - else - animategoal[i] = daz; - animatevel[i] = 0; - } - else //else insert the elevator's ceiling on the animation list - { - if (sector[dasector].floorz == sector[dasector].ceilingz) - daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; - else - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].ceilingz; - } - if ((j = setanimation(§or[dasector].floorz,daz,6L,6L)) >= 0) - wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); - } - } - - if (datag == 9) //Smooshy-wall sideways double-door - { - //find any points with either same x or same y coordinate - // as center (centx, centy) - should be 2 points found. - wallfind[0] = -1; - wallfind[1] = -1; - for (i=startwall; i>1)-wall[wallfind[j]].x; - day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; - if (dax2 != 0) - { - dax2 = wall[wall[wall[wallfind[j]].point2].point2].x; - dax2 -= wall[wall[wallfind[j]].point2].x; - setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); - setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); - } - else if (day2 != 0) - { - day2 = wall[wall[wall[wallfind[j]].point2].point2].y; - day2 -= wall[wall[wallfind[j]].point2].y; - setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); - setanimation(&wall[i].y,wall[i].y+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); - } - } - else - { - i = wallfind[j]-1; if (i < startwall) i = endwall-1; - dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x; - day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; - if (dax2 != 0) - { - setanimation(&wall[wallfind[j]].x,centx,4L,0L); - setanimation(&wall[i].x,centx+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L); - } - else if (day2 != 0) - { - setanimation(&wall[wallfind[j]].y,centy,4L,0L); - setanimation(&wall[i].y,centy+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L); - } - } - } - wsayfollow("updowndr.wav",4096L-256L,256L,¢x,¢y,0); - wsayfollow("updowndr.wav",4096L+256L,256L,¢x,¢y,0); - } - - if (datag == 13) //Swinging door - { - for (i=0; i>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy)) - { - //door was closed - //find what direction door should open - i = wallfind[j]-1; if (i < startwall) i = endwall-1; - dax2 = wall[i].x-wall[wallfind[j]].x; - day2 = wall[i].y-wall[wallfind[j]].y; - if (dax2 != 0) - { - dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x; - dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x; - setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); - setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L); - } - else if (day2 != 0) - { - day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y; - day2 -= wall[wall[wall[wallfind[j]].point2].point2].y; - setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); - setanimation(&wall[i].y,wall[i].y+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L); - } - } - else - { - //door was not closed - i = wallfind[j]-1; if (i < startwall) i = endwall-1; - dax2 = wall[i].x-wall[wallfind[j]].x; - day2 = wall[i].y-wall[wallfind[j]].y; - if (dax2 != 0) - { - setanimation(&wall[wallfind[j]].x,centx,4L,0L); - setanimation(&wall[i].x,centx+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L); - } - else if (day2 != 0) - { - setanimation(&wall[wallfind[j]].y,centy,4L,0L); - setanimation(&wall[i].y,centy+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L); - } - } - } - wsayfollow("updowndr.wav",4096L-64L,256L,¢x,¢y,0); - wsayfollow("updowndr.wav",4096L+64L,256L,¢x,¢y,0); - } -} - -void operatesprite(short dasprite) -{ - int datag; - - datag = sprite[dasprite].lotag; - - if (datag == 2) //A sprite that shoots a bomb - { - vec3_t vector = { sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z }; - shootgun(dasprite, &vector, - sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2); - } -} - -int changehealth(short snum, short deltahealth) -{ - // int dax, day; - // short good, k, startwall, endwall, s; - - if (health[snum] > 0) - { - health[snum] += deltahealth; - if (health[snum] > 999) health[snum] = 999; - - if (health[snum] <= 0) - { - health[snum] = -1; - wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - sprite[playersprite[snum]].picnum = SKELETON; - } - - if ((snum == screenpeek) && (screensize <= xdim)) - { - if (health[snum] > 0) - sprintf((char *)tempbuf,"Health:%3d",health[snum]); - else - sprintf((char *)tempbuf,"YOU STINK!"); - - printext((xdim>>1)-(Bstrlen((char *)tempbuf)<<2),ydim-24,(char *)tempbuf,ALPHABET /*,80*/); - } - } - return health[snum] <= 0; //You were just injured -} - -void changenumbombs(short snum, short deltanumbombs) // Andy did this -{ - numbombs[snum] += deltanumbombs; - if (numbombs[snum] > 999) numbombs[snum] = 999; - if (numbombs[snum] <= 0) - { - wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - numbombs[snum] = 0; - } - - if ((snum == screenpeek) && (screensize <= xdim)) - { - sprintf((char *)tempbuf,"B:%3d",numbombs[snum]); - printext(8L,(ydim - 28L),(char *)tempbuf,ALPHABET /*,80*/); - } -} - -void changenummissiles(short snum, short deltanummissiles) // Andy did this -{ - nummissiles[snum] += deltanummissiles; - if (nummissiles[snum] > 999) nummissiles[snum] = 999; - if (nummissiles[snum] <= 0) - { - wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - nummissiles[snum] = 0; - } - - if ((snum == screenpeek) && (screensize <= xdim)) - { - sprintf((char *)tempbuf,"M:%3d",nummissiles[snum]); - printext(8L,(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/); - } -} - -void changenumgrabbers(short snum, short deltanumgrabbers) // Andy did this -{ - numgrabbers[snum] += deltanumgrabbers; - if (numgrabbers[snum] > 999) numgrabbers[snum] = 999; - if (numgrabbers[snum] <= 0) - { - wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - numgrabbers[snum] = 0; - } - - if ((snum == screenpeek) && (screensize <= xdim)) - { - sprintf((char *)tempbuf,"G:%3d",numgrabbers[snum]); - printext(8L,(ydim - 12L),(char *)tempbuf,ALPHABET /*,80*/); - } -} - -static int ostatusflytime = 0x80000000; -void drawstatusflytime(short snum) // Andy did this -{ - int nstatusflytime; - - if ((snum == screenpeek) && (screensize <= xdim)) - { - nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); - if (nstatusflytime > 1000) nstatusflytime = 1000; - else if (nstatusflytime < 0) nstatusflytime = 0; - if (nstatusflytime != ostatusflytime) - { - if (nstatusflytime > 999) sprintf((char *)tempbuf,"FT:BIG"); - else sprintf((char *)tempbuf,"FT:%3d",nstatusflytime); - printext((xdim - 56L),(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/); - ostatusflytime = nstatusflytime; - } - } -} - -void drawstatusbar(short snum) // Andy did this -{ - int nstatusflytime; - - if ((snum == screenpeek) && (screensize <= xdim)) - { - sprintf((char *)tempbuf,"Deaths:%d",deaths[snum]); - printext((xdim>>1)-(strlen((char *)tempbuf)<<2),ydim-16,(char *)tempbuf,ALPHABET /*,80*/); - sprintf((char *)tempbuf,"Health:%3d",health[snum]); - printext((xdim>>1)-(strlen((char *)tempbuf)<<2),ydim-24,(char *)tempbuf,ALPHABET /*,80*/); - - sprintf((char *)tempbuf,"B:%3d",numbombs[snum]); - printext(8L,(ydim - 28L),(char *)tempbuf,ALPHABET /*,80*/); - sprintf((char *)tempbuf,"M:%3d",nummissiles[snum]); - printext(8L,(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/); - sprintf((char *)tempbuf,"G:%3d",numgrabbers[snum]); - printext(8L,(ydim - 12L),(char *)tempbuf,ALPHABET /*,80*/); - - nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); - if (nstatusflytime < 0) - { - sprintf((char *)tempbuf,"FT: 0"); - ostatusflytime = 0; - } - else if (nstatusflytime > 999) - { - sprintf((char *)tempbuf,"FT:BIG"); - ostatusflytime = 999; - } - else - { - sprintf((char *)tempbuf,"FT:%3d",nstatusflytime); - ostatusflytime = nstatusflytime; - } - printext((xdim - 56L),(ydim - 20L),(char *)tempbuf,ALPHABET /*,80*/); - } -} - -void prepareboard(char *daboardfilename) -{ - short startwall, endwall, dasector; - int i, j, k=0, s, dax, day, /*daz,*/ dax2, day2; - - getmessageleng = 0; - typemessageleng = 0; - - randomseed = 17L; - - //Clear (do)animation's list - animatecnt = 0; - typemode = 0; - locselectedgun = 0; - locselectedgun2 = 0; - - if (loadboard(daboardfilename,0,&pos[0],&ang[0],&cursectnum[0]) == -1) - { - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - printf("Board not found\n"); - exit(0); - } - else - { - char tempfn[BMAX_PATH + 1], *fp; - - strncpy(tempfn, daboardfilename, BMAX_PATH); - tempfn[BMAX_PATH] = 0; - - fp = strrchr(tempfn,'.'); - if (fp) *fp = 0; - - if (strlen(tempfn) <= BMAX_PATH-4) - { - strcat(tempfn,".mhk"); - loadmaphack(tempfn); - } - } - - setup3dscreen(); - - for (i=0; i dax2) dax2 = wall[j].x; - if (wall[j].y > day2) day2 = wall[j].y; - if (wall[j].lotag == 3) k = j; - } - if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16; - if (wall[k].y == day) dragydir[dragsectorcnt] = -16; - if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16; - if (wall[k].y == day2) dragydir[dragsectorcnt] = 16; - - dasector = wall[startwall].nextsector; - dragx1[dragsectorcnt] = 0x7fffffff; - dragy1[dragsectorcnt] = 0x7fffffff; - dragx2[dragsectorcnt] = 0x80000000; - dragy2[dragsectorcnt] = 0x80000000; - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - for (j=startwall; j dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x; - if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y; - - setinterpolation(§or[dasector].floorz); - setinterpolation(&wall[j].x); - setinterpolation(&wall[j].y); - setinterpolation(&wall[wall[j].nextwall].x); - setinterpolation(&wall[wall[j].nextwall].y); - } - - dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax); - dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day); - dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x); - dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y); - - dragfloorz[dragsectorcnt] = sector[i].floorz; - - dragsectorlist[dragsectorcnt++] = i; - break; - case 13: - startwall = sector[i].wallptr; - endwall = startwall+sector[i].wallnum; - for (j=startwall; j dax2) dax2 = wall[j].x; - if (wall[j].y > day2) day2 = wall[j].y; - } - for (j=startwall; j dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2)) - { - subwayx[subwaytrackcnt] = wall[j].x; - } - else - { - subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x; - subwaystopcnt[subwaytrackcnt]++; - } - } - } - - for (j=1; j subwaytrackx1[subwaytrackcnt]) - if (wall[startwall].y > subwaytracky1[subwaytrackcnt]) - if (wall[startwall].x < subwaytrackx2[subwaytrackcnt]) - if (wall[startwall].y < subwaytracky2[subwaytrackcnt]) - { - if (sector[j].floorz != sector[i].floorz) - { - sector[j].ceilingstat |= 64; - sector[j].floorstat |= 64; - } - subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j; - subwaynumsectors[subwaytrackcnt]++; - } - } - - subwayvel[subwaytrackcnt] = 64; - subwaypausetime[subwaytrackcnt] = 720; - - startwall = sector[i].wallptr; - endwall = startwall+sector[i].wallnum; - for (k=startwall; k subwaytrackx1[subwaytrackcnt]) - if (wall[k].y > subwaytracky1[subwaytrackcnt]) - if (wall[k].x < subwaytrackx2[subwaytrackcnt]) - if (wall[k].y < subwaytracky2[subwaytrackcnt]) - setinterpolation(&wall[k].x); - - for (j=1; j=0; k=nextspritesect[k]) - if (statrate[sprite[k].statnum] < 0) - setinterpolation(&sprite[k].x); - } - - - subwaytrackcnt++; - break; - } - if (sector[i].floorpicnum == FLOORMIRROR) - floormirrorsector[mirrorcnt++] = i; - //if (sector[i].ceilingpicnum == FLOORMIRROR) floormirrorsector[mirrorcnt++] = i; //SOS - } - - //Scan wall tags - - mirrorcnt = 0; - tilesiz[MIRROR].x = 0; - tilesiz[MIRROR].y = 0; - for (i=0; i= 0) && (wall[i].overpicnum == MIRROR) && (wall[i].cstat&32)) - { - if ((sector[s].floorstat&1) == 0) - { - wall[i].overpicnum = MIRRORLABEL+mirrorcnt; - sector[s].ceilingpicnum = MIRRORLABEL+mirrorcnt; - sector[s].floorpicnum = MIRRORLABEL+mirrorcnt; - sector[s].floorstat |= 1; - mirrorwall[mirrorcnt] = i; - mirrorsector[mirrorcnt] = s; - mirrorcnt++; - } - else - wall[i].overpicnum = sector[s].ceilingpicnum; - } - } - - //Invalidate textures in sector behind mirror - for (i=0; i=0; i--) copybuf(&sprite[i].x,&osprite[i].x,3); - - searchmap(cursectnum[connecthead]); - - lockclock = 0; - ototalclock = 0; - gotlastpacketclock = 0; - - screensize = xdim; - dax = ((xdim-screensize)>>1); - dax2 = dax+screensize-1; - day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - day2 = day + scale(screensize,ydim-32,xdim)-1; - setview(dax,day,dax2,day2); - - startofdynamicinterpolations = numinterpolations; - -#if 0 - for (i=connecthead; i>=0; i=connectpoint2[i]) myminlag[i] = 0; - otherminlag = mymaxlag = 0; -#endif -} - -void checktouchsprite(short snum, short sectnum) -{ - int i, nexti; - - if ((sectnum < 0) || (sectnum >= numsectors)) return; - - for (i=headspritesect[sectnum]; i>=0; i=nexti) - { - nexti = nextspritesect[i]; - if (sprite[i].cstat&0x8000) continue; - if ((klabs(pos[snum].x-sprite[i].x)+klabs(pos[snum].y-sprite[i].y) < 512) && (klabs((pos[snum].z>>8)-((sprite[i].z>>8)-(tilesiz[sprite[i].picnum].y>>1))) <= 40)) - { - switch (sprite[i].picnum) - { - case COIN: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,5); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*60; - changespritestat((short)i,11); - } - break; - case DIAMONDS: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,15); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*120; - changespritestat((short)i,11); - } - break; - case COINSTACK: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,25); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*180; - changespritestat((short)i,11); - } - break; - case GIFTBOX: - wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case CANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (snum == myconnectindex) keystatus[4] = 1; - changenumbombs(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case LAUNCHER: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (snum == myconnectindex) keystatus[5] = 1; - changenummissiles(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case GRABCANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (snum == myconnectindex) keystatus[6] = 1; - changenumgrabbers(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case AIRPLANE: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (flytime[snum] < lockclock) flytime[snum] = lockclock; - flytime[snum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); - drawstatusflytime(snum); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - } - } - } -} - -void checkgrabbertouchsprite(short snum, short sectnum) // Andy did this -{ - int i, nexti; - short onum; - - if ((sectnum < 0) || (sectnum >= numsectors)) return; - onum = (sprite[snum].owner & (MAXSPRITES - 1)); - - for (i=headspritesect[sectnum]; i>=0; i=nexti) - { - nexti = nextspritesect[i]; - if (sprite[i].cstat&0x8000) continue; - if ((klabs(sprite[snum].x-sprite[i].x)+klabs(sprite[snum].y-sprite[i].y) < 512) && (klabs((sprite[snum].z>>8)-((sprite[i].z>>8)-(tilesiz[sprite[i].picnum].y>>1))) <= 40)) - { - switch (sprite[i].picnum) - { - case COIN: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,5); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*60; - changespritestat((short)i,11); - } - break; - case DIAMONDS: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,15); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*120; - changespritestat((short)i,11); - } - break; - case COINSTACK: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,25); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*180; - changespritestat((short)i,11); - } - break; - case GIFTBOX: - wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case CANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (onum == myconnectindex) keystatus[4] = 1; - changenumbombs(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case LAUNCHER: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (onum == myconnectindex) keystatus[5] = 1; - changenummissiles(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case GRABCANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (onum == myconnectindex) keystatus[6] = 1; - changenumgrabbers(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case AIRPLANE: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (flytime[snum] < lockclock) flytime[snum] = lockclock; - flytime[onum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); - drawstatusflytime(onum); - if (sprite[i].statnum == 12) deletesprite((short)i); - else - { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - } - } - } -} - -void shootgun(short snum, const vec3_t *vector, - short daang, int dahoriz, short dasectnum, char guntype) -{ - short daang2; - int /*i,*/ j, daz2; - hitdata_t hitinfo; - - switch (guntype) - { - case 0: //Shoot chain gun - daang2 = ((daang + (krand()&31)-16)&2047); - daz2 = ((100-dahoriz)*2000) + ((krand()-32768)>>1); - - hitscan(vector,dasectnum, //Start position - sintable[(daang2+512)&2047], //X vector of 3D ang - sintable[daang2&2047], //Y vector of 3D ang - daz2, //Z vector of 3D ang - &hitinfo,CLIPMASK1); - - if (wall[hitinfo.wall].picnum == KENPICTURE) - { - if (waloff[MAXTILES-1] != 0) wall[hitinfo.wall].picnum = MAXTILES-1; - wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&wall[hitinfo.wall].x,&wall[hitinfo.wall].y,0); - } - else if (((hitinfo.wall < 0) && (hitinfo.sprite < 0) && (hitinfo.pos.z >= vector->z) && ((sector[hitinfo.sect].floorpicnum == SLIME) || (sector[hitinfo.sect].floorpicnum == FLOORMIRROR))) || ((hitinfo.wall >= 0) && (wall[hitinfo.wall].picnum == SLIME))) - { - //If you shoot slime, make a splash - wsayfollow("splash.wav",4096L+(krand()&511)-256,256L,&hitinfo.pos.x,&hitinfo.pos.y,0); - spawnsprite(j,hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z,2,0,0,32,64,64,0,0,SPLASH,daang, - 0,0,0,snum+4096,hitinfo.sect,4,63,0,0); //63=time left for splash - } - else - { - wsayfollow("shoot.wav",4096L+(krand()&127)-64,256L,&hitinfo.pos.x,&hitinfo.pos.y,0); - - if ((hitinfo.sprite >= 0) && (sprite[hitinfo.sprite].statnum < MAXSTATUS)) - switch (sprite[hitinfo.sprite].picnum) - { - case BROWNMONSTER: - if (sprite[hitinfo.sprite].lotag > 0) sprite[hitinfo.sprite].lotag -= 10; - if (sprite[hitinfo.sprite].lotag > 0) - { - wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&hitinfo.pos.x,&hitinfo.pos.y,0); - if (sprite[hitinfo.sprite].lotag <= 25) - sprite[hitinfo.sprite].cstat |= 2; - } - else - { - wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&hitinfo.pos.x,&hitinfo.pos.y,0); - sprite[hitinfo.sprite].z += ((tilesiz[sprite[hitinfo.sprite].picnum].y*sprite[hitinfo.sprite].yrepeat)<<1); - sprite[hitinfo.sprite].picnum = GIFTBOX; - sprite[hitinfo.sprite].cstat &= ~0x83; //Should not clip, foot-z - changespritestat(hitinfo.sprite,12); - - spawnsprite(j,hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z+(32<<8),0,-4,0,32,64,64, - 0,0,EXPLOSION,daang,0,0,0,snum+4096, - hitinfo.sect,5,31,0,0); - } - break; - case EVILAL: - wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&hitinfo.pos.x,&hitinfo.pos.y,0); - sprite[hitinfo.sprite].picnum = EVILALGRAVE; - sprite[hitinfo.sprite].cstat = 0; - sprite[hitinfo.sprite].xvel = (krand()&255)-128; - sprite[hitinfo.sprite].yvel = (krand()&255)-128; - sprite[hitinfo.sprite].zvel = (krand()&4095)-3072; - changespritestat(hitinfo.sprite,9); - - spawnsprite(j,hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z+(32<<8),0,-4,0,32,64,64,0, - 0,EXPLOSION,daang,0,0,0,snum+4096,hitinfo.sect,5,31,0,0); - //31=time left for explosion - - break; - case PLAYER: - for (j=connecthead; j>=0; j=connectpoint2[j]) - if (playersprite[j] == hitinfo.sprite) - { - wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&hitinfo.pos.x,&hitinfo.pos.y,0); - changehealth(j,-10); - break; - } - break; - } - - spawnsprite(j,hitinfo.pos.x,hitinfo.pos.y,hitinfo.pos.z+(8<<8),2,-4,0,32,16,16,0,0, - EXPLOSION,daang,0,0,0,snum+4096,hitinfo.sect,3,63,0,0); - - //Sprite starts out with center exactly on wall. - //This moves it back enough to see it at all angles. - movesprite((short)j,-(((int)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),-(((int)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,CLIPMASK1); - } - break; - case 1: //Shoot silver sphere bullet - spawnsprite(j,vector->x,vector->y,vector->z,1+128,0,0,16,64,64,0,0,BULLET,daang, - sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, - (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot2.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); - break; - case 2: //Shoot bomb - spawnsprite(j,vector->x,vector->y,vector->z,128,0,0,12,16,16,0,0,BOMB,daang, - sintable[(daang+512)&2047]*5>>8,sintable[daang&2047]*5>>8, - (80-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); - break; - case 3: //Shoot missile (Andy did this) - spawnsprite(j,vector->x,vector->y,vector->z,1+128,0,0,16,32,32,0,0,MISSILE,daang, - sintable[(daang+512)&2047]>>4,sintable[daang&2047]>>4, - (100-dahoriz)<<7,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); - break; - case 4: //Shoot grabber (Andy did this) - spawnsprite(j,vector->x,vector->y,vector->z,1+128,0,0,16,64,64,0,0,GRABBER,daang, - sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, - (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot4.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); - break; - } -} - -#define MAXVOXMIPS 5 -extern intptr_t voxoff[][MAXVOXMIPS]; -void analyzesprites(int dax, int day) -{ - int i, j=0, k, *intptr; - vec3_t *ospr; - uspritetype *tspr; - - //This function is called between drawrooms() and drawmasks() - //It has a list of possible sprites that may be drawn on this frame - - for (i=0,tspr=&tsprite[0]; ipicnum] >= 0) - switch (tspr->picnum) - { - case PLAYER: - // //Get which of the 8 angles of the sprite to draw (0-7) - // //k ranges from 0-7 - //k = getangle(tspr->x-dax,tspr->y-day); - //k = (((tspr->ang+3072+128-k)&2047)>>8)&7; - // //This guy has only 5 pictures for 8 angles (3 are x-flipped) - //if (k <= 4) - //{ - // tspr->picnum += (k<<2); - // tspr->cstat &= ~4; //clear x-flipping bit - //} - //else - //{ - // tspr->picnum += ((8-k)<<2); - // tspr->cstat |= 4; //set x-flipping bit - //} - - if ((tspr->cstat&2) == 0) - { - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - intptr = (int *)voxoff[tiletovox[PLAYER]][0]; - tspr->xrepeat = scale(tspr->xrepeat,56,intptr[2]); - tspr->yrepeat = scale(tspr->yrepeat,56,intptr[2]); - tspr->shade -= 6; - } - break; - case BROWNMONSTER: - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - break; - } - - k = statrate[tspr->statnum]; - if (k >= 0) //Interpolate moving sprite - { - ospr = &osprite[tspr->owner]; - switch (k) - { - case 0: j = smoothratio; break; - case 1: j = (smoothratio>>1)+(((nummoves-tspr->owner)&1)<<15); break; - case 3: j = (smoothratio>>2)+(((nummoves-tspr->owner)&3)<<14); break; - case 7: j = (smoothratio>>3)+(((nummoves-tspr->owner)&7)<<13); break; - case 15: j = (smoothratio>>4)+(((nummoves-tspr->owner)&15)<<12); break; - } - k = tspr->x-ospr->x; tspr->x = ospr->x; - if (k != 0) tspr->x += mulscale16(k,j); - k = tspr->y-ospr->y; tspr->y = ospr->y; - if (k != 0) tspr->y += mulscale16(k,j); - k = tspr->z-ospr->z; tspr->z = ospr->z; - if (k != 0) tspr->z += mulscale16(k,j); - } - - //Don't allow close explosion sprites to be transluscent - k = tspr->statnum; - if ((k == 3) || (k == 4) || (k == 5) || (k == 7)) - if (klabs(dax-tspr->x) < 256) - if (klabs(day-tspr->y) < 256) - tspr->cstat &= ~2; - - tspr->shade += 6; - if (sector[tspr->sectnum].ceilingstat&1) - tspr->shade += sector[tspr->sectnum].ceilingshade; - else - tspr->shade += sector[tspr->sectnum].floorshade; - } -} - -void tagcode(void) -{ - int i, /*nexti,*/ j, k, l, s, /*daz, dax2, day2,*/ cnt, good; - short startwall, endwall, dasector, p, oldang; - - for (p=connecthead; p>=0; p=connectpoint2[p]) - { - if (sector[cursectnum[p]].lotag == 1) - { - activatehitag(sector[cursectnum[p]].hitag); - sector[cursectnum[p]].lotag = 0; - sector[cursectnum[p]].hitag = 0; - } - if ((sector[cursectnum[p]].lotag == 2) && (cursectnum[p] != ocursectnum[p])) - activatehitag(sector[cursectnum[p]].hitag); - } - - for (i=0; i>2); - if (j >= 16) j = 31-j; - { - sector[dasector].ceilingshade = j; - sector[dasector].floorshade = j; - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - for (s=startwall; s=0; p=connectpoint2[p]) - if (sector[cursectnum[p]].lotag == 10) //warp sector - { - if (cursectnum[p] != ocursectnum[p]) - { - warpsprite(playersprite[p]); - pos[p].x = sprite[playersprite[p]].x; - pos[p].y = sprite[playersprite[p]].y; - pos[p].z = sprite[playersprite[p]].z; - ang[p] = sprite[playersprite[p]].ang; - cursectnum[p] = sprite[playersprite[p]].sectnum; - - sprite[playersprite[p]].z += EYEHEIGHT; - - //warp(&pos[p].x,&pos[p].y,&pos[p].z,&ang[p],&cursectnum[p]); - //Update sprite representation of player - //setsprite_eyeheight(playersprite[p],&pos[p]); - //sprite[playersprite[p]].ang = ang[p]; - } - } - - for (i=0; i>2)&255); - } - - for (i=0; i>2)&255); - sector[floorpanninglist[i]].floorypanning = ((lockclock>>2)&255); - } - - for (i=0; i dragx2[i]) dragxdir[i] = -16; - if (wall[startwall].y+dragydir[i] > dragy2[i]) dragydir[i] = -16; - - for (j=startwall; j>3); - - for (p=connecthead; p>=0; p=connectpoint2[p]) - if (cursectnum[p] == dasector) - { - pos[p].x += dragxdir[i]; - pos[p].y += dragydir[i]; - if (p == myconnectindex) - { my.x += dragxdir[i]; my.y += dragydir[i]; } - //pos[p].z += (sector[dasector].floorz-j); - - //Update sprite representation of player - setsprite_eyeheight(playersprite[p],&pos[p]); - sprite[playersprite[p]].ang = ang[p]; - } - } - - for (i=0; i=0; p=connectpoint2[p]) - if ((cursectnum[p] == swingsector[i]) || (testneighborsectors(cursectnum[p],swingsector[i]) == 1)) - { - cnt = 256; - do - { - good = 1; - - //swingangopendir is -1 if forwards, 1 is backwards - l = (swingangopendir[i] > 0); - for (k=l+3; k>=l; k--) - if (clipinsidebox((vec2_t *)&pos[p],swingwall[i][k],128L) != 0) - { - good = 0; - break; - } - if (good == 0) - { - if (cnt == 256) - { - swinganginc[i] = -swinganginc[i]; - swingang[i] = oldang; - } - else - { - swingang[i] = ((swingang[i]-swinganginc[i])&2047); - } - for (k=1; k<=3; k++) - { - vec2_t const pivot = { swingx[i][0], swingy[i][0] }; - vec2_t const p = { swingx[i][k], swingy[i][k] }; - rotatepoint(pivot, p, swingang[i], (vec2_t *)&wall[swingwall[i][k]].x); - } - if (swingang[i] == swingangclosed[i]) - { - wsayfollow("closdoor.wav",4096L+(krand()&511)-256,256L,&swingx[i][0],&swingy[i][0],0); - swinganginc[i] = 0; - break; - } - if (swingang[i] == swingangopen[i]) - { - swinganginc[i] = 0; - break; - } - cnt--; - } - } - while ((good == 0) && (cnt > 0)); - } - } - } - if (swinganginc[i] == 0) - for (j=1; j<=3; j++) - { - stopinterpolation(&wall[swingwall[i][j]].x); - stopinterpolation(&wall[swingwall[i][j]].y); - } - } - - for (i=0; i 2)) - { - dasector = subwaytracksector[i][0]; - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - for (k=startwall; k subwaytrackx1[i]) - if (wall[k].y > subwaytracky1[i]) - if (wall[k].x < subwaytrackx2[i]) - if (wall[k].y < subwaytracky2[i]) - wall[k].x += subwayvel[i]; - - for (j=1; j=0; s=nextspritesect[s]) - sprite[s].x += subwayvel[i]; - } - - for (p=connecthead; p>=0; p=connectpoint2[p]) - if (cursectnum[p] != subwaytracksector[i][0]) - if (sector[cursectnum[p]].floorz != sector[subwaytracksector[i][0]].floorz) - if (pos[p].x > subwaytrackx1[i]) - if (pos[p].y > subwaytracky1[i]) - if (pos[p].x < subwaytrackx2[i]) - if (pos[p].y < subwaytracky2[i]) - { - pos[p].x += subwayvel[i]; - if (p == myconnectindex) - { my.x += subwayvel[i]; } - - //Update sprite representation of player - setsprite_eyeheight(playersprite[p],&pos[p]); - sprite[playersprite[p]].ang = ang[p]; - } - - subwayx[i] += subwayvel[i]; - } - - j = subwayvel[i]; - k = subwaystop[i][subwaygoalstop[i]] - subwayx[i]; - if (k > 0) - { - if (k > 4096) - { - if (subwayvel[i] < 256) subwayvel[i]++; - } - else - subwayvel[i] = (k>>4)+1; - } - else if (k < 0) - { - if (k < -4096) - { - if (subwayvel[i] > -256) subwayvel[i]--; - } - else - subwayvel[i] = (k>>4)-1; - } - if ((j < 0) && (subwayvel[i] >= 0)) subwayvel[i] = -1; - if ((j > 0) && (subwayvel[i] <= 0)) subwayvel[i] = 1; - - if ((subwayvel[i] <= 2) && (subwayvel[i] >= -2) && (klabs(k) < 2048)) - { - //Open / close doors - if ((subwaypausetime[i] == 720) || ((subwaypausetime[i] >= 120) && (subwaypausetime[i]-TICSPERFRAME < 120))) - activatehitag(sector[subwaytracksector[i][0]].hitag); - - subwaypausetime[i] -= TICSPERFRAME; - if (subwaypausetime[i] < 0) - { - subwaypausetime[i] = 720; - if (subwayvel[i] < 0) - { - subwaygoalstop[i]--; - if (subwaygoalstop[i] < 0) - { - subwaygoalstop[i] = 1; - subwayvel[i] = 1; - } - } - else if (subwayvel[i] > 0) - { - subwaygoalstop[i]++; - if (subwaygoalstop[i] >= subwaystopcnt[i]) - { - subwaygoalstop[i] = subwaystopcnt[i]-2; - subwayvel[i] = -1; - } - } - } - } - } -} - -static FORCE_INLINE int32_t sqr(int32_t a) { return a * a; } - -void statuslistcode(void) -{ - short p, target, hitobject, daang, osectnum, movestat; - int i, nexti, j, nextj, k, l, dax, day, daz, dist=0, ox, oy, mindist; - int doubvel, xvect, yvect; - - //Go through active BROWNMONSTER list - for (i=headspritestat[1]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - k = krand(); - - //Choose a target player - mindist = 0x7fffffff; target = connecthead; - for (p=connecthead; p>=0; p=connectpoint2[p]) - { - dist = klabs(sprite[i].x-pos[p].x)+klabs(sprite[i].y-pos[p].y); - if (dist < mindist) mindist = dist, target = p; - } - - //brown monster decides to shoot bullet - if ((k&63) == 23) - { - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[target].x,pos[target].y,pos[target].z,cursectnum[target]) == 0) - { - if ((k&0xf00) == 0xb00) changespritestat(i,2); - } - else - { - wsayfollow("monshoot.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - - doubvel = (TICSPERFRAME<<((ssync[target].bits&256)>0)); - xvect = 0, yvect = 0; - if (ssync[target].fvel != 0) - { - xvect += ((((int)ssync[target].fvel)*doubvel*(int)sintable[(ang[target]+512)&2047])>>3); - yvect += ((((int)ssync[target].fvel)*doubvel*(int)sintable[ang[target]&2047])>>3); - } - if (ssync[target].svel != 0) - { - xvect += ((((int)ssync[target].svel)*doubvel*(int)sintable[ang[target]&2047])>>3); - yvect += ((((int)ssync[target].svel)*doubvel*(int)sintable[(ang[target]+1536)&2047])>>3); - } - - ox = pos[target].x; oy = pos[target].y; - - //distance is j - j = ksqrt((ox-sprite[i].x)*(ox-sprite[i].x)+(oy-sprite[i].y)*(oy-sprite[i].y)); - - switch ((sprite[i].extra>>11)&3) - { - case 1: j = -(j>>1); break; - case 3: j = 0; break; - case 0: case 2: break; - } - sprite[i].extra += 2048; - - //rate is (TICSPERFRAME<<19) - xvect = scale(xvect,j,TICSPERFRAME<<19); - yvect = scale(yvect,j,TICSPERFRAME<<19); - clipmove_old(&ox,&oy,&pos[target].z,&cursectnum[target],xvect<<14,yvect<<14,128L,4<<8,4<<8,CLIPMASK0); - ox -= sprite[i].x; - oy -= sprite[i].y; - - daang = ((getangle(ox,oy)+(krand()&7)-4)&2047); - - dax = (sintable[(daang+512)&2047]>>6); - day = (sintable[daang&2047]>>6); - daz = 0; - if (ox != 0) - daz = scale(dax,pos[target].z+(8<<8)-sprite[i].z,ox); - else if (oy != 0) - daz = scale(day,pos[target].z+(8<<8)-sprite[i].z,oy); - - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,128,0,0, - 16,sprite[i].xrepeat,sprite[i].yrepeat,0,0,BULLET,daang,dax,day,daz,i,sprite[i].sectnum,6,0,0,0); - - sprite[i].extra &= (~2047); - } - } - - //Move brown monster - dax = sprite[i].x; //Back up old x&y if stepping off cliff - day = sprite[i].y; - - doubvel = max(mulscale7(sprite[i].xrepeat,sprite[i].yrepeat),4); - - osectnum = sprite[i].sectnum; - movestat = movesprite((short)i,(int)sintable[(sprite[i].ang+512)&2047]*doubvel,(int)sintable[sprite[i].ang]*doubvel,0L,4L<<8,4L<<8,CLIPMASK0); - if (globloz > sprite[i].z+(48<<8)) - { sprite[i].x = dax; sprite[i].y = day; movestat = 1; } - else - sprite[i].z = globloz-((tilesiz[sprite[i].picnum].y*sprite[i].yrepeat)<<1); - - if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) - { warpsprite((short)i); movestat = 0; } - - if ((movestat != 0) || ((k&63) == 1)) - { - if (sprite[i].ang == (sprite[i].extra&2047)) - { - daang = (getangle(pos[target].x-sprite[i].x,pos[target].y-sprite[i].y)&2047); - daang = ((daang+(krand()&1023)-512)&2047); - sprite[i].extra = ((sprite[i].extra&(~2047))|daang); - } - if ((sprite[i].extra-sprite[i].ang)&1024) - { - sprite[i].ang = ((sprite[i].ang-32)&2047); - if (!((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); - } - else - { - sprite[i].ang = ((sprite[i].ang+32)&2047); - if (((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); - } - } - } - - for (i=headspritestat[10]; i>=0; i=nexti) //EVILAL list - { - nexti = nextspritestat[i]; - - if (sprite[i].yrepeat < 38) continue; - if (sprite[i].yrepeat < 64) - { - sprite[i].xrepeat++; - sprite[i].yrepeat++; - continue; - } - - if ((nummoves-i)&statrate[10]) continue; - - //Choose a target player - mindist = 0x7fffffff; target = connecthead; - for (p=connecthead; p>=0; p=connectpoint2[p]) - { - dist = klabs(sprite[i].x-pos[p].x)+klabs(sprite[i].y-pos[p].y); - if (dist < mindist) mindist = dist, target = p; - } - - k = (krand()&255); - - if ((sprite[i].lotag&32) && (k < 48)) //Al decides to reproduce - { - l = 0; - if ((sprite[i].lotag&64) && (k < 2)) //Give him a chance to reproduce without seeing you - l = 1; - else if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[target].x,pos[target].y,pos[target].z,cursectnum[target]) == 1) - l = 1; - if (l != 0) - { - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].cstat,sprite[i].shade,sprite[i].pal, - sprite[i].clipdist,38,38,sprite[i].xoffset,sprite[i].yoffset,sprite[i].picnum,krand()&2047,0,0,0,i, - sprite[i].sectnum,10,sprite[i].lotag,sprite[i].hitag,sprite[i].extra); - switch (krand()&31) //Mutations! - { - case 0: sprite[i].cstat ^= 2; break; - case 1: sprite[i].cstat ^= 512; break; - case 2: sprite[i].shade++; break; - case 3: sprite[i].shade--; break; - case 4: sprite[i].pal ^= 16; break; - case 5: case 6: case 7: sprite[i].lotag ^= (1<<(krand()&7)); break; - case 8: sprite[i].lotag = (krand()&255); break; - } - } - } - if (k >= 208+((sprite[i].lotag&128)>>2)) //Al decides to shoot bullet - { - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[target].x,pos[target].y,pos[target].z,cursectnum[target]) == 1) - { - wsayfollow("zipguns.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - - spawnsprite(j,sprite[i].x,sprite[i].y, - sector[sprite[i].sectnum].floorz-(24<<8), - 0,0,0,16,32,32,0,0,BULLET, - (getangle(pos[target].x-sprite[j].x, - pos[target].y-sprite[j].y)+(krand()&15)-8)&2047, - sintable[(sprite[j].ang+512)&2047]>>6, - sintable[sprite[j].ang&2047]>>6, - ((pos[target].z+(8<<8)-sprite[j].z)<<8) / - (ksqrt((pos[target].x-sprite[j].x) * - (pos[target].x-sprite[j].x) + - (pos[target].y-sprite[j].y) * - (pos[target].y-sprite[j].y))+1), - i,sprite[i].sectnum,6,0,0,0); - } - } - - //Move Al - l = (((sprite[i].lotag&3)+2)<<8); - if (sprite[i].lotag&4) l = -l; - dax = sintable[(sprite[i].ang+512)&2047]*l; - day = sintable[sprite[i].ang]*l; - - osectnum = sprite[i].sectnum; - movestat = movesprite((short)i,dax,day,0L,-(8L<<8),-(8L<<8),CLIPMASK0); - sprite[i].z = globloz; - if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) - { - warpsprite((short)i); - movestat = 0; - } - - if (sprite[i].lotag&16) - { - if (((k&124) >= 120) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[target].x,pos[target].y,pos[target].z,cursectnum[target]) == 1)) - sprite[i].ang = getangle(pos[target].x-sprite[i].x,pos[target].y-sprite[i].y); - else - sprite[i].ang = (krand()&2047); - } - - if (movestat != 0) - { - if ((k&2) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[target].x,pos[target].y,pos[target].z,cursectnum[target]) == 1)) - sprite[i].ang = getangle(pos[target].x-sprite[i].x,pos[target].y-sprite[i].y); - else - sprite[i].ang = (krand()&2047); - - if ((movestat&49152) == 49152) - if (sprite[movestat&16383].picnum == EVILAL) - if ((k&31) >= 30) - { - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[i].picnum = EVILALGRAVE; - sprite[i].cstat = 0; - sprite[i].xvel = (krand()&255)-128; - sprite[i].yvel = (krand()&255)-128; - sprite[i].zvel = (krand()&4095)-3072; - changespritestat(i,9); - } - - if (sprite[i].lotag&8) - if ((k&31) >= 30) - { - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[i].picnum = EVILALGRAVE; - sprite[i].cstat = 0; - sprite[i].xvel = (krand()&255)-128; - sprite[i].yvel = (krand()&255)-128; - sprite[i].zvel = (krand()&4095)-3072; - changespritestat(i,9); - } - - if (movestat == -1) - { - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[i].picnum = EVILALGRAVE; - sprite[i].cstat = 0; - sprite[i].xvel = (krand()&255)-128; - sprite[i].yvel = (krand()&255)-128; - sprite[i].zvel = (krand()&4095)-3072; - changespritestat(i,9); - } - } - } - - //Go through travelling bullet sprites - for (i=headspritestat[6]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - if ((nummoves-i)&statrate[6]) continue; - - //If the sprite is a bullet then... - if ((sprite[i].picnum == BULLET) || (sprite[i].picnum == GRABBER) || (sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) - { - dax = ((((int)sprite[i].xvel)*TICSPERFRAME)<<12); - day = ((((int)sprite[i].yvel)*TICSPERFRAME)<<12); - daz = ((((int)sprite[i].zvel)*TICSPERFRAME)>>2); - if (sprite[i].picnum == BOMB) daz = 0; - - osectnum = sprite[i].sectnum; - hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,CLIPMASK1); - if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) - { - warpsprite((short)i); - hitobject = 0; - } - - if (sprite[i].picnum == GRABBER) // Andy did this (& Ken) !Homing! - { - checkgrabbertouchsprite(i,sprite[i].sectnum); - l = 0x7fffffff; - for (j = connecthead; j >= 0; j = connectpoint2[j]) // Players - if (j != (sprite[i].owner & (MAXSPRITES - 1))) - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,pos[j].x,pos[j].y,pos[j].z,cursectnum[j])) - { - k = ksqrt(sqr(pos[j].x - sprite[i].x) + sqr(pos[j].y - sprite[i].y) + (sqr(pos[j].z - sprite[i].z) >> 8)); - if (k < l) - { - l = k; - dax = (pos[j].x - sprite[i].x); - day = (pos[j].y - sprite[i].y); - daz = (pos[j].z - sprite[i].z); - } - } - for (j = headspritestat[1]; j >= 0; j = nextj) // Active monsters - { - nextj = nextspritestat[j]; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) - { - k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); - if (k < l) - { - l = k; - dax = (sprite[j].x - sprite[i].x); - day = (sprite[j].y - sprite[i].y); - daz = (sprite[j].z - sprite[i].z); - } - } - } - for (j = headspritestat[2]; j >= 0; j = nextj) // Inactive monsters - { - nextj = nextspritestat[j]; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) - { - k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); - if (k < l) - { - l = k; - dax = (sprite[j].x - sprite[i].x); - day = (sprite[j].y - sprite[i].y); - daz = (sprite[j].z - sprite[i].z); - } - } - } - if (l != 0x7fffffff) - { - sprite[i].xvel = (divscale7(dax,l) + sprite[i].xvel); // 1/5 of velocity is homing, 4/5 is momentum - sprite[i].yvel = (divscale7(day,l) + sprite[i].yvel); // 1/5 of velocity is homing, 4/5 is momentum - sprite[i].zvel = (divscale7(daz,l) + sprite[i].zvel); // 1/5 of velocity is homing, 4/5 is momentum - l = ksqrt((sprite[i].xvel * sprite[i].xvel) + (sprite[i].yvel * sprite[i].yvel) + ((sprite[i].zvel * sprite[i].zvel) >> 8)); - sprite[i].xvel = divscale9(sprite[i].xvel,l); - sprite[i].yvel = divscale9(sprite[i].yvel,l); - sprite[i].zvel = divscale9(sprite[i].zvel,l); - sprite[i].ang = getangle(sprite[i].xvel,sprite[i].yvel); - } - } - - if (sprite[i].picnum == BOMB) - { - j = sprite[i].sectnum; - if ((sector[j].floorstat&2) && (sprite[i].z > globloz-(8<<8))) - { - k = sector[j].wallptr; - daang = getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y); - sprite[i].xvel += mulscale22(sintable[(daang+1024)&2047],sector[j].floorheinum); - sprite[i].yvel += mulscale22(sintable[(daang+512)&2047],sector[j].floorheinum); - } - } - - if (sprite[i].picnum == BOMB) - { - sprite[i].z += sprite[i].zvel; - sprite[i].zvel += (TICSPERFRAME<<7); - if (sprite[i].z < globhiz+(tilesiz[BOMB].y<<6)) - { - sprite[i].z = globhiz+(tilesiz[BOMB].y<<6); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - if (sprite[i].z > globloz-(tilesiz[BOMB].y<<6)) - { - sprite[i].z = globloz-(tilesiz[BOMB].y<<6); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - dax = sprite[i].xvel; day = sprite[i].yvel; - dist = dax*dax+day*day; - if (dist < 512) - { - bombexplode(i); - goto bulletisdeletedskip; - } - if (dist < 4096) - { - sprite[i].xrepeat = ((4096+2048)*16) / (dist+2048); - sprite[i].yrepeat = sprite[i].xrepeat; - sprite[i].xoffset = (krand()&15)-8; - sprite[i].yoffset = (krand()&15)-8; - } - if (mulscale30(krand(),dist) == 0) - { - sprite[i].xvel -= ksgn(sprite[i].xvel); - sprite[i].yvel -= ksgn(sprite[i].yvel); - sprite[i].zvel -= ksgn(sprite[i].zvel); - } - } - - //Check for bouncy objects before killing bullet - if ((hitobject&0xc000) == 16384) //Bullet hit a ceiling/floor - { - k = sector[hitobject&(MAXSECTORS-1)].wallptr; l = wall[k].point2; - daang = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y); - - getzsofslope(hitobject&(MAXSECTORS-1),sprite[i].x,sprite[i].y,&k,&l); - if (sprite[i].z < ((k+l)>>1)) k = sector[hitobject&(MAXSECTORS-1)].ceilingheinum; - else k = sector[hitobject&(MAXSECTORS-1)].floorheinum; - - dax = mulscale14(k,sintable[(daang)&2047]); - day = mulscale14(k,sintable[(daang+1536)&2047]); - daz = 4096; - - k = sprite[i].xvel*dax+sprite[i].yvel*day+mulscale4(sprite[i].zvel,daz); - l = dax*dax+day*day+daz*daz; - if ((klabs(k)>>14) < l) - { - k = divscale17(k,l); - sprite[i].xvel -= mulscale16(dax,k); - sprite[i].yvel -= mulscale16(day,k); - sprite[i].zvel -= mulscale12(daz,k); - } - wsayfollow("bouncy.wav",4096L+(krand()&127)-64,255,&sprite[i].x,&sprite[i].y,1); - hitobject = 0; - sprite[i].owner = -1; //Bullet turns evil! - } - else if ((hitobject&0xc000) == 32768) //Bullet hit a wall - { - if (wall[hitobject&4095].lotag == 8) - { - dax = sprite[i].xvel; day = sprite[i].yvel; - if ((sprite[i].picnum != BOMB) || (dax*dax+day*day >= 512)) - { - k = (hitobject&4095); l = wall[k].point2; - j = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y)+512; - - //k = cos(ang) * sin(ang) * 2 - k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); - //l = cos(ang * 2) - l = sintable[((j<<1)+512)&2047]; - - ox = sprite[i].xvel; oy = sprite[i].yvel; - dax = -ox; day = -oy; - sprite[i].xvel = dmulscale14(day,k,dax,l); - sprite[i].yvel = dmulscale14(dax,k,-day,l); - - if (sprite[i].picnum == BOMB) - { - sprite[i].xvel -= (sprite[i].xvel>>3); - sprite[i].yvel -= (sprite[i].yvel>>3); - sprite[i].zvel -= (sprite[i].zvel>>3); - } - ox -= sprite[i].xvel; oy -= sprite[i].yvel; - dist = ((ox*ox+oy*oy)>>8); - wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); - hitobject = 0; - sprite[i].owner = -1; //Bullet turns evil! - } - } - } - else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite - { - if (sprite[hitobject&4095].picnum == BOUNCYMAT) - { - if ((sprite[hitobject&4095].cstat&48) == 0) - { - sprite[i].xvel = -sprite[i].xvel; - sprite[i].yvel = -sprite[i].yvel; - sprite[i].zvel = -sprite[i].zvel; - dist = 255; - } - else if ((sprite[hitobject&4095].cstat&48) == 16) - { - j = sprite[hitobject&4095].ang; - - //k = cos(ang) * sin(ang) * 2 - k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); - //l = cos(ang * 2) - l = sintable[((j<<1)+512)&2047]; - - ox = sprite[i].xvel; oy = sprite[i].yvel; - dax = -ox; day = -oy; - sprite[i].xvel = dmulscale14(day,k,dax,l); - sprite[i].yvel = dmulscale14(dax,k,-day,l); - - ox -= sprite[i].xvel; oy -= sprite[i].yvel; - dist = ((ox*ox+oy*oy)>>8); - } - sprite[i].owner = -1; //Bullet turns evil! - wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); - hitobject = 0; - } - } - - if (hitobject != 0) - { - if ((sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) - { - if ((hitobject&0xc000) == 49152) - if (sprite[hitobject&4095].lotag == 5) //Basketball hoop - { - wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); - goto bulletisdeletedskip; - } - - bombexplode(i); - goto bulletisdeletedskip; - } - - if ((hitobject&0xc000) == 16384) //Hits a ceiling / floor - { - wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); - goto bulletisdeletedskip; - } - else if ((hitobject&0xc000) == 32768) //Bullet hit a wall - { - if (wall[hitobject&4095].picnum == KENPICTURE) - { - if (waloff[MAXTILES-1] != 0) - wall[hitobject&4095].picnum = MAXTILES-1; - wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); //Ken says, "Hello... how are you today!" - } - else - wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - - deletesprite((short)i); - goto bulletisdeletedskip; - } - else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite - { - if ((sprite[hitobject&4095].lotag == 5) && (sprite[i].picnum == GRABBER)) // Basketball hoop (Andy's addition) - { - wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - switch (krand() & 63) - { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: - sprite[i].picnum = COIN; break; - case 10: case 11: case 12: case 13: case 14: case 15: case 16: - sprite[i].picnum = DIAMONDS; break; - case 17: case 18: case 19: - sprite[i].picnum = COINSTACK; break; - case 20: case 21: case 22: case 23: - sprite[i].picnum = GIFTBOX; break; - case 24: case 25: - sprite[i].picnum = GRABCANNON; break; - case 26: case 27: - sprite[i].picnum = LAUNCHER; break; - case 28: case 29: case 30: - sprite[i].picnum = CANNON; break; - case 31: - sprite[i].picnum = AIRPLANE; break; - default: - deletesprite((short)i); - goto bulletisdeletedskip; - } - sprite[i].xvel = sprite[i].yvel = sprite[i].zvel = 0; - sprite[i].cstat &= ~0x83; //Should not clip, foot-z - changespritestat(i,12); - goto bulletisdeletedskip; - } - - //Check if bullet hit a player & find which player it was... - if (sprite[hitobject&4095].picnum == PLAYER) - for (j=connecthead; j>=0; j=connectpoint2[j]) - if (sprite[i].owner != j+4096) - if (playersprite[j] == (hitobject&4095)) - { - wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (sprite[i].picnum == GRABBER) // Andy did this - { - k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; - changehealth((sprite[i].owner - 4096),k); - changehealth(j,-k); - } - else changehealth(j,-mulscale8(sprite[i].xrepeat,sprite[i].yrepeat)); - deletesprite((short)i); - goto bulletisdeletedskip; - } - - //Check if bullet hit any monsters... - j = (hitobject&4095); //j is the spritenum that the bullet (spritenum i) hit - if (sprite[i].owner != j) - { - switch (sprite[j].picnum) - { - case BROWNMONSTER: - if (sprite[j].lotag > 0) - { - if (sprite[i].picnum == GRABBER) // Andy did this - { - k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; - changehealth((sprite[i].owner - 4096),k); - sprite[j].lotag -= k; - } - sprite[j].lotag -= mulscale8(sprite[i].xrepeat,sprite[i].yrepeat); - } - if (sprite[j].lotag > 0) - { - if (sprite[j].lotag <= 25) sprite[j].cstat |= 2; - wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&sprite[i].x,&sprite[i].y,1); - } - else - { - wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[j].z += ((tilesiz[sprite[j].picnum].y*sprite[j].yrepeat)<<1); - sprite[j].picnum = GIFTBOX; - sprite[j].cstat &= ~0x83; //Should not clip, foot-z - - spawnsprite(k,sprite[j].x,sprite[j].y,sprite[j].z, - 0,-4,0,32,64,64,0,0,EXPLOSION,sprite[j].ang, - 0,0,0,j,sprite[j].sectnum,5,31,0,0); - //31=Time left for explosion to stay - - changespritestat(j,12); - } - deletesprite((short)i); - goto bulletisdeletedskip; - case EVILAL: - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[j].picnum = EVILALGRAVE; - sprite[j].cstat = 0; - sprite[j].xvel = (krand()&255)-128; - sprite[j].yvel = (krand()&255)-128; - sprite[j].zvel = (krand()&4095)-3072; - changespritestat(j,9); - - deletesprite((short)i); - goto bulletisdeletedskip; - case AL: - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[j].xrepeat += 2; - sprite[j].yrepeat += 2; - if (sprite[j].yrepeat >= 38) - { - sprite[j].picnum = EVILAL; - //sprite[j].cstat |= 2; //Make him transluscent - changespritestat(j,10); - } - deletesprite((short)i); - goto bulletisdeletedskip; - default: - wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); - goto bulletisdeletedskip; - } - } - } - } - } -bulletisdeletedskip: continue; - } - - //Go through monster waiting for you list - for (i=headspritestat[2]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - if ((nummoves-i)&15) continue; - - //Use dot product to see if monster's angle is towards a player - for (p=connecthead; p>=0; p=connectpoint2[p]) - if (sintable[(sprite[i].ang+512)&2047]*(pos[p].x-sprite[i].x) + sintable[sprite[i].ang&2047]*(pos[p].y-sprite[i].y) >= 0) - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[p].x,pos[p].y,pos[p].z,cursectnum[p]) == 1) - { - changespritestat(i,1); - //if (sprite[i].lotag == 100) - //{ - wsayfollow("iseeyou.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - // sprite[i].lotag = 99; - //} - } - } - - //Go through smoke sprites - for (i=headspritestat[3]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].z -= (TICSPERFRAME<<6); - sprite[i].lotag -= TICSPERFRAME; - if ((int16_t)sprite[i].lotag < 0) deletesprite(i); - } - - //Go through splash sprites - for (i=headspritestat[4]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].lotag -= TICSPERFRAME; - sprite[i].picnum = SPLASH + ((63-sprite[i].lotag)>>4); - if ((int16_t)sprite[i].lotag < 0) deletesprite(i); - } - - //Go through explosion sprites - for (i=headspritestat[5]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].lotag -= TICSPERFRAME; - if ((int16_t)sprite[i].lotag < 0) deletesprite(i); - } - - //Go through bomb spriral-explosion sprites - for (i=headspritestat[7]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].xrepeat = (sprite[i].lotag>>2); - sprite[i].yrepeat = (sprite[i].lotag>>2); - sprite[i].lotag -= (TICSPERFRAME<<2); - if ((int16_t)sprite[i].lotag < 0) { deletesprite(i); continue; } - - if ((nummoves-i)&statrate[7]) continue; - - sprite[i].x += ((sprite[i].xvel*TICSPERFRAME)>>2); - sprite[i].y += ((sprite[i].yvel*TICSPERFRAME)>>2); - sprite[i].z += ((sprite[i].zvel*TICSPERFRAME)>>2); - - sprite[i].zvel += (TICSPERFRAME<<9); - if (sprite[i].z < sector[sprite[i].sectnum].ceilingz+(4<<8)) - { - sprite[i].z = sector[sprite[i].sectnum].ceilingz+(4<<8); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - if (sprite[i].z > sector[sprite[i].sectnum].floorz-(4<<8)) - { - sprite[i].z = sector[sprite[i].sectnum].floorz-(4<<8); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - } - - //EVILALGRAVE shrinking list - for (i=headspritestat[9]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].xrepeat = (sprite[i].lotag>>2); - sprite[i].yrepeat = (sprite[i].lotag>>2); - sprite[i].lotag -= TICSPERFRAME; - if ((int16_t)sprite[i].lotag < 0) { deletesprite(i); continue; } - - if ((nummoves-i)&statrate[9]) continue; - - sprite[i].x += (sprite[i].xvel*TICSPERFRAME); - sprite[i].y += (sprite[i].yvel*TICSPERFRAME); - sprite[i].z += (sprite[i].zvel*TICSPERFRAME); - - sprite[i].zvel += (TICSPERFRAME<<8); - if (sprite[i].z < sector[sprite[i].sectnum].ceilingz) - { - sprite[i].z = sector[sprite[i].sectnum].ceilingz; - sprite[i].xvel -= (sprite[i].xvel>>2); - sprite[i].yvel -= (sprite[i].yvel>>2); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - if (sprite[i].z > sector[sprite[i].sectnum].floorz) - { - sprite[i].z = sector[sprite[i].sectnum].floorz; - sprite[i].xvel -= (sprite[i].xvel>>2); - sprite[i].yvel -= (sprite[i].yvel>>2); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - } - - //Re-spawning sprite list - for (i=headspritestat[11]; i>=0; i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].extra -= TICSPERFRAME; - if (sprite[i].extra < 0) - { - wsayfollow("warp.wav",6144L+(krand()&127)-64,128L,&sprite[i].x,&sprite[i].y,0); - sprite[i].cstat &= (uint16_t) ~0x8000; - sprite[i].extra = -1; - changespritestat((short)i,0); - } - } -} - -void activatehitag(short dahitag) -{ - int i, nexti; - - for (i=0; i=0; i=nexti) - { - nexti = nextspritestat[i]; - if (sprite[i].hitag == dahitag) operatesprite(i); - } -} - -void bombexplode(int i) -{ - int j, nextj, k, daang, dax, day, dist; - - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,0,-4,0, - 32,64,64,0,0,EXPLOSION,sprite[i].ang, - 0,0,0,sprite[i].owner,sprite[i].sectnum,5,31,0,0); - //31=Time left for explosion to stay - - for (k=0; k<12; k++) - { - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, - 32,24,24,0,0,EXPLOSION,sprite[i].ang, - (krand()>>7)-256,(krand()>>7)-256,(krand()>>2)-8192, - sprite[i].owner,sprite[i].sectnum,7,96,0,0); - //96=Time left for smoke to be alive - } - - for (j=connecthead; j>=0; j=connectpoint2[j]) - { - dist = (pos[j].x-sprite[i].x)*(pos[j].x-sprite[i].x); - dist += (pos[j].y-sprite[i].y)*(pos[j].y-sprite[i].y); - dist += ((pos[j].z-sprite[i].z)>>4)*((pos[j].z-sprite[i].z)>>4); - if (dist < 4194304) - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,pos[j].x,pos[j].y,pos[j].z,cursectnum[j]) == 1) - { - k = ((32768/((dist>>16)+4))>>5); - if (j == myconnectindex) - { - daang = getangle(pos[j].x-sprite[i].x,pos[j].y-sprite[i].y); - dax = ((k*sintable[(daang+512)&2047])>>14); - day = ((k*sintable[daang&2047])>>14); - fvel += ((dax*sintable[(ang[j]+512)&2047]+day*sintable[ang[j]&2047])>>14); - svel += ((day*sintable[(ang[j]+512)&2047]-dax*sintable[ang[j]&2047])>>14); - } - changehealth(j,-k); //if changehealth returns 1, you're dead - } - } - - for (k=1; k<=2; k++) //Check for hurting monsters - { - for (j=headspritestat[k]; j>=0; j=nextj) - { - nextj = nextspritestat[j]; - - dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); - dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); - dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); - if (dist >= 4194304) continue; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesiz[sprite[j].picnum].y<<7),sprite[j].sectnum) == 0) - continue; - if (sprite[j].picnum == BROWNMONSTER) - { - sprite[j].z += ((tilesiz[sprite[j].picnum].y*sprite[j].yrepeat)<<1); - sprite[j].picnum = GIFTBOX; - sprite[j].cstat &= ~0x83; //Should not clip, foot-z - changespritestat(j,12); - } - } - } - - for (j=headspritestat[10]; j>=0; j=nextj) //Check for EVILAL's - { - nextj = nextspritestat[j]; - - dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); - dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); - dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); - if (dist >= 4194304) continue; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesiz[sprite[i].picnum].y<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesiz[sprite[j].picnum].y<<7),sprite[j].sectnum) == 0) - continue; - - sprite[j].picnum = EVILALGRAVE; - sprite[j].cstat = 0; - sprite[j].xvel = (krand()&255)-128; - sprite[j].yvel = (krand()&255)-128; - sprite[j].zvel = (krand()&4095)-3072; - changespritestat(j,9); - } - - wsayfollow("blowup.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); -} - -void processinput(short snum) -{ - // int oldposx, oldposy, nexti; - int i, j, k, doubvel, xvect, yvect, goalz; - int dax, day /*, dax2, day2, odax, oday, odax2, oday2*/; - // short startwall, endwall; - // char *ptr; - - //SHARED KEYS: - //Movement code - if ((ssync[snum].fvel|ssync[snum].svel) != 0) - { - doubvel = (TICSPERFRAME<<((ssync[snum].bits&256)>0)); - - xvect = 0, yvect = 0; - if (ssync[snum].fvel != 0) - { - xvect += ((((int)ssync[snum].fvel)*doubvel*(int)sintable[(ang[snum]+512)&2047])>>3); - yvect += ((((int)ssync[snum].fvel)*doubvel*(int)sintable[ang[snum]&2047])>>3); - } - if (ssync[snum].svel != 0) - { - xvect += ((((int)ssync[snum].svel)*doubvel*(int)sintable[ang[snum]&2047])>>3); - yvect += ((((int)ssync[snum].svel)*doubvel*(int)sintable[(ang[snum]+1536)&2047])>>3); - } - if (flytime[snum] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed - clipmove(&pos[snum],&cursectnum[snum],xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); - revolvedoorstat[snum] = 1; - } - else - { - revolvedoorstat[snum] = 0; - } - - sprite[playersprite[snum]].cstat &= ~1; - //Push player away from walls if clipmove doesn't work - if (pushmove(&pos[snum],&cursectnum[snum],128L,4<<8,4<<8,CLIPMASK0) < 0) - changehealth(snum,-1000); //If this screws up, then instant death!!! - - // Getzrange returns the highest and lowest z's for an entire box, - // NOT just a point. This prevents you from falling off cliffs - // when you step only slightly over the cliff. - getzrange(&pos[snum],cursectnum[snum],&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); - sprite[playersprite[snum]].cstat |= 1; - - if (ssync[snum].avel != 0) //ang += avel * constant - { - //ENGINE calculates avel for you - doubvel = TICSPERFRAME; - if ((ssync[snum].bits&256) > 0) //Lt. shift makes turn velocity 50% faster - doubvel += (TICSPERFRAME>>1); - ang[snum] += ((((int)ssync[snum].avel)*doubvel)>>4); - ang[snum] &= 2047; - } - - if (health[snum] < 0) - { - health[snum] -= TICSPERFRAME; - if (health[snum] <= -160) - { - hvel[snum] = 0; - if (snum == myconnectindex) - fvel = 0, svel = 0, avel = 0, keystatus[3] = 1; - - deaths[snum]++; - health[snum] = 100; - numbombs[snum] = 0; - numgrabbers[snum] = 0; - nummissiles[snum] = 0; - flytime[snum] = 0; - - findrandomspot(&pos[snum].x,&pos[snum].y,&cursectnum[snum]); - pos[snum].z = getflorzofslope(cursectnum[snum],pos[snum].x,pos[snum].y)-(1<<8); - horiz[snum] = 100; - ang[snum] = (krand()&2047); - - sprite[playersprite[snum]].x = pos[snum].x; - sprite[playersprite[snum]].y = pos[snum].y; - sprite[playersprite[snum]].z = pos[snum].z+EYEHEIGHT; - sprite[playersprite[snum]].picnum = PLAYER; - sprite[playersprite[snum]].ang = ang[snum]; - sprite[playersprite[snum]].xrepeat = 64; - sprite[playersprite[snum]].yrepeat = 64; - changespritesect(playersprite[snum],cursectnum[snum]); - - drawstatusbar(snum); // Andy did this - - i = playersprite[snum]; - wsayfollow("zipguns.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - for (k=0; k<16; k++) - { - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, - 32,24,24,0,0,EXPLOSION,sprite[i].ang, - (krand()&511)-256,(krand()&511)-256,(krand()&16384)-8192, - sprite[i].owner,sprite[i].sectnum,7,96,0,0); - //96=Time left for smoke to be alive - } - } - else - { - sprite[playersprite[snum]].xrepeat = max(((128+health[snum])>>1),0); - sprite[playersprite[snum]].yrepeat = max(((128+health[snum])>>1),0); - - hvel[snum] += (TICSPERFRAME<<2); - horiz[snum] = max(horiz[snum]-4,0); - pos[snum].z += hvel[snum]; - if (pos[snum].z > globloz-(4<<8)) - { - pos[snum].z = globloz-(4<<8); - horiz[snum] = min(horiz[snum]+5,200); - hvel[snum] = 0; - } - } - } - - if (((ssync[snum].bits&8) > 0) && (horiz[snum] > 100-(200>>1))) horiz[snum] -= 4; //- - if (((ssync[snum].bits&4) > 0) && (horiz[snum] < 100+(200>>1))) horiz[snum] += 4; //+ - - goalz = globloz-EYEHEIGHT; - if (sector[cursectnum[snum]].lotag == 4) //slime sector - if ((globlohit&0xc000) != 49152) //You're not on a sprite - { - goalz = globloz-(8<<8); - if (pos[snum].z >= goalz-(2<<8)) - { - clipmove(&pos[snum],&cursectnum[snum],-(TICSPERFRAME<<14),-(TICSPERFRAME<<14),128L,4<<8,4<<8,CLIPMASK0); - - if (slimesoundcnt[snum] >= 0) - { - slimesoundcnt[snum] -= TICSPERFRAME; - while (slimesoundcnt[snum] < 0) - { - slimesoundcnt[snum] += 120; - wsayfollow("slime.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - } - } - } - } - if (goalz < globhiz+(16<<8)) //ceiling&floor too close - goalz = ((globloz+globhiz)>>1); - //goalz += mousz; - if (health[snum] >= 0) - { - if ((ssync[snum].bits&1) > 0) //A (stand high) - { - if (flytime[snum] <= lockclock) - { - if (pos[snum].z >= globloz-(32<<8)) - { - goalz -= (16<<8); - if (ssync[snum].bits&256) goalz -= (24<<8); - } - } - else - { - hvel[snum] -= 192; - if (ssync[snum].bits&256) hvel[snum] -= 192; - } - } - if ((ssync[snum].bits&2) > 0) //Z (stand low) - { - if (flytime[snum] <= lockclock) - { - goalz += (12<<8); - if (ssync[snum].bits&256) goalz += (12<<8); - } - else - { - hvel[snum] += 192; - if (ssync[snum].bits&256) hvel[snum] += 192; - } - } - } - - if (flytime[snum] <= lockclock) - { - if (pos[snum].z < goalz) - hvel[snum] += (TICSPERFRAME<<4); - else - hvel[snum] = (((goalz-pos[snum].z)*TICSPERFRAME)>>5); - } - else - { - hvel[snum] -= (hvel[snum]>>2); - hvel[snum] -= ksgn(hvel[snum]); - } - - pos[snum].z += hvel[snum]; - if (pos[snum].z > globloz-(4<<8)) pos[snum].z = globloz-(4<<8), hvel[snum] = 0; - if (pos[snum].z < globhiz+(4<<8)) pos[snum].z = globhiz+(4<<8), hvel[snum] = 0; - - if (dimensionmode[snum] != 3) - { - if (((ssync[snum].bits&32) > 0) && (zoom[snum] > 48)) zoom[snum] -= (zoom[snum]>>4); - if (((ssync[snum].bits&16) > 0) && (zoom[snum] < 4096)) zoom[snum] += (zoom[snum]>>4); - } - - //Update sprite representation of player - // -should be after movement, but before shooting code - setsprite_eyeheight(playersprite[snum],&pos[snum]); - sprite[playersprite[snum]].ang = ang[snum]; - - if (health[snum] >= 0) - { - if ((cursectnum[snum] < 0) || (cursectnum[snum] >= numsectors)) - { - //How did you get in the wrong sector? - wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&pos[snum].x,&pos[snum].y,1); - changehealth(snum,-TICSPERFRAME); - } - else if (globhiz+(8<<8) > globloz) - { - //Ceiling and floor are smooshing you! - wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&pos[snum].x,&pos[snum].y,1); - changehealth(snum,-TICSPERFRAME); - } - } - - if ((waterfountainwall[snum] >= 0) && (health[snum] >= 0)) - if ((wall[neartagwall].lotag != 7) || ((ssync[snum].bits&1024) == 0)) - { - i = waterfountainwall[snum]; - if (wall[i].overpicnum == USEWATERFOUNTAIN) - wall[i].overpicnum = WATERFOUNTAIN; - else if (wall[i].picnum == USEWATERFOUNTAIN) - wall[i].picnum = WATERFOUNTAIN; - - waterfountainwall[snum] = -1; - } - - if ((ssync[snum].bits&1024) > 0) //Space bar - { - //Continuous triggers... - - neartag(pos[snum].x,pos[snum].y,pos[snum].z,cursectnum[snum],ang[snum],&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1024L,3,NULL); - if (neartagsector == -1) - { - i = cursectnum[snum]; - if ((sector[i].lotag|sector[i].hitag) != 0) - neartagsector = i; - } - - if (wall[neartagwall].lotag == 7) //Water fountain - { - if (wall[neartagwall].overpicnum == WATERFOUNTAIN) - { - wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - wall[neartagwall].overpicnum = USEWATERFOUNTAIN; - waterfountainwall[snum] = neartagwall; - } - else if (wall[neartagwall].picnum == WATERFOUNTAIN) - { - wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - wall[neartagwall].picnum = USEWATERFOUNTAIN; - waterfountainwall[snum] = neartagwall; - } - - if (waterfountainwall[snum] >= 0) - { - waterfountaincnt[snum] -= TICSPERFRAME; - while (waterfountaincnt[snum] < 0) - { - waterfountaincnt[snum] += 120; - wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&pos[snum].x,&pos[snum].y,1); - changehealth(snum,2); - } - } - } - - //1-time triggers... - if ((oflags[snum]&1024) == 0) - { - if (neartagsector >= 0) - if (sector[neartagsector].hitag == 0) - operatesector(neartagsector); - - if (neartagwall >= 0) - if (wall[neartagwall].lotag == 2) //Switch - { - activatehitag(wall[neartagwall].hitag); - - j = wall[neartagwall].overpicnum; - if (j == SWITCH1ON) //1-time switch - { - wall[neartagwall].overpicnum = GIFTBOX; - wall[neartagwall].lotag = 0; - wall[neartagwall].hitag = 0; - } - if (j == GIFTBOX) //1-time switch - { - wall[neartagwall].overpicnum = SWITCH1ON; - wall[neartagwall].lotag = 0; - wall[neartagwall].hitag = 0; - } - if (j == SWITCH2ON) wall[neartagwall].overpicnum = SWITCH2OFF; - if (j == SWITCH2OFF) wall[neartagwall].overpicnum = SWITCH2ON; - if (j == SWITCH3ON) wall[neartagwall].overpicnum = SWITCH3OFF; - if (j == SWITCH3OFF) wall[neartagwall].overpicnum = SWITCH3ON; - - i = wall[neartagwall].point2; - dax = ((wall[neartagwall].x+wall[i].x)>>1); - day = ((wall[neartagwall].y+wall[i].y)>>1); - wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); - } - - if (neartagsprite >= 0) - { - if (sprite[neartagsprite].lotag == 1) - { - //if you're shoving innocent little AL around, he gets mad! - if (sprite[neartagsprite].picnum == AL) - { - sprite[neartagsprite].picnum = EVILAL; - sprite[neartagsprite].cstat |= 2; //Make him transluscent - sprite[neartagsprite].xrepeat = 38; - sprite[neartagsprite].yrepeat = 38; - changespritestat(neartagsprite,10); - } - } - if (sprite[neartagsprite].lotag == 4) - { - activatehitag(sprite[neartagsprite].hitag); - - j = sprite[neartagsprite].picnum; - if (j == SWITCH1ON) //1-time switch - { - sprite[neartagsprite].picnum = GIFTBOX; - sprite[neartagsprite].lotag = 0; - sprite[neartagsprite].hitag = 0; - } - if (j == GIFTBOX) //1-time switch - { - sprite[neartagsprite].picnum = SWITCH1ON; - sprite[neartagsprite].lotag = 0; - sprite[neartagsprite].hitag = 0; - } - if (j == SWITCH2ON) sprite[neartagsprite].picnum = SWITCH2OFF; - if (j == SWITCH2OFF) sprite[neartagsprite].picnum = SWITCH2ON; - if (j == SWITCH3ON) sprite[neartagsprite].picnum = SWITCH3OFF; - if (j == SWITCH3OFF) sprite[neartagsprite].picnum = SWITCH3ON; - - dax = sprite[neartagsprite].x; - day = sprite[neartagsprite].y; - wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); - } - } - } - } - - if ((ssync[snum].bits & 2048) > 0) // Shoot a bullet - { - if ((numbombs[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 2) && (myconnectindex == snum)) - locselectedgun = 0; - if ((nummissiles[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 3) && (myconnectindex == snum)) - locselectedgun = 1; - if ((numgrabbers[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 4) && (myconnectindex == snum)) - locselectedgun = 1; - - if ((health[snum] >= 0) || ((krand() & 127) > -health[snum])) - switch ((ssync[snum].bits >> 13) & 7) - { - case 0: - if (lockclock > lastchaingun[snum]+8) - { - lastchaingun[snum] = lockclock; - shootgun(snum,&pos[snum],ang[snum],horiz[snum],cursectnum[snum],0); - } - break; - case 1: - if ((oflags[snum] & 2048) == 0) - shootgun(snum,&pos[snum],ang[snum],horiz[snum],cursectnum[snum],1); - break; - case 2: - if ((oflags[snum] & 2048) == 0) - if (numbombs[snum] > 0) - { - shootgun(snum,&pos[snum],ang[snum],horiz[snum],cursectnum[snum],2); - changenumbombs(snum,-1); - } - break; - case 3: - if ((oflags[snum] & 2048) == 0) - if (nummissiles[snum] > 0) - { - shootgun(snum,&pos[snum],ang[snum],horiz[snum],cursectnum[snum],3); - changenummissiles(snum,-1); - } - break; - case 4: - if ((oflags[snum] & 2048) == 0) - if (numgrabbers[snum] > 0) - { - shootgun(snum,&pos[snum],ang[snum],horiz[snum],cursectnum[snum],4); - changenumgrabbers(snum,-1); - } - break; - } - } - - if ((ssync[snum].bits&4096) > (oflags[snum]&4096)) //Keypad enter - { - dimensionmode[snum]++; - if (dimensionmode[snum] > 3) dimensionmode[snum] = 1; - } - - oflags[snum] = ssync[snum].bits; -} - -void view(short snum, vec3_t *v, short *vsectnum, short ang, int horiz) -{ - spritetype *sp; - int i, nx, ny, nz, hx, hy /*, hz*/; - short bakcstat, daang; - hitdata_t hitinfo; - - nx = (sintable[(ang+1536)&2047]>>4); - ny = (sintable[(ang+1024)&2047]>>4); - nz = (horiz-100)*128; - - sp = &sprite[snum]; - - bakcstat = sp->cstat; - sp->cstat &= (short)~0x101; - - updatesectorz(v->x,v->y,v->z,vsectnum); - hitscan(v,*vsectnum,nx,ny,nz,&hitinfo,CLIPMASK1); - hx = hitinfo.pos.x-v->x; hy = hitinfo.pos.y-v->y; - if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy)) - { - *vsectnum = hitinfo.sect; - if (hitinfo.wall >= 0) - { - daang = getangle(wall[wall[hitinfo.wall].point2].x-wall[hitinfo.wall].x, - wall[wall[hitinfo.wall].point2].y-wall[hitinfo.wall].y); - - i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047]; - if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i); - else hy -= mulscale28(ny,i); - } - else if (hitinfo.sprite < 0) - { - if (klabs(nx) > klabs(ny)) hx -= (nx>>5); - else hy -= (ny>>5); - } - if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx); - else i = divscale16(hy,ny); - if (i < cameradist) cameradist = i; - } - v->x = v->x+mulscale16(nx,cameradist); - v->y = v->y+mulscale16(ny,cameradist); - v->z = v->z+mulscale16(nz,cameradist); - - updatesectorz(v->x,v->y,v->z,vsectnum); - - sp->cstat = bakcstat; -} - -void drawscreen(short snum, int dasmoothratio) -{ - int i, j, k=0, l, charsperline, tempint; - int x1, y1, x2, y2, ox1, oy1, ox2, oy2, dist, maxdist; - vec3_t cpos; - int choriz, czoom, tposx, tposy; - int tiltlock, *intptr, ovisibility, oparallaxvisibility; - short cang, tang, csect; - char ch, *ptr, *ptr2, *ptr3, *ptr4; - uspritetype *tspr; - - smoothratio = max(min(dasmoothratio,65536),0); - - dointerpolations(); - - if ((snum == myconnectindex) && ((networkmode == 1) || (myconnectindex != connecthead))) - { - cpos.x = omy.x+mulscale16(my.x-omy.x,smoothratio); - cpos.y = omy.y+mulscale16(my.y-omy.y,smoothratio); - cpos.z = omy.z+mulscale16(my.z-omy.z,smoothratio); - choriz = omyhoriz+mulscale16(myhoriz-omyhoriz,smoothratio); - cang = omyang+mulscale16((int)(((myang+1024-omyang)&2047)-1024),smoothratio); - } - else - { - cpos.x = opos[snum].x+mulscale16(pos[snum].x-opos[snum].x,smoothratio); - cpos.y = opos[snum].y+mulscale16(pos[snum].y-opos[snum].y,smoothratio); - cpos.z = opos[snum].z+mulscale16(pos[snum].z-opos[snum].z,smoothratio); - choriz = ohoriz[snum]+mulscale16(horiz[snum]-ohoriz[snum],smoothratio); - cang = oang[snum]+mulscale16(((ang[snum]+1024-oang[snum])&2047)-1024,smoothratio); - } - czoom = ozoom[snum]+mulscale16(zoom[snum]-ozoom[snum],smoothratio); - - setears(cpos.x,cpos.y,(int)sintable[(cang+512)&2047]<<14,(int)sintable[cang&2047]<<14); - - if (dimensionmode[myconnectindex] == 3) - { - tempint = screensize; - - if (((loc.bits&32) > (screensizeflag&32)) && (screensize > 64)) - { - ox1 = ((xdim-screensize)>>1); - ox2 = ox1+screensize-1; - oy1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - oy2 = oy1 + scale(screensize,ydim-32,xdim)-1; - screensize -= (screensize>>3); - - if (tempint > xdim) - { - screensize = xdim; - - flushperms(); - - rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1); - while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1)+320; - while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; - if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; - - drawstatusbar(screenpeek); // Andy did this - } - - x1 = ((xdim-screensize)>>1); - x2 = x1+screensize-1; - y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - y2 = y1 + scale(screensize,ydim-32,xdim)-1; - setview(x1,y1,x2,y2); - - // (ox1,oy1)℃ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒø - // ≥ (x1,y1) ≥ - // ≥ ℃ƒƒƒƒø ≥ - // ≥ ≥ ≥ ≥ - // ≥ ¿ƒƒƒƒƒŸ ≥ - // ≥ (x2,y2) ≥ - // ¿ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ(ox2,oy2) - - drawtilebackground(/*0L,0L,*/ BACKGROUND,8,ox1,oy1,x1-1,oy2,0); - drawtilebackground(/*0L,0L,*/ BACKGROUND,8,x2+1,oy1,ox2,oy2,0); - drawtilebackground(/*0L,0L,*/ BACKGROUND,8,x1,oy1,x2,y1-1,0); - drawtilebackground(/*0L,0L,*/ BACKGROUND,8,x1,y2+1,x2,oy2,0); - } - if (((loc.bits&16) > (screensizeflag&16)) && (screensize <= xdim)) - { - screensize += (screensize>>3); - if ((screensize > xdim) && (tempint == xdim)) - { - screensize = xdim+1; - x1 = 0; y1 = 0; - x2 = xdim-1; y2 = ydim-1; - } - else - { - if (screensize > xdim) screensize = xdim; - x1 = ((xdim-screensize)>>1); - x2 = x1+screensize-1; - y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - y2 = y1 + scale(screensize,ydim-32,xdim)-1; - } - setview(x1,y1,x2,y2); - } - screensizeflag = loc.bits; - } - - if (dimensionmode[snum] != 2) - { - if ((numplayers > 1) && (option[4] == 0)) - { - //Do not draw other views constantly if they're staying still - //It's a shame this trick will only work in screen-buffer mode - //At least screen-buffer mode covers all the HI hi-res modes - //if (vidoption == 2) - //{ - for (i=connecthead; i>=0; i=connectpoint2[i]) frame2draw[i] = 0; - frame2draw[snum] = 1; - - //2-1,3-1,4-2 - //5-2,6-2,7-2,8-3,9-3,10-3,11-3,12-4,13-4,14-4,15-4,16-5 - x1 = pos[snum].x; y1 = pos[snum].y; - for (j=(numplayers>>2)+1; j>0; j--) - { - maxdist = 0x80000000; - for (i=connecthead; i>=0; i=connectpoint2[i]) - if (frame2draw[i] == 0) - { - x2 = pos[i].x-x1; y2 = pos[i].y-y1; - dist = dmulscale12(x2,x2,y2,y2); - - if (dist < 64) dist = 16384; - else if (dist > 16384) dist = 64; - else dist = 1048576 / dist; - - dist *= frameskipcnt[i]; - - //Increase frame rate if screen is moving - if ((pos[i].x != opos[i].x) || (pos[i].y != opos[i].y) || - (pos[i].z != opos[i].z) || (ang[i] != oang[i]) || - (horiz[i] != ohoriz[i])) dist += dist; - - if (dist > maxdist) maxdist = dist, k = i; - } - - for (i=connecthead; i>=0; i=connectpoint2[i]) - frameskipcnt[i] += (frameskipcnt[i]>>3)+1; - frameskipcnt[k] = 0; - - frame2draw[k] = 1; - } - //} - //else - //{ - // for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 1; - //} - - for (i=connecthead,j=0; i>=0; i=connectpoint2[i],j++) - if (frame2draw[i] != 0) - { - if (numplayers <= 4) - { - switch (j) - { - case 0: setview(0,0,(xdim>>1)-1,(ydim>>1)-1); break; - case 1: setview((xdim>>1),0,xdim-1,(ydim>>1)-1); break; - case 2: setview(0,(ydim>>1),(xdim>>1)-1,ydim-1); break; - case 3: setview((xdim>>1),(ydim>>1),xdim-1,ydim-1); break; - } - } - else - { - switch (j) - { - case 0: setview(0,0,(xdim>>2)-1,(ydim>>2)-1); break; - case 1: setview(xdim>>2,0,(xdim>>1)-1,(ydim>>2)-1); break; - case 2: setview(xdim>>1,0,xdim-(xdim>>2)-1,(ydim>>2)-1); break; - case 3: setview(xdim-(xdim>>2),0,xdim-1,(ydim>>2)-1); break; - case 4: setview(0,ydim>>2,(xdim>>2)-1,(ydim>>1)-1); break; - case 5: setview(xdim>>2,ydim>>2,(xdim>>1)-1,(ydim>>1)-1); break; - case 6: setview(xdim>>1,ydim>>2,xdim-(xdim>>2)-1,(ydim>>1)-1); break; - case 7: setview(xdim-(xdim>>2),ydim>>2,xdim-1,(ydim>>1)-1); break; - case 8: setview(0,ydim>>1,(xdim>>2)-1,ydim-(ydim>>2)-1); break; - case 9: setview(xdim>>2,ydim>>1,(xdim>>1)-1,ydim-(ydim>>2)-1); break; - case 10: setview(xdim>>1,ydim>>1,xdim-(xdim>>2)-1,ydim-(ydim>>2)-1); break; - case 11: setview(xdim-(xdim>>2),ydim>>1,xdim-1,ydim-(ydim>>2)-1); break; - case 12: setview(0,ydim-(ydim>>2),(xdim>>2)-1,ydim-1); break; - case 13: setview(xdim>>2,ydim-(ydim>>2),(xdim>>1)-1,ydim-1); break; - case 14: setview(xdim>>1,ydim-(ydim>>2),xdim-(xdim>>2)-1,ydim-1); break; - case 15: setview(xdim-(xdim>>2),ydim-(ydim>>2),xdim-1,ydim-1); break; - } - } - - if (i == snum) - { - sprite[playersprite[snum]].cstat |= 0x8000; - drawrooms(cpos.x,cpos.y,cpos.z,cang,choriz,cursectnum[i]); - sprite[playersprite[snum]].cstat &= (uint16_t) ~0x8000; - analyzesprites(cpos.x,cpos.y); - } - else - { - sprite[playersprite[i]].cstat |= 0x8000; - drawrooms(pos[i].x,pos[i].y,pos[i].z,ang[i],horiz[i],cursectnum[i]); - sprite[playersprite[i]].cstat &= (uint16_t) ~0x8000; - analyzesprites(pos[i].x,pos[i].y); - } - drawmasks(); - if ((numgrabbers[i] > 0) || (nummissiles[i] > 0) || (numbombs[i] > 0)) - rotatesprite(160<<16,184L<<16,65536,0,GUNONBOTTOM,sector[cursectnum[i]].floorshade,0,2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - - if (lockclock < 384) - { - if (lockclock < 128) - rotatesprite(320<<15,200<<15,lockclock<<9,lockclock<<4,DEMOSIGN,(128-lockclock)>>2,0,1+2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - else if (lockclock < 256) - rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - else - rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - } - - if (health[i] <= 0) - rotatesprite(320<<15,200<<15,(-health[i])<<11,(-health[i])<<5,NO,0,0,2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - } - } - else - { - //Init for screen rotation - if (getrendermode() == 0) // JBF 20031220 - { - tiltlock = screentilt; - if ((tiltlock) || (detailmode)) - { - walock[TILE_TILT] = 255; - if (waloff[TILE_TILT] == 0) - allocache(&waloff[TILE_TILT],320L*320L,&walock[TILE_TILT]); - if ((tiltlock&1023) == 0) - setviewtotile(TILE_TILT,200L>>detailmode,320L>>detailmode); - else - setviewtotile(TILE_TILT,320L>>detailmode,320L>>detailmode); - if ((tiltlock&1023) == 512) - { - //Block off unscreen section of 90¯ tilted screen - j = ((320-60)>>detailmode); - for (i=(60>>detailmode)-1; i>=0; i--) - { - startumost[i] = 1; startumost[i+j] = 1; - startdmost[i] = 0; startdmost[i+j] = 0; - } - } - - i = (tiltlock&511); if (i > 256) i = 512-i; - i = sintable[i+512]*8 + sintable[i]*5L; - setaspect(i>>1,yxaspect); - } - } - else - { - tiltlock = screentilt; - // Ken loves to interpolate - setrollangle(oscreentilt + mulscale16(((screentilt-oscreentilt+1024)&2047)-1024,smoothratio)); - } - - if ((gotpic[FLOORMIRROR>>3]&(1<<(FLOORMIRROR&7))) > 0) - { - dist = 0x7fffffff; i = 0; - for (k=floormirrorcnt-1; k>=0; k--) - { - j = klabs(wall[sector[floormirrorsector[k]].wallptr].x-cpos.x); - j += klabs(wall[sector[floormirrorsector[k]].wallptr].y-cpos.y); - if (j < dist) dist = j, i = k; - } - - //if (cpos.z > sector[floormirrorsector[i]].ceilingz) i = 1-i; //SOS - - j = floormirrorsector[i]; - - if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; - drawrooms(cpos.x,cpos.y,(sector[j].floorz<<1)-cpos.z,cang,201-choriz,j); //SOS - //drawrooms(cpos.x,cpos.y,cpos.z,cang,choriz,j+MAXSECTORS); //SOS - sprite[playersprite[snum]].cstat &= (uint16_t) ~0x8000; - analyzesprites(cpos.x,cpos.y); - drawmasks(); - - //Temp horizon - if (getrendermode() == 0) - { - l = scale(choriz-100,windowxy2.x-windowxy1.x,320)+((windowxy1.y+windowxy2.y)>>1); - begindrawing(); //{{{ - for (y1=windowxy1.y,y2=windowxy2.y; y1>2,31)<<8); - ptr4 = palookup[18]; - ptr4 += (min(klabs(y2-l)>>2,31)<<8); - - j = sintable[((y2+(int32_t) totalclock)<<6)&2047]; - j += sintable[((y2-(int32_t) totalclock)<<7)&2047]; - j >>= 14; - - //ptr2 += j; - - //for(x1=windowxy1.x;x1<=windowxy2.x;x1++) - // { ch = ptr[x1]; ptr[x1] = ptr3[ptr2[x1]]; ptr2[x1] = ptr4[ch]; } - - ox1 = windowxy1.x-min(j,0); - ox2 = windowxy2.x-max(j,0); - - for (x1=windowxy1.x; x1>3] &= ~(1<<(FLOORMIRROR&7)); - } - - - //Over the shoulder mode - csect = cursectnum[snum]; - if (cameradist >= 0) - { - cang += cameraang; - view(playersprite[snum],&cpos,&csect,cang,choriz); - } - - //WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 - intptr = (int *)&gotpic[MIRRORLABEL>>3]; // CHECK! - if (intptr[0]|intptr[1]) - for (i=MAXMIRRORS-1; i>=0; i--) - if (gotpic[(i+MIRRORLABEL)>>3]&(1<<(i&7))) - { - gotpic[(i+MIRRORLABEL)>>3] &= ~(1<<(i&7)); - - //Prepare drawrooms for drawing mirror and calculate reflected - //position into tposx, tposy, and tang (tpos.z == cpos.z) - //Must call renderPrepareMirror before drawrooms and - // renderCompleteMirror after drawrooms - renderPrepareMirror(cpos.x,cpos.y,cpos.z,fix16_from_int(cang),choriz, - mirrorwall[i],/*mirrorsector[i],*/ &tposx,&tposy,&tang); - - ovisibility = g_visibility; - oparallaxvisibility = parallaxvisibility; - g_visibility <<= 1; - parallaxvisibility <<= 1; - ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; - - drawrooms(tposx,tposy,cpos.z,tang,choriz,mirrorsector[i]|MAXSECTORS); - for (j=0,tspr=&tsprite[0]; jcstat&48) == 0) tspr->cstat |= 4; - analyzesprites(tposx,tposy); - drawmasks(); - - ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; - g_visibility = ovisibility; - parallaxvisibility = oparallaxvisibility; - - completemirror(); //Reverse screen x-wise in this function - - break; - } - - if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; - drawrooms(cpos.x,cpos.y,cpos.z,cang,choriz,csect); - sprite[playersprite[snum]].cstat &= (uint16_t) ~0x8000; - analyzesprites(cpos.x,cpos.y); - drawmasks(); - - //Finish for screen rotation - if (getrendermode() == 0) // JBF 20031220 - { - if ((tiltlock) || (detailmode)) - { - setviewback(); - i = (tiltlock&511); if (i > 256) i = 512-i; - i = sintable[i+512]*8 + sintable[i]*5L; - if (detailmode == 0) i >>= 1; - rotatesprite(320<<15,200<<15,i,tiltlock+512,TILE_TILT,0,0,2+4+64,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - walock[TILE_TILT] = 1; - } - } - - if (((numgrabbers[screenpeek] > 0) || (nummissiles[screenpeek] > 0) || (numbombs[screenpeek] > 0)) && (cameradist < 0)) - { - //Reset startdmost to bottom of screen - if ((windowxy1.x == 0) && (windowxy2.x == 319) && (yxaspect == 65536) && (tiltlock == 0)) - { - x1 = 160L-(tilesiz[GUNONBOTTOM].x>>1); y1 = windowxy2.y+1; - for (i=0; i>2,0,1+2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - else if (lockclock < 256) - rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - else - rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - } - - if (health[screenpeek] <= 0) - rotatesprite(320<<15,200<<15,(-health[screenpeek])<<11,(-health[screenpeek])<<5,NO,0,0,2,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - } - } - - //Only animate lava if its picnum is on screen - //gotpic is a bit array where the tile number's bit is set - //whenever it is drawn (ceilings, walls, sprites, etc.) - if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0) - { - gotpic[SLIME>>3] &= ~(1<<(SLIME&7)); - if (waloff[SLIME] != 0) - { - movelava((char *)waloff[SLIME]); - invalidatetile(SLIME,0,1); // JBF 20031228 - } - } - - if ((show2dsector[cursectnum[snum]>>3]&(1<<(cursectnum[snum]&7))) == 0) - searchmap(cursectnum[snum]); - - if (dimensionmode[snum] != 3) - { - //Move back pivot point - i = scale(czoom,screensize,320); - if (dimensionmode[snum] == 2) - { - clearview(0L); //Clear screen to specified color - drawmapview(cpos.x,cpos.y,i,cang); - } - drawoverheadmap(cpos.x,cpos.y,i,cang); - } - - if (typemode != 0) - { - charsperline = 40; - //if (dimensionmode[snum] == 2) charsperline = 80; - - for (i=0; i<=typemessageleng; i+=charsperline) - { - for (j=0; j 0) - { - charsperline = 40; - //if (dimensionmode[snum] == 2) charsperline = 80; - - for (i=0; i<=getmessageleng; i+=charsperline) - { - for (j=0; j getmessagetimeoff) - getmessageleng = 0; - } - if ((numplayers >= 2) && (screenpeek != myconnectindex)) - { - j = 1; - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - if (i == screenpeek) break; - j++; - } - Bsprintf((char *)tempbuf,"(Player %d's view)",j); - printext256((xdim>>1)-(Bstrlen((char *)tempbuf)<<2),0,24,-1,(char *)tempbuf,0); - } - - if (syncstat != 0) printext256(68L,84L,31,0,"OUT OF SYNC!",0); - if (syncstate != 0) printext256(68L,92L,31,0,"Missed Network packet!",0); - -// //Uncomment this to test cache locks -//extern int cacnum; -//typedef struct { int *hand, leng; char *lock; } cactype; -//extern cactype cac[]; -// -// j = 0; -// for(i=0;i= 200) -// { -// Bsprintf(tempbuf,"Locked- %ld: Leng:%ld, Lock:%ld",i,cac[i].leng,*cac[i].lock); -// printext256(0L,j,31,-1,tempbuf,1); j += 6; -// } - - nextpage(); // send completed frame to display - - while (totalclock >= ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) - faketimerhandler(); - - if (keystatus[0x3f]) //F5 - { - keystatus[0x3f] = 0; - detailmode ^= 1; - //setrendermode(3); - } - if (keystatus[0x58]) //F12 - { - keystatus[0x58] = 0; - screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]); - } - if (keystatus[0x3e]) //F4 - screen re-size - { - keystatus[0x3e] = 0; - - if (keystatus[0x2a]|keystatus[0x36]) - { - setgamemode(!fullscreen, xdim, ydim, bpp); - } - else - { - - //cycle through all modes - j=-1; - - // work out a mask to select the mode - for (i=0; i 8) brightness = 0; - setbrightness(brightness,0,0); - } - - if (option[4] == 0) //Single player only keys - { - if (keystatus[0xd2]) //Insert - Insert player - { - keystatus[0xd2] = 0; - if (numplayers < MAXPLAYERS) - { - connectpoint2[numplayers-1] = numplayers; - connectpoint2[numplayers] = -1; - - movefifoend[numplayers] = movefifoend[0]; //HACK 01/05/2000 - - initplayersprite(numplayers); - - clearallviews(0L); //Clear screen to specified color - - numplayers++; - } - } - if (keystatus[0xd3]) //Delete - Delete player - { - keystatus[0xd3] = 0; - if (numplayers > 1) - { - numplayers--; - connectpoint2[numplayers-1] = -1; - - deletesprite(playersprite[numplayers]); - playersprite[numplayers] = -1; - - if (myconnectindex >= numplayers) myconnectindex = 0; - if (screenpeek >= numplayers) screenpeek = 0; - - if (numplayers < 2) - setup3dscreen(); - else - clearallviews(0L); //Clear screen to specified color - } - } - if (keystatus[0x46]) //Scroll Lock - { - keystatus[0x46] = 0; - - myconnectindex = connectpoint2[myconnectindex]; - if (myconnectindex < 0) myconnectindex = connecthead; - screenpeek = myconnectindex; - } - } - - restoreinterpolations(); -} - -void movethings(void) -{ - int i; - - gotlastpacketclock = (int32_t) totalclock; - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - copybufbyte(&ffsync[i],&baksync[movefifoend[i]][i],sizeof(input)); - movefifoend[i] = ((movefifoend[i]+1)&(MOVEFIFOSIZ-1)); - } -} - -void fakedomovethings(void) -{ - input *syn; - int /*i, j, k,*/ doubvel, xvect, yvect, goalz; - short bakcstat; - - syn = (input *)&baksync[fakemovefifoplc][myconnectindex]; - - omy = my; - omyang = myang; - omyhoriz = myhoriz; - - bakcstat = sprite[playersprite[myconnectindex]].cstat; - sprite[playersprite[myconnectindex]].cstat &= ~0x101; - - if ((syn->fvel|syn->svel) != 0) - { - doubvel = (TICSPERFRAME<<((syn->bits&256)>0)); - - xvect = 0, yvect = 0; - if (syn->fvel != 0) - { - xvect += ((((int)syn->fvel)*doubvel*(int)sintable[(myang+512)&2047])>>3); - yvect += ((((int)syn->fvel)*doubvel*(int)sintable[myang&2047])>>3); - } - if (syn->svel != 0) - { - xvect += ((((int)syn->svel)*doubvel*(int)sintable[myang&2047])>>3); - yvect += ((((int)syn->svel)*doubvel*(int)sintable[(myang+1536)&2047])>>3); - } - if (flytime[myconnectindex] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed - clipmove(&my,&mycursectnum,xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); - } - - pushmove(&my,&mycursectnum,128L,4<<8,4<<8,CLIPMASK0); - getzrange(&my,mycursectnum,&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); - - if (syn->avel != 0) //ang += avel * constant - { - //ENGINE calculates avel for you - doubvel = TICSPERFRAME; - if ((syn->bits&256) > 0) //Lt. shift makes turn velocity 50% faster - doubvel += (TICSPERFRAME>>1); - myang += ((((int)syn->avel)*doubvel)>>4); - myang &= 2047; - } - - if (((syn->bits&8) > 0) && (myhoriz > 100-(200>>1))) myhoriz -= 4; //- - if (((syn->bits&4) > 0) && (myhoriz < 100+(200>>1))) myhoriz += 4; //+ - - goalz = globloz-EYEHEIGHT; - if (sector[mycursectnum].lotag == 4) //slime sector - if ((globlohit&0xc000) != 49152) //You're not on a sprite - { - goalz = globloz-(8<<8); - if (my.z >= goalz-(2<<8)) - clipmove(&my,&mycursectnum,-(TICSPERFRAME<<14),-(TICSPERFRAME<<14),128L,4<<8,4<<8,CLIPMASK0); - } - if (goalz < globhiz+(16<<8)) //ceiling&floor too close - goalz = ((globloz+globhiz)>>1); - - if (health[myconnectindex] >= 0) - { - if ((syn->bits&1) > 0) //A (stand high) - { - if (flytime[myconnectindex] <= lockclock) - { - if (my.z >= globloz-(32<<8)) - { - goalz -= (16<<8); - if (syn->bits&256) goalz -= (24<<8); - } - } - else - { - myzvel -= 192; - if (syn->bits&256) myzvel -= 192; - } - } - if ((syn->bits&2) > 0) //Z (stand low) - { - if (flytime[myconnectindex] <= lockclock) - { - goalz += (12<<8); - if (syn->bits&256) goalz += (12<<8); - } - else - { - myzvel += 192; - if (syn->bits&256) myzvel += 192; - } - } - } - - if (flytime[myconnectindex] <= lockclock) - { - if (my.z < goalz) - myzvel += (TICSPERFRAME<<4); - else - myzvel = (((goalz-my.z)*TICSPERFRAME)>>5); - } - else - { - myzvel -= (myzvel>>2); - myzvel -= ksgn(myzvel); - } - - my.z += myzvel; - if (my.z > globloz-(4<<8)) my.z = globloz-(4<<8), myzvel = 0; - if (my.z < globhiz+(4<<8)) my.z = globhiz+(4<<8), myzvel = 0; - - sprite[playersprite[myconnectindex]].cstat = bakcstat; - - mybak[fakemovefifoplc] = my; - myangbak[fakemovefifoplc] = myang; - myhorizbak[fakemovefifoplc] = myhoriz; - fakemovefifoplc = (fakemovefifoplc+1)&(MOVEFIFOSIZ-1); -} - -//Prediction correction -void fakedomovethingscorrect(void) -{ - int i; - - if ((networkmode == 0) && (myconnectindex == connecthead)) return; - - i = ((movefifoplc-1)&(MOVEFIFOSIZ-1)); - - if ((pos[myconnectindex].x == mybak[i].x) && - (pos[myconnectindex].y == mybak[i].y) && - (pos[myconnectindex].z == mybak[i].z) && - (horiz[myconnectindex] == myhorizbak[i]) && - (ang[myconnectindex] == myangbak[i])) - return; - - //Re-start fakedomovethings back to place of error - my = omy; - myzvel = hvel[myconnectindex]; - myang = omyang = ang[myconnectindex]; - mycursectnum = cursectnum[myconnectindex]; - myhoriz = omyhoriz = horiz[myconnectindex]; - - fakemovefifoplc = movefifoplc; - while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); -} - -void domovethings(void) -{ - short i, j, startwall, endwall; - // spritetype *spr; - walltype *wal; - // vec3_t *ospr; - - nummoves++; - - for (i=connecthead; i>=0; i=connectpoint2[i]) - copybufbyte(&baksync[movefifoplc][i],&ssync[i],sizeof(input)); - movefifoplc = ((movefifoplc+1)&(MOVEFIFOSIZ-1)); - - if (option[4] != 0) - { - syncval[syncvalhead] = (char)(randomseed&255); - syncvalhead = ((syncvalhead+1)&(MOVEFIFOSIZ-1)); - } - - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - opos[i] = pos[i]; - ohoriz[i] = horiz[i]; - ozoom[i] = zoom[i]; - oang[i] = ang[i]; - } - - for (i=NUMSTATS-1; i>=0; i--) - if (statrate[i] >= 0) - for (j=headspritestat[i]; j>=0; j=nextspritestat[j]) - if (((nummoves-j)&statrate[i]) == 0) - copybuf(&sprite[j].x,&osprite[j].x,3); - - for (i=connecthead; i>=0; i=connectpoint2[i]) - ocursectnum[i] = cursectnum[i]; - - updateinterpolations(); - - if ((numplayers <= 2) && (recstat == 1)) - { - j = 0; - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - copybufbyte(&ssync[i],&recsync[reccnt][j],sizeof(input)); - j++; - } - reccnt++; if (reccnt > 16383) reccnt = 16383; - } - - lockclock += TICSPERFRAME; - drawstatusflytime(screenpeek); // Andy did this - - if (cameradist >= 0) - { - cameradist = min(cameradist+(((int32_t) totalclock-cameraclock)<<10),65536); - if (keystatus[0x52]) //0 - cameraang -= (((int32_t) totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); - if (keystatus[0x53]) //. - cameraang += (((int32_t) totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); - cameraclock = (int32_t) totalclock; - } - - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - processinput(i); //Move player - - checktouchsprite(i,cursectnum[i]); //Pick up coins - startwall = sector[cursectnum[i]].wallptr; - endwall = startwall + sector[cursectnum[i]].wallnum; - for (j=startwall,wal=&wall[j]; jnextsector >= 0) checktouchsprite(i,wal->nextsector); - } - - doanimations(); - tagcode(); //Door code, moving sector code, other stuff - statuslistcode(); //Monster / bullet code / explosions - - fakedomovethingscorrect(); - - checkmasterslaveswitch(); -} - -void getinput(void) -{ - char ch /*, keystate, *ptr*/; - int i, j /*, k*/; - int mousx, mousy, bstatus; - - if (typemode == 0) //if normal game keys active - { - if (keystatus[keys[15]]) - { - keystatus[keys[15]] = 0; - - screenpeek = connectpoint2[screenpeek]; - if (screenpeek < 0) screenpeek = connecthead; - drawstatusbar(screenpeek); // Andy did this - } - - for (i=7; i>=0; i--) - if (keystatus[i+2]) - { keystatus[i+2] = 0; locselectedgun = i; break; } - } - - - //KEYTIMERSTUFF - if (!keystatus[keys[5]]) - { - if (keystatus[keys[2]]) avel = max(avel-16*TICSPERFRAME,-128); - if (keystatus[keys[3]]) avel = min(avel+16*TICSPERFRAME,127); - } - else - { - if (keystatus[keys[2]]) svel = min(svel+8*TICSPERFRAME,127); - if (keystatus[keys[3]]) svel = max(svel-8*TICSPERFRAME,-128); - } - if (keystatus[keys[0]]) fvel = min(fvel+8*TICSPERFRAME,127); - if (keystatus[keys[1]]) fvel = max(fvel-8*TICSPERFRAME,-128); - if (keystatus[keys[12]]) svel = min(svel+8*TICSPERFRAME,127); - if (keystatus[keys[13]]) svel = max(svel-8*TICSPERFRAME,-128); - - if (avel < 0) avel = min(avel+12*TICSPERFRAME,0); - if (avel > 0) avel = max(avel-12*TICSPERFRAME,0); - if (svel < 0) svel = min(svel+2*TICSPERFRAME,0); - if (svel > 0) svel = max(svel-2*TICSPERFRAME,0); - if (fvel < 0) fvel = min(fvel+2*TICSPERFRAME,0); - if (fvel > 0) fvel = max(fvel-2*TICSPERFRAME,0); - - if ((option[4] == 0) && (numplayers >= 2)) - { - if (!keystatus[0x4f]) - { - if (keystatus[0x4b]) avel2 = max(avel2-16*TICSPERFRAME,-128); - if (keystatus[0x4d]) avel2 = min(avel2+16*TICSPERFRAME,127); - } - else - { - if (keystatus[0x4b]) svel2 = min(svel2+8*TICSPERFRAME,127); - if (keystatus[0x4d]) svel2 = max(svel2-8*TICSPERFRAME,-128); - } - if (keystatus[0x48]) fvel2 = min(fvel2+8*TICSPERFRAME,127); - if (keystatus[0x4c]) fvel2 = max(fvel2-8*TICSPERFRAME,-128); - - if (avel2 < 0) avel2 = min(avel2+12*TICSPERFRAME,0); - if (avel2 > 0) avel2 = max(avel2-12*TICSPERFRAME,0); - if (svel2 < 0) svel2 = min(svel2+2*TICSPERFRAME,0); - if (svel2 > 0) svel2 = max(svel2-2*TICSPERFRAME,0); - if (fvel2 < 0) fvel2 = min(fvel2+2*TICSPERFRAME,0); - if (fvel2 > 0) fvel2 = max(fvel2-2*TICSPERFRAME,0); - } - - oscreentilt = screentilt; - if (keystatus[0x1a]) screentilt += ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); - if (keystatus[0x1b]) screentilt -= ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); - - i = (TICSPERFRAME<<1); - while ((screentilt != 0) && (i > 0)) - { screentilt = ((screentilt+ksgn(screentilt-1024))&2047); i--; } - if (keystatus[0x28]) screentilt = 1536; - - - loc.fvel = min(max(fvel,-128+8),127-8); - loc.svel = min(max(svel,-128+8),127-8); - loc.avel = min(max(avel,-128+16),127-16); - - getmousevalues(&mousx,&mousy,&bstatus); - loc.avel = min(max(loc.avel+(mousx<<3),-128),127); - loc.fvel = min(max(loc.fvel-(mousy<<3),-128),127); - - loc.bits = (locselectedgun<<13); - if (typemode == 0) //if normal game keys active - { - loc.bits |= (keystatus[0x32]<<9); //M (be master) - loc.bits |= ((keystatus[keys[14]]==1)<<12); //Map mode - } - loc.bits |= keystatus[keys[8]]; //Stand high - loc.bits |= (keystatus[keys[9]]<<1); //Stand low - loc.bits |= (keystatus[keys[16]]<<4); //Zoom in - loc.bits |= (keystatus[keys[17]]<<5); //Zoom out - loc.bits |= (keystatus[keys[4]]<<8); //Run - loc.bits |= (keystatus[keys[10]]<<2); //Look up - loc.bits |= (keystatus[keys[11]]<<3); //Look down - loc.bits |= ((keystatus[keys[7]]==1)<<10); //Space - loc.bits |= ((keystatus[keys[6]]==1)<<11); //Shoot - loc.bits |= (((bstatus&6)>(oldmousebstatus&6))<<10); //Space - loc.bits |= (((bstatus&1)>(oldmousebstatus&1))<<11); //Shoot - - oldmousebstatus = bstatus; - if (((loc.bits&2048) > 0) && (locselectedgun == 0)) - oldmousebstatus &= ~1; //Allow continous fire with mouse for chain gun - - //PRIVATE KEYS: -#if 0 - if (keystatus[0xb7]) //Printscreen - { - keystatus[0xb7] = 0; - printscreeninterrupt(); - } -#endif - if (keystatus[0x2f]) //V - { - keystatus[0x2f] = 0; - if (cameradist < 0) cameradist = 0; else cameradist = -1; - cameraang = 0; - } - - if (typemode == 0) //if normal game keys active - { - if (keystatus[0x19]) //P - { - keystatus[0x19] = 0; - parallaxtype++; - if (parallaxtype > 2) parallaxtype = 0; - } - if (keystatus[0x38]|keystatus[0xb8]) //ALT - { - if (keystatus[0x4a]) // Keypad - - g_visibility = min(g_visibility+(g_visibility>>3),16384); - if (keystatus[0x4e]) // Keypad + - g_visibility = max(g_visibility-(g_visibility>>3),128); - } - - if (keystatus[keys[18]]) //Typing mode - { - keystatus[keys[18]] = 0; - typemode = 1; - bflushchars(); - keyfifoplc = keyfifoend; //Reset keyboard fifo - } - } - else - { - while ((ch = bgetchar())) - { - if (ch == 8) //Backspace - { - if (typemessageleng == 0) { typemode = 0; break; } - typemessageleng--; - } - else if (ch == 9) // tab - { - keystatus[0xf] = 0; - typemode = 0; - break; - } - else if (ch == 13) //Either ENTER - { - keystatus[0x1c] = 0; keystatus[0x9c] = 0; - if (typemessageleng > 0) - { - packbuf[0] = 2; //Sending text is message type 4 - for (j=typemessageleng-1; j>=0; j--) - packbuf[j+1] = typemessage[j]; - - for (i=connecthead; i>=0; i=connectpoint2[i]) - if (i != myconnectindex) - sendpacket(i,packbuf,typemessageleng+1); - - typemessageleng = 0; - } - typemode = 0; - break; - } - else if ((typemessageleng < 159) && (ch >= 32) && (ch < 128)) - { - typemessage[typemessageleng++] = ch; - } - } - } -} - -void initplayersprite(short snum) -{ - int i; - - if (playersprite[snum] >= 0) return; - - spawnsprite(playersprite[snum],pos[snum].x,pos[snum].y,pos[snum].z+EYEHEIGHT, - 1+256,0,snum,32,64,64,0,0,PLAYER,ang[snum],0,0,0,snum+4096, - cursectnum[snum],8,0,0,0); - - switch (snum) - { - case 1: for (i=0; i<32; i++) tempbuf[i+192] = i+128; break; //green->red - case 2: for (i=0; i<32; i++) tempbuf[i+192] = i+32; break; //green->blue - case 3: for (i=0; i<32; i++) tempbuf[i+192] = i+224; break; //green->pink - case 4: for (i=0; i<32; i++) tempbuf[i+192] = i+64; break; //green->brown - case 5: for (i=0; i<32; i++) tempbuf[i+192] = i+96; break; - case 6: for (i=0; i<32; i++) tempbuf[i+192] = i+160; break; - case 7: for (i=0; i<32; i++) tempbuf[i+192] = i+192; break; - default: for (i=0; i<256; i++) tempbuf[i] = i; break; - } - makepalookup(snum,tempbuf,0,0,0,1); -} - -void playback(void) -{ - int i, j, k; - - ready2send = 0; - recstat = 0; i = reccnt; - while (!keystatus[1]) - { - if (handleevents()) - { - if (quitevent) - { - keystatus[1] = 1; - quitevent = 0; - } - } - - refreshaudio(); - - while (totalclock >= lockclock+TICSPERFRAME) - { - sampletimer(); - if (i >= reccnt) - { - prepareboard(boardfilename); - for (i=connecthead; i>=0; i=connectpoint2[i]) - initplayersprite((short)i); - totalclock = 0; - i = 0; - } - - k = 0; - for (j=connecthead; j>=0; j=connectpoint2[j]) - { - copybufbyte(&recsync[i][k],&ffsync[j],sizeof(input)); - k++; - } - movethings(); domovethings(); - i++; - } - drawscreen(screenpeek,((int32_t) totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND))); - - if (keystatus[keys[15]]) - { - keystatus[keys[15]] = 0; - screenpeek = connectpoint2[screenpeek]; - if (screenpeek < 0) screenpeek = connecthead; - drawstatusbar(screenpeek); // Andy did this - } - if (keystatus[keys[14]]) - { - keystatus[keys[14]] = 0; - dimensionmode[screenpeek]++; - if (dimensionmode[screenpeek] > 3) dimensionmode[screenpeek] = 1; - } - } - - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); -} - -void setup3dscreen(void) -{ - int i, dax, day, dax2, day2; - - i = setgamemode(fullscreen,xdimgame,ydimgame,bppgame); - if (i < 0) - { - printf("Error setting video mode.\n"); - sendlogoff(); - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); - } - -#if 0 - //Make that ugly pink into black in case it ever shows up! - i = 0L; - setpalette(255,1,(char *)&i); - //outp(0x3c8,255); outp(0x3c9,0); outp(0x3c9,0); outp(0x3c9,0); -#endif - - screensize = xdim; - if (screensize > xdim) - { - dax = 0; day = 0; - dax2 = xdim-1; day2 = ydim-1; - } - else - { - dax = ((xdim-screensize)>>1); - dax2 = dax+screensize-1; - day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - day2 = day + scale(screensize,ydim-32,xdim)-1; - setview(dax,day,dax2,day2); - } - - flushperms(); - - if (screensize < xdim) - drawtilebackground(/*0L,0L,*/ BACKGROUND,8,0L,0L,xdim-1L,ydim-1L,0); //Draw background - - if (screensize <= xdim) - { - rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1); - while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1)+320; - while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; - if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; - - drawstatusbar(screenpeek); // Andy did this - } -} - -void findrandomspot(int *x, int *y, short *sectnum) -{ - short startwall, endwall, s, dasector; - vec3_t da = { 0, 0, 0 }; - int minx, maxx, miny, maxy, cnt; - - for (cnt=256; cnt>=0; cnt--) - { - do - { - dasector = mulscale16(krand(),numsectors); - } - while ((sector[dasector].ceilingz+(8<<8) >= sector[dasector].floorz) || ((sector[dasector].lotag|sector[dasector].hitag) != 0) || ((sector[dasector].floorstat&1) != 0)); - - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - if (endwall <= startwall) continue; - - minx = 0x7fffffff; maxx = 0x80000000; - miny = 0x7fffffff; maxy = 0x80000000; - - for (s=startwall; s maxx) maxx = wall[s].x; - if (wall[s].y < miny) miny = wall[s].y; - if (wall[s].y > maxy) maxy = wall[s].y; - } - - if ((maxx-minx <= 256) || (maxy-miny <= 256)) continue; - - da.x /= (endwall-startwall); - da.y /= (endwall-startwall); - - if (inside(da.x,da.y,dasector) == 0) continue; - - da.z = sector[dasector].floorz-(32<<8); - if (pushmove(&da,&dasector,128L,4<<8,4<<8,CLIPMASK0) < 0) continue; - - *x = da.x; *y = da.y; *sectnum = dasector; - return; - } -} - -void warp(int *x, int *y, int *z, short *daang, short *dasector) -{ - short startwall, endwall, s; - int i, j, dax, day, ox, oy; - - ox = *x; oy = *y; - - for (i=0; i= warpsectorcnt) i = 0; - } - while (sector[warpsectorlist[i]].hitag != j); - *dasector = warpsectorlist[i]; - break; - } - - //Find center of sector - startwall = sector[*dasector].wallptr; - endwall = startwall+sector[*dasector].wallnum; - dax = 0L, day = 0L; - for (s=startwall; s= 0) - i = s; - } - *x = dax / (endwall-startwall); - *y = day / (endwall-startwall); - *z = sector[*dasector].floorz-(32<<8); - updatesector(*x,*y,dasector); - dax = ((wall[i].x+wall[wall[i].point2].x)>>1); - day = ((wall[i].y+wall[wall[i].point2].y)>>1); - *daang = getangle(dax-*x,day-*y); - - wsayfollow("warp.wav",3072L+(krand()&127)-64,192L,&ox,&oy,0); - wsayfollow("warp.wav",4096L+(krand()&127)-64,256L,x,y,0); -} - -void warpsprite(short spritenum) -{ - short dasectnum; - - dasectnum = sprite[spritenum].sectnum; - warp(&sprite[spritenum].x,&sprite[spritenum].y,&sprite[spritenum].z, - &sprite[spritenum].ang,&dasectnum); - - copybuf(&sprite[spritenum].x,&osprite[spritenum].x,3); - changespritesect(spritenum,dasectnum); - - show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7)); - if (show2dsector[dasectnum>>3]&(1<<(dasectnum&7))) - show2dsprite[spritenum>>3] |= (1<<(spritenum&7)); -} - -void initlava(void) -{ - int x, y, z, r; - - for (z=0; z<32; z++) lavaradcnt[z] = 0; - for (x=-16; x<=16; x++) - for (y=-16; y<=16; y++) - { - r = ksqrt(x*x + y*y); - lavaradx[r][lavaradcnt[r]] = x; - lavarady[r][lavaradcnt[r]] = y; - lavaradcnt[r]++; - } - - for (z=0; z<16; z++) - lavadropsizlookup[z] = 8 / (ksqrt(z)+1); - - for (z=0; z>4)&7)-4)+12; - - lavanumdrops = 0; - lavanumframes = 0; -} - -#if defined(__WATCOMC__) && !defined(NOASM) -#pragma aux addlava = \ - "mov al, byte ptr [ebx-133]", \ - "mov dl, byte ptr [ebx-1]", \ - "add al, byte ptr [ebx-132]", \ - "add dl, byte ptr [ebx+131]", \ - "add al, byte ptr [ebx-131]", \ - "add dl, byte ptr [ebx+132]", \ - "add al, byte ptr [ebx+1]", \ - "add al, dl", \ - parm [ebx] \ - modify exact [eax edx] -int addlava(int); -#elif defined(_MSC_VER) && !defined(NOASM) -int addlava(void *b) -{ - _asm - { - mov ebx, b - mov al, byte ptr [ebx-133] - mov dl, byte ptr [ebx-1] - add al, byte ptr [ebx-132] - add dl, byte ptr [ebx+131] - add al, byte ptr [ebx-131] - add dl, byte ptr [ebx+132] - add al, byte ptr [ebx+1] - add al, dl - } -} -#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM) -int addlava(void *b) -{ - int r; - __asm__ __volatile__( - "movb -133(%%ebx), %%al\n\t" - "movb -1(%%ebx), %%dl\n\t" - "addb -132(%%ebx), %%al\n\t" - "addb 131(%%ebx), %%dl\n\t" - "addb -131(%%ebx), %%al\n\t" - "addb 132(%%ebx), %%dl\n\t" - "addb 1(%%ebx), %%al\n\t" - "addb %%dl, %%al" - : "=a" (r) : "b" (b) - : "dx" - ); - return r; -} -#else -int addlava(void *bx) -{ - char *b = (char *)bx; - return b[-133] + b[-132] + b[-131] + b[1] + b[-1] + b[131] + b[132]; -} -#endif - -void movelava(char *dapic) -{ - int i, /*j,*/ x, y, z, zz, dalavadropsiz, dadropsizlookup; - int dalavax, dalavay, *ptr, *ptr2; - char *pi, *pj, *py; - - for (z=min(LAVAMAXDROPS-lavanumdrops-1,3); z>=0; z--) - { - lavadropx[lavanumdrops] = (Brand()&(LAVASIZ-1)); - lavadropy[lavanumdrops] = (Brand()&(LAVASIZ-1)); - lavadropsiz[lavanumdrops] = 1; - lavanumdrops++; - } - - for (z=lavanumdrops-1; z>=0; z--) - { - dadropsizlookup = lavadropsizlookup[lavadropsiz[z]]*(((z&1)<<1)-1); - dalavadropsiz = lavadropsiz[z]; - dalavax = lavadropx[z]; dalavay = lavadropy[z]; - for (zz=lavaradcnt[lavadropsiz[z]]-1; zz>=0; zz--) - { - i = (((lavaradx[dalavadropsiz][zz]+dalavax)&(LAVASIZ-1))< 10) - { - lavanumdrops--; - lavadropx[z] = lavadropx[lavanumdrops]; - lavadropy[z] = lavadropy[lavanumdrops]; - lavadropsiz[z] = lavadropsiz[lavanumdrops]; - } - } - - //Back up dapic with 1 pixel extra on each boundary - //(to prevent anding for wrap-around) - ptr = (int *)dapic; - ptr2 = (int *)((LAVASIZ+4)+1+((intptr_t)lavabakpic)); - for (x=0; x>2); y>0; y--) *ptr2++ = ((*ptr++)&0x1f1f1f1f); - ptr2++; - } - for (y=0; y>3)+ - ((addlava(&py[1])&0xf8)<<5)+ - ((addlava(&py[2])&0xf8)<<13)+ - ((addlava(&py[3])&0xf8)<<21)+ - 0xc2c2c2c2; - } - } - - lavanumframes++; -} - -void doanimations(void) -{ - int i, j; - - for (i=animatecnt-1; i>=0; i--) - { - j = *animateptr[i]; - - if (j < animategoal[i]) - j = min(j+animatevel[i]*TICSPERFRAME,animategoal[i]); - else - j = max(j-animatevel[i]*TICSPERFRAME,animategoal[i]); - animatevel[i] += animateacc[i]; - - *animateptr[i] = j; - - if (j == animategoal[i]) - { - animatecnt--; - if (i != animatecnt) - { - stopinterpolation(animateptr[i]); - animateptr[i] = animateptr[animatecnt]; - animategoal[i] = animategoal[animatecnt]; - animatevel[i] = animatevel[animatecnt]; - animateacc[i] = animateacc[animatecnt]; - } - } - } -} - -int getanimationgoal(int *animptr) -{ - int i; - - for (i=animatecnt-1; i>=0; i--) - if (animptr == animateptr[i]) return i; - return -1; -} - -int setanimation(int *animptr, int thegoal, int thevel, int theacc) -{ - int i, j; - - if (animatecnt >= MAXANIMATES) return -1; - - j = animatecnt; - for (i=animatecnt-1; i>=0; i--) - if (animptr == animateptr[i]) - { j = i; break; } - - setinterpolation(animptr); - - animateptr[j] = animptr; - animategoal[j] = thegoal; - animatevel[j] = thevel; - animateacc[j] = theacc; - if (j == animatecnt) animatecnt++; - return j; -} - -void checkmasterslaveswitch(void) -{ - int i, j; - - if (option[4] == 0) return; - - j = 0; - for (i=connecthead; i>=0; i=connectpoint2[i]) - if (ssync[i].bits&512) j++; - if (j != 1) return; - - i = connecthead; - for (j=connectpoint2[i]; j>=0; j=connectpoint2[j]) - { - if (ssync[j].bits&512) - { - connectpoint2[i] = connectpoint2[j]; - connectpoint2[j] = connecthead; - connecthead = (short)j; - - oloc.fvel = loc.fvel+1; - oloc.svel = loc.svel+1; - oloc.avel = loc.avel+1; - oloc.bits = loc.bits+1; - for (i=0; i=0; i=connectpoint2[i]) - { - if (myconnectindex == i) break; - j++; - } - if (j == 1) - Bstrcpy(getmessage,"Player 1 (Master)"); - else - Bsprintf(getmessage,"Player %d (Slave)",j); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = (int32_t) totalclock+120; - - return; - } - i = j; - } -} - - -int testneighborsectors(short sect1, short sect2) -{ - short i, startwall, num1, num2; - - num1 = sector[sect1].wallnum; - num2 = sector[sect2].wallnum; - if (num1 < num2) //Traverse walls of sector with fewest walls (for speed) - { - startwall = sector[sect1].wallptr; - for (i=num1-1; i>=0; i--) - if (wall[i+startwall].nextsector == sect2) - return 1; - } - else - { - startwall = sector[sect2].wallptr; - for (i=num2-1; i>=0; i--) - if (wall[i+startwall].nextsector == sect1) - return 1; - } - return 0; -} - -int loadgame(void) -{ - int dummy = 0; - int i; - int fil; - int tmpanimateptr[MAXANIMATES]; - - if ((fil = kopen4load("save0000.gam",0)) == -1) return -1; - - kdfread(&numplayers,4,1,fil); - kdfread(&myconnectindex,4,1,fil); - kdfread(&connecthead,4,1,fil); - kdfread(connectpoint2,4,MAXPLAYERS,fil); - - //Make sure palookups get set, sprites will get overwritten later - for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i); - - for (i = 0; i < MAXPLAYERS; ++i) - kdfread(&pos[i].x,4,1,fil); - for (i = 0; i < MAXPLAYERS; ++i) - kdfread(&pos[i].y,4,1,fil); - for (i = 0; i < MAXPLAYERS; ++i) - kdfread(&pos[i].z,4,1,fil); - - kdfread(horiz,4,MAXPLAYERS,fil); - kdfread(zoom,4,MAXPLAYERS,fil); - kdfread(hvel,4,MAXPLAYERS,fil); - kdfread(ang,2,MAXPLAYERS,fil); - kdfread(cursectnum,2,MAXPLAYERS,fil); - kdfread(ocursectnum,2,MAXPLAYERS,fil); - kdfread(playersprite,2,MAXPLAYERS,fil); - kdfread(deaths,2,MAXPLAYERS,fil); - kdfread(lastchaingun,4,MAXPLAYERS,fil); - kdfread(health,4,MAXPLAYERS,fil); - kdfread(numgrabbers,2,MAXPLAYERS,fil); - kdfread(nummissiles,2,MAXPLAYERS,fil); - kdfread(numbombs,2,MAXPLAYERS,fil); - kdfread(flytime,4,MAXPLAYERS,fil); - kdfread(oflags,2,MAXPLAYERS,fil); - kdfread(dimensionmode,1,MAXPLAYERS,fil); - kdfread(revolvedoorstat,1,MAXPLAYERS,fil); - kdfread(revolvedoorang,2,MAXPLAYERS,fil); - kdfread(revolvedoorrotang,2,MAXPLAYERS,fil); - kdfread(revolvedoorx,4,MAXPLAYERS,fil); - kdfread(revolvedoory,4,MAXPLAYERS,fil); - - kdfread(&numsectors,2,1,fil); - kdfread(sector,sizeof(sectortype),numsectors,fil); - kdfread(&numwalls,2,1,fil); - kdfread(wall,sizeof(walltype),numwalls,fil); - //Store all sprites (even holes) to preserve indeces - kdfread(sprite,sizeof(spritetype),MAXSPRITES,fil); - kdfread(headspritesect,2,MAXSECTORS+1,fil); - kdfread(prevspritesect,2,MAXSPRITES,fil); - kdfread(nextspritesect,2,MAXSPRITES,fil); - kdfread(headspritestat,2,MAXSTATUS+1,fil); - kdfread(prevspritestat,2,MAXSPRITES,fil); - kdfread(nextspritestat,2,MAXSPRITES,fil); - - kdfread(&fvel,4,1,fil); - kdfread(&svel,4,1,fil); - kdfread(&avel,4,1,fil); - - kdfread(&locselectedgun,4,1,fil); - kdfread(&loc.fvel,1,1,fil); - kdfread(&oloc.fvel,1,1,fil); - kdfread(&loc.svel,1,1,fil); - kdfread(&oloc.svel,1,1,fil); - kdfread(&loc.avel,1,1,fil); - kdfread(&oloc.avel,1,1,fil); - kdfread(&loc.bits,2,1,fil); - kdfread(&oloc.bits,2,1,fil); - - kdfread(&locselectedgun2,4,1,fil); - kdfread(&loc2.fvel,sizeof(input),1,fil); - - kdfread(ssync,sizeof(input),MAXPLAYERS,fil); - kdfread(osync,sizeof(input),MAXPLAYERS,fil); - - kdfread(boardfilename,1,80,fil); - kdfread(&screenpeek,2,1,fil); - kdfread(&oldmousebstatus,2,1,fil); - kdfread(&brightness,2,1,fil); - kdfread(&neartagsector,2,1,fil); - kdfread(&neartagwall,2,1,fil); - kdfread(&neartagsprite,2,1,fil); - kdfread(&lockclock,4,1,fil); - kdfread(&neartagdist,4,1,fil); - kdfread(&neartaghitdist,4,1,fil); - - kdfread(turnspritelist,2,16,fil); - kdfread(&turnspritecnt,2,1,fil); - kdfread(warpsectorlist,2,16,fil); - kdfread(&warpsectorcnt,2,1,fil); - kdfread(xpanningsectorlist,2,16,fil); - kdfread(&xpanningsectorcnt,2,1,fil); - kdfread(ypanningwalllist,2,64,fil); - kdfread(&ypanningwallcnt,2,1,fil); - kdfread(floorpanninglist,2,64,fil); - kdfread(&floorpanningcnt,2,1,fil); - kdfread(dragsectorlist,2,16,fil); - kdfread(dragxdir,2,16,fil); - kdfread(dragydir,2,16,fil); - kdfread(&dragsectorcnt,2,1,fil); - kdfread(dragx1,4,16,fil); - kdfread(dragy1,4,16,fil); - kdfread(dragx2,4,16,fil); - kdfread(dragy2,4,16,fil); - kdfread(dragfloorz,4,16,fil); - kdfread(&swingcnt,2,1,fil); - kdfread(swingwall,2,32*5,fil); - kdfread(swingsector,2,32,fil); - kdfread(swingangopen,2,32,fil); - kdfread(swingangclosed,2,32,fil); - kdfread(swingangopendir,2,32,fil); - kdfread(swingang,2,32,fil); - kdfread(swinganginc,2,32,fil); - kdfread(swingx,4,32*8,fil); - kdfread(swingy,4,32*8,fil); - kdfread(revolvesector,2,4,fil); - kdfread(revolveang,2,4,fil); - kdfread(&revolvecnt,2,1,fil); - kdfread(revolvex,4,4*16,fil); - kdfread(revolvey,4,4*16,fil); - kdfread(revolvepivotx,4,4,fil); - kdfread(revolvepivoty,4,4,fil); - kdfread(subwaytracksector,2,4*128,fil); - kdfread(subwaynumsectors,2,4,fil); - kdfread(&subwaytrackcnt,2,1,fil); - kdfread(subwaystop,4,4*8,fil); - kdfread(subwaystopcnt,4,4,fil); - kdfread(subwaytrackx1,4,4,fil); - kdfread(subwaytracky1,4,4,fil); - kdfread(subwaytrackx2,4,4,fil); - kdfread(subwaytracky2,4,4,fil); - kdfread(subwayx,4,4,fil); - kdfread(subwaygoalstop,4,4,fil); - kdfread(subwayvel,4,4,fil); - kdfread(subwaypausetime,4,4,fil); - kdfread(waterfountainwall,2,MAXPLAYERS,fil); - kdfread(waterfountaincnt,2,MAXPLAYERS,fil); - kdfread(slimesoundcnt,2,MAXPLAYERS,fil); - - //Warning: only works if all pointers are in sector structures! - kdfread(tmpanimateptr,4,MAXANIMATES,fil); - for (i=MAXANIMATES-1; i>=0; i--) - animateptr[i] = (int *)(tmpanimateptr[i]+(intptr_t)sector); - - kdfread(animategoal,4,MAXANIMATES,fil); - kdfread(animatevel,4,MAXANIMATES,fil); - kdfread(animateacc,4,MAXANIMATES,fil); - kdfread(&animatecnt,4,1,fil); - - kdfread(&totalclock,4,1,fil); - kdfread(&numframes,4,1,fil); - kdfread(&randomseed,4,1,fil); - kdfread(&numshades,2,1,fil); - - kdfread(&g_visibility,4,1,fil); - kdfread(¶llaxvisibility,4,1,fil); - kdfread(¶llaxtype,1,1,fil); - kdfread(&dummy,4,1,fil); - kdfread(&dummy,2,MAXPSKYTILES,fil); - kdfread(&dummy,2,1,fil); - - kdfread(&mirrorcnt,2,1,fil); - kdfread(mirrorwall,2,mirrorcnt,fil); - kdfread(mirrorsector,2,mirrorcnt,fil); - - //I should save off interpolation list, but they're pointers :( - numinterpolations = 0; - startofdynamicinterpolations = 0; - - kclose(fil); - - for (i=connecthead; i>=0; i=connectpoint2[i]) initplayersprite((short)i); - - totalclock = lockclock; - ototalclock = lockclock; - - Bstrcpy(getmessage,"Game loaded."); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = (int32_t) totalclock+360+(getmessageleng<<4); - return 0; -} - -int savegame(void) -{ - int dummy = 0; - int i; - BFILE *fil; - int tmpanimateptr[MAXANIMATES]; - - if ((fil = Bfopen("save0000.gam","wb")) == 0) return -1; - - dfwrite(&numplayers,4,1,fil); - dfwrite(&myconnectindex,4,1,fil); - dfwrite(&connecthead,4,1,fil); - dfwrite(connectpoint2,4,MAXPLAYERS,fil); - - for (i = 0; i < MAXPLAYERS; ++i) - dfwrite(&pos[i].x,4,1,fil); - for (i = 0; i < MAXPLAYERS; ++i) - dfwrite(&pos[i].y,4,1,fil); - for (i = 0; i < MAXPLAYERS; ++i) - dfwrite(&pos[i].z,4,1,fil); - - dfwrite(horiz,4,MAXPLAYERS,fil); - dfwrite(zoom,4,MAXPLAYERS,fil); - dfwrite(hvel,4,MAXPLAYERS,fil); - dfwrite(ang,2,MAXPLAYERS,fil); - dfwrite(cursectnum,2,MAXPLAYERS,fil); - dfwrite(ocursectnum,2,MAXPLAYERS,fil); - dfwrite(playersprite,2,MAXPLAYERS,fil); - dfwrite(deaths,2,MAXPLAYERS,fil); - dfwrite(lastchaingun,4,MAXPLAYERS,fil); - dfwrite(health,4,MAXPLAYERS,fil); - dfwrite(numgrabbers,2,MAXPLAYERS,fil); - dfwrite(nummissiles,2,MAXPLAYERS,fil); - dfwrite(numbombs,2,MAXPLAYERS,fil); - dfwrite(flytime,4,MAXPLAYERS,fil); - dfwrite(oflags,2,MAXPLAYERS,fil); - dfwrite(dimensionmode,1,MAXPLAYERS,fil); - dfwrite(revolvedoorstat,1,MAXPLAYERS,fil); - dfwrite(revolvedoorang,2,MAXPLAYERS,fil); - dfwrite(revolvedoorrotang,2,MAXPLAYERS,fil); - dfwrite(revolvedoorx,4,MAXPLAYERS,fil); - dfwrite(revolvedoory,4,MAXPLAYERS,fil); - - dfwrite(&numsectors,2,1,fil); - dfwrite(sector,sizeof(sectortype),numsectors,fil); - dfwrite(&numwalls,2,1,fil); - dfwrite(wall,sizeof(walltype),numwalls,fil); - //Store all sprites (even holes) to preserve indeces - dfwrite(sprite,sizeof(spritetype),MAXSPRITES,fil); - dfwrite(headspritesect,2,MAXSECTORS+1,fil); - dfwrite(prevspritesect,2,MAXSPRITES,fil); - dfwrite(nextspritesect,2,MAXSPRITES,fil); - dfwrite(headspritestat,2,MAXSTATUS+1,fil); - dfwrite(prevspritestat,2,MAXSPRITES,fil); - dfwrite(nextspritestat,2,MAXSPRITES,fil); - - dfwrite(&fvel,4,1,fil); - dfwrite(&svel,4,1,fil); - dfwrite(&avel,4,1,fil); - - dfwrite(&locselectedgun,4,1,fil); - dfwrite(&loc.fvel,1,1,fil); - dfwrite(&oloc.fvel,1,1,fil); - dfwrite(&loc.svel,1,1,fil); - dfwrite(&oloc.svel,1,1,fil); - dfwrite(&loc.avel,1,1,fil); - dfwrite(&oloc.avel,1,1,fil); - dfwrite(&loc.bits,2,1,fil); - dfwrite(&oloc.bits,2,1,fil); - - dfwrite(&locselectedgun2,4,1,fil); - dfwrite(&loc2.fvel,sizeof(input),1,fil); - - dfwrite(ssync,sizeof(input),MAXPLAYERS,fil); - dfwrite(osync,sizeof(input),MAXPLAYERS,fil); - - dfwrite(boardfilename,1,80,fil); - dfwrite(&screenpeek,2,1,fil); - dfwrite(&oldmousebstatus,2,1,fil); - dfwrite(&brightness,2,1,fil); - dfwrite(&neartagsector,2,1,fil); - dfwrite(&neartagwall,2,1,fil); - dfwrite(&neartagsprite,2,1,fil); - dfwrite(&lockclock,4,1,fil); - dfwrite(&neartagdist,4,1,fil); - dfwrite(&neartaghitdist,4,1,fil); - - dfwrite(turnspritelist,2,16,fil); - dfwrite(&turnspritecnt,2,1,fil); - dfwrite(warpsectorlist,2,16,fil); - dfwrite(&warpsectorcnt,2,1,fil); - dfwrite(xpanningsectorlist,2,16,fil); - dfwrite(&xpanningsectorcnt,2,1,fil); - dfwrite(ypanningwalllist,2,64,fil); - dfwrite(&ypanningwallcnt,2,1,fil); - dfwrite(floorpanninglist,2,64,fil); - dfwrite(&floorpanningcnt,2,1,fil); - dfwrite(dragsectorlist,2,16,fil); - dfwrite(dragxdir,2,16,fil); - dfwrite(dragydir,2,16,fil); - dfwrite(&dragsectorcnt,2,1,fil); - dfwrite(dragx1,4,16,fil); - dfwrite(dragy1,4,16,fil); - dfwrite(dragx2,4,16,fil); - dfwrite(dragy2,4,16,fil); - dfwrite(dragfloorz,4,16,fil); - dfwrite(&swingcnt,2,1,fil); - dfwrite(swingwall,2,32*5,fil); - dfwrite(swingsector,2,32,fil); - dfwrite(swingangopen,2,32,fil); - dfwrite(swingangclosed,2,32,fil); - dfwrite(swingangopendir,2,32,fil); - dfwrite(swingang,2,32,fil); - dfwrite(swinganginc,2,32,fil); - dfwrite(swingx,4,32*8,fil); - dfwrite(swingy,4,32*8,fil); - dfwrite(revolvesector,2,4,fil); - dfwrite(revolveang,2,4,fil); - dfwrite(&revolvecnt,2,1,fil); - dfwrite(revolvex,4,4*16,fil); - dfwrite(revolvey,4,4*16,fil); - dfwrite(revolvepivotx,4,4,fil); - dfwrite(revolvepivoty,4,4,fil); - dfwrite(subwaytracksector,2,4*128,fil); - dfwrite(subwaynumsectors,2,4,fil); - dfwrite(&subwaytrackcnt,2,1,fil); - dfwrite(subwaystop,4,4*8,fil); - dfwrite(subwaystopcnt,4,4,fil); - dfwrite(subwaytrackx1,4,4,fil); - dfwrite(subwaytracky1,4,4,fil); - dfwrite(subwaytrackx2,4,4,fil); - dfwrite(subwaytracky2,4,4,fil); - dfwrite(subwayx,4,4,fil); - dfwrite(subwaygoalstop,4,4,fil); - dfwrite(subwayvel,4,4,fil); - dfwrite(subwaypausetime,4,4,fil); - dfwrite(waterfountainwall,2,MAXPLAYERS,fil); - dfwrite(waterfountaincnt,2,MAXPLAYERS,fil); - dfwrite(slimesoundcnt,2,MAXPLAYERS,fil); - - //Warning: only works if all pointers are in sector structures! - for (i=MAXANIMATES-1; i>=0; i--) - tmpanimateptr[i] = (int)((intptr_t)animateptr[i]-(intptr_t)sector); - dfwrite(tmpanimateptr,4,MAXANIMATES,fil); - - dfwrite(animategoal,4,MAXANIMATES,fil); - dfwrite(animatevel,4,MAXANIMATES,fil); - dfwrite(animateacc,4,MAXANIMATES,fil); - dfwrite(&animatecnt,4,1,fil); - - dfwrite(&totalclock,4,1,fil); - dfwrite(&numframes,4,1,fil); - dfwrite(&randomseed,4,1,fil); - dfwrite(&numshades,2,1,fil); - - dfwrite(&g_visibility,4,1,fil); - dfwrite(¶llaxvisibility,4,1,fil); - dfwrite(¶llaxtype,1,1,fil); - dfwrite(&dummy,4,1,fil); - dfwrite(&dummy,2,MAXPSKYTILES,fil); - dfwrite(&dummy,2,1,fil); - - dfwrite(&mirrorcnt,2,1,fil); - dfwrite(mirrorwall,2,mirrorcnt,fil); - dfwrite(mirrorsector,2,mirrorcnt,fil); - - Bfclose(fil); - - Bstrcpy(getmessage,"Game saved."); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = (int32_t) totalclock+360+(getmessageleng<<4); - return 0; -} - -void faketimerhandler(void) -{ - short other /*, packbufleng*/; - int i, j, k, l; - - sampletimer(); - if ((totalclock < ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) || (ready2send == 0)) return; - ototalclock += (TIMERINTSPERSECOND/MOVESPERSECOND); - - getpackets(); - if (getoutputcirclesize() >= 16) return; - getinput(); - -#if 0 - for (i=connecthead; i>=0; i=connectpoint2[i]) - if (i != myconnectindex) - { - k = (movefifoend[myconnectindex]-1)-movefifoend[i]; - myminlag[i] = min(myminlag[i],k); - mymaxlag = max(mymaxlag,k); - } - - if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) - { - i = mymaxlag-bufferjitter; mymaxlag = 0; - if (i > 0) bufferjitter += ((2+i)>>2); - else if (i < 0) bufferjitter -= ((2-i)>>2); - } -#endif - - if (networkmode == 1) - { - packbuf[2] = 0; j = 3; - if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[2] |= 1; - if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[2] |= 2; - if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[2] |= 4; - if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[2] |= 8; - if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[2] |= 16; - copybufbyte(&loc,&oloc,sizeof(input)); - - copybufbyte(&loc,&baksync[movefifoend[myconnectindex]][myconnectindex],sizeof(input)); - movefifoend[myconnectindex] = ((movefifoend[myconnectindex]+1)&(MOVEFIFOSIZ-1)); - - for (i=connecthead; i>=0; i=connectpoint2[i]) - if (i != myconnectindex) - { - packbuf[0] = 17; - packbuf[1] = (char)((movefifoend[myconnectindex]-movefifoend[i])&(MOVEFIFOSIZ-1)); - - k = j; - if ((myconnectindex == connecthead) || ((i == connecthead) && (myconnectindex == connectpoint2[connecthead]))) - { - while (syncvalhead != syncvaltail) - { - packbuf[j++] = syncval[syncvaltail]; - syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); - } - } - sendpacket(i,packbuf,j); - j = k; - } - - gotlastpacketclock = (int32_t) totalclock; - return; - } - - //MASTER (or 1 player game) - if ((myconnectindex == connecthead) || (option[4] == 0)) - { - copybufbyte(&loc,&ffsync[myconnectindex],sizeof(input)); - - if (option[4] != 0) - { - packbuf[0] = 0; - j = ((numplayers+1)>>1)+1; - for (k=1; k=0; i=connectpoint2[i]) - { - l = 0; - if (ffsync[i].fvel != osync[i].fvel) packbuf[j++] = ffsync[i].fvel, l |= 1; - if (ffsync[i].svel != osync[i].svel) packbuf[j++] = ffsync[i].svel, l |= 2; - if (ffsync[i].avel != osync[i].avel) packbuf[j++] = ffsync[i].avel, l |= 4; - if (ffsync[i].bits != osync[i].bits) - { - packbuf[j++] = (ffsync[i].bits&255); - packbuf[j++] = ((ffsync[i].bits>>8)&255); - l |= 8; - } - packbuf[k>>3] |= (l<<(k&7)); - k += 4; - - copybufbyte(&ffsync[i],&osync[i],sizeof(input)); - } - - while (syncvalhead != syncvaltail) - { - packbuf[j++] = syncval[syncvaltail]; - syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); - } - - for (i=connectpoint2[connecthead]; i>=0; i=connectpoint2[i]) - sendpacket(i,packbuf,j); - } - else if (numplayers >= 2) - { - if (keystatus[0xb5]) - { - keystatus[0xb5] = 0; - locselectedgun2++; if (locselectedgun2 >= 3) locselectedgun2 = 0; - } - - //Second player on 1 computer mode - loc2.fvel = min(max(fvel2,-128+8),127-8); - loc2.svel = min(max(svel2,-128+8),127-8); - loc2.avel = min(max(avel2,-128+16),127-16); - loc2.bits = (locselectedgun2<<13); - loc2.bits |= keystatus[0x45]; //Stand high - loc2.bits |= (keystatus[0x47]<<1); //Stand low - loc2.bits |= (1<<8); //Run - loc2.bits |= (keystatus[0x49]<<2); //Look up - loc2.bits |= (keystatus[0x37]<<3); //Look down - loc2.bits |= (keystatus[0x50]<<10); //Space - loc2.bits |= (keystatus[0x52]<<11); //Shoot - - other = connectpoint2[myconnectindex]; - if (other < 0) other = connecthead; - - copybufbyte(&loc2,&ffsync[other],sizeof(input)); - } - movethings(); //Move EVERYTHING (you too!) - } - else //I am a SLAVE - { - packbuf[0] = 1; packbuf[1] = 0; j = 2; - if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[1] |= 1; - if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[1] |= 2; - if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[1] |= 4; - if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[1] |= 8; - if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[1] |= 16; - copybufbyte(&loc,&oloc,sizeof(input)); - sendpacket(connecthead,packbuf,j); - } -} - -void getpackets(void) -{ - int i, j, k, l; - int other, packbufleng, movecnt; - - if (option[4] == 0) return; - - movecnt = 0; - while ((packbufleng = getpacket(&other,packbuf)) > 0) - { - switch (packbuf[0]) - { - case 0: //[0] (receive master sync buffer) - j = ((numplayers+1)>>1)+1; k = (1<<3); - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - l = (packbuf[k>>3]>>(k&7)); - if (l&1) ffsync[i].fvel = packbuf[j++]; - if (l&2) ffsync[i].svel = packbuf[j++]; - if (l&4) ffsync[i].avel = packbuf[j++]; - if (l&8) - { - ffsync[i].bits = ((short)packbuf[j])+(((short)packbuf[j+1])<<8); - j += 2; - } - k += 4; - } - - while (j != packbufleng) - { - othersyncval[othersyncvalhead] = packbuf[j++]; - othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); - } - if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) - { - syncstat = 0; - do - { - syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); - syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); - } - while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); - } - - movethings(); //Move all players and sprites - movecnt++; - break; - case 1: //[1] (receive slave sync buffer) - j = 2; k = packbuf[1]; - if (k&1) ffsync[other].fvel = packbuf[j++]; - if (k&2) ffsync[other].svel = packbuf[j++]; - if (k&4) ffsync[other].avel = packbuf[j++]; - if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); - if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); - break; - case 2: - getmessageleng = packbufleng-1; - for (j=getmessageleng-1; j>=0; j--) getmessage[j] = packbuf[j+1]; - getmessagetimeoff = (int32_t) totalclock+360+(getmessageleng<<4); - wsay("getstuff.wav",8192L,63L,63L); //Added 12/2004 - break; - case 3: - wsay("getstuff.wav",4096L,63L,63L); - break; -#if 0 - case 5: - playerreadyflag[other] = packbuf[1]; - if ((other == connecthead) && (packbuf[1] == 2)) - sendpacket(connecthead,packbuf,2); - break; -#endif - case 250: - playerreadyflag[other]++; - break; - case 17: - j = 3; k = packbuf[2]; - if (k&1) ffsync[other].fvel = packbuf[j++]; - if (k&2) ffsync[other].svel = packbuf[j++]; - if (k&4) ffsync[other].avel = packbuf[j++]; - if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); - if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); - otherlag[other] = packbuf[1]; - - copybufbyte(&ffsync[other],&baksync[movefifoend[other]][other],sizeof(input)); - movefifoend[other] = ((movefifoend[other]+1)&(MOVEFIFOSIZ-1)); - - while (j != packbufleng) - { - othersyncval[othersyncvalhead] = packbuf[j++]; - othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); - } - if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) - { - syncstat = 0; - do - { - syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); - syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); - } - while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); - } - - break; - case 255: //[255] (logout) - keystatus[1] = 1; - break; - } - } - if ((networkmode == 0) && (myconnectindex != connecthead) && ((movecnt&1) == 0)) - { - if (rand()&1) ototalclock += (TICSPERFRAME>>1); - else ototalclock -= (TICSPERFRAME>>1); - } -} - -void drawoverheadmap(int cposx, int cposy, int czoom, short cang) -{ - int i, j, k, l=0, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; - int dax, day, cosang, sinang, xspan, yspan, sprx, spry; - int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; - int xvect, yvect, xvect2, yvect2; - char col; - walltype *wal, *wal2; - spritetype *spr; - - xvect = sintable[(-cang)&2047] * czoom; - yvect = sintable[(1536-cang)&2047] * czoom; - xvect2 = mulscale16(xvect,yxaspect); - yvect2 = mulscale16(yvect,yxaspect); - - //Draw red lines - for (i=0; inextwall; if (k < 0) continue; - - if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; - if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue; - - if (sector[wal->nextsector].ceilingz == z1) - if (sector[wal->nextsector].floorz == z2) - if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; - - col = 152; - - if (dimensionmode[screenpeek] == 2) - { - if (sector[i].floorz != sector[i].ceilingz) - if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz) - if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) - if (sector[i].floorz == sector[wal->nextsector].floorz) continue; - if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum) continue; - if (sector[i].floorshade != sector[wal->nextsector].floorshade) continue; - col = 12; - } - - ox = wal->x-cposx; oy = wal->y-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - wal2 = &wall[wal->point2]; - ox = wal2->x-cposx; oy = wal2->y-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - drawline256(x1,y1,x2,y2,col); - } - } - - //Draw sprites - k = playersprite[screenpeek]; - for (i=0; i=0; j=nextspritesect[j]) - if ((show2dsprite[j>>3]&(1<<(j&7))) > 0) - { - spr = &sprite[j]; if (spr->cstat&0x8000) continue; - col = 56; - if (spr->cstat&1) col = 248; - if (j == k) col = 31; - - k = statrate[spr->statnum]; - sprx = spr->x; - spry = spr->y; - if (k >= 0) - { - switch (k) - { - case 0: l = smoothratio; break; - case 1: l = (smoothratio>>1)+(((nummoves-j)&1)<<15); break; - case 3: l = (smoothratio>>2)+(((nummoves-j)&3)<<14); break; - case 7: l = (smoothratio>>3)+(((nummoves-j)&7)<<13); break; - case 15: l = (smoothratio>>4)+(((nummoves-j)&15)<<12); break; - } - sprx = osprite[j].x+mulscale16(sprx-osprite[j].x,l); - spry = osprite[j].y+mulscale16(spry-osprite[j].y,l); - } - - switch (spr->cstat&48) - { - case 0: - ox = sprx-cposx; oy = spry-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - if (dimensionmode[screenpeek] == 1) - { - ox = (sintable[(spr->ang+512)&2047]>>7); - oy = (sintable[(spr->ang)&2047]>>7); - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect,ox,yvect); - - if (j == playersprite[screenpeek]) - { - x2 = 0L; - y2 = -(czoom<<5); - } - - x3 = mulscale16(x2,yxaspect); - y3 = mulscale16(y2,yxaspect); - - drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - } - else - { - if (((gotsector[i>>3]&(1<<(i&7))) > 0) && (czoom > 96)) - { - daang = (spr->ang-cang)&2047; - if (j == playersprite[screenpeek]) { x1 = 0; y1 = 0; daang = 0; } - rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),mulscale16(czoom*spr->yrepeat,yxaspect),daang,spr->picnum,spr->shade,spr->pal,(spr->cstat&2)>>1,windowxy1.x,windowxy1.y,windowxy2.x,windowxy2.y); - } - } - break; - case 16: - x1 = sprx; y1 = spry; - tilenum = spr->picnum; - xoff = (int)picanm[tilenum].xofs+((int)spr->xoffset); - if ((spr->cstat&4) > 0) xoff = -xoff; - k = spr->ang; l = spr->xrepeat; - dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; - l = tilesiz[tilenum].x; k = (l>>1)+xoff; - x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); - y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); - - ox = x1-cposx; oy = y1-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x2-cposx; oy = y2-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect2,ox,yvect2); - - drawline256(x1+(xdim<<11),y1+(ydim<<11), - x2+(xdim<<11),y2+(ydim<<11),col); - - break; - case 32: - if (dimensionmode[screenpeek] == 1) - { - tilenum = spr->picnum; - xoff = (int)picanm[tilenum].xofs+((int)spr->xoffset); - yoff = (int)picanm[tilenum].yofs+((int)spr->yoffset); - if ((spr->cstat&4) > 0) xoff = -xoff; - if ((spr->cstat&8) > 0) yoff = -yoff; - - k = spr->ang; - cosang = sintable[(k+512)&2047]; sinang = sintable[k]; - xspan = tilesiz[tilenum].x; xrepeat = spr->xrepeat; - yspan = tilesiz[tilenum].y; yrepeat = spr->yrepeat; - - dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; - x1 = sprx + dmulscale16(sinang,dax,cosang,day); - y1 = spry + dmulscale16(sinang,day,-cosang,dax); - l = xspan*xrepeat; - x2 = x1 - mulscale16(sinang,l); - y2 = y1 + mulscale16(cosang,l); - l = yspan*yrepeat; - k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; - k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; - - ox = x1-cposx; oy = y1-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x2-cposx; oy = y2-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x3-cposx; oy = y3-cposy; - x3 = dmulscale16(ox,xvect,-oy,yvect); - y3 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x4-cposx; oy = y4-cposy; - x4 = dmulscale16(ox,xvect,-oy,yvect); - y4 = dmulscale16(oy,xvect2,ox,yvect2); - - drawline256(x1+(xdim<<11),y1+(ydim<<11), - x2+(xdim<<11),y2+(ydim<<11),col); - - drawline256(x2+(xdim<<11),y2+(ydim<<11), - x3+(xdim<<11),y3+(ydim<<11),col); - - drawline256(x3+(xdim<<11),y3+(ydim<<11), - x4+(xdim<<11),y4+(ydim<<11),col); - - drawline256(x4+(xdim<<11),y4+(ydim<<11), - x1+(xdim<<11),y1+(ydim<<11),col); - - } - break; - } - } - - //Draw white lines - for (i=0; inextwall >= 0) continue; - - if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; - - if (tilesiz[wal->picnum].x == 0) continue; - if (tilesiz[wal->picnum].y == 0) continue; - - if (j == k) - { x1 = x2; y1 = y2; } - else - { - ox = wal->x-cposx; oy = wal->y-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - } - - k = wal->point2; wal2 = &wall[k]; - ox = wal2->x-cposx; oy = wal2->y-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - drawline256(x1,y1,x2,y2,24); - } - } -} - -//New movesprite using getzrange. Note that I made the getzrange -//parameters global (&globhiz,&globhihit,&globloz,&globlohit) so they -//don't need to be passed everywhere. Also this should make this -//movesprite function compatible with the older movesprite functions. -int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, int clipmask) -{ - int daz, zoffs /*, tempint*/; - short retval, dasectnum, datempshort; - spritetype *spr; - - spr = &sprite[spritenum]; - - if ((spr->cstat&128) == 0) - zoffs = -((tilesiz[spr->picnum].y*spr->yrepeat)<<1); - else - zoffs = 0; - - dasectnum = spr->sectnum; //Can't modify sprite sectors directly becuase of linked lists - daz = spr->z+zoffs; //Must do this if not using the new centered centering (of course) - retval = clipmove_old(&spr->x,&spr->y,&daz,&dasectnum,dx,dy, - ((int)spr->clipdist)<<2,ceildist,flordist,clipmask); - - if (dasectnum < 0) retval = -1; - - if ((dasectnum != spr->sectnum) && (dasectnum >= 0)) - changespritesect(spritenum,dasectnum); - - //Set the blocking bit to 0 temporarly so getzrange doesn't pick up - //its own sprite - datempshort = spr->cstat; spr->cstat &= ~1; - getzrange_old(spr->x,spr->y,spr->z-1,spr->sectnum, - &globhiz,&globhihit,&globloz,&globlohit, - ((int)spr->clipdist)<<2,clipmask); - spr->cstat = datempshort; - - daz = spr->z+zoffs + dz; - if ((daz <= globhiz) || (daz > globloz)) - { - if (retval != 0) return retval; - return 16384+dasectnum; - } - spr->z = daz-zoffs; - return retval; -} - - -void waitforeverybody() -{ - int i; - if (numplayers < 2) return; - packbuf[0] = 250; - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - if (i != myconnectindex) sendpacket(i,packbuf,1); - if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master - } - playerreadyflag[myconnectindex]++; - while (1) - { - handleevents(); - refreshaudio(); - - drawrooms(pos[myconnectindex].x,pos[myconnectindex].y,pos[myconnectindex].z,ang[myconnectindex],horiz[myconnectindex],cursectnum[myconnectindex]); - if (!networkmode) Bsprintf((char *)tempbuf,"Master/slave mode"); - else Bsprintf((char *)tempbuf,"Peer-peer mode"); - printext256((xdim>>1)-(strlen((char *)tempbuf)<<2),(ydim>>1)-24,31,0,(char *)tempbuf,0); - Bsprintf((char *)tempbuf,"Waiting for players"); - printext256((xdim>>1)-(strlen((char *)tempbuf)<<2),(ydim>>1)-16,31,0,(char *)tempbuf,0); - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - if (playerreadyflag[i] < playerreadyflag[myconnectindex]) - { - //slaves in M/S mode only wait for master - if ((!networkmode) && (myconnectindex != connecthead) && (i != connecthead)) - { - Bsprintf((char *)tempbuf,"Player %d",i); - printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,15,0,(char *)tempbuf,0); - } - else - { - Bsprintf((char *)tempbuf,"Player %d NOT ready",i); - printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,127,0,(char *)tempbuf,0); - } - } - else - { - Bsprintf((char *)tempbuf,"Player %d ready",i); - printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,31,0,(char *)tempbuf,0); - } - if (i == myconnectindex) - { - Bsprintf((char *)tempbuf,"You->"); - printext256((xdim>>1)-(26<<2),(ydim>>1)+i*8,95,0,(char *)tempbuf,0); - } - } - nextpage(); - - - if (quitevent || keystatus[1]) - { - sendlogoff(); //Signing off - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); - } - - getpackets(); - - for (i=connecthead; i>=0; i=connectpoint2[i]) - { - if (playerreadyflag[i] < playerreadyflag[myconnectindex]) break; - if ((!networkmode) && (myconnectindex != connecthead)) { i = -1; break; } //slaves in M/S mode only wait for master - } - if (i < 0) return; - } -} - - -void searchmap(short startsector) -{ - int i, j, dasect, splc, send, startwall, endwall; - short dapic; - walltype *wal; - - if ((startsector < 0) || (startsector >= numsectors)) return; - for (i=0; i<(MAXSECTORS>>3); i++) show2dsector[i] = 0; - for (i=0; i<(MAXWALLS>>3); i++) show2dwall[i] = 0; - for (i=0; i<(MAXSPRITES>>3); i++) show2dsprite[i] = 0; - - //Search your area recursively & set all show2dsector/show2dwalls - tempshort[0] = startsector; - show2dsector[startsector>>3] |= (1<<(startsector&7)); - dapic = sector[startsector].ceilingpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - dapic = sector[startsector].floorpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - for (splc=0,send=1; splc>3] |= (1<<(i&7)); - dapic = wall[i].picnum; - if (waloff[dapic] == 0) loadtile(dapic); - dapic = wall[i].overpicnum; - if (((dapic&0xfffff000) == 0) && (waloff[dapic] == 0)) loadtile(dapic); - - j = wal->nextsector; - if ((j >= 0) && ((show2dsector[j>>3]&(1<<(j&7))) == 0)) - { - show2dsector[j>>3] |= (1<<(j&7)); - - dapic = sector[j].ceilingpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - dapic = sector[j].floorpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - - tempshort[send++] = (short)j; - } - } - - for (i=headspritesect[dasect]; i>=0; i=nextspritesect[i]) - { - show2dsprite[i>>3] |= (1<<(i&7)); - dapic = sprite[i].picnum; - if (waloff[dapic] == 0) loadtile(dapic); - } - } -} - -void setinterpolation(int *posptr) -{ - int i; - - if (numinterpolations >= MAXINTERPOLATIONS) return; - for (i=numinterpolations-1; i>=0; i--) - if (curipos[i] == posptr) return; - curipos[numinterpolations] = posptr; - oldipos[numinterpolations] = *posptr; - numinterpolations++; -} - -void stopinterpolation(int *posptr) -{ - int i; - - for (i=numinterpolations-1; i>=startofdynamicinterpolations; i--) - if (curipos[i] == posptr) - { - numinterpolations--; - oldipos[i] = oldipos[numinterpolations]; - bakipos[i] = bakipos[numinterpolations]; - curipos[i] = curipos[numinterpolations]; - } -} - -void updateinterpolations(void) //Stick at beginning of domovethings -{ - int i; - - for (i=numinterpolations-1; i>=0; i--) oldipos[i] = *curipos[i]; -} - -void dointerpolations(void) //Stick at beginning of drawscreen -{ - int i, j, odelta, ndelta; - - ndelta = 0; j = 0; - for (i=numinterpolations-1; i>=0; i--) - { - bakipos[i] = *curipos[i]; - odelta = ndelta; ndelta = (*curipos[i])-oldipos[i]; - if (odelta != ndelta) j = mulscale16(ndelta,smoothratio); - *curipos[i] = oldipos[i]+j; - } -} - -void restoreinterpolations(void) //Stick at end of drawscreen -{ - int i; - - for (i=numinterpolations-1; i>=0; i--) *curipos[i] = bakipos[i]; -} - -void printext(int x, int y, char *buffer, short tilenum /*, char invisiblecol*/) -{ - int i; - char ch; - - for (i=0; buffer[i]!=0; i++) - { - ch = (char)buffer[i]; - rotatesprite((x-((8&15)<<3))<<16,(y-((8>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+64+128,x,y,x+7,y+7); - rotatesprite((x-((ch&15)<<3))<<16,(y-((ch>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+128,x,y,x+7,y+7); - x += 8; - } -} - -void drawtilebackground(/*int thex, int they,*/ short tilenum, - signed char shade, int cx1, int cy1, - int cx2, int cy2, char dapalnum) -{ - int x, y, xsiz, ysiz, tx1, ty1, tx2, ty2; - - xsiz = tilesiz[tilenum].x; tx1 = cx1/xsiz; tx2 = cx2/xsiz; - ysiz = tilesiz[tilenum].y; ty1 = cy1/ysiz; ty2 = cy2/ysiz; - - for (x=tx1; x<=tx2; x++) - for (y=ty1; y<=ty2; y++) - rotatesprite(x*xsiz<<16,y*ysiz<<16,65536L,0,tilenum,shade,dapalnum,8+16+64+128,cx1,cy1,cx2,cy2); -} - -void M32RunScript(const char *s) { UNREFERENCED_PARAMETER(s); } -void G_Polymer_UnInit(void) { } -void app_crashhandler(void) { } - -/* - * vim:ts=4:sw=4: - */ diff --git a/source/kenbuild/src/game.h b/source/kenbuild/src/game.h deleted file mode 100644 index e2bb67aa8..000000000 --- a/source/kenbuild/src/game.h +++ /dev/null @@ -1,55 +0,0 @@ -// game.h - -void operatesector(short dasector); -void operatesprite(short dasprite); -int changehealth(short snum, short deltahealth); -void changenumbombs(short snum, short deltanumbombs); -void changenummissiles(short snum, short deltanummissiles); -void changenumgrabbers(short snum, short deltanumgrabbers); -void drawstatusflytime(short snum); -void drawstatusbar(short snum); -void prepareboard(char *daboardfilename); -void checktouchsprite(short snum, short sectnum); -void checkgrabbertouchsprite(short snum, short sectnum); -void shootgun(short snum, const vec3_t *vector, short daang, int dahoriz, short dasectnum, char guntype); -void analyzesprites(int dax, int day); -void tagcode(void); -void statuslistcode(void); -void activatehitag(short dahitag); -void bombexplode(int i); -void processinput(short snum); -void view(short snum, vec3_t *v, short *vsectnum, short ang, int horiz); -void drawscreen(short snum, int dasmoothratio); -void movethings(void); -void fakedomovethings(void); -void fakedomovethingscorrect(void); -void domovethings(void); -void getinput(void); -void initplayersprite(short snum); -void playback(void); -void setup3dscreen(void); -void findrandomspot(int *x, int *y, short *sectnum); -void warp(int *x, int *y, int *z, short *daang, short *dasector); -void warpsprite(short spritenum); -void initlava(void); -void movelava(char *dapic); -void doanimations(void); -int getanimationgoal(int *animptr); -int setanimation(int *animptr, int thegoal, int thevel, int theacc); -void checkmasterslaveswitch(void); -int testneighborsectors(short sect1, short sect2); -int loadgame(void); -int savegame(void); -void faketimerhandler(void); -void getpackets(void); -void drawoverheadmap(int cposx, int cposy, int czoom, short cang); -int movesprite(short spritenum, int dx, int dy, int dz, int ceildist, int flordist, int clipmask); -void waitforeverybody(void); -void searchmap(short startsector); -void setinterpolation(int *posptr); -void stopinterpolation(int *posptr); -void updateinterpolations(void); -void dointerpolations(void); -void restoreinterpolations(void); -void printext(int x, int y, char *buffer, short tilenum /*, char invisiblecol*/); -void drawtilebackground(/*int thex, int they,*/ short tilenum, signed char shade, int cx1, int cy1, int cx2, int cy2, char dapalnum); diff --git a/source/kenbuild/src/names.h b/source/kenbuild/src/names.h deleted file mode 100644 index 6373be4d8..000000000 --- a/source/kenbuild/src/names.h +++ /dev/null @@ -1,49 +0,0 @@ -//Be careful when changing this file - it is parsed by Editart and Build. -#define SWITCH1ON 15 -#define SLIME 34 -#define BACKGROUND 37 -#define KENPICTURE 48 -#define BUILDDISK 49 -#define SWITCH2ON 66 -#define SWITCH2OFF 69 -#define ALPHABET 73 -#define NO 74 -#define DEMOSIGN 75 -#define COIN 76 -#define COINSTACK 77 -#define GIFTBOX 78 -#define DIAMONDS 79 -#define EVILALGRAVE 83 -#define STATUSBAR 87 -#define DAYSKY 89 -#define WATERFOUNTAIN 90 -#define USEWATERFOUNTAIN 91 -#define NIGHTSKY 93 -#define BULLET 98 -#define BOMB 100 -#define CANNON 101 -#define GUNONBOTTOM 102 -#define BOMBEMITTER 103 -#define EXPLOSION 105 -#define SPLASH 106 -#define BROWNMONSTER 110 -#define SKELETON 113 -#define AL 114 -#define EVILAL 115 -#define PLAYER 120 -#define SWITCH3OFF 146 -#define SWITCH3ON 147 -#define AIRPLANE 148 -#define SPIRAL 149 -#define COMPASS 150 -#define FOOTPRINT 156 -#define STATUSBARFILL8 160 -#define STATUSBARFILL4 161 -#define BOUNCYMAT 162 -#define MIRROR 165 -#define FLOORMIRROR 166 -#define GRABBER 167 -#define GRABCANNON 168 -#define MISSILE 169 -#define LAUNCHER 171 -#define MIRRORLABEL 4000 diff --git a/source/kenbuild/src/sound_stub.cpp b/source/kenbuild/src/sound_stub.cpp deleted file mode 100644 index 8e2c3dd40..000000000 --- a/source/kenbuild/src/sound_stub.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -#include "compat.h" - -void initsb(char dadigistat, char damusistat, int dasamplerate, char danumspeakers, char dabytespersample, char daintspersec, char daquality) -{ - UNREFERENCED_PARAMETER(dadigistat); - UNREFERENCED_PARAMETER(damusistat); - UNREFERENCED_PARAMETER(dasamplerate); - UNREFERENCED_PARAMETER(danumspeakers); - UNREFERENCED_PARAMETER(dabytespersample); - UNREFERENCED_PARAMETER(daintspersec); - UNREFERENCED_PARAMETER(daquality); -} - -void uninitsb(void) -{ -} - -void setears(int daposx, int daposy, int daxvect, int dayvect) -{ - UNREFERENCED_PARAMETER(daposx); - UNREFERENCED_PARAMETER(daposy); - UNREFERENCED_PARAMETER(daxvect); - UNREFERENCED_PARAMETER(dayvect); -} - -void wsayfollow(char const *dafilename, int dafreq, int davol, int *daxplc, int *dayplc, char followstat) -{ - UNREFERENCED_PARAMETER(dafilename); - UNREFERENCED_PARAMETER(dafreq); - UNREFERENCED_PARAMETER(davol); - UNREFERENCED_PARAMETER(daxplc); - UNREFERENCED_PARAMETER(dayplc); - UNREFERENCED_PARAMETER(followstat); -} - -void wsay(char const *dafilename, int dafreq, int volume1, int volume2) -{ - UNREFERENCED_PARAMETER(dafilename); - UNREFERENCED_PARAMETER(dafreq); - UNREFERENCED_PARAMETER(volume1); - UNREFERENCED_PARAMETER(volume2); -} - -void loadwaves(void) -{ -} - -void loadsong(char const *filename) -{ - UNREFERENCED_PARAMETER(filename); -} - -void musicon(void) -{ -} - -void musicoff(void) -{ -} - -void refreshaudio(void) -{ -} diff --git a/source/kenbuild/src/startgtk.game.cpp b/source/kenbuild/src/startgtk.game.cpp deleted file mode 100644 index 4d6457e44..000000000 --- a/source/kenbuild/src/startgtk.game.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* NOTE: Glade will generate code for a dialogue box which you should - * then patch into this file whenever you make a change to the Glade - * template. - */ - -#include "compat.h" - -#include "gtkpixdata.h" -#include -#include -#include -#include - -#include "dynamicgtk.h" - -#include "baselayer.h" -#include "compat.h" -#include "build.h" - -#define TAB_CONFIG 0 -#define TAB_MESSAGES 1 - -static struct -{ - int fullscreen; - int xdim3d, ydim3d, bpp3d; - int forcesetup; -} settings; - -extern int gtkenabled; - -static GtkWidget *startwin = NULL; -static int retval = -1, mode = TAB_MESSAGES; - -// -- SUPPORT FUNCTIONS ------------------------------------------------------- - -#define GLADE_HOOKUP_OBJECT(component,widget,name) \ - g_object_set_data_full (G_OBJECT (component), name, \ - gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) - -#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ - g_object_set_data (G_OBJECT (component), name, widget) - -#define lookup_widget(x,w) \ - (GtkWidget*) g_object_get_data(G_OBJECT(x), w) - -static GdkPixbuf *load_banner(void) -{ - return gdk_pixbuf_from_pixdata((GdkPixdata const *)&startbanner_pixdata, FALSE, NULL); -} - -static void SetPage(int n) -{ - if (!gtkenabled || !startwin) return; - mode = n; - gtk_notebook_set_current_page(GTK_NOTEBOOK(lookup_widget(startwin,"tabs")), n); - - // each control in the config page vertical layout plus the start button should be made (in)sensitive - if (n == TAB_CONFIG) n = TRUE; else n = FALSE; - gtk_widget_set_sensitive(lookup_widget(startwin,"startbutton"), n); - gtk_container_foreach(GTK_CONTAINER(lookup_widget(startwin,"configvlayout")), - (GtkCallback)gtk_widget_set_sensitive, (gpointer)n); -} - -static void on_vmode3dcombo_changed(GtkComboBox *, gpointer); -static void PopulateForm(void) -{ - int mode3d, i; - GtkListStore *modes3d; - GtkTreeIter iter; - GtkComboBox *box3d; - char buf[64]; - - mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1); - if (mode3d < 0) - { - int i, cd[] = { 32, 24, 16, 15, 8, 0 }; - for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp3d) i++; else break; } - for (; cd[i]; i++) - { - mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1); - if (mode3d < 0) continue; - settings.bpp3d = cd[i]; - break; - } - } - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"fullscreencheck")), settings.fullscreen); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"alwaysshowcheck")), settings.forcesetup); - - box3d = GTK_COMBO_BOX(lookup_widget(startwin,"vmode3dcombo")); - modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(box3d)); - gtk_list_store_clear(modes3d); - - for (i=0; i aptr) - gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1); -#if GTK_CHECK_VERSION(2,6,0) - gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE); -#else - { - GtkTextIter iter2 = enditer; - gtk_text_iter_backward_cursor_position(&iter2); - //FIXME: this seems be deleting one too many chars somewhere! - if (!gtk_text_iter_equal(&iter2, &enditer)) - gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE); - } -#endif - aptr = ++bptr; - break; - case 0: - if (bptr > aptr) - gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)); - aptr = bptr; - break; - case '\r': // FIXME - default: - bptr++; - break; - } - } - - mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1); - gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0); - gtk_text_buffer_delete_mark(textbuffer, mark); - - return 0; -} - -int startwin_settitle(const char *title) -{ - if (!gtkenabled) return 0; - if (!startwin) return 1; - gtk_window_set_title(GTK_WINDOW(startwin), title); - return 0; -} - -int startwin_idle(void *s) -{ - if (!gtkenabled) return 0; - //if (!startwin) return 1; - gtk_main_iteration_do(FALSE); - return 0; -} - -extern int xdimgame, ydimgame, bppgame, forcesetup; - -int startwin_run(void) -{ - if (!gtkenabled) return 0; - if (!startwin) return 1; - - SetPage(TAB_CONFIG); - - settings.fullscreen = fullscreen; - settings.xdim3d = xdimgame; - settings.ydim3d = ydimgame; - settings.bpp3d = bppgame; - settings.forcesetup = forcesetup; - PopulateForm(); - - gtk_main(); - - SetPage(TAB_MESSAGES); - if (retval) - { - fullscreen = settings.fullscreen; - xdimgame = settings.xdim3d; - ydimgame = settings.ydim3d; - bppgame = settings.bpp3d; - forcesetup = settings.forcesetup; - } - - return retval; -} diff --git a/source/kenbuild/src/startwin.game.cpp b/source/kenbuild/src/startwin.game.cpp deleted file mode 100644 index 128dd4452..000000000 --- a/source/kenbuild/src/startwin.game.cpp +++ /dev/null @@ -1,450 +0,0 @@ -#ifndef _WIN32 -#error Only for Windows -#endif - -#include "compat.h" -#include "build.h" - -#define NEED_WINDOWSX_H -#define NEED_COMMCTRL_H -#include "windows_inc.h" - -#include "winlayer.h" - -#include "startwin.game.h" - -#define TAB_CONFIG 0 -#define TAB_MESSAGES 1 - -static struct -{ - int fullscreen; - int xdim3d, ydim3d, bpp3d; - int forcesetup; -} settings; - -static HWND startupdlg = NULL; -static HWND pages[2] = { NULL, NULL}; -static int done = -1, mode = TAB_CONFIG; - -static void PopulateForm(void) -{ - int i,j; - char buf[64]; - int mode3d; - HWND hwnd3d; - - hwnd3d = GetDlgItem(pages[TAB_CONFIG], IDC3DVMODE); - - mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1); - if (mode3d < 0) - { - int cd[] = { 32, 24, 16, 15, 8, 0 }; - for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp3d) i++; else break; } - for (; cd[i]; i++) - { - mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1); - if (mode3d < 0) continue; - settings.bpp3d = cd[i]; - break; - } - } - - Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCFULLSCREEN), (settings.fullscreen ? BST_CHECKED : BST_UNCHECKED)); - Button_SetCheck(GetDlgItem(pages[TAB_CONFIG], IDCALWAYSSHOW), (settings.forcesetup ? BST_CHECKED : BST_UNCHECKED)); - - ComboBox_ResetContent(hwnd3d); - for (i=0; iidFrom != WIN_STARTWIN_TABCTL) break; - cur = (int)SendMessage(nmhdr->hwndFrom, TCM_GETCURSEL,0,0); - switch (nmhdr->code) - { - case TCN_SELCHANGING: - { - if (cur < 0 || !pages[cur]) break; - ShowWindow(pages[cur],SW_HIDE); - return TRUE; - } - case TCN_SELCHANGE: - { - if (cur < 0 || !pages[cur]) break; - ShowWindow(pages[cur],SW_SHOW); - return TRUE; - } - } - break; - } - - case WM_CLOSE: - if (mode == TAB_CONFIG) done = 0; - else quitevent++; - return TRUE; - - case WM_DESTROY: - if (hbmp) - { - DeleteObject(hbmp); - hbmp = NULL; - } - - if (pages[TAB_CONFIG]) - { - DestroyWindow(pages[TAB_CONFIG]); - pages[TAB_CONFIG] = NULL; - } - - startupdlg = NULL; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case WIN_STARTWIN_CANCEL: - if (mode == TAB_CONFIG) done = 0; - else quitevent++; - return TRUE; - case WIN_STARTWIN_START: done = 1; return TRUE; - } - return FALSE; - - case WM_CTLCOLORSTATIC: - if ((HWND)lParam == pages[TAB_MESSAGES]) - return (BOOL)(intptr_t)GetSysColorBrush(COLOR_WINDOW); - break; - - default: break; - } - - return FALSE; -} - - -int startwin_open(void) -{ - INITCOMMONCONTROLSEX icc; - if (startupdlg) return 1; - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_TAB_CLASSES; - InitCommonControlsEx(&icc); - startupdlg = CreateDialog((HINSTANCE)win_gethinstance(), MAKEINTRESOURCE(WIN_STARTWIN), NULL, startup_dlgproc); - if (startupdlg) - { - SetPage(TAB_MESSAGES); - EnableConfig(0); - return 0; - } - return -1; -} - -int startwin_close(void) -{ - if (!startupdlg) return 1; - DestroyWindow(startupdlg); - startupdlg = NULL; - return 0; -} - -int startwin_puts(const char *buf) -{ - const char *p = NULL, *q = NULL; - char workbuf[1024]; - static int newline = 0; - int curlen, linesbefore, linesafter; - HWND edctl; - int vis; - - if (!startupdlg) return 1; - - edctl = pages[TAB_MESSAGES]; - if (!edctl) return -1; - - vis = ((int)SendMessage(GetDlgItem(startupdlg, WIN_STARTWIN_TABCTL), TCM_GETCURSEL,0,0) == TAB_MESSAGES); - - if (vis) SendMessage(edctl, WM_SETREDRAW, FALSE,0); - curlen = SendMessage(edctl, WM_GETTEXTLENGTH, 0,0); - SendMessage(edctl, EM_SETSEL, (WPARAM)curlen, (LPARAM)curlen); - linesbefore = SendMessage(edctl, EM_GETLINECOUNT, 0,0); - p = buf; - while (*p) - { - if (newline) - { - SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)"\r\n"); - newline = 0; - } - q = p; - while (*q && *q != '\n') q++; - memcpy(workbuf, p, q-p); - if (*q == '\n') - { - if (!q[1]) - { - newline = 1; - workbuf[q-p] = 0; - } - else - { - workbuf[q-p] = '\r'; - workbuf[q-p+1] = '\n'; - workbuf[q-p+2] = 0; - } - p = q+1; - } - else - { - workbuf[q-p] = 0; - p = q; - } - SendMessage(edctl, EM_REPLACESEL, 0, (LPARAM)workbuf); - } - linesafter = SendMessage(edctl, EM_GETLINECOUNT, 0,0); - SendMessage(edctl, EM_LINESCROLL, 0, linesafter-linesbefore); - if (vis) SendMessage(edctl, WM_SETREDRAW, TRUE,0); - return 0; -} - -int startwin_settitle(const char *str) -{ - if (!startupdlg) return 1; - SetWindowText(startupdlg, str); - return 0; -} - -int startwin_idle(void *v) -{ - if (!startupdlg || !IsWindow(startupdlg)) return 0; - if (IsDialogMessage(startupdlg, (MSG *)v)) return 1; - return 0; -} - -extern int xdimgame, ydimgame, bppgame, forcesetup; - -int startwin_run(void) -{ - MSG msg; - if (!startupdlg) return 1; - - done = -1; - - SetPage(TAB_CONFIG); - EnableConfig(1); - - settings.fullscreen = fullscreen; - settings.xdim3d = xdimgame; - settings.ydim3d = ydimgame; - settings.bpp3d = bppgame; - settings.forcesetup = forcesetup; - PopulateForm(); - - while (done < 0) - { - switch (GetMessage(&msg, NULL, 0,0)) - { - case 0: done = 1; break; - case -1: return -1; - default: - if (IsWindow(startupdlg) && IsDialogMessage(startupdlg, &msg)) break; - TranslateMessage(&msg); - DispatchMessage(&msg); - break; - } - } - - SetPage(TAB_MESSAGES); - EnableConfig(0); - if (done) - { - fullscreen = settings.fullscreen; - xdimgame = settings.xdim3d; - ydimgame = settings.ydim3d; - bppgame = settings.bpp3d; - forcesetup = settings.forcesetup; - } - - return done; -} diff --git a/source/kenbuild/src/startwin.game.h b/source/kenbuild/src/startwin.game.h deleted file mode 100644 index 154f2c68f..000000000 --- a/source/kenbuild/src/startwin.game.h +++ /dev/null @@ -1,17 +0,0 @@ -// resource ids -#define WIN_STARTWIN 1000 -#define WIN_STARTWINPAGE_CONFIG 2000 -#define WIN_STARTWIN_BITMAP 100 // banner bitmap -#define WIN_STARTWIN_TABCTL 101 -#define WIN_STARTWIN_CANCEL IDCANCEL -#define WIN_STARTWIN_START IDOK - -#define WIN_STARTWIN_MESSAGES 104 // output list box - -#define RSRC_ICON 100 -#define RSRC_BMP 200 - -// config page -#define IDCFULLSCREEN 100 -#define IDC3DVMODE 101 -#define IDCALWAYSSHOW 102 diff --git a/source/lpeg/LICENSE.txt b/source/lpeg/LICENSE.txt deleted file mode 100644 index 272058a15..000000000 --- a/source/lpeg/LICENSE.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright © 2007-2017 Lua.org, PUC-Rio. - -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 THE AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/source/lpeg/src/lpcap.c b/source/lpeg/src/lpcap.c deleted file mode 100644 index 978ad90e8..000000000 --- a/source/lpeg/src/lpcap.c +++ /dev/null @@ -1,537 +0,0 @@ -/* -** $Id: lpcap.c,v 1.6 2015/06/15 16:09:57 roberto Exp $ -** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) -*/ - -#include "elua.h" -#include "elauxlib.h" - -#include "lpcap.h" -#include "lptypes.h" - - -#define captype(cap) ((cap)->kind) - -#define isclosecap(cap) (captype(cap) == Cclose) - -#define closeaddr(c) ((c)->s + (c)->siz - 1) - -#define isfullcap(cap) ((cap)->siz != 0) - -#define getfromktable(cs,v) lua_rawgeti((cs)->L, ktableidx((cs)->ptop), v) - -#define pushluaval(cs) getfromktable(cs, (cs)->cap->idx) - - - -/* -** Put at the cache for Lua values the value indexed by 'v' in ktable -** of the running pattern (if it is not there yet); returns its index. -*/ -static int updatecache (CapState *cs, int v) { - int idx = cs->ptop + 1; /* stack index of cache for Lua values */ - if (v != cs->valuecached) { /* not there? */ - getfromktable(cs, v); /* get value from 'ktable' */ - lua_replace(cs->L, idx); /* put it at reserved stack position */ - cs->valuecached = v; /* keep track of what is there */ - } - return idx; -} - - -static int pushcapture (CapState *cs); - - -/* -** Goes back in a list of captures looking for an open capture -** corresponding to a close -*/ -static Capture *findopen (Capture *cap) { - int n = 0; /* number of closes waiting an open */ - for (;;) { - cap--; - if (isclosecap(cap)) n++; /* one more open to skip */ - else if (!isfullcap(cap)) - if (n-- == 0) return cap; - } -} - - -/* -** Go to the next capture -*/ -static void nextcap (CapState *cs) { - Capture *cap = cs->cap; - if (!isfullcap(cap)) { /* not a single capture? */ - int n = 0; /* number of opens waiting a close */ - for (;;) { /* look for corresponding close */ - cap++; - if (isclosecap(cap)) { - if (n-- == 0) break; - } - else if (!isfullcap(cap)) n++; - } - } - cs->cap = cap + 1; /* + 1 to skip last close (or entire single capture) */ -} - - -/* -** Push on the Lua stack all values generated by nested captures inside -** the current capture. Returns number of values pushed. 'addextra' -** makes it push the entire match after all captured values. The -** entire match is pushed also if there are no other nested values, -** so the function never returns zero. -*/ -static int pushnestedvalues (CapState *cs, int addextra) { - Capture *co = cs->cap; - if (isfullcap(cs->cap++)) { /* no nested captures? */ - lua_pushlstring(cs->L, co->s, co->siz - 1); /* push whole match */ - return 1; /* that is it */ - } - else { - int n = 0; - while (!isclosecap(cs->cap)) /* repeat for all nested patterns */ - n += pushcapture(cs); - if (addextra || n == 0) { /* need extra? */ - lua_pushlstring(cs->L, co->s, cs->cap->s - co->s); /* push whole match */ - n++; - } - cs->cap++; /* skip close entry */ - return n; - } -} - - -/* -** Push only the first value generated by nested captures -*/ -static void pushonenestedvalue (CapState *cs) { - int n = pushnestedvalues(cs, 0); - if (n > 1) - lua_pop(cs->L, n - 1); /* pop extra values */ -} - - -/* -** Try to find a named group capture with the name given at the top of -** the stack; goes backward from 'cap'. -*/ -static Capture *findback (CapState *cs, Capture *cap) { - lua_State *L = cs->L; - while (cap-- > cs->ocap) { /* repeat until end of list */ - if (isclosecap(cap)) - cap = findopen(cap); /* skip nested captures */ - else if (!isfullcap(cap)) - continue; /* opening an enclosing capture: skip and get previous */ - if (captype(cap) == Cgroup) { - getfromktable(cs, cap->idx); /* get group name */ - if (lp_equal(L, -2, -1)) { /* right group? */ - lua_pop(L, 2); /* remove reference name and group name */ - return cap; - } - else lua_pop(L, 1); /* remove group name */ - } - } - luaL_error(L, "back reference '%s' not found", lua_tostring(L, -1)); - return NULL; /* to avoid warnings */ -} - - -/* -** Back-reference capture. Return number of values pushed. -*/ -static int backrefcap (CapState *cs) { - int n; - Capture *curr = cs->cap; - pushluaval(cs); /* reference name */ - cs->cap = findback(cs, curr); /* find corresponding group */ - n = pushnestedvalues(cs, 0); /* push group's values */ - cs->cap = curr + 1; - return n; -} - - -/* -** Table capture: creates a new table and populates it with nested -** captures. -*/ -static int tablecap (CapState *cs) { - lua_State *L = cs->L; - int n = 0; - lua_newtable(L); - if (isfullcap(cs->cap++)) - return 1; /* table is empty */ - while (!isclosecap(cs->cap)) { - if (captype(cs->cap) == Cgroup && cs->cap->idx != 0) { /* named group? */ - pushluaval(cs); /* push group name */ - pushonenestedvalue(cs); - lua_settable(L, -3); - } - else { /* not a named group */ - int i; - int k = pushcapture(cs); - for (i = k; i > 0; i--) /* store all values into table */ - lua_rawseti(L, -(i + 1), n + i); - n += k; - } - } - cs->cap++; /* skip close entry */ - return 1; /* number of values pushed (only the table) */ -} - - -/* -** Table-query capture -*/ -static int querycap (CapState *cs) { - int idx = cs->cap->idx; - pushonenestedvalue(cs); /* get nested capture */ - lua_gettable(cs->L, updatecache(cs, idx)); /* query cap. value at table */ - if (!lua_isnil(cs->L, -1)) - return 1; - else { /* no value */ - lua_pop(cs->L, 1); /* remove nil */ - return 0; - } -} - - -/* -** Fold capture -*/ -static int foldcap (CapState *cs) { - int n; - lua_State *L = cs->L; - int idx = cs->cap->idx; - if (isfullcap(cs->cap++) || /* no nested captures? */ - isclosecap(cs->cap) || /* no nested captures (large subject)? */ - (n = pushcapture(cs)) == 0) /* nested captures with no values? */ - return luaL_error(L, "no initial value for fold capture"); - if (n > 1) - lua_pop(L, n - 1); /* leave only one result for accumulator */ - while (!isclosecap(cs->cap)) { - lua_pushvalue(L, updatecache(cs, idx)); /* get folding function */ - lua_insert(L, -2); /* put it before accumulator */ - n = pushcapture(cs); /* get next capture's values */ - lua_call(L, n + 1, 1); /* call folding function */ - } - cs->cap++; /* skip close entry */ - return 1; /* only accumulator left on the stack */ -} - - -/* -** Function capture -*/ -static int functioncap (CapState *cs) { - int n; - int top = lua_gettop(cs->L); - pushluaval(cs); /* push function */ - n = pushnestedvalues(cs, 0); /* push nested captures */ - lua_call(cs->L, n, LUA_MULTRET); /* call function */ - return lua_gettop(cs->L) - top; /* return function's results */ -} - - -/* -** Select capture -*/ -static int numcap (CapState *cs) { - int idx = cs->cap->idx; /* value to select */ - if (idx == 0) { /* no values? */ - nextcap(cs); /* skip entire capture */ - return 0; /* no value produced */ - } - else { - int n = pushnestedvalues(cs, 0); - if (n < idx) /* invalid index? */ - return luaL_error(cs->L, "no capture '%d'", idx); - else { - lua_pushvalue(cs->L, -(n - idx + 1)); /* get selected capture */ - lua_replace(cs->L, -(n + 1)); /* put it in place of 1st capture */ - lua_pop(cs->L, n - 1); /* remove other captures */ - return 1; - } - } -} - - -/* -** Return the stack index of the first runtime capture in the given -** list of captures (or zero if no runtime captures) -*/ -int finddyncap (Capture *cap, Capture *last) { - for (; cap < last; cap++) { - if (cap->kind == Cruntime) - return cap->idx; /* stack position of first capture */ - } - return 0; /* no dynamic captures in this segment */ -} - - -/* -** Calls a runtime capture. Returns number of captures removed by -** the call, including the initial Cgroup. (Captures to be added are -** on the Lua stack.) -*/ -int runtimecap (CapState *cs, Capture *close, const char *s, int *rem) { - int n, id; - lua_State *L = cs->L; - int otop = lua_gettop(L); - Capture *open = findopen(close); - assert(captype(open) == Cgroup); - id = finddyncap(open, close); /* get first dynamic capture argument */ - close->kind = Cclose; /* closes the group */ - close->s = s; - cs->cap = open; cs->valuecached = 0; /* prepare capture state */ - luaL_checkstack(L, 4, "too many runtime captures"); - pushluaval(cs); /* push function to be called */ - lua_pushvalue(L, SUBJIDX); /* push original subject */ - lua_pushinteger(L, s - cs->s + 1); /* push current position */ - n = pushnestedvalues(cs, 0); /* push nested captures */ - lua_call(L, n + 2, LUA_MULTRET); /* call dynamic function */ - if (id > 0) { /* are there old dynamic captures to be removed? */ - int i; - for (i = id; i <= otop; i++) - lua_remove(L, id); /* remove old dynamic captures */ - *rem = otop - id + 1; /* total number of dynamic captures removed */ - } - else - *rem = 0; /* no dynamic captures removed */ - return close - open; /* number of captures of all kinds removed */ -} - - -/* -** Auxiliary structure for substitution and string captures: keep -** information about nested captures for future use, avoiding to push -** string results into Lua -*/ -typedef struct StrAux { - int isstring; /* whether capture is a string */ - union { - Capture *cp; /* if not a string, respective capture */ - struct { /* if it is a string... */ - const char *s; /* ... starts here */ - const char *e; /* ... ends here */ - } s; - } u; -} StrAux; - -#define MAXSTRCAPS 10 - -/* -** Collect values from current capture into array 'cps'. Current -** capture must be Cstring (first call) or Csimple (recursive calls). -** (In first call, fills %0 with whole match for Cstring.) -** Returns number of elements in the array that were filled. -*/ -static int getstrcaps (CapState *cs, StrAux *cps, int n) { - int k = n++; - cps[k].isstring = 1; /* get string value */ - cps[k].u.s.s = cs->cap->s; /* starts here */ - if (!isfullcap(cs->cap++)) { /* nested captures? */ - while (!isclosecap(cs->cap)) { /* traverse them */ - if (n >= MAXSTRCAPS) /* too many captures? */ - nextcap(cs); /* skip extra captures (will not need them) */ - else if (captype(cs->cap) == Csimple) /* string? */ - n = getstrcaps(cs, cps, n); /* put info. into array */ - else { - cps[n].isstring = 0; /* not a string */ - cps[n].u.cp = cs->cap; /* keep original capture */ - nextcap(cs); - n++; - } - } - cs->cap++; /* skip close */ - } - cps[k].u.s.e = closeaddr(cs->cap - 1); /* ends here */ - return n; -} - - -/* -** add next capture value (which should be a string) to buffer 'b' -*/ -static int addonestring (luaL_Buffer *b, CapState *cs, const char *what); - - -/* -** String capture: add result to buffer 'b' (instead of pushing -** it into the stack) -*/ -static void stringcap (luaL_Buffer *b, CapState *cs) { - StrAux cps[MAXSTRCAPS]; - int n; - size_t len, i; - const char *fmt; /* format string */ - fmt = lua_tolstring(cs->L, updatecache(cs, cs->cap->idx), &len); - n = getstrcaps(cs, cps, 0) - 1; /* collect nested captures */ - for (i = 0; i < len; i++) { /* traverse them */ - if (fmt[i] != '%') /* not an escape? */ - luaL_addchar(b, fmt[i]); /* add it to buffer */ - else if (fmt[++i] < '0' || fmt[i] > '9') /* not followed by a digit? */ - luaL_addchar(b, fmt[i]); /* add to buffer */ - else { - int l = fmt[i] - '0'; /* capture index */ - if (l > n) - luaL_error(cs->L, "invalid capture index (%d)", l); - else if (cps[l].isstring) - luaL_addlstring(b, cps[l].u.s.s, cps[l].u.s.e - cps[l].u.s.s); - else { - Capture *curr = cs->cap; - cs->cap = cps[l].u.cp; /* go back to evaluate that nested capture */ - if (!addonestring(b, cs, "capture")) - luaL_error(cs->L, "no values in capture index %d", l); - cs->cap = curr; /* continue from where it stopped */ - } - } - } -} - - -/* -** Substitution capture: add result to buffer 'b' -*/ -static void substcap (luaL_Buffer *b, CapState *cs) { - const char *curr = cs->cap->s; - if (isfullcap(cs->cap)) /* no nested captures? */ - luaL_addlstring(b, curr, cs->cap->siz - 1); /* keep original text */ - else { - cs->cap++; /* skip open entry */ - while (!isclosecap(cs->cap)) { /* traverse nested captures */ - const char *next = cs->cap->s; - luaL_addlstring(b, curr, next - curr); /* add text up to capture */ - if (addonestring(b, cs, "replacement")) - curr = closeaddr(cs->cap - 1); /* continue after match */ - else /* no capture value */ - curr = next; /* keep original text in final result */ - } - luaL_addlstring(b, curr, cs->cap->s - curr); /* add last piece of text */ - } - cs->cap++; /* go to next capture */ -} - - -/* -** Evaluates a capture and adds its first value to buffer 'b'; returns -** whether there was a value -*/ -static int addonestring (luaL_Buffer *b, CapState *cs, const char *what) { - switch (captype(cs->cap)) { - case Cstring: - stringcap(b, cs); /* add capture directly to buffer */ - return 1; - case Csubst: - substcap(b, cs); /* add capture directly to buffer */ - return 1; - default: { - lua_State *L = cs->L; - int n = pushcapture(cs); - if (n > 0) { - if (n > 1) lua_pop(L, n - 1); /* only one result */ - if (!lua_isstring(L, -1)) - luaL_error(L, "invalid %s value (a %s)", what, luaL_typename(L, -1)); - luaL_addvalue(b); - } - return n; - } - } -} - - -/* -** Push all values of the current capture into the stack; returns -** number of values pushed -*/ -static int pushcapture (CapState *cs) { - lua_State *L = cs->L; - luaL_checkstack(L, 4, "too many captures"); - switch (captype(cs->cap)) { - case Cposition: { - lua_pushinteger(L, cs->cap->s - cs->s + 1); - cs->cap++; - return 1; - } - case Cconst: { - pushluaval(cs); - cs->cap++; - return 1; - } - case Carg: { - int arg = (cs->cap++)->idx; - if (arg + FIXEDARGS > cs->ptop) - return luaL_error(L, "reference to absent extra argument #%d", arg); - lua_pushvalue(L, arg + FIXEDARGS); - return 1; - } - case Csimple: { - int k = pushnestedvalues(cs, 1); - lua_insert(L, -k); /* make whole match be first result */ - return k; - } - case Cruntime: { - lua_pushvalue(L, (cs->cap++)->idx); /* value is in the stack */ - return 1; - } - case Cstring: { - luaL_Buffer b; - luaL_buffinit(L, &b); - stringcap(&b, cs); - luaL_pushresult(&b); - return 1; - } - case Csubst: { - luaL_Buffer b; - luaL_buffinit(L, &b); - substcap(&b, cs); - luaL_pushresult(&b); - return 1; - } - case Cgroup: { - if (cs->cap->idx == 0) /* anonymous group? */ - return pushnestedvalues(cs, 0); /* add all nested values */ - else { /* named group: add no values */ - nextcap(cs); /* skip capture */ - return 0; - } - } - case Cbackref: return backrefcap(cs); - case Ctable: return tablecap(cs); - case Cfunction: return functioncap(cs); - case Cnum: return numcap(cs); - case Cquery: return querycap(cs); - case Cfold: return foldcap(cs); - default: assert(0); return 0; - } -} - - -/* -** Prepare a CapState structure and traverse the entire list of -** captures in the stack pushing its results. 's' is the subject -** string, 'r' is the final position of the match, and 'ptop' -** the index in the stack where some useful values were pushed. -** Returns the number of results pushed. (If the list produces no -** results, push the final position of the match.) -*/ -int getcaptures (lua_State *L, const char *s, const char *r, int ptop) { - Capture *capture = (Capture *)lua_touserdata(L, caplistidx(ptop)); - int n = 0; - if (!isclosecap(capture)) { /* is there any capture? */ - CapState cs; - cs.ocap = cs.cap = capture; cs.L = L; - cs.s = s; cs.valuecached = 0; cs.ptop = ptop; - do { /* collect their values */ - n += pushcapture(&cs); - } while (!isclosecap(cs.cap)); - } - if (n == 0) { /* no capture values? */ - lua_pushinteger(L, r - s + 1); /* return only end position */ - n = 1; - } - return n; -} - - diff --git a/source/lpeg/src/lpcap.h b/source/lpeg/src/lpcap.h deleted file mode 100644 index 6133df2a0..000000000 --- a/source/lpeg/src/lpcap.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -** $Id: lpcap.h,v 1.3 2016/09/13 17:45:58 roberto Exp $ -*/ - -#if !defined(lpcap_h) -#define lpcap_h - - -#include "lptypes.h" - - -/* kinds of captures */ -typedef enum CapKind { - Cclose, /* not used in trees */ - Cposition, - Cconst, /* ktable[key] is Lua constant */ - Cbackref, /* ktable[key] is "name" of group to get capture */ - Carg, /* 'key' is arg's number */ - Csimple, /* next node is pattern */ - Ctable, /* next node is pattern */ - Cfunction, /* ktable[key] is function; next node is pattern */ - Cquery, /* ktable[key] is table; next node is pattern */ - Cstring, /* ktable[key] is string; next node is pattern */ - Cnum, /* numbered capture; 'key' is number of value to return */ - Csubst, /* substitution capture; next node is pattern */ - Cfold, /* ktable[key] is function; next node is pattern */ - Cruntime, /* not used in trees (is uses another type for tree) */ - Cgroup /* ktable[key] is group's "name" */ -} CapKind; - - -typedef struct Capture { - const char *s; /* subject position */ - unsigned short idx; /* extra info (group name, arg index, etc.) */ - byte kind; /* kind of capture */ - byte siz; /* size of full capture + 1 (0 = not a full capture) */ -} Capture; - - -typedef struct CapState { - Capture *cap; /* current capture */ - Capture *ocap; /* (original) capture list */ - lua_State *L; - int ptop; /* index of last argument to 'match' */ - const char *s; /* original string */ - int valuecached; /* value stored in cache slot */ -} CapState; - - -int runtimecap (CapState *cs, Capture *close, const char *s, int *rem); -int getcaptures (lua_State *L, const char *s, const char *r, int ptop); -int finddyncap (Capture *cap, Capture *last); - -#endif - - diff --git a/source/lpeg/src/lpcode.c b/source/lpeg/src/lpcode.c deleted file mode 100644 index 2d33febd4..000000000 --- a/source/lpeg/src/lpcode.c +++ /dev/null @@ -1,1014 +0,0 @@ -/* -** $Id: lpcode.c,v 1.24 2016/09/15 17:46:13 roberto Exp $ -** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) -*/ - -#include - - -#include "elua.h" -#include "elauxlib.h" - -#include "lptypes.h" -#include "lpcode.h" - - -/* signals a "no-instruction */ -#define NOINST -1 - - - -static const Charset fullset_ = - {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; - -static const Charset *fullset = &fullset_; - -/* -** {====================================================== -** Analysis and some optimizations -** ======================================================= -*/ - -/* -** Check whether a charset is empty (returns IFail), singleton (IChar), -** full (IAny), or none of those (ISet). When singleton, '*c' returns -** which character it is. (When generic set, the set was the input, -** so there is no need to return it.) -*/ -static Opcode charsettype (const byte *cs, int *c) { - int count = 0; /* number of characters in the set */ - int i; - int candidate = -1; /* candidate position for the singleton char */ - for (i = 0; i < CHARSETSIZE; i++) { /* for each byte */ - int b = cs[i]; - if (b == 0) { /* is byte empty? */ - if (count > 1) /* was set neither empty nor singleton? */ - return ISet; /* neither full nor empty nor singleton */ - /* else set is still empty or singleton */ - } - else if (b == 0xFF) { /* is byte full? */ - if (count < (i * BITSPERCHAR)) /* was set not full? */ - return ISet; /* neither full nor empty nor singleton */ - else count += BITSPERCHAR; /* set is still full */ - } - else if ((b & (b - 1)) == 0) { /* has byte only one bit? */ - if (count > 0) /* was set not empty? */ - return ISet; /* neither full nor empty nor singleton */ - else { /* set has only one char till now; track it */ - count++; - candidate = i; - } - } - else return ISet; /* byte is neither empty, full, nor singleton */ - } - switch (count) { - case 0: return IFail; /* empty set */ - case 1: { /* singleton; find character bit inside byte */ - int b = cs[candidate]; - *c = candidate * BITSPERCHAR; - if ((b & 0xF0) != 0) { *c += 4; b >>= 4; } - if ((b & 0x0C) != 0) { *c += 2; b >>= 2; } - if ((b & 0x02) != 0) { *c += 1; } - return IChar; - } - default: { - assert(count == CHARSETSIZE * BITSPERCHAR); /* full set */ - return IAny; - } - } -} - - -/* -** A few basic operations on Charsets -*/ -static void cs_complement (Charset *cs) { - loopset(i, cs->cs[i] = ~cs->cs[i]); -} - -static int cs_equal (const byte *cs1, const byte *cs2) { - loopset(i, if (cs1[i] != cs2[i]) return 0); - return 1; -} - -static int cs_disjoint (const Charset *cs1, const Charset *cs2) { - loopset(i, if ((cs1->cs[i] & cs2->cs[i]) != 0) return 0;) - return 1; -} - - -/* -** If 'tree' is a 'char' pattern (TSet, TChar, TAny), convert it into a -** charset and return 1; else return 0. -*/ -int tocharset (TTree *tree, Charset *cs) { - switch (tree->tag) { - case TSet: { /* copy set */ - loopset(i, cs->cs[i] = treebuffer(tree)[i]); - return 1; - } - case TChar: { /* only one char */ - assert(0 <= tree->u.n && tree->u.n <= UCHAR_MAX); - loopset(i, cs->cs[i] = 0); /* erase all chars */ - setchar(cs->cs, tree->u.n); /* add that one */ - return 1; - } - case TAny: { - loopset(i, cs->cs[i] = 0xFF); /* add all characters to the set */ - return 1; - } - default: return 0; - } -} - - -/* -** Visit a TCall node taking care to stop recursion. If node not yet -** visited, return 'f(sib2(tree))', otherwise return 'def' (default -** value) -*/ -static int callrecursive (TTree *tree, int f (TTree *t), int def) { - int key = tree->key; - assert(tree->tag == TCall); - assert(sib2(tree)->tag == TRule); - if (key == 0) /* node already visited? */ - return def; /* return default value */ - else { /* first visit */ - int result; - tree->key = 0; /* mark call as already visited */ - result = f(sib2(tree)); /* go to called rule */ - tree->key = key; /* restore tree */ - return result; - } -} - - -/* -** Check whether a pattern tree has captures -*/ -int hascaptures (TTree *tree) { - tailcall: - switch (tree->tag) { - case TCapture: case TRunTime: - return 1; - case TCall: - return callrecursive(tree, hascaptures, 0); - case TRule: /* do not follow siblings */ - tree = sib1(tree); goto tailcall; - case TOpenCall: assert(0); - default: { - switch (numsiblings[tree->tag]) { - case 1: /* return hascaptures(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case 2: - if (hascaptures(sib1(tree))) - return 1; - /* else return hascaptures(sib2(tree)); */ - tree = sib2(tree); goto tailcall; - default: assert(numsiblings[tree->tag] == 0); return 0; - } - } - } -} - - -/* -** Checks how a pattern behaves regarding the empty string, -** in one of two different ways: -** A pattern is *nullable* if it can match without consuming any character; -** A pattern is *nofail* if it never fails for any string -** (including the empty string). -** The difference is only for predicates and run-time captures; -** for other patterns, the two properties are equivalent. -** (With predicates, &'a' is nullable but not nofail. Of course, -** nofail => nullable.) -** These functions are all convervative in the following way: -** p is nullable => nullable(p) -** nofail(p) => p cannot fail -** The function assumes that TOpenCall is not nullable; -** this will be checked again when the grammar is fixed. -** Run-time captures can do whatever they want, so the result -** is conservative. -*/ -int checkaux (TTree *tree, int pred) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - case TFalse: case TOpenCall: - return 0; /* not nullable */ - case TRep: case TTrue: - return 1; /* no fail */ - case TNot: case TBehind: /* can match empty, but can fail */ - if (pred == PEnofail) return 0; - else return 1; /* PEnullable */ - case TAnd: /* can match empty; fail iff body does */ - if (pred == PEnullable) return 1; - /* else return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TRunTime: /* can fail; match empty iff body does */ - if (pred == PEnofail) return 0; - /* else return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TSeq: - if (!checkaux(sib1(tree), pred)) return 0; - /* else return checkaux(sib2(tree), pred); */ - tree = sib2(tree); goto tailcall; - case TChoice: - if (checkaux(sib2(tree), pred)) return 1; - /* else return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TCapture: case TGrammar: case TRule: - /* return checkaux(sib1(tree), pred); */ - tree = sib1(tree); goto tailcall; - case TCall: /* return checkaux(sib2(tree), pred); */ - tree = sib2(tree); goto tailcall; - default: assert(0); return 0; - } -} - - -/* -** number of characters to match a pattern (or -1 if variable) -*/ -int fixedlen (TTree *tree) { - int len = 0; /* to accumulate in tail calls */ - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - return len + 1; - case TFalse: case TTrue: case TNot: case TAnd: case TBehind: - return len; - case TRep: case TRunTime: case TOpenCall: - return -1; - case TCapture: case TRule: case TGrammar: - /* return fixedlen(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case TCall: { - int n1 = callrecursive(tree, fixedlen, -1); - if (n1 < 0) - return -1; - else - return len + n1; - } - case TSeq: { - int n1 = fixedlen(sib1(tree)); - if (n1 < 0) - return -1; - /* else return fixedlen(sib2(tree)) + len; */ - len += n1; tree = sib2(tree); goto tailcall; - } - case TChoice: { - int n1 = fixedlen(sib1(tree)); - int n2 = fixedlen(sib2(tree)); - if (n1 != n2 || n1 < 0) - return -1; - else - return len + n1; - } - default: assert(0); return 0; - }; -} - - -/* -** Computes the 'first set' of a pattern. -** The result is a conservative aproximation: -** match p ax -> x (for some x) ==> a belongs to first(p) -** or -** a not in first(p) ==> match p ax -> fail (for all x) -** -** The set 'follow' is the first set of what follows the -** pattern (full set if nothing follows it). -** -** The function returns 0 when this resulting set can be used for -** test instructions that avoid the pattern altogether. -** A non-zero return can happen for two reasons: -** 1) match p '' -> '' ==> return has bit 1 set -** (tests cannot be used because they would always fail for an empty input); -** 2) there is a match-time capture ==> return has bit 2 set -** (optimizations should not bypass match-time captures). -*/ -static int getfirst (TTree *tree, const Charset *follow, Charset *firstset) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: { - tocharset(tree, firstset); - return 0; - } - case TTrue: { - loopset(i, firstset->cs[i] = follow->cs[i]); - return 1; /* accepts the empty string */ - } - case TFalse: { - loopset(i, firstset->cs[i] = 0); - return 0; - } - case TChoice: { - Charset csaux; - int e1 = getfirst(sib1(tree), follow, firstset); - int e2 = getfirst(sib2(tree), follow, &csaux); - loopset(i, firstset->cs[i] |= csaux.cs[i]); - return e1 | e2; - } - case TSeq: { - if (!nullable(sib1(tree))) { - /* when p1 is not nullable, p2 has nothing to contribute; - return getfirst(sib1(tree), fullset, firstset); */ - tree = sib1(tree); follow = fullset; goto tailcall; - } - else { /* FIRST(p1 p2, fl) = FIRST(p1, FIRST(p2, fl)) */ - Charset csaux; - int e2 = getfirst(sib2(tree), follow, &csaux); - int e1 = getfirst(sib1(tree), &csaux, firstset); - if (e1 == 0) return 0; /* 'e1' ensures that first can be used */ - else if ((e1 | e2) & 2) /* one of the children has a matchtime? */ - return 2; /* pattern has a matchtime capture */ - else return e2; /* else depends on 'e2' */ - } - } - case TRep: { - getfirst(sib1(tree), follow, firstset); - loopset(i, firstset->cs[i] |= follow->cs[i]); - return 1; /* accept the empty string */ - } - case TCapture: case TGrammar: case TRule: { - /* return getfirst(sib1(tree), follow, firstset); */ - tree = sib1(tree); goto tailcall; - } - case TRunTime: { /* function invalidates any follow info. */ - int e = getfirst(sib1(tree), fullset, firstset); - if (e) return 2; /* function is not "protected"? */ - else return 0; /* pattern inside capture ensures first can be used */ - } - case TCall: { - /* return getfirst(sib2(tree), follow, firstset); */ - tree = sib2(tree); goto tailcall; - } - case TAnd: { - int e = getfirst(sib1(tree), follow, firstset); - loopset(i, firstset->cs[i] &= follow->cs[i]); - return e; - } - case TNot: { - if (tocharset(sib1(tree), firstset)) { - cs_complement(firstset); - return 1; - } - /* else go through */ - } - case TBehind: { /* instruction gives no new information */ - /* call 'getfirst' only to check for math-time captures */ - int e = getfirst(sib1(tree), follow, firstset); - loopset(i, firstset->cs[i] = follow->cs[i]); /* uses follow */ - return e | 1; /* always can accept the empty string */ - } - default: assert(0); return 0; - } -} - - -/* -** If 'headfail(tree)' true, then 'tree' can fail only depending on the -** next character of the subject. -*/ -static int headfail (TTree *tree) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: case TFalse: - return 1; - case TTrue: case TRep: case TRunTime: case TNot: - case TBehind: - return 0; - case TCapture: case TGrammar: case TRule: case TAnd: - tree = sib1(tree); goto tailcall; /* return headfail(sib1(tree)); */ - case TCall: - tree = sib2(tree); goto tailcall; /* return headfail(sib2(tree)); */ - case TSeq: - if (!nofail(sib2(tree))) return 0; - /* else return headfail(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case TChoice: - if (!headfail(sib1(tree))) return 0; - /* else return headfail(sib2(tree)); */ - tree = sib2(tree); goto tailcall; - default: assert(0); return 0; - } -} - - -/* -** Check whether the code generation for the given tree can benefit -** from a follow set (to avoid computing the follow set when it is -** not needed) -*/ -static int needfollow (TTree *tree) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - case TFalse: case TTrue: case TAnd: case TNot: - case TRunTime: case TGrammar: case TCall: case TBehind: - return 0; - case TChoice: case TRep: - return 1; - case TCapture: - tree = sib1(tree); goto tailcall; - case TSeq: - tree = sib2(tree); goto tailcall; - default: assert(0); return 0; - } -} - -/* }====================================================== */ - - - -/* -** {====================================================== -** Code generation -** ======================================================= -*/ - - -/* -** size of an instruction -*/ -int sizei (const Instruction *i) { - switch((Opcode)i->i.code) { - case ISet: case ISpan: return CHARSETINSTSIZE; - case ITestSet: return CHARSETINSTSIZE + 1; - case ITestChar: case ITestAny: case IChoice: case IJmp: case ICall: - case IOpenCall: case ICommit: case IPartialCommit: case IBackCommit: - return 2; - default: return 1; - } -} - - -/* -** state for the compiler -*/ -typedef struct CompileState { - Pattern *p; /* pattern being compiled */ - int ncode; /* next position in p->code to be filled */ - lua_State *L; -} CompileState; - - -/* -** code generation is recursive; 'opt' indicates that the code is being -** generated as the last thing inside an optional pattern (so, if that -** code is optional too, it can reuse the 'IChoice' already in place for -** the outer pattern). 'tt' points to a previous test protecting this -** code (or NOINST). 'fl' is the follow set of the pattern. -*/ -static void codegen (CompileState *compst, TTree *tree, int opt, int tt, - const Charset *fl); - - -void realloccode (lua_State *L, Pattern *p, int nsize) { - void *ud; - lua_Alloc f = lua_getallocf(L, &ud); - void *newblock = f(ud, p->code, p->codesize * sizeof(Instruction), - nsize * sizeof(Instruction)); - if (newblock == NULL && nsize > 0) - luaL_error(L, "not enough memory"); - p->code = (Instruction *)newblock; - p->codesize = nsize; -} - - -static int nextinstruction (CompileState *compst) { - int size = compst->p->codesize; - if (compst->ncode >= size) - realloccode(compst->L, compst->p, size * 2); - return compst->ncode++; -} - - -#define getinstr(cs,i) ((cs)->p->code[i]) - - -static int addinstruction (CompileState *compst, Opcode op, int aux) { - int i = nextinstruction(compst); - getinstr(compst, i).i.code = op; - getinstr(compst, i).i.aux = aux; - return i; -} - - -/* -** Add an instruction followed by space for an offset (to be set later) -*/ -static int addoffsetinst (CompileState *compst, Opcode op) { - int i = addinstruction(compst, op, 0); /* instruction */ - addinstruction(compst, (Opcode)0, 0); /* open space for offset */ - assert(op == ITestSet || sizei(&getinstr(compst, i)) == 2); - return i; -} - - -/* -** Set the offset of an instruction -*/ -static void setoffset (CompileState *compst, int instruction, int offset) { - getinstr(compst, instruction + 1).offset = offset; -} - - -/* -** Add a capture instruction: -** 'op' is the capture instruction; 'cap' the capture kind; -** 'key' the key into ktable; 'aux' is the optional capture offset -** -*/ -static int addinstcap (CompileState *compst, Opcode op, int cap, int key, - int aux) { - int i = addinstruction(compst, op, joinkindoff(cap, aux)); - getinstr(compst, i).i.key = key; - return i; -} - - -#define gethere(compst) ((compst)->ncode) - -#define target(code,i) ((i) + code[i + 1].offset) - - -/* -** Patch 'instruction' to jump to 'target' -*/ -static void jumptothere (CompileState *compst, int instruction, int target) { - if (instruction >= 0) - setoffset(compst, instruction, target - instruction); -} - - -/* -** Patch 'instruction' to jump to current position -*/ -static void jumptohere (CompileState *compst, int instruction) { - jumptothere(compst, instruction, gethere(compst)); -} - - -/* -** Code an IChar instruction, or IAny if there is an equivalent -** test dominating it -*/ -static void codechar (CompileState *compst, int c, int tt) { - if (tt >= 0 && getinstr(compst, tt).i.code == ITestChar && - getinstr(compst, tt).i.aux == c) - addinstruction(compst, IAny, 0); - else - addinstruction(compst, IChar, c); -} - - -/* -** Add a charset posfix to an instruction -*/ -static void addcharset (CompileState *compst, const byte *cs) { - int p = gethere(compst); - int i; - for (i = 0; i < (int)CHARSETINSTSIZE - 1; i++) - nextinstruction(compst); /* space for buffer */ - /* fill buffer with charset */ - loopset(j, getinstr(compst, p).buff[j] = cs[j]); -} - - -/* -** code a char set, optimizing unit sets for IChar, "complete" -** sets for IAny, and empty sets for IFail; also use an IAny -** when instruction is dominated by an equivalent test. -*/ -static void codecharset (CompileState *compst, const byte *cs, int tt) { - int c = 0; /* (=) to avoid warnings */ - Opcode op = charsettype(cs, &c); - switch (op) { - case IChar: codechar(compst, c, tt); break; - case ISet: { /* non-trivial set? */ - if (tt >= 0 && getinstr(compst, tt).i.code == ITestSet && - cs_equal(cs, getinstr(compst, tt + 2).buff)) - addinstruction(compst, IAny, 0); - else { - addinstruction(compst, ISet, 0); - addcharset(compst, cs); - } - break; - } - default: addinstruction(compst, op, c); break; - } -} - - -/* -** code a test set, optimizing unit sets for ITestChar, "complete" -** sets for ITestAny, and empty sets for IJmp (always fails). -** 'e' is true iff test should accept the empty string. (Test -** instructions in the current VM never accept the empty string.) -*/ -static int codetestset (CompileState *compst, Charset *cs, int e) { - if (e) return NOINST; /* no test */ - else { - int c = 0; - Opcode op = charsettype(cs->cs, &c); - switch (op) { - case IFail: return addoffsetinst(compst, IJmp); /* always jump */ - case IAny: return addoffsetinst(compst, ITestAny); - case IChar: { - int i = addoffsetinst(compst, ITestChar); - getinstr(compst, i).i.aux = c; - return i; - } - case ISet: { - int i = addoffsetinst(compst, ITestSet); - addcharset(compst, cs->cs); - return i; - } - default: assert(0); return 0; - } - } -} - - -/* -** Find the final destination of a sequence of jumps -*/ -static int finaltarget (Instruction *code, int i) { - while (code[i].i.code == IJmp) - i = target(code, i); - return i; -} - - -/* -** final label (after traversing any jumps) -*/ -static int finallabel (Instruction *code, int i) { - return finaltarget(code, target(code, i)); -} - - -/* -** == behind n;

(where n = fixedlen(p)) -*/ -static void codebehind (CompileState *compst, TTree *tree) { - if (tree->u.n > 0) - addinstruction(compst, IBehind, tree->u.n); - codegen(compst, sib1(tree), 0, NOINST, fullset); -} - - -/* -** Choice; optimizations: -** - when p1 is headfail or -** when first(p1) and first(p2) are disjoint, than -** a character not in first(p1) cannot go to p1, and a character -** in first(p1) cannot go to p2 (at it is not in first(p2)). -** (The optimization is not valid if p1 accepts the empty string, -** as then there is no character at all...) -** - when p2 is empty and opt is true; a IPartialCommit can reuse -** the Choice already active in the stack. -*/ -static void codechoice (CompileState *compst, TTree *p1, TTree *p2, int opt, - const Charset *fl) { - int emptyp2 = (p2->tag == TTrue); - Charset cs1, cs2; - int e1 = getfirst(p1, fullset, &cs1); - if (headfail(p1) || - (!e1 && (getfirst(p2, fl, &cs2), cs_disjoint(&cs1, &cs2)))) { - /* == test (fail(p1)) -> L1 ; p1 ; jmp L2; L1: p2; L2: */ - int test = codetestset(compst, &cs1, 0); - int jmp = NOINST; - codegen(compst, p1, 0, test, fl); - if (!emptyp2) - jmp = addoffsetinst(compst, IJmp); - jumptohere(compst, test); - codegen(compst, p2, opt, NOINST, fl); - jumptohere(compst, jmp); - } - else if (opt && emptyp2) { - /* p1? == IPartialCommit; p1 */ - jumptohere(compst, addoffsetinst(compst, IPartialCommit)); - codegen(compst, p1, 1, NOINST, fullset); - } - else { - /* == - test(first(p1)) -> L1; choice L1; ; commit L2; L1: ; L2: */ - int pcommit; - int test = codetestset(compst, &cs1, e1); - int pchoice = addoffsetinst(compst, IChoice); - codegen(compst, p1, emptyp2, test, fullset); - pcommit = addoffsetinst(compst, ICommit); - jumptohere(compst, pchoice); - jumptohere(compst, test); - codegen(compst, p2, opt, NOINST, fl); - jumptohere(compst, pcommit); - } -} - - -/* -** And predicate -** optimization: fixedlen(p) = n ==> <&p> ==

; behind n -** (valid only when 'p' has no captures) -*/ -static void codeand (CompileState *compst, TTree *tree, int tt) { - int n = fixedlen(tree); - if (n >= 0 && n <= MAXBEHIND && !hascaptures(tree)) { - codegen(compst, tree, 0, tt, fullset); - if (n > 0) - addinstruction(compst, IBehind, n); - } - else { /* default: Choice L1; p1; BackCommit L2; L1: Fail; L2: */ - int pcommit; - int pchoice = addoffsetinst(compst, IChoice); - codegen(compst, tree, 0, tt, fullset); - pcommit = addoffsetinst(compst, IBackCommit); - jumptohere(compst, pchoice); - addinstruction(compst, IFail, 0); - jumptohere(compst, pcommit); - } -} - - -/* -** Captures: if pattern has fixed (and not too big) length, and it -** has no nested captures, use a single IFullCapture instruction -** after the match; otherwise, enclose the pattern with OpenCapture - -** CloseCapture. -*/ -static void codecapture (CompileState *compst, TTree *tree, int tt, - const Charset *fl) { - int len = fixedlen(sib1(tree)); - if (len >= 0 && len <= MAXOFF && !hascaptures(sib1(tree))) { - codegen(compst, sib1(tree), 0, tt, fl); - addinstcap(compst, IFullCapture, tree->cap, tree->key, len); - } - else { - addinstcap(compst, IOpenCapture, tree->cap, tree->key, 0); - codegen(compst, sib1(tree), 0, tt, fl); - addinstcap(compst, ICloseCapture, Cclose, 0, 0); - } -} - - -static void coderuntime (CompileState *compst, TTree *tree, int tt) { - addinstcap(compst, IOpenCapture, Cgroup, tree->key, 0); - codegen(compst, sib1(tree), 0, tt, fullset); - addinstcap(compst, ICloseRunTime, Cclose, 0, 0); -} - - -/* -** Repetion; optimizations: -** When pattern is a charset, can use special instruction ISpan. -** When pattern is head fail, or if it starts with characters that -** are disjoint from what follows the repetions, a simple test -** is enough (a fail inside the repetition would backtrack to fail -** again in the following pattern, so there is no need for a choice). -** When 'opt' is true, the repetion can reuse the Choice already -** active in the stack. -*/ -static void coderep (CompileState *compst, TTree *tree, int opt, - const Charset *fl) { - Charset st; - if (tocharset(tree, &st)) { - addinstruction(compst, ISpan, 0); - addcharset(compst, st.cs); - } - else { - int e1 = getfirst(tree, fullset, &st); - if (headfail(tree) || (!e1 && cs_disjoint(&st, fl))) { - /* L1: test (fail(p1)) -> L2;

; jmp L1; L2: */ - int jmp; - int test = codetestset(compst, &st, 0); - codegen(compst, tree, 0, test, fullset); - jmp = addoffsetinst(compst, IJmp); - jumptohere(compst, test); - jumptothere(compst, jmp, test); - } - else { - /* test(fail(p1)) -> L2; choice L2; L1:

; partialcommit L1; L2: */ - /* or (if 'opt'): partialcommit L1; L1:

; partialcommit L1; */ - int commit, l2; - int test = codetestset(compst, &st, e1); - int pchoice = NOINST; - if (opt) - jumptohere(compst, addoffsetinst(compst, IPartialCommit)); - else - pchoice = addoffsetinst(compst, IChoice); - l2 = gethere(compst); - codegen(compst, tree, 0, NOINST, fullset); - commit = addoffsetinst(compst, IPartialCommit); - jumptothere(compst, commit, l2); - jumptohere(compst, pchoice); - jumptohere(compst, test); - } - } -} - - -/* -** Not predicate; optimizations: -** In any case, if first test fails, 'not' succeeds, so it can jump to -** the end. If pattern is headfail, that is all (it cannot fail -** in other parts); this case includes 'not' of simple sets. Otherwise, -** use the default code (a choice plus a failtwice). -*/ -static void codenot (CompileState *compst, TTree *tree) { - Charset st; - int e = getfirst(tree, fullset, &st); - int test = codetestset(compst, &st, e); - if (headfail(tree)) /* test (fail(p1)) -> L1; fail; L1: */ - addinstruction(compst, IFail, 0); - else { - /* test(fail(p))-> L1; choice L1;

; failtwice; L1: */ - int pchoice = addoffsetinst(compst, IChoice); - codegen(compst, tree, 0, NOINST, fullset); - addinstruction(compst, IFailTwice, 0); - jumptohere(compst, pchoice); - } - jumptohere(compst, test); -} - - -/* -** change open calls to calls, using list 'positions' to find -** correct offsets; also optimize tail calls -*/ -static void correctcalls (CompileState *compst, int *positions, - int from, int to) { - int i; - Instruction *code = compst->p->code; - for (i = from; i < to; i += sizei(&code[i])) { - if (code[i].i.code == IOpenCall) { - int n = code[i].i.key; /* rule number */ - int rule = positions[n]; /* rule position */ - assert(rule == from || code[rule - 1].i.code == IRet); - if (code[finaltarget(code, i + 2)].i.code == IRet) /* call; ret ? */ - code[i].i.code = IJmp; /* tail call */ - else - code[i].i.code = ICall; - jumptothere(compst, i, rule); /* call jumps to respective rule */ - } - } - assert(i == to); -} - - -/* -** Code for a grammar: -** call L1; jmp L2; L1: rule 1; ret; rule 2; ret; ...; L2: -*/ -static void codegrammar (CompileState *compst, TTree *grammar) { - int positions[MAXRULES]; - int rulenumber = 0; - TTree *rule; - int firstcall = addoffsetinst(compst, ICall); /* call initial rule */ - int jumptoend = addoffsetinst(compst, IJmp); /* jump to the end */ - int start = gethere(compst); /* here starts the initial rule */ - jumptohere(compst, firstcall); - for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) { - positions[rulenumber++] = gethere(compst); /* save rule position */ - codegen(compst, sib1(rule), 0, NOINST, fullset); /* code rule */ - addinstruction(compst, IRet, 0); - } - assert(rule->tag == TTrue); - jumptohere(compst, jumptoend); - correctcalls(compst, positions, start, gethere(compst)); -} - - -static void codecall (CompileState *compst, TTree *call) { - int c = addoffsetinst(compst, IOpenCall); /* to be corrected later */ - getinstr(compst, c).i.key = sib2(call)->cap; /* rule number */ - assert(sib2(call)->tag == TRule); -} - - -/* -** Code first child of a sequence -** (second child is called in-place to allow tail call) -** Return 'tt' for second child -*/ -static int codeseq1 (CompileState *compst, TTree *p1, TTree *p2, - int tt, const Charset *fl) { - if (needfollow(p1)) { - Charset fl1; - getfirst(p2, fl, &fl1); /* p1 follow is p2 first */ - codegen(compst, p1, 0, tt, &fl1); - } - else /* use 'fullset' as follow */ - codegen(compst, p1, 0, tt, fullset); - if (fixedlen(p1) != 0) /* can 'p1' consume anything? */ - return NOINST; /* invalidate test */ - else return tt; /* else 'tt' still protects sib2 */ -} - - -/* -** Main code-generation function: dispatch to auxiliar functions -** according to kind of tree. ('needfollow' should return true -** only for consructions that use 'fl'.) -*/ -static void codegen (CompileState *compst, TTree *tree, int opt, int tt, - const Charset *fl) { - tailcall: - switch (tree->tag) { - case TChar: codechar(compst, tree->u.n, tt); break; - case TAny: addinstruction(compst, IAny, 0); break; - case TSet: codecharset(compst, treebuffer(tree), tt); break; - case TTrue: break; - case TFalse: addinstruction(compst, IFail, 0); break; - case TChoice: codechoice(compst, sib1(tree), sib2(tree), opt, fl); break; - case TRep: coderep(compst, sib1(tree), opt, fl); break; - case TBehind: codebehind(compst, tree); break; - case TNot: codenot(compst, sib1(tree)); break; - case TAnd: codeand(compst, sib1(tree), tt); break; - case TCapture: codecapture(compst, tree, tt, fl); break; - case TRunTime: coderuntime(compst, tree, tt); break; - case TGrammar: codegrammar(compst, tree); break; - case TCall: codecall(compst, tree); break; - case TSeq: { - tt = codeseq1(compst, sib1(tree), sib2(tree), tt, fl); /* code 'p1' */ - /* codegen(compst, p2, opt, tt, fl); */ - tree = sib2(tree); goto tailcall; - } - default: assert(0); - } -} - - -/* -** Optimize jumps and other jump-like instructions. -** * Update labels of instructions with labels to their final -** destinations (e.g., choice L1; ... L1: jmp L2: becomes -** choice L2) -** * Jumps to other instructions that do jumps become those -** instructions (e.g., jump to return becomes a return; jump -** to commit becomes a commit) -*/ -static void peephole (CompileState *compst) { - Instruction *code = compst->p->code; - int i; - for (i = 0; i < compst->ncode; i += sizei(&code[i])) { - redo: - switch (code[i].i.code) { - case IChoice: case ICall: case ICommit: case IPartialCommit: - case IBackCommit: case ITestChar: case ITestSet: - case ITestAny: { /* instructions with labels */ - jumptothere(compst, i, finallabel(code, i)); /* optimize label */ - break; - } - case IJmp: { - int ft = finaltarget(code, i); - switch (code[ft].i.code) { /* jumping to what? */ - case IRet: case IFail: case IFailTwice: - case IEnd: { /* instructions with unconditional implicit jumps */ - code[i] = code[ft]; /* jump becomes that instruction */ - code[i + 1].i.code = IAny; /* 'no-op' for target position */ - break; - } - case ICommit: case IPartialCommit: - case IBackCommit: { /* inst. with unconditional explicit jumps */ - int fft = finallabel(code, ft); - code[i] = code[ft]; /* jump becomes that instruction... */ - jumptothere(compst, i, fft); /* but must correct its offset */ - goto redo; /* reoptimize its label */ - } - default: { - jumptothere(compst, i, ft); /* optimize label */ - break; - } - } - break; - } - default: break; - } - } - assert(code[i - 1].i.code == IEnd); -} - - -/* -** Compile a pattern -*/ -Instruction *compile (lua_State *L, Pattern *p) { - CompileState compst; - compst.p = p; compst.ncode = 0; compst.L = L; - realloccode(L, p, 2); /* minimum initial size */ - codegen(&compst, p->tree, 0, NOINST, fullset); - addinstruction(&compst, IEnd, 0); - realloccode(L, p, compst.ncode); /* set final size */ - peephole(&compst); - return p->code; -} - - -/* }====================================================== */ - diff --git a/source/lpeg/src/lpcode.h b/source/lpeg/src/lpcode.h deleted file mode 100644 index 5eb4a959d..000000000 --- a/source/lpeg/src/lpcode.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -** $Id: lpcode.h,v 1.8 2016/09/15 17:46:13 roberto Exp $ -*/ - -#if !defined(lpcode_h) -#define lpcode_h - -#include "elua.h" - -#include "lptypes.h" -#include "lptree.h" -#include "lpvm.h" - -int tocharset (TTree *tree, Charset *cs); -int checkaux (TTree *tree, int pred); -int fixedlen (TTree *tree); -int hascaptures (TTree *tree); -int lp_gc (lua_State *L); -Instruction *compile (lua_State *L, Pattern *p); -void realloccode (lua_State *L, Pattern *p, int nsize); -int sizei (const Instruction *i); - - -#define PEnullable 0 -#define PEnofail 1 - -/* -** nofail(t) implies that 't' cannot fail with any input -*/ -#define nofail(t) checkaux(t, PEnofail) - -/* -** (not nullable(t)) implies 't' cannot match without consuming -** something -*/ -#define nullable(t) checkaux(t, PEnullable) - - - -#endif diff --git a/source/lpeg/src/lpprint.c b/source/lpeg/src/lpprint.c deleted file mode 100644 index f7be408f7..000000000 --- a/source/lpeg/src/lpprint.c +++ /dev/null @@ -1,244 +0,0 @@ -/* -** $Id: lpprint.c,v 1.10 2016/09/13 16:06:03 roberto Exp $ -** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) -*/ - -#include -#include -#include - - -#include "lptypes.h" -#include "lpprint.h" -#include "lpcode.h" - - -#if defined(LPEG_DEBUG) - -/* -** {====================================================== -** Printing patterns (for debugging) -** ======================================================= -*/ - - -void printcharset (const byte *st) { - int i; - printf("["); - for (i = 0; i <= UCHAR_MAX; i++) { - int first = i; - while (testchar(st, i) && i <= UCHAR_MAX) i++; - if (i - 1 == first) /* unary range? */ - printf("(%02x)", first); - else if (i - 1 > first) /* non-empty range? */ - printf("(%02x-%02x)", first, i - 1); - } - printf("]"); -} - - -static const char *capkind (int kind) { - const char *const modes[] = { - "close", "position", "constant", "backref", - "argument", "simple", "table", "function", - "query", "string", "num", "substitution", "fold", - "runtime", "group"}; - return modes[kind]; -} - - -static void printjmp (const Instruction *op, const Instruction *p) { - printf("-> %d", (int)(p + (p + 1)->offset - op)); -} - - -void printinst (const Instruction *op, const Instruction *p) { - const char *const names[] = { - "any", "char", "set", - "testany", "testchar", "testset", - "span", "behind", - "ret", "end", - "choice", "jmp", "call", "open_call", - "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup", - "fullcapture", "opencapture", "closecapture", "closeruntime" - }; - printf("%02ld: %s ", (long)(p - op), names[p->i.code]); - switch ((Opcode)p->i.code) { - case IChar: { - printf("'%c'", p->i.aux); - break; - } - case ITestChar: { - printf("'%c'", p->i.aux); printjmp(op, p); - break; - } - case IFullCapture: { - printf("%s (size = %d) (idx = %d)", - capkind(getkind(p)), getoff(p), p->i.key); - break; - } - case IOpenCapture: { - printf("%s (idx = %d)", capkind(getkind(p)), p->i.key); - break; - } - case ISet: { - printcharset((p+1)->buff); - break; - } - case ITestSet: { - printcharset((p+2)->buff); printjmp(op, p); - break; - } - case ISpan: { - printcharset((p+1)->buff); - break; - } - case IOpenCall: { - printf("-> %d", (p + 1)->offset); - break; - } - case IBehind: { - printf("%d", p->i.aux); - break; - } - case IJmp: case ICall: case ICommit: case IChoice: - case IPartialCommit: case IBackCommit: case ITestAny: { - printjmp(op, p); - break; - } - default: break; - } - printf("\n"); -} - - -void printpatt (Instruction *p, int n) { - Instruction *op = p; - while (p < op + n) { - printinst(op, p); - p += sizei(p); - } -} - - -#if defined(LPEG_DEBUG) -static void printcap (Capture *cap) { - printf("%s (idx: %d - size: %d) -> %p\n", - capkind(cap->kind), cap->idx, cap->siz, cap->s); -} - - -void printcaplist (Capture *cap, Capture *limit) { - printf(">======\n"); - for (; cap->s && (limit == NULL || cap < limit); cap++) - printcap(cap); - printf("=======\n"); -} -#endif - -/* }====================================================== */ - - -/* -** {====================================================== -** Printing trees (for debugging) -** ======================================================= -*/ - -static const char *tagnames[] = { - "char", "set", "any", - "true", "false", - "rep", - "seq", "choice", - "not", "and", - "call", "opencall", "rule", "grammar", - "behind", - "capture", "run-time" -}; - - -void printtree (TTree *tree, int ident) { - int i; - for (i = 0; i < ident; i++) printf(" "); - printf("%s", tagnames[tree->tag]); - switch (tree->tag) { - case TChar: { - int c = tree->u.n; - if (isprint(c)) - printf(" '%c'\n", c); - else - printf(" (%02X)\n", c); - break; - } - case TSet: { - printcharset(treebuffer(tree)); - printf("\n"); - break; - } - case TOpenCall: case TCall: { - assert(sib2(tree)->tag == TRule); - printf(" key: %d (rule: %d)\n", tree->key, sib2(tree)->cap); - break; - } - case TBehind: { - printf(" %d\n", tree->u.n); - printtree(sib1(tree), ident + 2); - break; - } - case TCapture: { - printf(" kind: '%s' key: %d\n", capkind(tree->cap), tree->key); - printtree(sib1(tree), ident + 2); - break; - } - case TRule: { - printf(" n: %d key: %d\n", tree->cap, tree->key); - printtree(sib1(tree), ident + 2); - break; /* do not print next rule as a sibling */ - } - case TGrammar: { - TTree *rule = sib1(tree); - printf(" %d\n", tree->u.n); /* number of rules */ - for (i = 0; i < tree->u.n; i++) { - printtree(rule, ident + 2); - rule = sib2(rule); - } - assert(rule->tag == TTrue); /* sentinel */ - break; - } - default: { - int sibs = numsiblings[tree->tag]; - printf("\n"); - if (sibs >= 1) { - printtree(sib1(tree), ident + 2); - if (sibs >= 2) - printtree(sib2(tree), ident + 2); - } - break; - } - } -} - - -void printktable (lua_State *L, int idx) { - int n, i; - lua_getuservalue(L, idx); - if (lua_isnil(L, -1)) /* no ktable? */ - return; - n = lua_rawlen(L, -1); - printf("["); - for (i = 1; i <= n; i++) { - printf("%d = ", i); - lua_rawgeti(L, -1, i); - if (lua_isstring(L, -1)) - printf("%s ", lua_tostring(L, -1)); - else - printf("%s ", lua_typename(L, lua_type(L, -1))); - lua_pop(L, 1); - } - printf("]\n"); - /* leave ktable at the stack */ -} - -/* }====================================================== */ - -#endif diff --git a/source/lpeg/src/lpprint.h b/source/lpeg/src/lpprint.h deleted file mode 100644 index 632976076..000000000 --- a/source/lpeg/src/lpprint.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -** $Id: lpprint.h,v 1.2 2015/06/12 18:18:08 roberto Exp $ -*/ - - -#if !defined(lpprint_h) -#define lpprint_h - - -#include "lptree.h" -#include "lpvm.h" - - -#if defined(LPEG_DEBUG) - -void printpatt (Instruction *p, int n); -void printtree (TTree *tree, int ident); -void printktable (lua_State *L, int idx); -void printcharset (const byte *st); -void printcaplist (Capture *cap, Capture *limit); -void printinst (const Instruction *op, const Instruction *p); - -#else - -#define printktable(L,idx) \ - luaL_error(L, "function only implemented in debug mode") -#define printtree(tree,i) \ - luaL_error(L, "function only implemented in debug mode") -#define printpatt(p,n) \ - luaL_error(L, "function only implemented in debug mode") - -#endif - - -#endif - diff --git a/source/lpeg/src/lptree.c b/source/lpeg/src/lptree.c deleted file mode 100644 index 7f55ab2eb..000000000 --- a/source/lpeg/src/lptree.c +++ /dev/null @@ -1,1306 +0,0 @@ -/* -** $Id: lptree.c,v 1.22 2016/09/13 18:10:22 roberto Exp $ -** Copyright 2013, Lua.org & PUC-Rio (see 'lpeg.html' for license) -*/ - -#include -#include -#include - - -#include "elua.h" -#include "elauxlib.h" - -#include "lptypes.h" -#include "lpcap.h" -#include "lpcode.h" -#include "lpprint.h" -#include "lptree.h" - - -/* number of siblings for each tree */ -const byte numsiblings[] = { - 0, 0, 0, /* char, set, any */ - 0, 0, /* true, false */ - 1, /* rep */ - 2, 2, /* seq, choice */ - 1, 1, /* not, and */ - 0, 0, 2, 1, /* call, opencall, rule, grammar */ - 1, /* behind */ - 1, 1 /* capture, runtime capture */ -}; - - -static TTree *newgrammar (lua_State *L, int arg); - - -/* -** returns a reasonable name for value at index 'idx' on the stack -*/ -static const char *val2str (lua_State *L, int idx) { - const char *k = lua_tostring(L, idx); - if (k != NULL) - return lua_pushfstring(L, "%s", k); - else - return lua_pushfstring(L, "(a %s)", luaL_typename(L, idx)); -} - - -/* -** Fix a TOpenCall into a TCall node, using table 'postable' to -** translate a key to its rule address in the tree. Raises an -** error if key does not exist. -*/ -static void fixonecall (lua_State *L, int postable, TTree *g, TTree *t) { - int n; - lua_rawgeti(L, -1, t->key); /* get rule's name */ - lua_gettable(L, postable); /* query name in position table */ - n = lua_tonumber(L, -1); /* get (absolute) position */ - lua_pop(L, 1); /* remove position */ - if (n == 0) { /* no position? */ - lua_rawgeti(L, -1, t->key); /* get rule's name again */ - luaL_error(L, "rule '%s' undefined in given grammar", val2str(L, -1)); - } - t->tag = TCall; - t->u.ps = n - (t - g); /* position relative to node */ - assert(sib2(t)->tag == TRule); - sib2(t)->key = t->key; /* fix rule's key */ -} - - -/* -** Transform left associative constructions into right -** associative ones, for sequence and choice; that is: -** (t11 + t12) + t2 => t11 + (t12 + t2) -** (t11 * t12) * t2 => t11 * (t12 * t2) -** (that is, Op (Op t11 t12) t2 => Op t11 (Op t12 t2)) -*/ -static void correctassociativity (TTree *tree) { - TTree *t1 = sib1(tree); - assert(tree->tag == TChoice || tree->tag == TSeq); - while (t1->tag == tree->tag) { - int n1size = tree->u.ps - 1; /* t1 == Op t11 t12 */ - int n11size = t1->u.ps - 1; - int n12size = n1size - n11size - 1; - memmove(sib1(tree), sib1(t1), n11size * sizeof(TTree)); /* move t11 */ - tree->u.ps = n11size + 1; - sib2(tree)->tag = tree->tag; - sib2(tree)->u.ps = n12size + 1; - } -} - - -/* -** Make final adjustments in a tree. Fix open calls in tree 't', -** making them refer to their respective rules or raising appropriate -** errors (if not inside a grammar). Correct associativity of associative -** constructions (making them right associative). Assume that tree's -** ktable is at the top of the stack (for error messages). -*/ -static void finalfix (lua_State *L, int postable, TTree *g, TTree *t) { - tailcall: - switch (t->tag) { - case TGrammar: /* subgrammars were already fixed */ - return; - case TOpenCall: { - if (g != NULL) /* inside a grammar? */ - fixonecall(L, postable, g, t); - else { /* open call outside grammar */ - lua_rawgeti(L, -1, t->key); - luaL_error(L, "rule '%s' used outside a grammar", val2str(L, -1)); - } - break; - } - case TSeq: case TChoice: - correctassociativity(t); - break; - } - switch (numsiblings[t->tag]) { - case 1: /* finalfix(L, postable, g, sib1(t)); */ - t = sib1(t); goto tailcall; - case 2: - finalfix(L, postable, g, sib1(t)); - t = sib2(t); goto tailcall; /* finalfix(L, postable, g, sib2(t)); */ - default: assert(numsiblings[t->tag] == 0); break; - } -} - - - -/* -** {=================================================================== -** KTable manipulation -** -** - The ktable of a pattern 'p' can be shared by other patterns that -** contain 'p' and no other constants. Because of this sharing, we -** should not add elements to a 'ktable' unless it was freshly created -** for the new pattern. -** -** - The maximum index in a ktable is USHRT_MAX, because trees and -** patterns use unsigned shorts to store those indices. -** ==================================================================== -*/ - -/* -** Create a new 'ktable' to the pattern at the top of the stack. -*/ -static void newktable (lua_State *L, int n) { - lua_createtable(L, n, 0); /* create a fresh table */ - lua_setuservalue(L, -2); /* set it as 'ktable' for pattern */ -} - - -/* -** Add element 'idx' to 'ktable' of pattern at the top of the stack; -** Return index of new element. -** If new element is nil, does not add it to table (as it would be -** useless) and returns 0, as ktable[0] is always nil. -*/ -static int addtoktable (lua_State *L, int idx) { - if (lua_isnil(L, idx)) /* nil value? */ - return 0; - else { - int n; - lua_getuservalue(L, -1); /* get ktable from pattern */ - n = lua_rawlen(L, -1); - if (n >= USHRT_MAX) - luaL_error(L, "too many Lua values in pattern"); - lua_pushvalue(L, idx); /* element to be added */ - lua_rawseti(L, -2, ++n); - lua_pop(L, 1); /* remove 'ktable' */ - return n; - } -} - - -/* -** Return the number of elements in the ktable at 'idx'. -** In Lua 5.2/5.3, default "environment" for patterns is nil, not -** a table. Treat it as an empty table. In Lua 5.1, assumes that -** the environment has no numeric indices (len == 0) -*/ -static int ktablelen (lua_State *L, int idx) { - if (!lua_istable(L, idx)) return 0; - else return lua_rawlen(L, idx); -} - - -/* -** Concatentate the contents of table 'idx1' into table 'idx2'. -** (Assume that both indices are negative.) -** Return the original length of table 'idx2' (or 0, if no -** element was added, as there is no need to correct any index). -*/ -static int concattable (lua_State *L, int idx1, int idx2) { - int i; - int n1 = ktablelen(L, idx1); - int n2 = ktablelen(L, idx2); - if (n1 + n2 > USHRT_MAX) - luaL_error(L, "too many Lua values in pattern"); - if (n1 == 0) return 0; /* nothing to correct */ - for (i = 1; i <= n1; i++) { - lua_rawgeti(L, idx1, i); - lua_rawseti(L, idx2 - 1, n2 + i); /* correct 'idx2' */ - } - return n2; -} - - -/* -** When joining 'ktables', constants from one of the subpatterns must -** be renumbered; 'correctkeys' corrects their indices (adding 'n' -** to each of them) -*/ -static void correctkeys (TTree *tree, int n) { - if (n == 0) return; /* no correction? */ - tailcall: - switch (tree->tag) { - case TOpenCall: case TCall: case TRunTime: case TRule: { - if (tree->key > 0) - tree->key += n; - break; - } - case TCapture: { - if (tree->key > 0 && tree->cap != Carg && tree->cap != Cnum) - tree->key += n; - break; - } - default: break; - } - switch (numsiblings[tree->tag]) { - case 1: /* correctkeys(sib1(tree), n); */ - tree = sib1(tree); goto tailcall; - case 2: - correctkeys(sib1(tree), n); - tree = sib2(tree); goto tailcall; /* correctkeys(sib2(tree), n); */ - default: assert(numsiblings[tree->tag] == 0); break; - } -} - - -/* -** Join the ktables from p1 and p2 the ktable for the new pattern at the -** top of the stack, reusing them when possible. -*/ -static void joinktables (lua_State *L, int p1, TTree *t2, int p2) { - int n1, n2; - lua_getuservalue(L, p1); /* get ktables */ - lua_getuservalue(L, p2); - n1 = ktablelen(L, -2); - n2 = ktablelen(L, -1); - if (n1 == 0 && n2 == 0) /* are both tables empty? */ - lua_pop(L, 2); /* nothing to be done; pop tables */ - else if (n2 == 0 || lp_equal(L, -2, -1)) { /* 2nd table empty or equal? */ - lua_pop(L, 1); /* pop 2nd table */ - lua_setuservalue(L, -2); /* set 1st ktable into new pattern */ - } - else if (n1 == 0) { /* first table is empty? */ - lua_setuservalue(L, -3); /* set 2nd table into new pattern */ - lua_pop(L, 1); /* pop 1st table */ - } - else { - lua_createtable(L, n1 + n2, 0); /* create ktable for new pattern */ - /* stack: new p; ktable p1; ktable p2; new ktable */ - concattable(L, -3, -1); /* from p1 into new ktable */ - concattable(L, -2, -1); /* from p2 into new ktable */ - lua_setuservalue(L, -4); /* new ktable becomes 'p' environment */ - lua_pop(L, 2); /* pop other ktables */ - correctkeys(t2, n1); /* correction for indices from p2 */ - } -} - - -/* -** copy 'ktable' of element 'idx' to new tree (on top of stack) -*/ -static void copyktable (lua_State *L, int idx) { - lua_getuservalue(L, idx); - lua_setuservalue(L, -2); -} - - -/* -** merge 'ktable' from 'stree' at stack index 'idx' into 'ktable' -** from tree at the top of the stack, and correct corresponding -** tree. -*/ -static void mergektable (lua_State *L, int idx, TTree *stree) { - int n; - lua_getuservalue(L, -1); /* get ktables */ - lua_getuservalue(L, idx); - n = concattable(L, -1, -2); - lua_pop(L, 2); /* remove both ktables */ - correctkeys(stree, n); -} - - -/* -** Create a new 'ktable' to the pattern at the top of the stack, adding -** all elements from pattern 'p' (if not 0) plus element 'idx' to it. -** Return index of new element. -*/ -static int addtonewktable (lua_State *L, int p, int idx) { - newktable(L, 1); - if (p) - mergektable(L, p, NULL); - return addtoktable(L, idx); -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Tree generation -** ======================================================= -*/ - -/* -** In 5.2, could use 'luaL_testudata'... -*/ -static int testpattern (lua_State *L, int idx) { - if (lua_touserdata(L, idx)) { /* value is a userdata? */ - if (lua_getmetatable(L, idx)) { /* does it have a metatable? */ - luaL_getmetatable(L, PATTERN_T); - if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */ - lua_pop(L, 2); /* remove both metatables */ - return 1; - } - } - } - return 0; -} - - -static Pattern *getpattern (lua_State *L, int idx) { - return (Pattern *)luaL_checkudata(L, idx, PATTERN_T); -} - - -static int getsize (lua_State *L, int idx) { - return (lua_rawlen(L, idx) - sizeof(Pattern)) / sizeof(TTree) + 1; -} - - -static TTree *gettree (lua_State *L, int idx, int *len) { - Pattern *p = getpattern(L, idx); - if (len) - *len = getsize(L, idx); - return p->tree; -} - - -/* -** create a pattern. Set its uservalue (the 'ktable') equal to its -** metatable. (It could be any empty sequence; the metatable is at -** hand here, so we use it.) -*/ -static TTree *newtree (lua_State *L, int len) { - size_t size = (len - 1) * sizeof(TTree) + sizeof(Pattern); - Pattern *p = (Pattern *)lua_newuserdata(L, size); - luaL_getmetatable(L, PATTERN_T); - lua_pushvalue(L, -1); - lua_setuservalue(L, -3); - lua_setmetatable(L, -2); - p->code = NULL; p->codesize = 0; - return p->tree; -} - - -static TTree *newleaf (lua_State *L, int tag) { - TTree *tree = newtree(L, 1); - tree->tag = tag; - return tree; -} - - -static TTree *newcharset (lua_State *L) { - TTree *tree = newtree(L, bytes2slots(CHARSETSIZE) + 1); - tree->tag = TSet; - loopset(i, treebuffer(tree)[i] = 0); - return tree; -} - - -/* -** add to tree a sequence where first sibling is 'sib' (with size -** 'sibsize'); returns position for second sibling -*/ -static TTree *seqaux (TTree *tree, TTree *sib, int sibsize) { - tree->tag = TSeq; tree->u.ps = sibsize + 1; - memcpy(sib1(tree), sib, sibsize * sizeof(TTree)); - return sib2(tree); -} - - -/* -** Build a sequence of 'n' nodes, each with tag 'tag' and 'u.n' got -** from the array 's' (or 0 if array is NULL). (TSeq is binary, so it -** must build a sequence of sequence of sequence...) -*/ -static void fillseq (TTree *tree, int tag, int n, const char *s) { - int i; - for (i = 0; i < n - 1; i++) { /* initial n-1 copies of Seq tag; Seq ... */ - tree->tag = TSeq; tree->u.ps = 2; - sib1(tree)->tag = tag; - sib1(tree)->u.n = s ? (byte)s[i] : 0; - tree = sib2(tree); - } - tree->tag = tag; /* last one does not need TSeq */ - tree->u.n = s ? (byte)s[i] : 0; -} - - -/* -** Numbers as patterns: -** 0 == true (always match); n == TAny repeated 'n' times; -** -n == not (TAny repeated 'n' times) -*/ -static TTree *numtree (lua_State *L, int n) { - if (n == 0) - return newleaf(L, TTrue); - else { - TTree *tree, *nd; - if (n > 0) - tree = nd = newtree(L, 2 * n - 1); - else { /* negative: code it as !(-n) */ - n = -n; - tree = newtree(L, 2 * n); - tree->tag = TNot; - nd = sib1(tree); - } - fillseq(nd, TAny, n, NULL); /* sequence of 'n' any's */ - return tree; - } -} - - -/* -** Convert value at index 'idx' to a pattern -*/ -static TTree *getpatt (lua_State *L, int idx, int *len) { - TTree *tree; - switch (lua_type(L, idx)) { - case LUA_TSTRING: { - size_t slen; - const char *s = lua_tolstring(L, idx, &slen); /* get string */ - if (slen == 0) /* empty? */ - tree = newleaf(L, TTrue); /* always match */ - else { - tree = newtree(L, 2 * (slen - 1) + 1); - fillseq(tree, TChar, slen, s); /* sequence of 'slen' chars */ - } - break; - } - case LUA_TNUMBER: { - int n = lua_tointeger(L, idx); - tree = numtree(L, n); - break; - } - case LUA_TBOOLEAN: { - tree = (lua_toboolean(L, idx) ? newleaf(L, TTrue) : newleaf(L, TFalse)); - break; - } - case LUA_TTABLE: { - tree = newgrammar(L, idx); - break; - } - case LUA_TFUNCTION: { - tree = newtree(L, 2); - tree->tag = TRunTime; - tree->key = addtonewktable(L, 0, idx); - sib1(tree)->tag = TTrue; - break; - } - default: { - return gettree(L, idx, len); - } - } - lua_replace(L, idx); /* put new tree into 'idx' slot */ - if (len) - *len = getsize(L, idx); - return tree; -} - - -/* -** create a new tree, whith a new root and one sibling. -** Sibling must be on the Lua stack, at index 1. -*/ -static TTree *newroot1sib (lua_State *L, int tag) { - int s1; - TTree *tree1 = getpatt(L, 1, &s1); - TTree *tree = newtree(L, 1 + s1); /* create new tree */ - tree->tag = tag; - memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); - copyktable(L, 1); - return tree; -} - - -/* -** create a new tree, whith a new root and 2 siblings. -** Siblings must be on the Lua stack, first one at index 1. -*/ -static TTree *newroot2sib (lua_State *L, int tag) { - int s1, s2; - TTree *tree1 = getpatt(L, 1, &s1); - TTree *tree2 = getpatt(L, 2, &s2); - TTree *tree = newtree(L, 1 + s1 + s2); /* create new tree */ - tree->tag = tag; - tree->u.ps = 1 + s1; - memcpy(sib1(tree), tree1, s1 * sizeof(TTree)); - memcpy(sib2(tree), tree2, s2 * sizeof(TTree)); - joinktables(L, 1, sib2(tree), 2); - return tree; -} - - -static int lp_P (lua_State *L) { - luaL_checkany(L, 1); - getpatt(L, 1, NULL); - lua_settop(L, 1); - return 1; -} - - -/* -** sequence operator; optimizations: -** false x => false, x true => x, true x => x -** (cannot do x . false => false because x may have runtime captures) -*/ -static int lp_seq (lua_State *L) { - TTree *tree1 = getpatt(L, 1, NULL); - TTree *tree2 = getpatt(L, 2, NULL); - if (tree1->tag == TFalse || tree2->tag == TTrue) - lua_pushvalue(L, 1); /* false . x == false, x . true = x */ - else if (tree1->tag == TTrue) - lua_pushvalue(L, 2); /* true . x = x */ - else - newroot2sib(L, TSeq); - return 1; -} - - -/* -** choice operator; optimizations: -** charset / charset => charset -** true / x => true, x / false => x, false / x => x -** (x / true is not equivalent to true) -*/ -static int lp_choice (lua_State *L) { - Charset st1, st2; - TTree *t1 = getpatt(L, 1, NULL); - TTree *t2 = getpatt(L, 2, NULL); - if (tocharset(t1, &st1) && tocharset(t2, &st2)) { - TTree *t = newcharset(L); - loopset(i, treebuffer(t)[i] = st1.cs[i] | st2.cs[i]); - } - else if (nofail(t1) || t2->tag == TFalse) - lua_pushvalue(L, 1); /* true / x => true, x / false => x */ - else if (t1->tag == TFalse) - lua_pushvalue(L, 2); /* false / x => x */ - else - newroot2sib(L, TChoice); - return 1; -} - - -/* -** p^n -*/ -static int lp_star (lua_State *L) { - int size1; - int n = (int)luaL_checkinteger(L, 2); - TTree *tree1 = getpatt(L, 1, &size1); - if (n >= 0) { /* seq tree1 (seq tree1 ... (seq tree1 (rep tree1))) */ - TTree *tree = newtree(L, (n + 1) * (size1 + 1)); - if (nullable(tree1)) - luaL_error(L, "loop body may accept empty string"); - while (n--) /* repeat 'n' times */ - tree = seqaux(tree, tree1, size1); - tree->tag = TRep; - memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); - } - else { /* choice (seq tree1 ... choice tree1 true ...) true */ - TTree *tree; - n = -n; - /* size = (choice + seq + tree1 + true) * n, but the last has no seq */ - tree = newtree(L, n * (size1 + 3) - 1); - for (; n > 1; n--) { /* repeat (n - 1) times */ - tree->tag = TChoice; tree->u.ps = n * (size1 + 3) - 2; - sib2(tree)->tag = TTrue; - tree = sib1(tree); - tree = seqaux(tree, tree1, size1); - } - tree->tag = TChoice; tree->u.ps = size1 + 1; - sib2(tree)->tag = TTrue; - memcpy(sib1(tree), tree1, size1 * sizeof(TTree)); - } - copyktable(L, 1); - return 1; -} - - -/* -** #p == &p -*/ -static int lp_and (lua_State *L) { - newroot1sib(L, TAnd); - return 1; -} - - -/* -** -p == !p -*/ -static int lp_not (lua_State *L) { - newroot1sib(L, TNot); - return 1; -} - - -/* -** [t1 - t2] == Seq (Not t2) t1 -** If t1 and t2 are charsets, make their difference. -*/ -static int lp_sub (lua_State *L) { - Charset st1, st2; - int s1, s2; - TTree *t1 = getpatt(L, 1, &s1); - TTree *t2 = getpatt(L, 2, &s2); - if (tocharset(t1, &st1) && tocharset(t2, &st2)) { - TTree *t = newcharset(L); - loopset(i, treebuffer(t)[i] = st1.cs[i] & ~st2.cs[i]); - } - else { - TTree *tree = newtree(L, 2 + s1 + s2); - tree->tag = TSeq; /* sequence of... */ - tree->u.ps = 2 + s2; - sib1(tree)->tag = TNot; /* ...not... */ - memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree)); /* ...t2 */ - memcpy(sib2(tree), t1, s1 * sizeof(TTree)); /* ... and t1 */ - joinktables(L, 1, sib1(tree), 2); - } - return 1; -} - - -static int lp_set (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - TTree *tree = newcharset(L); - while (l--) { - setchar(treebuffer(tree), (byte)(*s)); - s++; - } - return 1; -} - - -static int lp_range (lua_State *L) { - int arg; - int top = lua_gettop(L); - TTree *tree = newcharset(L); - for (arg = 1; arg <= top; arg++) { - int c; - size_t l; - const char *r = luaL_checklstring(L, arg, &l); - luaL_argcheck(L, l == 2, arg, "range must have two characters"); - for (c = (byte)r[0]; c <= (byte)r[1]; c++) - setchar(treebuffer(tree), c); - } - return 1; -} - - -/* -** Look-behind predicate -*/ -static int lp_behind (lua_State *L) { - TTree *tree; - TTree *tree1 = getpatt(L, 1, NULL); - int n = fixedlen(tree1); - luaL_argcheck(L, n >= 0, 1, "pattern may not have fixed length"); - luaL_argcheck(L, !hascaptures(tree1), 1, "pattern have captures"); - luaL_argcheck(L, n <= MAXBEHIND, 1, "pattern too long to look behind"); - tree = newroot1sib(L, TBehind); - tree->u.n = n; - return 1; -} - - -/* -** Create a non-terminal -*/ -static int lp_V (lua_State *L) { - TTree *tree = newleaf(L, TOpenCall); - luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); - tree->key = addtonewktable(L, 0, 1); - return 1; -} - - -/* -** Create a tree for a non-empty capture, with a body and -** optionally with an associated Lua value (at index 'labelidx' in the -** stack) -*/ -static int capture_aux (lua_State *L, int cap, int labelidx) { - TTree *tree = newroot1sib(L, TCapture); - tree->cap = cap; - tree->key = (labelidx == 0) ? 0 : addtonewktable(L, 1, labelidx); - return 1; -} - - -/* -** Fill a tree with an empty capture, using an empty (TTrue) sibling. -*/ -static TTree *auxemptycap (TTree *tree, int cap) { - tree->tag = TCapture; - tree->cap = cap; - sib1(tree)->tag = TTrue; - return tree; -} - - -/* -** Create a tree for an empty capture -*/ -static TTree *newemptycap (lua_State *L, int cap) { - return auxemptycap(newtree(L, 2), cap); -} - - -/* -** Create a tree for an empty capture with an associated Lua value -*/ -static TTree *newemptycapkey (lua_State *L, int cap, int idx) { - TTree *tree = auxemptycap(newtree(L, 2), cap); - tree->key = addtonewktable(L, 0, idx); - return tree; -} - - -/* -** Captures with syntax p / v -** (function capture, query capture, string capture, or number capture) -*/ -static int lp_divcapture (lua_State *L) { - switch (lua_type(L, 2)) { - case LUA_TFUNCTION: return capture_aux(L, Cfunction, 2); - case LUA_TTABLE: return capture_aux(L, Cquery, 2); - case LUA_TSTRING: return capture_aux(L, Cstring, 2); - case LUA_TNUMBER: { - int n = lua_tointeger(L, 2); - TTree *tree = newroot1sib(L, TCapture); - luaL_argcheck(L, 0 <= n && n <= SHRT_MAX, 1, "invalid number"); - tree->cap = Cnum; - tree->key = n; - return 1; - } - default: return luaL_argerror(L, 2, "invalid replacement value"); - } -} - - -static int lp_substcapture (lua_State *L) { - return capture_aux(L, Csubst, 0); -} - - -static int lp_tablecapture (lua_State *L) { - return capture_aux(L, Ctable, 0); -} - - -static int lp_groupcapture (lua_State *L) { - if (lua_isnoneornil(L, 2)) - return capture_aux(L, Cgroup, 0); - else - return capture_aux(L, Cgroup, 2); -} - - -static int lp_foldcapture (lua_State *L) { - luaL_checktype(L, 2, LUA_TFUNCTION); - return capture_aux(L, Cfold, 2); -} - - -static int lp_simplecapture (lua_State *L) { - return capture_aux(L, Csimple, 0); -} - - -static int lp_poscapture (lua_State *L) { - newemptycap(L, Cposition); - return 1; -} - - -static int lp_argcapture (lua_State *L) { - int n = (int)luaL_checkinteger(L, 1); - TTree *tree = newemptycap(L, Carg); - tree->key = n; - luaL_argcheck(L, 0 < n && n <= SHRT_MAX, 1, "invalid argument index"); - return 1; -} - - -static int lp_backref (lua_State *L) { - luaL_checkany(L, 1); - newemptycapkey(L, Cbackref, 1); - return 1; -} - - -/* -** Constant capture -*/ -static int lp_constcapture (lua_State *L) { - int i; - int n = lua_gettop(L); /* number of values */ - if (n == 0) /* no values? */ - newleaf(L, TTrue); /* no capture */ - else if (n == 1) - newemptycapkey(L, Cconst, 1); /* single constant capture */ - else { /* create a group capture with all values */ - TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); - newktable(L, n); /* create a 'ktable' for new tree */ - tree->tag = TCapture; - tree->cap = Cgroup; - tree->key = 0; - tree = sib1(tree); - for (i = 1; i <= n - 1; i++) { - tree->tag = TSeq; - tree->u.ps = 3; /* skip TCapture and its sibling */ - auxemptycap(sib1(tree), Cconst); - sib1(tree)->key = addtoktable(L, i); - tree = sib2(tree); - } - auxemptycap(tree, Cconst); - tree->key = addtoktable(L, i); - } - return 1; -} - - -static int lp_matchtime (lua_State *L) { - TTree *tree; - luaL_checktype(L, 2, LUA_TFUNCTION); - tree = newroot1sib(L, TRunTime); - tree->key = addtonewktable(L, 1, 2); - return 1; -} - -/* }====================================================== */ - - -/* -** {====================================================== -** Grammar - Tree generation -** ======================================================= -*/ - -/* -** push on the stack the index and the pattern for the -** initial rule of grammar at index 'arg' in the stack; -** also add that index into position table. -*/ -static void getfirstrule (lua_State *L, int arg, int postab) { - lua_rawgeti(L, arg, 1); /* access first element */ - if (lua_isstring(L, -1)) { /* is it the name of initial rule? */ - lua_pushvalue(L, -1); /* duplicate it to use as key */ - lua_gettable(L, arg); /* get associated rule */ - } - else { - lua_pushinteger(L, 1); /* key for initial rule */ - lua_insert(L, -2); /* put it before rule */ - } - if (!testpattern(L, -1)) { /* initial rule not a pattern? */ - if (lua_isnil(L, -1)) - luaL_error(L, "grammar has no initial rule"); - else - luaL_error(L, "initial rule '%s' is not a pattern", lua_tostring(L, -2)); - } - lua_pushvalue(L, -2); /* push key */ - lua_pushinteger(L, 1); /* push rule position (after TGrammar) */ - lua_settable(L, postab); /* insert pair at position table */ -} - -/* -** traverse grammar at index 'arg', pushing all its keys and patterns -** into the stack. Create a new table (before all pairs key-pattern) to -** collect all keys and their associated positions in the final tree -** (the "position table"). -** Return the number of rules and (in 'totalsize') the total size -** for the new tree. -*/ -static int collectrules (lua_State *L, int arg, int *totalsize) { - int n = 1; /* to count number of rules */ - int postab = lua_gettop(L) + 1; /* index of position table */ - int size; /* accumulator for total size */ - lua_newtable(L); /* create position table */ - getfirstrule(L, arg, postab); - size = 2 + getsize(L, postab + 2); /* TGrammar + TRule + rule */ - lua_pushnil(L); /* prepare to traverse grammar table */ - while (lua_next(L, arg) != 0) { - if (lua_tonumber(L, -2) == 1 || - lp_equal(L, -2, postab + 1)) { /* initial rule? */ - lua_pop(L, 1); /* remove value (keep key for lua_next) */ - continue; - } - if (!testpattern(L, -1)) /* value is not a pattern? */ - luaL_error(L, "rule '%s' is not a pattern", val2str(L, -2)); - luaL_checkstack(L, LUA_MINSTACK, "grammar has too many rules"); - lua_pushvalue(L, -2); /* push key (to insert into position table) */ - lua_pushinteger(L, size); - lua_settable(L, postab); - size += 1 + getsize(L, -1); /* update size */ - lua_pushvalue(L, -2); /* push key (for next lua_next) */ - n++; - } - *totalsize = size + 1; /* TTrue to finish list of rules */ - return n; -} - - -static void buildgrammar (lua_State *L, TTree *grammar, int frule, int n) { - int i; - TTree *nd = sib1(grammar); /* auxiliary pointer to traverse the tree */ - for (i = 0; i < n; i++) { /* add each rule into new tree */ - int ridx = frule + 2*i + 1; /* index of i-th rule */ - int rulesize; - TTree *rn = gettree(L, ridx, &rulesize); - nd->tag = TRule; - nd->key = 0; /* will be fixed when rule is used */ - nd->cap = i; /* rule number */ - nd->u.ps = rulesize + 1; /* point to next rule */ - memcpy(sib1(nd), rn, rulesize * sizeof(TTree)); /* copy rule */ - mergektable(L, ridx, sib1(nd)); /* merge its ktable into new one */ - nd = sib2(nd); /* move to next rule */ - } - nd->tag = TTrue; /* finish list of rules */ -} - - -/* -** Check whether a tree has potential infinite loops -*/ -static int checkloops (TTree *tree) { - tailcall: - if (tree->tag == TRep && nullable(sib1(tree))) - return 1; - else if (tree->tag == TGrammar) - return 0; /* sub-grammars already checked */ - else { - switch (numsiblings[tree->tag]) { - case 1: /* return checkloops(sib1(tree)); */ - tree = sib1(tree); goto tailcall; - case 2: - if (checkloops(sib1(tree))) return 1; - /* else return checkloops(sib2(tree)); */ - tree = sib2(tree); goto tailcall; - default: assert(numsiblings[tree->tag] == 0); return 0; - } - } -} - - -/* -** Give appropriate error message for 'verifyrule'. If a rule appears -** twice in 'passed', there is path from it back to itself without -** advancing the subject. -*/ -static int verifyerror (lua_State *L, int *passed, int npassed) { - int i, j; - for (i = npassed - 1; i >= 0; i--) { /* search for a repetition */ - for (j = i - 1; j >= 0; j--) { - if (passed[i] == passed[j]) { - lua_rawgeti(L, -1, passed[i]); /* get rule's key */ - return luaL_error(L, "rule '%s' may be left recursive", val2str(L, -1)); - } - } - } - return luaL_error(L, "too many left calls in grammar"); -} - - -/* -** Check whether a rule can be left recursive; raise an error in that -** case; otherwise return 1 iff pattern is nullable. -** The return value is used to check sequences, where the second pattern -** is only relevant if the first is nullable. -** Parameter 'nb' works as an accumulator, to allow tail calls in -** choices. ('nb' true makes function returns true.) -** Parameter 'passed' is a list of already visited rules, 'npassed' -** counts the elements in 'passed'. -** Assume ktable at the top of the stack. -*/ -static int verifyrule (lua_State *L, TTree *tree, int *passed, int npassed, - int nb) { - tailcall: - switch (tree->tag) { - case TChar: case TSet: case TAny: - case TFalse: - return nb; /* cannot pass from here */ - case TTrue: - case TBehind: /* look-behind cannot have calls */ - return 1; - case TNot: case TAnd: case TRep: - /* return verifyrule(L, sib1(tree), passed, npassed, 1); */ - tree = sib1(tree); nb = 1; goto tailcall; - case TCapture: case TRunTime: - /* return verifyrule(L, sib1(tree), passed, npassed, nb); */ - tree = sib1(tree); goto tailcall; - case TCall: - /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ - tree = sib2(tree); goto tailcall; - case TSeq: /* only check 2nd child if first is nb */ - if (!verifyrule(L, sib1(tree), passed, npassed, 0)) - return nb; - /* else return verifyrule(L, sib2(tree), passed, npassed, nb); */ - tree = sib2(tree); goto tailcall; - case TChoice: /* must check both children */ - nb = verifyrule(L, sib1(tree), passed, npassed, nb); - /* return verifyrule(L, sib2(tree), passed, npassed, nb); */ - tree = sib2(tree); goto tailcall; - case TRule: - if (npassed >= MAXRULES) - return verifyerror(L, passed, npassed); - else { - passed[npassed++] = tree->key; - /* return verifyrule(L, sib1(tree), passed, npassed); */ - tree = sib1(tree); goto tailcall; - } - case TGrammar: - return nullable(tree); /* sub-grammar cannot be left recursive */ - default: assert(0); return 0; - } -} - - -static void verifygrammar (lua_State *L, TTree *grammar) { - int passed[MAXRULES]; - TTree *rule; - /* check left-recursive rules */ - for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) { - if (rule->key == 0) continue; /* unused rule */ - verifyrule(L, sib1(rule), passed, 0, 0); - } - assert(rule->tag == TTrue); - /* check infinite loops inside rules */ - for (rule = sib1(grammar); rule->tag == TRule; rule = sib2(rule)) { - if (rule->key == 0) continue; /* unused rule */ - if (checkloops(sib1(rule))) { - lua_rawgeti(L, -1, rule->key); /* get rule's key */ - luaL_error(L, "empty loop in rule '%s'", val2str(L, -1)); - } - } - assert(rule->tag == TTrue); -} - - -/* -** Give a name for the initial rule if it is not referenced -*/ -static void initialrulename (lua_State *L, TTree *grammar, int frule) { - if (sib1(grammar)->key == 0) { /* initial rule is not referenced? */ - int n = lua_rawlen(L, -1) + 1; /* index for name */ - lua_pushvalue(L, frule); /* rule's name */ - lua_rawseti(L, -2, n); /* ktable was on the top of the stack */ - sib1(grammar)->key = n; - } -} - - -static TTree *newgrammar (lua_State *L, int arg) { - int treesize; - int frule = lua_gettop(L) + 2; /* position of first rule's key */ - int n = collectrules(L, arg, &treesize); - TTree *g = newtree(L, treesize); - luaL_argcheck(L, n <= MAXRULES, arg, "grammar has too many rules"); - g->tag = TGrammar; g->u.n = n; - lua_newtable(L); /* create 'ktable' */ - lua_setuservalue(L, -2); - buildgrammar(L, g, frule, n); - lua_getuservalue(L, -1); /* get 'ktable' for new tree */ - finalfix(L, frule - 1, g, sib1(g)); - initialrulename(L, g, frule); - verifygrammar(L, g); - lua_pop(L, 1); /* remove 'ktable' */ - lua_insert(L, -(n * 2 + 2)); /* move new table to proper position */ - lua_pop(L, n * 2 + 1); /* remove position table + rule pairs */ - return g; /* new table at the top of the stack */ -} - -/* }====================================================== */ - - -static Instruction *prepcompile (lua_State *L, Pattern *p, int idx) { - lua_getuservalue(L, idx); /* push 'ktable' (may be used by 'finalfix') */ - finalfix(L, 0, NULL, p->tree); - lua_pop(L, 1); /* remove 'ktable' */ - return compile(L, p); -} - - -static int lp_printtree (lua_State *L) { - TTree *tree = getpatt(L, 1, NULL); - int c = lua_toboolean(L, 2); - if (c) { - lua_getuservalue(L, 1); /* push 'ktable' (may be used by 'finalfix') */ - finalfix(L, 0, NULL, tree); - lua_pop(L, 1); /* remove 'ktable' */ - } - printktable(L, 1); - printtree(tree, 0); - return 0; -} - - -static int lp_printcode (lua_State *L) { - Pattern *p = getpattern(L, 1); - printktable(L, 1); - if (p->code == NULL) /* not compiled yet? */ - prepcompile(L, p, 1); - printpatt(p->code, p->codesize); - return 0; -} - - -/* -** Get the initial position for the match, interpreting negative -** values from the end of the subject -*/ -static size_t initposition (lua_State *L, size_t len) { - lua_Integer ii = luaL_optinteger(L, 3, 1); - if (ii > 0) { /* positive index? */ - if ((size_t)ii <= len) /* inside the string? */ - return (size_t)ii - 1; /* return it (corrected to 0-base) */ - else return len; /* crop at the end */ - } - else { /* negative index */ - if ((size_t)(-ii) <= len) /* inside the string? */ - return len - ((size_t)(-ii)); /* return position from the end */ - else return 0; /* crop at the beginning */ - } -} - - -/* -** Main match function -*/ -static int lp_match (lua_State *L) { - Capture capture[INITCAPSIZE]; - const char *r; - size_t l; - Pattern *p = (getpatt(L, 1, NULL), getpattern(L, 1)); - Instruction *code = (p->code != NULL) ? p->code : prepcompile(L, p, 1); - const char *s = luaL_checklstring(L, SUBJIDX, &l); - size_t i = initposition(L, l); - int ptop = lua_gettop(L); - lua_pushnil(L); /* initialize subscache */ - lua_pushlightuserdata(L, capture); /* initialize caplistidx */ - lua_getuservalue(L, 1); /* initialize penvidx */ - r = match(L, s, s + i, s + l, code, capture, ptop); - if (r == NULL) { - lua_pushnil(L); - return 1; - } - return getcaptures(L, s, r, ptop); -} - - - -/* -** {====================================================== -** Library creation and functions not related to matching -** ======================================================= -*/ - -/* maximum limit for stack size */ -#define MAXLIM (INT_MAX / 100) - -static int lp_setmax (lua_State *L) { - lua_Integer lim = luaL_checkinteger(L, 1); - luaL_argcheck(L, 0 < lim && lim <= MAXLIM, 1, "out of range"); - lua_settop(L, 1); - lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); - return 0; -} - - -static int lp_version (lua_State *L) { - lua_pushstring(L, VERSION); - return 1; -} - - -static int lp_type (lua_State *L) { - if (testpattern(L, 1)) - lua_pushliteral(L, "pattern"); - else - lua_pushnil(L); - return 1; -} - - -int lp_gc (lua_State *L) { - Pattern *p = getpattern(L, 1); - realloccode(L, p, 0); /* delete code block */ - return 0; -} - - -static void createcat (lua_State *L, const char *catname, int (catf) (int)) { - TTree *t = newcharset(L); - int i; - for (i = 0; i <= UCHAR_MAX; i++) - if (catf(i)) setchar(treebuffer(t), i); - lua_setfield(L, -2, catname); -} - - -static int lp_locale (lua_State *L) { - if (lua_isnoneornil(L, 1)) { - lua_settop(L, 0); - lua_createtable(L, 0, 12); - } - else { - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); - } - createcat(L, "alnum", isalnum); - createcat(L, "alpha", isalpha); - createcat(L, "cntrl", iscntrl); - createcat(L, "digit", isdigit); - createcat(L, "graph", isgraph); - createcat(L, "lower", islower); - createcat(L, "print", isprint); - createcat(L, "punct", ispunct); - createcat(L, "space", isspace); - createcat(L, "upper", isupper); - createcat(L, "xdigit", isxdigit); - return 1; -} - - -static struct luaL_Reg pattreg[] = { - {"ptree", lp_printtree}, - {"pcode", lp_printcode}, - {"match", lp_match}, - {"B", lp_behind}, - {"V", lp_V}, - {"C", lp_simplecapture}, - {"Cc", lp_constcapture}, - {"Cmt", lp_matchtime}, - {"Cb", lp_backref}, - {"Carg", lp_argcapture}, - {"Cp", lp_poscapture}, - {"Cs", lp_substcapture}, - {"Ct", lp_tablecapture}, - {"Cf", lp_foldcapture}, - {"Cg", lp_groupcapture}, - {"P", lp_P}, - {"S", lp_set}, - {"R", lp_range}, - {"locale", lp_locale}, - {"version", lp_version}, - {"setmaxstack", lp_setmax}, - {"type", lp_type}, - {NULL, NULL} -}; - - -static struct luaL_Reg metareg[] = { - {"__mul", lp_seq}, - {"__add", lp_choice}, - {"__pow", lp_star}, - {"__gc", lp_gc}, - {"__len", lp_and}, - {"__div", lp_divcapture}, - {"__unm", lp_not}, - {"__sub", lp_sub}, - {NULL, NULL} -}; - - -#ifdef __cplusplus -extern "C" -#endif -int luaopen_lpeg (lua_State *L); -int luaopen_lpeg (lua_State *L) { - luaL_newmetatable(L, PATTERN_T); - lua_pushnumber(L, MAXBACK); /* initialize maximum backtracking */ - lua_setfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); - luaL_setfuncs(L, metareg, 0); - luaL_newlib(L, pattreg); - lua_pushvalue(L, -1); - lua_setfield(L, -3, "__index"); - return 1; -} - -/* }====================================================== */ diff --git a/source/lpeg/src/lptree.h b/source/lpeg/src/lptree.h deleted file mode 100644 index 34ee15cad..000000000 --- a/source/lpeg/src/lptree.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -** $Id: lptree.h,v 1.3 2016/09/13 18:07:51 roberto Exp $ -*/ - -#if !defined(lptree_h) -#define lptree_h - - -#include "lptypes.h" - - -/* -** types of trees -*/ -typedef enum TTag { - TChar = 0, /* 'n' = char */ - TSet, /* the set is stored in next CHARSETSIZE bytes */ - TAny, - TTrue, - TFalse, - TRep, /* 'sib1'* */ - TSeq, /* 'sib1' 'sib2' */ - TChoice, /* 'sib1' / 'sib2' */ - TNot, /* !'sib1' */ - TAnd, /* &'sib1' */ - TCall, /* ktable[key] is rule's key; 'sib2' is rule being called */ - TOpenCall, /* ktable[key] is rule's key */ - TRule, /* ktable[key] is rule's key (but key == 0 for unused rules); - 'sib1' is rule's pattern; - 'sib2' is next rule; 'cap' is rule's sequential number */ - TGrammar, /* 'sib1' is initial (and first) rule */ - TBehind, /* 'sib1' is pattern, 'n' is how much to go back */ - TCapture, /* captures: 'cap' is kind of capture (enum 'CapKind'); - ktable[key] is Lua value associated with capture; - 'sib1' is capture body */ - TRunTime /* run-time capture: 'key' is Lua function; - 'sib1' is capture body */ -} TTag; - - -/* -** Tree trees -** The first child of a tree (if there is one) is immediately after -** the tree. A reference to a second child (ps) is its position -** relative to the position of the tree itself. -*/ -typedef struct TTree { - byte tag; - byte cap; /* kind of capture (if it is a capture) */ - unsigned short key; /* key in ktable for Lua data (0 if no key) */ - union { - int ps; /* occasional second child */ - int n; /* occasional counter */ - } u; -} TTree; - - -/* -** A complete pattern has its tree plus, if already compiled, -** its corresponding code -*/ -typedef struct Pattern { - union Instruction *code; - int codesize; - TTree tree[1]; -} Pattern; - - -/* number of children for each tree */ -extern const byte numsiblings[]; - -/* access to children */ -#define sib1(t) ((t) + 1) -#define sib2(t) ((t) + (t)->u.ps) - - - - - - -#endif - diff --git a/source/lpeg/src/lptypes.h b/source/lpeg/src/lptypes.h deleted file mode 100644 index 10ca1b2e7..000000000 --- a/source/lpeg/src/lptypes.h +++ /dev/null @@ -1,149 +0,0 @@ -/* -** $Id: lptypes.h,v 1.16 2017/01/13 13:33:17 roberto Exp $ -** LPeg - PEG pattern matching for Lua -** Copyright 2007-2017, Lua.org & PUC-Rio (see 'lpeg.html' for license) -** written by Roberto Ierusalimschy -*/ - -#if !defined(lptypes_h) -#define lptypes_h - - -#if !defined(LPEG_DEBUG) -#define NDEBUG -#endif - -#include -#include - -#include "elua.h" - - -#define VERSION "1.0.1" - - -#define PATTERN_T "lpeg-pattern" -#define MAXSTACKIDX "lpeg-maxstack" - - -/* -** compatibility with Lua 5.1 -*/ -#if (LUA_VERSION_NUM == 501) - -#define lp_equal lua_equal - -#define lua_getuservalue lua_getfenv -#define lua_setuservalue lua_setfenv - -#define lua_rawlen lua_objlen - -#define luaL_setfuncs(L,f,n) luaL_register(L,NULL,f) -#define luaL_newlib(L,f) luaL_register(L,"lpeg",f) - -#endif - - -#if !defined(lp_equal) -#define lp_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) -#endif - - -/* default maximum size for call/backtrack stack */ -#if !defined(MAXBACK) -#define MAXBACK 400 -#endif - - -/* maximum number of rules in a grammar (limited by 'unsigned char') */ -#if !defined(MAXRULES) -#define MAXRULES 250 -#endif - - - -/* initial size for capture's list */ -#define INITCAPSIZE 32 - - -/* index, on Lua stack, for subject */ -#define SUBJIDX 2 - -/* number of fixed arguments to 'match' (before capture arguments) */ -#define FIXEDARGS 3 - -/* index, on Lua stack, for capture list */ -#define caplistidx(ptop) ((ptop) + 2) - -/* index, on Lua stack, for pattern's ktable */ -#define ktableidx(ptop) ((ptop) + 3) - -/* index, on Lua stack, for backtracking stack */ -#define stackidx(ptop) ((ptop) + 4) - - - -typedef unsigned char byte; - - -#define BITSPERCHAR 8 - -#define CHARSETSIZE ((UCHAR_MAX/BITSPERCHAR) + 1) - - - -typedef struct Charset { - byte cs[CHARSETSIZE]; -} Charset; - - - -#define loopset(v,b) { int v; for (v = 0; v < CHARSETSIZE; v++) {b;} } - -/* access to charset */ -#define treebuffer(t) ((byte *)((t) + 1)) - -/* number of slots needed for 'n' bytes */ -#define bytes2slots(n) (((n) - 1) / sizeof(TTree) + 1) - -/* set 'b' bit in charset 'cs' */ -#define setchar(cs,b) ((cs)[(b) >> 3] |= (1 << ((b) & 7))) - - -/* -** in capture instructions, 'kind' of capture and its offset are -** packed in field 'aux', 4 bits for each -*/ -#define getkind(op) ((op)->i.aux & 0xF) -#define getoff(op) (((op)->i.aux >> 4) & 0xF) -#define joinkindoff(k,o) ((k) | ((o) << 4)) - -#define MAXOFF 0xF -#define MAXAUX 0xFF - - -/* maximum number of bytes to look behind */ -#define MAXBEHIND MAXAUX - - -/* maximum size (in elements) for a pattern */ -#define MAXPATTSIZE (SHRT_MAX - 10) - - -/* size (in elements) for an instruction plus extra l bytes */ -#define instsize(l) (((l) + sizeof(Instruction) - 1)/sizeof(Instruction) + 1) - - -/* size (in elements) for a ISet instruction */ -#define CHARSETINSTSIZE instsize(CHARSETSIZE) - -/* size (in elements) for a IFunc instruction */ -#define funcinstsize(p) ((p)->i.aux + 2) - - - -#define testchar(st,c) (((int)(st)[((c) >> 3)] & (1 << ((c) & 7)))) - - -#endif - diff --git a/source/lpeg/src/lpvm.c b/source/lpeg/src/lpvm.c deleted file mode 100644 index 205581eb1..000000000 --- a/source/lpeg/src/lpvm.c +++ /dev/null @@ -1,364 +0,0 @@ -/* -** $Id: lpvm.c,v 1.9 2016/06/03 20:11:18 roberto Exp $ -** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license) -*/ - -#include -#include - - -#include "elua.h" -#include "elauxlib.h" - -#include "lpcap.h" -#include "lptypes.h" -#include "lpvm.h" -#include "lpprint.h" - - -/* initial size for call/backtrack stack */ -#if !defined(INITBACK) -#define INITBACK MAXBACK -#endif - - -#define getoffset(p) (((p) + 1)->offset) - -static const Instruction giveup = {{IGiveup, 0, 0}}; - - -/* -** {====================================================== -** Virtual Machine -** ======================================================= -*/ - - -typedef struct Stack { - const char *s; /* saved position (or NULL for calls) */ - const Instruction *p; /* next instruction */ - int caplevel; -} Stack; - - -#define getstackbase(L, ptop) ((Stack *)lua_touserdata(L, stackidx(ptop))) - - -/* -** Make the size of the array of captures 'cap' twice as large as needed -** (which is 'captop'). ('n' is the number of new elements.) -*/ -static Capture *doublecap (lua_State *L, Capture *cap, int captop, - int n, int ptop) { - Capture *newc; - if (captop >= INT_MAX/((int)sizeof(Capture) * 2)) - luaL_error(L, "too many captures"); - newc = (Capture *)lua_newuserdata(L, captop * 2 * sizeof(Capture)); - memcpy(newc, cap, (captop - n) * sizeof(Capture)); - lua_replace(L, caplistidx(ptop)); - return newc; -} - - -/* -** Double the size of the stack -*/ -static Stack *doublestack (lua_State *L, Stack **stacklimit, int ptop) { - Stack *stack = getstackbase(L, ptop); - Stack *newstack; - int n = *stacklimit - stack; /* current stack size */ - int max, newn; - lua_getfield(L, LUA_REGISTRYINDEX, MAXSTACKIDX); - max = lua_tointeger(L, -1); /* maximum allowed size */ - lua_pop(L, 1); - if (n >= max) /* already at maximum size? */ - luaL_error(L, "backtrack stack overflow (current limit is %d)", max); - newn = 2 * n; /* new size */ - if (newn > max) newn = max; - newstack = (Stack *)lua_newuserdata(L, newn * sizeof(Stack)); - memcpy(newstack, stack, n * sizeof(Stack)); - lua_replace(L, stackidx(ptop)); - *stacklimit = newstack + newn; - return newstack + n; /* return next position */ -} - - -/* -** Interpret the result of a dynamic capture: false -> fail; -** true -> keep current position; number -> next position. -** Return new subject position. 'fr' is stack index where -** is the result; 'curr' is current subject position; 'limit' -** is subject's size. -*/ -static int resdyncaptures (lua_State *L, int fr, int curr, int limit) { - lua_Integer res; - if (!lua_toboolean(L, fr)) { /* false value? */ - lua_settop(L, fr - 1); /* remove results */ - return -1; /* and fail */ - } - else if (lua_isboolean(L, fr)) /* true? */ - res = curr; /* keep current position */ - else { - res = lua_tointeger(L, fr) - 1; /* new position */ - if (res < curr || res > limit) - luaL_error(L, "invalid position returned by match-time capture"); - } - lua_remove(L, fr); /* remove first result (offset) */ - return res; -} - - -/* -** Add capture values returned by a dynamic capture to the capture list -** 'base', nested inside a group capture. 'fd' indexes the first capture -** value, 'n' is the number of values (at least 1). -*/ -static void adddyncaptures (const char *s, Capture *base, int n, int fd) { - int i; - base[0].kind = Cgroup; /* create group capture */ - base[0].siz = 0; - base[0].idx = 0; /* make it an anonymous group */ - for (i = 1; i <= n; i++) { /* add runtime captures */ - base[i].kind = Cruntime; - base[i].siz = 1; /* mark it as closed */ - base[i].idx = fd + i - 1; /* stack index of capture value */ - base[i].s = s; - } - base[i].kind = Cclose; /* close group */ - base[i].siz = 1; - base[i].s = s; -} - - -/* -** Remove dynamic captures from the Lua stack (called in case of failure) -*/ -static int removedyncap (lua_State *L, Capture *capture, - int level, int last) { - int id = finddyncap(capture + level, capture + last); /* index of 1st cap. */ - int top = lua_gettop(L); - if (id == 0) return 0; /* no dynamic captures? */ - lua_settop(L, id - 1); /* remove captures */ - return top - id + 1; /* number of values removed */ -} - - -/* -** Opcode interpreter -*/ -const char *match (lua_State *L, const char *o, const char *s, const char *e, - Instruction *op, Capture *capture, int ptop) { - Stack stackbase[INITBACK]; - Stack *stacklimit = stackbase + INITBACK; - Stack *stack = stackbase; /* point to first empty slot in stack */ - int capsize = INITCAPSIZE; - int captop = 0; /* point to first empty slot in captures */ - int ndyncap = 0; /* number of dynamic captures (in Lua stack) */ - const Instruction *p = op; /* current instruction */ - stack->p = &giveup; stack->s = s; stack->caplevel = 0; stack++; - lua_pushlightuserdata(L, stackbase); - for (;;) { -#if defined(DEBUG) - printf("-------------------------------------\n"); - printcaplist(capture, capture + captop); - printf("s: |%s| stck:%d, dyncaps:%d, caps:%d ", - s, (int)(stack - getstackbase(L, ptop)), ndyncap, captop); - printinst(op, p); -#endif - assert(stackidx(ptop) + ndyncap == lua_gettop(L) && ndyncap <= captop); - switch ((Opcode)p->i.code) { - case IEnd: { - assert(stack == getstackbase(L, ptop) + 1); - capture[captop].kind = Cclose; - capture[captop].s = NULL; - return s; - } - case IGiveup: { - assert(stack == getstackbase(L, ptop)); - return NULL; - } - case IRet: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s == NULL); - p = (--stack)->p; - continue; - } - case IAny: { - if (s < e) { p++; s++; } - else goto fail; - continue; - } - case ITestAny: { - if (s < e) p += 2; - else p += getoffset(p); - continue; - } - case IChar: { - if ((byte)*s == p->i.aux && s < e) { p++; s++; } - else goto fail; - continue; - } - case ITestChar: { - if ((byte)*s == p->i.aux && s < e) p += 2; - else p += getoffset(p); - continue; - } - case ISet: { - int c = (byte)*s; - if (testchar((p+1)->buff, c) && s < e) - { p += CHARSETINSTSIZE; s++; } - else goto fail; - continue; - } - case ITestSet: { - int c = (byte)*s; - if (testchar((p + 2)->buff, c) && s < e) - p += 1 + CHARSETINSTSIZE; - else p += getoffset(p); - continue; - } - case IBehind: { - int n = p->i.aux; - if (n > s - o) goto fail; - s -= n; p++; - continue; - } - case ISpan: { - for (; s < e; s++) { - int c = (byte)*s; - if (!testchar((p+1)->buff, c)) break; - } - p += CHARSETINSTSIZE; - continue; - } - case IJmp: { - p += getoffset(p); - continue; - } - case IChoice: { - if (stack == stacklimit) - stack = doublestack(L, &stacklimit, ptop); - stack->p = p + getoffset(p); - stack->s = s; - stack->caplevel = captop; - stack++; - p += 2; - continue; - } - case ICall: { - if (stack == stacklimit) - stack = doublestack(L, &stacklimit, ptop); - stack->s = NULL; - stack->p = p + 2; /* save return address */ - stack++; - p += getoffset(p); - continue; - } - case ICommit: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); - stack--; - p += getoffset(p); - continue; - } - case IPartialCommit: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); - (stack - 1)->s = s; - (stack - 1)->caplevel = captop; - p += getoffset(p); - continue; - } - case IBackCommit: { - assert(stack > getstackbase(L, ptop) && (stack - 1)->s != NULL); - s = (--stack)->s; - captop = stack->caplevel; - p += getoffset(p); - continue; - } - case IFailTwice: - assert(stack > getstackbase(L, ptop)); - stack--; - /* go through */ - case IFail: - fail: { /* pattern failed: try to backtrack */ - do { /* remove pending calls */ - assert(stack > getstackbase(L, ptop)); - s = (--stack)->s; - } while (s == NULL); - if (ndyncap > 0) /* is there matchtime captures? */ - ndyncap -= removedyncap(L, capture, stack->caplevel, captop); - captop = stack->caplevel; - p = stack->p; -#if defined(DEBUG) - printf("**FAIL**\n"); -#endif - continue; - } - case ICloseRunTime: { - CapState cs; - int rem, res, n; - int fr = lua_gettop(L) + 1; /* stack index of first result */ - cs.s = o; cs.L = L; cs.ocap = capture; cs.ptop = ptop; - n = runtimecap(&cs, capture + captop, s, &rem); /* call function */ - captop -= n; /* remove nested captures */ - ndyncap -= rem; /* update number of dynamic captures */ - fr -= rem; /* 'rem' items were popped from Lua stack */ - res = resdyncaptures(L, fr, s - o, e - o); /* get result */ - if (res == -1) /* fail? */ - goto fail; - s = o + res; /* else update current position */ - n = lua_gettop(L) - fr + 1; /* number of new captures */ - ndyncap += n; /* update number of dynamic captures */ - if (n > 0) { /* any new capture? */ - if (fr + n >= SHRT_MAX) - luaL_error(L, "too many results in match-time capture"); - if ((captop += n + 2) >= capsize) { - capture = doublecap(L, capture, captop, n + 2, ptop); - capsize = 2 * captop; - } - /* add new captures to 'capture' list */ - adddyncaptures(s, capture + captop - n - 2, n, fr); - } - p++; - continue; - } - case ICloseCapture: { - const char *s1 = s; - assert(captop > 0); - /* if possible, turn capture into a full capture */ - if (capture[captop - 1].siz == 0 && - s1 - capture[captop - 1].s < UCHAR_MAX) { - capture[captop - 1].siz = s1 - capture[captop - 1].s + 1; - p++; - continue; - } - else { - capture[captop].siz = 1; /* mark entry as closed */ - capture[captop].s = s; - goto pushcapture; - } - } - case IOpenCapture: - capture[captop].siz = 0; /* mark entry as open */ - capture[captop].s = s; - goto pushcapture; - case IFullCapture: - capture[captop].siz = getoff(p) + 1; /* save capture size */ - capture[captop].s = s - getoff(p); - /* goto pushcapture; */ - pushcapture: { - capture[captop].idx = p->i.key; - capture[captop].kind = getkind(p); - if (++captop >= capsize) { - capture = doublecap(L, capture, captop, 0, ptop); - capsize = 2 * captop; - } - p++; - continue; - } - default: assert(0); return NULL; - } - } -} - -/* }====================================================== */ - - diff --git a/source/lpeg/src/lpvm.h b/source/lpeg/src/lpvm.h deleted file mode 100644 index 757b9e135..000000000 --- a/source/lpeg/src/lpvm.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -** $Id: lpvm.h,v 1.3 2014/02/21 13:06:41 roberto Exp $ -*/ - -#if !defined(lpvm_h) -#define lpvm_h - -#include "lpcap.h" - - -/* Virtual Machine's instructions */ -typedef enum Opcode { - IAny, /* if no char, fail */ - IChar, /* if char != aux, fail */ - ISet, /* if char not in buff, fail */ - ITestAny, /* in no char, jump to 'offset' */ - ITestChar, /* if char != aux, jump to 'offset' */ - ITestSet, /* if char not in buff, jump to 'offset' */ - ISpan, /* read a span of chars in buff */ - IBehind, /* walk back 'aux' characters (fail if not possible) */ - IRet, /* return from a rule */ - IEnd, /* end of pattern */ - IChoice, /* stack a choice; next fail will jump to 'offset' */ - IJmp, /* jump to 'offset' */ - ICall, /* call rule at 'offset' */ - IOpenCall, /* call rule number 'key' (must be closed to a ICall) */ - ICommit, /* pop choice and jump to 'offset' */ - IPartialCommit, /* update top choice to current position and jump */ - IBackCommit, /* "fails" but jump to its own 'offset' */ - IFailTwice, /* pop one choice and then fail */ - IFail, /* go back to saved state on choice and jump to saved offset */ - IGiveup, /* internal use */ - IFullCapture, /* complete capture of last 'off' chars */ - IOpenCapture, /* start a capture */ - ICloseCapture, - ICloseRunTime -} Opcode; - - - -typedef union Instruction { - struct Inst { - byte code; - byte aux; - short key; - } i; - int offset; - byte buff[1]; -} Instruction; - - -void printpatt (Instruction *p, int n); -const char *match (lua_State *L, const char *o, const char *s, const char *e, - Instruction *op, Capture *capture, int ptop); - - -#endif - diff --git a/source/tools/src/arttool.cpp b/source/tools/src/arttool.cpp deleted file mode 100644 index feed7630e..000000000 --- a/source/tools/src/arttool.cpp +++ /dev/null @@ -1,1438 +0,0 @@ -/** - * BUILD ART file editing tool - * @author Jonathon Fowler - * @license Artistic License 2.0 (http://www.perlfoundation.org/artistic_license_2_0) - */ -// Bstring and C++ STL --> C conversion by Hendricks266 - -#include "compat.h" - -////////// Bstring ////////// - -class Bstring { - public: - Bstring(void); - Bstring(const char*); - Bstring(const Bstring&); - ~Bstring(void); - - operator const char*() const; - const char* operator()(void) const; - char& operator[](int); - - Bstring& operator=(const char*); - Bstring& operator=(const Bstring&); - - Bstring& operator+=(const char*); - Bstring& operator+=(const Bstring&); - - bool operator==(const Bstring&) const; - bool operator!=(const Bstring&) const; - bool operator< (const Bstring&) const; - bool operator<=(const Bstring&) const; - bool operator> (const Bstring&) const; - bool operator>=(const Bstring&) const; - - bool operator==(const char*) const; - bool operator!=(const char*) const; - bool operator< (const char*) const; - bool operator<=(const char*) const; - bool operator> (const char*) const; - bool operator>=(const char*) const; - - int compare(const char*) const; - int compare(const Bstring&) const; - - unsigned length(void) const; - - void clear(void); - - protected: - char* data; -}; - -Bstring::Bstring(void) { data = NULL; } -Bstring::Bstring(const Bstring &value) { - if (&value != this) - (*this)=value(); -} -Bstring::Bstring(const char *str) { - data = NULL; - (*this)=str; -} - -Bstring::~Bstring(void) { clear(); } - -Bstring::operator const char*() const { return data; } -const char* Bstring::operator()(void) const { return data; } -char& Bstring::operator[](int index) { return data[index]; } - -Bstring& Bstring::operator=(const Bstring &value) -{ - if (&value != this) - (*this)=value(); - - return *this; -} -Bstring& Bstring::operator=(const char *str) -{ - clear(); - data = Bstrdup(str); - - return *this; -} - -Bstring& Bstring::operator+=(const Bstring &value) -{ - (*this)+=value(); - - return *this; -} -Bstring& Bstring::operator+=(const char *str) -{ - data = (char*) Brealloc(data, (Bstrlen(data) + Bstrlen(str) + 1) * sizeof(char)); - Bstrcat(data, str); - - return *this; -} - -bool Bstring::operator==(const Bstring &value) const { return Bstrcmp(data, value()) == 0; } -bool Bstring::operator!=(const Bstring &value) const { return Bstrcmp(data, value()) != 0; } -bool Bstring::operator< (const Bstring &value) const { return Bstrcmp(data, value()) < 0; } -bool Bstring::operator<=(const Bstring &value) const { return Bstrcmp(data, value()) <= 0; } -bool Bstring::operator> (const Bstring &value) const { return Bstrcmp(data, value()) > 0; } -bool Bstring::operator>=(const Bstring &value) const { return Bstrcmp(data, value()) >= 0; } - -bool Bstring::operator==(const char *str) const { return Bstrcmp(data, str) == 0; } -bool Bstring::operator!=(const char *str) const { return Bstrcmp(data, str) != 0; } -bool Bstring::operator< (const char *str) const { return Bstrcmp(data, str) < 0; } -bool Bstring::operator<=(const char *str) const { return Bstrcmp(data, str) <= 0; } -bool Bstring::operator> (const char *str) const { return Bstrcmp(data, str) > 0; } -bool Bstring::operator>=(const char *str) const { return Bstrcmp(data, str) >= 0; } - -int Bstring::compare(const Bstring &value) const { return Bstrcmp(data,value()); } -int Bstring::compare(const char *str) const { return Bstrcmp(data,str); } - -unsigned Bstring::length(void) const { return Bstrlen(data); } - -void Bstring::clear(void) -{ - DO_FREE_AND_NULL(data); -} - -////////// arttool ////////// - -void usage() -{ - Bprintf("BUILD ART file editing tool\n"); - Bprintf("Copyright (C) 2008 Jonathon Fowler \n"); - Bprintf("Released under the Artistic License 2.0\n"); - Bprintf("\n"); - Bprintf(" arttool info [tilenum]\n"); - Bprintf(" Display information about a specific tile, or all if none is specified\n"); - Bprintf("\n"); - Bprintf(" arttool create [options]\n"); - Bprintf(" -f Selects which numbered ART file to create (default 0)\n"); - Bprintf(" -o Specifies the first tile in the file (default 0)\n"); - Bprintf(" -n The number of tiles for the art file (default 256)\n"); - Bprintf(" Creates an empty ART file named 'tilesXXX.art'\n"); - Bprintf("\n"); - Bprintf(" arttool addtile [options] \n"); - Bprintf(" -x X-centre\n"); - Bprintf(" -y Y-centre\n"); - Bprintf(" -ann Animation frame span\n"); - Bprintf(" -ant Animation type (0=none, 1=oscillate, 2=forward, 3=reverse)\n"); - Bprintf(" -ans Animation speed\n"); - Bprintf(" Adds a tile to the 'tilesXXX.art' set from a TGA or PCX source\n"); - Bprintf("\n"); - Bprintf(" arttool rmtile \n"); - Bprintf(" Removes a tile from the 'tilesXXX.art' set\n"); - Bprintf("\n"); - Bprintf(" arttool exporttile \n"); - Bprintf(" Exports a tile from the 'tilesXXX.art' set to a PCX file\n"); - Bprintf("\n"); - Bprintf(" arttool tileprop [options] \n"); - Bprintf(" -x X-centre\n"); - Bprintf(" -y Y-centre\n"); - Bprintf(" -ann Animation frame span, may be negative\n"); - Bprintf(" -ant Animation type (0=none, 1=oscillate, 2=forward, 3=reverse)\n"); - Bprintf(" -ans Animation speed\n"); - Bprintf(" Changes tile properties\n"); - Bprintf("\n"); -} - -class ARTFile { -private: - Bstring filename_; - int localtilestart_; - int localtileend_; - short * tilesizx_; - short * tilesizy_; - int * picanm_; - int datastartoffset_; - - // for removing or replacing tile data - int markprelength_, markskiplength_, markpostlength_; - char * insert_; - int insertlen_; - - void writeShort(BFILE *ofs, short s) - { - Bassert(ofs); - char d[2] = { static_cast(s&255), static_cast((s>>8)&255) }; - Bfwrite(d,1,2,ofs); // 2 == sizeof(d) - } - - void writeLong(BFILE *ofs, int l) - { - Bassert(ofs); - char d[4] = { static_cast(l&255), static_cast((l>>8)&255), static_cast((l>>16)&255), static_cast((l>>24)&255) }; - Bfwrite(d,1,4,ofs); // 4 == sizeof(d) - } - - short readShort(BFILE *ifs) - { - Bassert(ifs); - unsigned char d[2]; - unsigned short s; - Bfread(d,1,2,ifs); // 2 == sizeof(d) - s = (unsigned short)d[0]; - s |= (unsigned short)d[1] << 8; - return (short)s; - } - - int readLong(BFILE *ifs) - { - Bassert(ifs); - unsigned char d[4]; - unsigned int l; - Bfread(d,1,4,ifs); // 4 == sizeof(d) - l = (unsigned int)d[0]; - l |= (unsigned int)d[1] << 8; - l |= (unsigned int)d[2] << 16; - l |= (unsigned int)d[3] << 24; - return (int)l; - } - - void dispose() - { - if (tilesizx_) delete [] tilesizx_; - if (tilesizy_) delete [] tilesizy_; - if (picanm_) delete [] picanm_; - if (insert_) delete [] insert_; - - insert_ = 0; - insertlen_ = 0; - } - - void load() - { - BFILE *infile = Bfopen(filename_(),"rb"); - int i, ntiles; - - if (infile != NULL && readLong(infile) == 1) - { - readLong(infile); // skip the numtiles - dispose(); - - localtilestart_ = readLong(infile); - localtileend_ = readLong(infile); - ntiles = localtileend_ - localtilestart_ + 1; - - tilesizx_ = new short[ntiles]; - tilesizy_ = new short[ntiles]; - picanm_ = new int[ntiles]; - - for (i = 0; i < ntiles; ++i) { - tilesizx_[i] = readShort(infile); - } - for (i = 0; i < ntiles; ++i) { - tilesizy_[i] = readShort(infile); - } - for (i = 0; i < ntiles; ++i) { - picanm_[i] = readLong(infile); - } - - datastartoffset_ = Bftell(infile); - - Bfclose(infile); - } - } - -public: - ARTFile(Bstring const & filename) - : filename_(filename), localtilestart_(0), localtileend_(-1), - tilesizx_(0), tilesizy_(0), picanm_(0), datastartoffset_(0), - markprelength_(0), markskiplength_(0), markpostlength_(0), - insert_(0), insertlen_(0) - { - load(); - } - - ~ARTFile() - { - dispose(); - } - - /** - * Sets up for an empty file - * @param start the starting tile - * @param ntiles the number of tiles total - */ - void init(int start, int ntiles) - { - dispose(); - - localtilestart_ = start; - localtileend_ = start + ntiles - 1; - tilesizx_ = new short[ntiles]; - tilesizy_ = new short[ntiles]; - picanm_ = new int[ntiles]; - datastartoffset_ = 0; - - memset(tilesizx_, 0, sizeof(short)*ntiles); - memset(tilesizy_, 0, sizeof(short)*ntiles); - memset(picanm_, 0, sizeof(int)*ntiles); - - markprelength_ = 0; - markskiplength_ = 0; - markpostlength_ = 0; - insert_ = 0; - insertlen_ = 0; - } - - /** - * Returns the number of tiles in the loaded file - * @return 0 means no file loaded - */ - int getNumTiles() - { - return (localtileend_ - localtilestart_ + 1); - } - - int getFirstTile() - { - return localtilestart_; - } - - int getLastTile() - { - return localtileend_; - } - - void removeTile(int tile) - { - int i, end; - - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - end = localtileend_ - tile; - tile -= localtilestart_; - - markprelength_ = markpostlength_ = 0; - - for (i = 0; i < tile; ++i) { - markprelength_ += tilesizx_[i] * tilesizy_[i]; - } - markskiplength_ = tilesizx_[tile] * tilesizy_[tile]; - for (i = tile + 1; i <= end; ++i) { - markpostlength_ += tilesizx_[i] * tilesizy_[i]; - } - - tilesizx_[tile] = tilesizy_[tile] = 0; - } - - void replaceTile(int tile, char * replace, int replacelen) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - removeTile(tile); - - insert_ = replace; - insertlen_ = replacelen; - } - - void getTileSize(int tile, int& x, int &y) - { - if (tile < localtilestart_ || tile > localtileend_) { - x = y = -1; - return; - } - - tile -= localtilestart_; - x = tilesizx_[tile]; - y = tilesizy_[tile]; - } - - void setTileSize(int tile, int x, int y) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - tile -= localtilestart_; - tilesizx_[tile] = x; - tilesizy_[tile] = y; - } - - void setXOfs(int tile, int x) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - tile -= localtilestart_; - picanm_[tile] &= ~(255<<8); - picanm_[tile] |= ((int)((unsigned char)x) << 8); - } - - void setYOfs(int tile, int y) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - tile -= localtilestart_; - picanm_[tile] &= ~(255<<16); - picanm_[tile] |= ((int)((unsigned char)y) << 16); - } - - int getXOfs(int tile) - { - if (tile < localtilestart_ || tile > localtileend_) { - return 0; - } - - tile -= localtilestart_; - return (picanm_[tile] >> 8) & 255; - } - - int getYOfs(int tile) - { - if (tile < localtilestart_ || tile > localtileend_) { - return 0; - } - - tile -= localtilestart_; - return (picanm_[tile] >> 16) & 255; - } - - void setAnimType(int tile, int type) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - tile -= localtilestart_; - picanm_[tile] &= ~(3<<6); - picanm_[tile] |= ((int)(type&3) << 6); - } - - int getAnimType(int tile) - { - if (tile < localtilestart_ || tile > localtileend_) { - return 0; - } - - tile -= localtilestart_; - return (picanm_[tile] >> 6) & 3; - } - - void setAnimFrames(int tile, int frames) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - tile -= localtilestart_; - picanm_[tile] &= ~(63); - picanm_[tile] |= ((int)(frames&63)); - } - - int getAnimFrames(int tile) - { - if (tile < localtilestart_ || tile > localtileend_) { - return 0; - } - - tile -= localtilestart_; - return picanm_[tile] & 63; - } - - void setAnimSpeed(int tile, int speed) - { - if (tile < localtilestart_ || tile > localtileend_) { - return; - } - - tile -= localtilestart_; - picanm_[tile] &= ~(15<<24); - picanm_[tile] |= ((int)(speed&15) << 24); - } - - int getAnimSpeed(int tile) - { - if (tile < localtilestart_ || tile > localtileend_) { - return 0; - } - - tile -= localtilestart_; - return (picanm_[tile] >> 24) & 15; - } - - int write() - { - BFILE *outfile = tmpfile(); - - BFILE *infile = Bfopen(filename_(),"rb"); - int tmp, left; - static const unsigned int blksize = 4096; - char blk[blksize]; - - if (infile == NULL && (markprelength_ > 0 || markskiplength_ > 0 || markpostlength_ > 0)) { - return -1; // couldn't open the original file for copying - } else if (infile != NULL) { - // skip to the start of the existing ART data - int ofs = 4+4+4+4+(2+2+4)*(localtileend_-localtilestart_+1); - Bfseek(infile, ofs, SEEK_CUR); - } - - // write a header to the temporary file - writeLong(outfile, 1); // version - writeLong(outfile, 0); // numtiles - writeLong(outfile, localtilestart_); - writeLong(outfile, localtileend_); - for (int i = 0; i < localtileend_ - localtilestart_ + 1; ++i) { - writeShort(outfile, tilesizx_[i]); - } - for (int i = 0; i < localtileend_ - localtilestart_ + 1; ++i) { - writeShort(outfile, tilesizy_[i]); - } - for (int i = 0; i < localtileend_ - localtilestart_ + 1; ++i) { - writeLong(outfile, picanm_[i]); - } - - // copy the existing leading tile data to be kept - left = markprelength_; - while (left > 0) { - tmp = left; - if ((unsigned int)tmp > blksize) { - tmp = blksize; - } - Bfread(blk, 1, tmp, infile); - Bfwrite(blk, 1, tmp, outfile); - left -= tmp; - } - - // insert the replacement data - if (insertlen_ > 0) { - Bfwrite(insert_, 1, insertlen_, outfile); - } - - if (markskiplength_ > 0) { - Bfseek(infile, markskiplength_, SEEK_CUR); - } - - // copy the existing trailing tile data to be kept - left = markpostlength_; - while (left > 0) { - tmp = left; - if ((unsigned int)tmp > blksize) { - tmp = blksize; - } - Bfread(blk, 1, tmp, infile); - Bfwrite(blk, 1, tmp, outfile); - left -= tmp; - } - - // clean up - const long int tempsize = Bftell(outfile); - Brewind(outfile); - - Bfclose(infile); - - infile = Bfopen(filename_(),"wb"); - - char * buffer = (char*)Bmalloc(tempsize * sizeof(char)); - - Bfread(buffer, 1, tempsize, outfile); - Bfwrite(buffer, 1, tempsize, infile); - - Bfclose(infile); - Bfclose(outfile); - - return 0; - } - - char * readTile(int tile, int& bytes) - { - bytes = -1; - - if (tile < localtilestart_ || tile > localtileend_) { - return 0; - } - tile -= localtilestart_; - - if (tilesizx_[tile] == 0 || tilesizy_[tile] == 0) { - bytes = 0; - return 0; - } - - BFILE *infile = Bfopen(filename_(),"rb"); - if (infile == NULL) { - return 0; - } else { - // skip to the start of the existing ART data - Bfseek(infile, datastartoffset_, SEEK_SET); - } - - bytes = tilesizx_[tile] * tilesizy_[tile]; - char * data = new char[bytes]; - - for (int i = 0; i < tile; i++) { - Bfseek(infile, tilesizx_[i] * tilesizy_[i], SEEK_CUR); - } - if (Bfread(data, bytes, 1, infile) != 1) { - delete [] data; - data = 0; - } - - Bfclose(infile); - - return data; - } -}; - - -class PCX { -private: - static int writebyte(unsigned char colour, unsigned char count, BFILE *ofs) - { - if (!count) return 0; - if (count == 1 && (colour & 0xc0) != 0xc0) { - Bfputc(colour, ofs); - return 1; - } else { - Bfputc(0xc0 | count, ofs); - Bfputc(colour, ofs); - return 2; - } - } - - static void writeline(unsigned char *buf, int bytes, int step, BFILE *ofs) - { - unsigned char ths, last; - int srcIndex; - unsigned char runCount; - - runCount = 1; - last = *buf; - - for (srcIndex=1; srcIndex= datalen)) - return 1; - repeat = *(data + roff++); - - if ((repeat & 192) == 192) { - if (EDUKE32_PREDICT_FALSE(roff >= datalen)) - return 1; - colour = *(data + roff++); - repeat = repeat & 63; - } else { - colour = repeat; - repeat = 1; - } - - for (; repeat > 0; repeat--, x++) { - if (x < imgdataw) { - *wptr = (unsigned char) colour; - wptr += imgdatah; // next column - } - } - } while (x < bpl); - } - - return 0; - } - - /** - * Writes a PCX file from data in BUILD's column-major pixel order - * @param ofs the output file stream - * @param imgdata a pointer to the image data - * @param imgdataw the image width - * @param imgdatah the image height - * @param palette the image palette, 256*3 bytes - * @return 0 on success - */ - static int write(BFILE *ofs, unsigned char * imgdata, int imgdataw, int imgdatah, unsigned char * palette) - { - unsigned char head[128]; - int bpl = imgdataw + (imgdataw&1); - - memset(head,0,128); - head[0] = 10; - head[1] = 5; - head[2] = 1; - head[3] = 8; - head[8] = (imgdataw-1) & 0xff; - head[9] = ((imgdataw-1) >> 8) & 0xff; - head[10] = (imgdatah-1) & 0xff; - head[11] = ((imgdatah-1) >> 8) & 0xff; - head[12] = 72; head[13] = 0; - head[14] = 72; head[15] = 0; - head[65] = 1; // 8-bit - head[66] = bpl & 0xff; - head[67] = (bpl >> 8) & 0xff; - head[68] = 1; - - Bfwrite(head, sizeof(head), 1, ofs); - for (int i = 0; i < imgdatah; i++) { - writeline(imgdata + i, imgdataw, imgdatah, ofs); - } - - Bfputc(12, ofs); - Bfwrite(palette, 768, 1, ofs); - - return 0; - } -}; - -/** - * Loads a tile from a picture file into memory - * @param filename the filename - * @param imgdata receives a pointer to the decoded image data - * @param imgdataw receives the decoded image width - * @param imgdatah receives the decoded image height - * @return 0 on success - */ -int loadimage(Bstring const & filename, char ** imgdata, int& imgdataw, int& imgdatah) -{ - BFILE *infile = Bfopen(filename(),"rb"); - unsigned char * data = 0; - int datalen = 0, err = 0; - - if (infile == NULL) - return 1; - - struct Bstat stbuf; - if (Bfstat(Bfileno(infile), &stbuf) == -1) - return 1; - - datalen = stbuf.st_size; - - data = new unsigned char [datalen]; - Bfread(data, 1, datalen, infile); - Bfclose(infile); - - err = PCX::decode(data, datalen, imgdata, imgdataw, imgdatah); - - delete [] data; - - return err; -} - -/** - * Saves a tile from memory to disk, taking the palette from palette.dat - * @param filename the filename - * @param imgdata a pointer to the image data - * @param imgdataw the image width - * @param imgdatah the image height - * @return 0 on success - */ -int saveimage(Bstring const & filename, char * imgdata, int imgdataw, int imgdatah) -{ - BFILE *outfile = Bfopen(filename(), "wb"); - BFILE *palfile = Bfopen("palette.dat", "rb"); - unsigned char palette[768]; - - if (palfile != NULL) { - Bfread(palette, 768, 1, palfile); - for (int i=0; i<256*3; i++) { - palette[i] <<= 2; - } - Bfclose(palfile); - } else { - Bfprintf(stderr, "warning: palette.dat could not be loaded\n"); - for (int i=0; i<256; i++) { - palette[i*3+0] = i; - palette[i*3+1] = i; - palette[i*3+2] = i; - } - } - - if (outfile == NULL) { - return 1; - } - - PCX::write(outfile, (unsigned char *)imgdata, imgdataw, imgdatah, palette); - - Bfclose(outfile); - - return 0; -} - -class Operation { -protected: - Bstring makefilename(int n) - { - Bstring filename("tilesXXX.art"); - filename[5] = '0' + (n / 100) % 10; - filename[6] = '0' + (n / 10) % 10; - filename[7] = '0' + (n / 1) % 10; - return filename; - } - -public: - typedef enum { - ERR_NO_ERROR = 0, - ERR_BAD_OPTION = 1, - ERR_BAD_VALUE = 2, - ERR_TOO_MANY_PARAMS = 3, - ERR_NO_ART_FILE = 4, - ERR_INVALID_IMAGE = 5, - } Result; - - static char const * translateResult(Result r) - { - switch (r) { - case ERR_NO_ERROR: return "no error"; - case ERR_BAD_OPTION: return "bad option"; - case ERR_BAD_VALUE: return "bad value"; - case ERR_TOO_MANY_PARAMS: return "too many parameters given"; - case ERR_NO_ART_FILE: return "no ART file was found"; - case ERR_INVALID_IMAGE: return "a nonexistent, corrupt, or unrecognised image was given"; - default: return "unknown error"; - } - } - - virtual ~Operation() - { - } - - /** - * Sets an option - * @param opt the option name - * @param value the option value - * @return a value from the Result enum - */ - virtual Result setOption(const Bstring &opt, const Bstring &value) = 0; - - /** - * Sets a parameter from the unnamed sequence - * @param number the parameter number - * @param value the parameter value - * @return a value from the Result enum - */ - virtual Result setParameter(const int &number, const Bstring &value) = 0; - - /** - * Do the operation - * @return a value from the Result enum - */ - virtual Result perform() = 0; -}; -class InfoOp : public Operation { -private: - int tilenum_; - - void outputInfo(ARTFile& art, int tile) - { - Bprintf(" Tile %i: ", tile); - - int w, h; - art.getTileSize(tile, w, h); - Bprintf("%ix%i ", w, h); - - Bprintf("Xofs: %i, ", art.getXOfs(tile)); - Bprintf("Yofs: %i, ", art.getYOfs(tile)); - Bprintf("AnimType: %i, ", art.getAnimType(tile)); - Bprintf("AnimFrames: %i, ", art.getAnimFrames(tile)); - Bprintf("AnimSpeed: %i\n", art.getAnimSpeed(tile)); - } - -public: - InfoOp() : tilenum_(-1) { } - - virtual Result setOption(const Bstring &opt ATTRIBUTE((unused)), const Bstring &value ATTRIBUTE((unused))) - { - return ERR_BAD_OPTION; - } - - virtual Result setParameter(const int &number, const Bstring &value) - { - switch (number) { - case 0: - tilenum_ = atoi(value()); - return ERR_NO_ERROR; - default: - return ERR_TOO_MANY_PARAMS; - } - } - - virtual Result perform() - { - int filenum = 0, tile; - - for (filenum = 0; filenum < 1000; filenum++) { - Bstring filename = makefilename(filenum); - ARTFile art(filename); - - if (art.getNumTiles() == 0) { - // no file exists, so give up - if (tilenum_ < 0) { - return ERR_NO_ERROR; - } - break; - } - - if (tilenum_ >= 0) { - if (tilenum_ > art.getLastTile()) { - // Not in this file. - continue; - } else { - Bprintf("File %s\n", filename()); - outputInfo(art, tilenum_); - } - return ERR_NO_ERROR; - } else { - Bprintf("File %s\n", filename()); - for (tile = art.getFirstTile(); tile <= art.getLastTile(); tile++) { - outputInfo(art, tile); - } - } - } - - return ERR_NO_ART_FILE; - } -}; - -class CreateOp : public Operation { -private: - int filen_, offset_, ntiles_; -public: - CreateOp() : filen_(0), offset_(0), ntiles_(256) { } - - virtual Result setOption(const Bstring &opt, const Bstring &value) - { - if (opt == "f") { - filen_ = atoi(value()); - if (filen_ < 0 || filen_ > 999) { - return ERR_BAD_VALUE; - } - } else if (opt == "o") { - offset_ = atoi(value()); - if (offset_ < 0) { - return ERR_BAD_VALUE; - } - } else if (opt == "n") { - ntiles_ = atoi(value()); - if (ntiles_ < 1) { - return ERR_BAD_VALUE; - } - } else { - return ERR_BAD_OPTION; - } - return ERR_NO_ERROR; - } - - virtual Result setParameter(const int &number ATTRIBUTE((unused)), const Bstring &value ATTRIBUTE((unused))) - { - return ERR_TOO_MANY_PARAMS; - } - - virtual Result perform() - { - ARTFile art(makefilename(filen_)); - - art.init(offset_, ntiles_); - art.write(); - - return ERR_NO_ERROR; - } -}; - -class AddTileOp : public Operation { -private: - int xofs_, yofs_; - int animframes_, animtype_, animspeed_; - int tilenum_; - Bstring filename_; -public: - AddTileOp() - : xofs_(0), yofs_(0), - animframes_(0), animtype_(0), animspeed_(0), - tilenum_(-1), filename_("") - { } - - virtual Result setOption(const Bstring &opt, const Bstring &value) - { - if (opt == "x") { - xofs_ = atoi(value()); - } else if (opt == "y") { - yofs_ = atoi(value()); - } else if (opt == "ann") { - animframes_ = atoi(value()); - if (animframes_ < 0 || animframes_ > 63) { - return ERR_BAD_VALUE; - } - } else if (opt == "ant") { - animtype_ = atoi(value()); - if (animtype_ < 0 || animtype_ > 3) { - return ERR_BAD_VALUE; - } - } else if (opt == "ans") { - animspeed_ = atoi(value()); - if (animspeed_ < 0 || animspeed_ > 15) { - return ERR_BAD_VALUE; - } - } else { - return ERR_BAD_OPTION; - } - return ERR_NO_ERROR; - } - - virtual Result setParameter(const int &number, const Bstring &value) - { - switch (number) { - case 0: - tilenum_ = atoi(value()); - return ERR_NO_ERROR; - case 1: - filename_ = value; - return ERR_NO_ERROR; - default: - return ERR_TOO_MANY_PARAMS; - } - } - - virtual Result perform() - { - int tilesperfile = 0, nextstart = 0; - int filenum = 0; - char * imgdata = 0; - int imgdataw = 0, imgdatah = 0; - - // open the first art file to get the file size used by default - { - ARTFile art(makefilename(0)); - tilesperfile = art.getNumTiles(); - if (tilesperfile == 0) { - return ERR_NO_ART_FILE; - } - } - - // load the tile image into memory - switch (loadimage(filename_, &imgdata, imgdataw, imgdatah)) { - case 0: break; // win - default: return ERR_INVALID_IMAGE; - } - - // open art files until we find one that encompasses the range we need - // and when we find it, make the change - for (filenum = 0; filenum < 1000; filenum++) { - ARTFile art(makefilename(filenum)); - bool dirty = false, done = false; - - if (art.getNumTiles() == 0) { - // no file exists, so we treat it as though it does - art.init(nextstart, tilesperfile); - dirty = true; - } - - if (tilenum_ >= art.getFirstTile() && tilenum_ <= art.getLastTile()) { - art.replaceTile(tilenum_, imgdata, imgdataw * imgdatah); - art.setTileSize(tilenum_, imgdataw, imgdatah); - art.setXOfs(tilenum_, xofs_); - art.setYOfs(tilenum_, yofs_); - art.setAnimFrames(tilenum_, animframes_); - art.setAnimSpeed(tilenum_, animspeed_); - art.setAnimType(tilenum_, animtype_); - done = true; - dirty = true; - - imgdata = 0; // ARTFile.replaceTile took ownership of the pointer - } - - nextstart += art.getNumTiles(); - - if (dirty) { - art.write(); - } - if (done) { - return ERR_NO_ERROR; - } - } - - if (imgdata) { - delete [] imgdata; - } - - return ERR_NO_ART_FILE; - } -}; - -class RmTileOp : public Operation { -private: - int tilenum_; -public: - RmTileOp() : tilenum_(-1) { } - - virtual Result setOption(const Bstring &opt ATTRIBUTE((unused)), const Bstring &value ATTRIBUTE((unused))) - { - return ERR_BAD_OPTION; - } - - virtual Result setParameter(const int &number, const Bstring &value) - { - switch (number) { - case 0: - tilenum_ = atoi(value()); - return ERR_NO_ERROR; - default: - return ERR_TOO_MANY_PARAMS; - } - } - - virtual Result perform() - { - int filenum = 0; - - // open art files until we find one that encompasses the range we need - // and when we find it, remove the tile - for (filenum = 0; filenum < 1000; filenum++) { - ARTFile art(makefilename(filenum)); - - if (art.getNumTiles() == 0) { - // no file exists, so give up - break; - } - - if (tilenum_ >= art.getFirstTile() && tilenum_ <= art.getLastTile()) { - art.removeTile(tilenum_); - art.write(); - return ERR_NO_ERROR; - } - } - - return ERR_NO_ART_FILE; - } -}; - -class ExportTileOp : public Operation { -private: - int tilenum_; -public: - ExportTileOp() : tilenum_(-1) { } - - virtual Result setOption(const Bstring &opt ATTRIBUTE((unused)), const Bstring &value ATTRIBUTE((unused))) - { - return ERR_BAD_OPTION; - } - - virtual Result setParameter(const int &number, const Bstring &value) - { - switch (number) { - case 0: - tilenum_ = atoi(value()); - return ERR_NO_ERROR; - default: - return ERR_TOO_MANY_PARAMS; - } - } - - virtual Result perform() - { - int filenum = 0; - - Bstring filename("tile0000.pcx"); - filename[4] = '0' + (tilenum_ / 1000) % 10; - filename[5] = '0' + (tilenum_ / 100) % 10; - filename[6] = '0' + (tilenum_ / 10) % 10; - filename[7] = '0' + (tilenum_) % 10; - - // open art files until we find the one that encompasses the range we need - // and when we find it, export it - for (filenum = 0; filenum < 1000; filenum++) { - ARTFile art(makefilename(filenum)); - - if (art.getNumTiles() == 0) { - // no file exists, so give up - break; - } - - if (tilenum_ >= art.getFirstTile() && tilenum_ <= art.getLastTile()) { - int bytes, w, h; - char * data = art.readTile(tilenum_, bytes); - art.getTileSize(tilenum_, w, h); - - if (bytes == 0) { - return ERR_NO_ERROR; - } - - switch (saveimage(filename, data, w, h)) { - case 0: break; // win - default: return ERR_INVALID_IMAGE; - } - - delete [] data; - - return ERR_NO_ERROR; - } - } - - return ERR_NO_ART_FILE; - } -}; - -class TilePropOp : public Operation { -private: - int xofs_, yofs_; - int animframes_, animtype_, animspeed_; - int tilenum_; - - int settings_; - - enum { - SET_XOFS = 1, - SET_YOFS = 2, - SET_ANIMFRAMES = 4, - SET_ANIMTYPE = 8, - SET_ANIMSPEED = 16, - }; -public: - TilePropOp() - : xofs_(0), yofs_(0), - animframes_(0), animtype_(0), animspeed_(0), - tilenum_(-1), settings_(0) - { } - - virtual Result setOption(const Bstring &opt, const Bstring &value) - { - if (opt == "x") { - xofs_ = atoi(value()); - settings_ |= SET_XOFS; - } else if (opt == "y") { - yofs_ = atoi(value()); - settings_ |= SET_YOFS; - } else if (opt == "ann") { - animframes_ = atoi(value()); - settings_ |= SET_ANIMFRAMES; - if (animframes_ < 0 || animframes_ > 63) { - return ERR_BAD_VALUE; - } - } else if (opt == "ant") { - animtype_ = atoi(value()); - settings_ |= SET_ANIMTYPE; - if (animtype_ < 0 || animtype_ > 3) { - return ERR_BAD_VALUE; - } - } else if (opt == "ans") { - animspeed_ = atoi(value()); - settings_ |= SET_ANIMSPEED; - if (animspeed_ < 0 || animspeed_ > 15) { - return ERR_BAD_VALUE; - } - } else { - return ERR_BAD_OPTION; - } - return ERR_NO_ERROR; - } - - virtual Result setParameter(const int &number, const Bstring &value) - { - switch (number) { - case 0: - tilenum_ = atoi(value()); - return ERR_NO_ERROR; - default: - return ERR_TOO_MANY_PARAMS; - } - } - - virtual Result perform() - { - int filenum = 0; - - if (settings_ == 0) { - return ERR_NO_ERROR; - } - - // open art files until we find one that encompasses the range we need - // and when we find it, make the change - for (filenum = 0; filenum < 1000; filenum++) { - ARTFile art(makefilename(filenum)); - - if (art.getNumTiles() == 0) { - // no file exists, so give up - break; - } - - if (tilenum_ >= art.getFirstTile() && tilenum_ <= art.getLastTile()) { - if (settings_ & SET_XOFS) { - art.setXOfs(tilenum_, xofs_); - } - if (settings_ & SET_YOFS) { - art.setYOfs(tilenum_, yofs_); - } - if (settings_ & SET_ANIMFRAMES) { - art.setAnimFrames(tilenum_, animframes_); - } - if (settings_ & SET_ANIMSPEED) { - art.setAnimSpeed(tilenum_, animspeed_); - } - if (settings_ & SET_ANIMTYPE) { - art.setAnimType(tilenum_, animtype_); - } - art.write(); - return ERR_NO_ERROR; - } - } - - return ERR_NO_ART_FILE; - } -}; - -int main(int argc, char ** argv) -{ - int showusage = 0; - Operation * oper = 0; - Operation::Result err = Operation::ERR_NO_ERROR; - - if (argc < 2) { - showusage = 1; - } else { - Bstring opt(argv[1]); - Bstring value; - - // create the option handler object according to the first param - if (opt == "info") { - oper = new InfoOp; - } else if (opt == "create") { - oper = new CreateOp; - } else if (opt == "addtile") { - oper = new AddTileOp; - } else if (opt == "rmtile") { - oper = new RmTileOp; - } else if (opt == "exporttile") { - oper = new ExportTileOp; - } else if (opt == "tileprop") { - oper = new TilePropOp; - } else { - showusage = 2; - } - - // apply the command line options given - if (oper) { - int unnamedParm = 0; - for (int i = 2; i < argc && !showusage; ++i) { - if (argv[i][0] == '-') { - opt = argv[i] + 1; - if (i+1 >= argc) { - showusage = 2; - break; - } - value = argv[i+1]; - ++i; - - switch (err = oper->setOption(opt, value)) { - case Operation::ERR_NO_ERROR: break; - default: - Bfprintf(stderr, "error: %s\n", Operation::translateResult(err)); - showusage = 2; - break; - } - } else { - value = argv[i]; - switch (oper->setParameter(unnamedParm, value)) { - case Operation::ERR_NO_ERROR: break; - default: - Bfprintf(stderr, "error: %s\n", Operation::translateResult(err)); - showusage = 2; - break; - } - ++unnamedParm; - } - } - } - } - - if (showusage) { - usage(); - if (oper) delete oper; - return (showusage - 1); - } else if (oper) { - err = oper->perform(); - delete oper; - - switch (err) { - case Operation::ERR_NO_ERROR: return 0; - default: - Bfprintf(stderr, "error: %s\n", Operation::translateResult(err)); - return 1; - } - } - - return 0; -} diff --git a/source/tools/src/ase_import.py b/source/tools/src/ase_import.py deleted file mode 100755 index 3473170d1..000000000 --- a/source/tools/src/ase_import.py +++ /dev/null @@ -1,452 +0,0 @@ -#!BPY - -""" -Name: 'ASCII Scene (.ase) v0.16' -Blender: 249 -Group: 'Import' -Tooltip: 'ASCII Scene import (*.ase)' -""" -__author__ = "Goofos & Plagman" -__version__ = "0.16" - -# goofos at epruegel.de -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ***** END GPL LICENCE BLOCK ***** - -import string, time, sys as osSys -import Blender -from Blender import Draw, Mesh, Window, Object, Scene, NMesh, Key, Ipo, IpoCurve -#import meshtools - - -def read_main(filename): - - global counts - counts = {'verts': 0, 'tris': 0} - - start = time.clock() - file = open(filename, "r") - - print_boxed("----------------start-----------------") - print 'Import Patch: ', filename - - editmode = Window.EditMode() # are we in edit mode? If so ... - if editmode: Window.EditMode(0) # leave edit mode before getting the mesh - - lines= file.readlines() - read_file(file, lines) - - Blender.Window.DrawProgressBar(1.0, '') # clear progressbar - file.close() - print "----------------end-----------------" - end = time.clock() - seconds = " in %.2f %s" % (end-start, "seconds") - totals = "Verts: %i Tris: %i " % (counts['verts'], counts['tris']) - print_boxed(totals) - message = "Successfully imported " + Blender.sys.basename(filename) + seconds - #meshtools.print_boxed(message) - print_boxed(message) - - -def print_boxed(text): #Copy/Paste from meshtools, only to remove the beep :) - lines = text.splitlines() - maxlinelen = max(map(len, lines)) - if osSys.platform[:3] == "win": - print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191) - for line in lines: - print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179) - print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217) - else: - print '+-' + '-'*maxlinelen + '-+' - for line in lines: print '| ' + line.ljust(maxlinelen) + ' |' - print '+-' + '-'*maxlinelen + '-+' - #print '\a\r', # beep when done - - -class ase_obj: - - def __init__(self): - self.name = 'Name' - self.objType = None - self.row0x = None - self.row0y = None - self.row0z = None - self.row1x = None - self.row1y = None - self.row1z = None - self.row2x = None - self.row2y = None - self.row2z = None - self.row3x = None - self.row3y = None - self.row3z = None - self.parent = None - self.obj = None - self.objName = 'Name' - -class ase_mesh: - - def __init__(self): - self.name = '' - self.vCount = 0 - self.fCount = 0 - self.frames = [] - self.verts = [] - self.faces = [] - self.animated = 0 - self.frameCount = -1 - -class mesh_vert: - - def __init__(self): - self.x = 0.0 - self.y = 0.0 - self.z = 0.0 - self.u = 0.0 - self.v = 0.0 - self.nx = 0.0 - self.ny = 0.0 - self.nz = 0.0 - self.origi = 0 - def make_tuple(self): - return (self.x, self.y, self.z, self.u, self.v, self.nx, self.ny, self.nz) - -class mesh_face: - - def __init__(self): - self.v1 = mesh_vert() - self.v2 = mesh_vert() - self.v3 = mesh_vert() - self.i1 = 0 - self.i2 = 0 - self.i3 = 0 - -def read_file(file, lines): - - objects = [] - objIdx = 0 - objCheck = -1 #needed to skip helper objects - PBidx = 0.0 - lineCount = float(len(lines)) - processed_indices = [] - curFaceID = 0 - faceVertID = 0 - - print 'Read file' - Blender.Window.DrawProgressBar(0.0, "Read File...") - - for line in lines: - words = string.split(line) - - if (PBidx % 10000) == 0.0: - Blender.Window.DrawProgressBar(PBidx / lineCount, "Read File...") - - if not words: - continue - elif objIdx > 0 and me.animated == 1: - # I don't know how to make empty statements, this is to skip everything else - me.animated = me.animated - elif words[0] == '*GEOMOBJECT': - objCheck = 0 - newObj = ase_obj() - objects.append(newObj) - obj = objects[objIdx] - objIdx += 1 - - obj.objType = 'Mesh' - obj.obj = ase_mesh() - me = obj.obj - elif words[0] == '*NODE_NAME' and objCheck != -1: - if objCheck == 0: - obj.name = words[1] - objCheck = 1 - elif objCheck == 1: - obj.objName = words[1] - elif words[0] == '*TM_ROW0' and objCheck != -1: - obj.row0x = float(words[1]) - obj.row0y = float(words[2]) - obj.row0z = float(words[3]) - elif words[0] == '*TM_ROW1' and objCheck != -1: - obj.row1x = float(words[1]) - obj.row1y = float(words[2]) - obj.row1z = float(words[3]) - elif words[0] == '*TM_ROW2' and objCheck != -1: - obj.row2x = float(words[1]) - obj.row2y = float(words[2]) - obj.row2z = float(words[3]) - elif words[0] == '*TM_ROW3' and objCheck != -1: - obj.row3x = float(words[1]) - obj.row3y = float(words[2]) - obj.row3z = float(words[3]) - objCheck = -1 - elif words[0] == '*MESH_NUMVERTEX': - me.vCount = int(words[1]) - for i in range(me.vCount): - me.verts.append(mesh_vert()) - elif words[0] == '*MESH_NUMFACES': - me.fCount = int(words[1]) - for i in range(me.fCount): - me.faces.append(mesh_face()) - elif words[0] == '*MESH_VERTEX': - i = int(words[1]) - me.verts[i].x = float(words[2]); - me.verts[i].y = float(words[3]); - me.verts[i].z = float(words[4]); - elif words[0] == '*MESH_FACE': - i = int(words[1].rstrip(":")) # looks like "13:" - v1 = int(words[3]); - v2 = int(words[5]); - v3 = int(words[7]); - me.faces[i].v1.x = me.verts[v1].x; - me.faces[i].v1.y = me.verts[v1].y; - me.faces[i].v1.z = me.verts[v1].z; - me.faces[i].v1.origi = v1 - - me.faces[i].v2.x = me.verts[v2].x; - me.faces[i].v2.y = me.verts[v2].y; - me.faces[i].v2.z = me.verts[v2].z; - me.faces[i].v2.origi = v2 - - me.faces[i].v3.x = me.verts[v3].x; - me.faces[i].v3.y = me.verts[v3].y; - me.faces[i].v3.z = me.verts[v3].z; - me.faces[i].v3.origi = v3 - elif words[0] == '*MESH_NUMTVERTEX': - del me.verts[:] - uvCount = int(words[1]) - for i in range(uvCount): - me.verts.append(mesh_vert()) - elif words[0] == '*MESH_TVERT': - i = int(words[1]) - me.verts[i].u = float(words[2]); - me.verts[i].v = float(words[3]); - elif words[0] == '*MESH_TFACE': - i = int(words[1]) - uv1 = int(words[2]); - uv2 = int(words[3]); - uv3 = int(words[4]); - - me.faces[i].v1.u = me.verts[uv1].u; - me.faces[i].v1.v = me.verts[uv1].v; - - me.faces[i].v2.u = me.verts[uv2].u; - me.faces[i].v2.v = me.verts[uv2].v; - - me.faces[i].v3.u = me.verts[uv3].u; - me.faces[i].v3.v = me.verts[uv3].v; - elif words[0] == '*MESH_FACENORMAL': - curFaceID = int(words[1]) # global, vertexnormal needs this - faceVertID = 0 # same - elif words[0] == '*MESH_VERTEXNORMAL': - nx = float(words[2]) - ny = float(words[3]) - nz = float(words[4]) - - if (faceVertID == 0): - me.faces[curFaceID].v1.nx = nx; - me.faces[curFaceID].v1.ny = ny; - me.faces[curFaceID].v1.nz = nz; - elif (faceVertID == 1): - me.faces[curFaceID].v2.nx = nx; - me.faces[curFaceID].v2.ny = ny; - me.faces[curFaceID].v2.nz = nz; - elif (faceVertID == 2): - me.faces[curFaceID].v3.nx = nx; - me.faces[curFaceID].v3.ny = ny; - me.faces[curFaceID].v3.nz = nz; - - faceVertID = faceVertID + 1; - elif words[0] == '*MESH_ANIMATION': - me.animated = 1 - - # now the loop for animation frames - if objIdx > 0 and me.animated == 1: - if words[0] == '*MESH_VERTEX_LIST': - me.frameCount += 1 - me.frames.append([]) - elif words[0] == '*MESH_VERTEX': - me.frames[me.frameCount].append(mesh_vert()) - i = int(words[1]) - me.frames[me.frameCount][i].x = float(words[2]); - me.frames[me.frameCount][i].y = float(words[3]); - me.frames[me.frameCount][i].z = float(words[4]); - - PBidx += 1.0 - - spawn_main(objects) - - Blender.Redraw() - -def spawn_main(objects): - - PBidx = 0.0 - objCount = float(len(objects)) - - print 'Import Objects' - Blender.Window.DrawProgressBar(0.0, "Importing Objects...") - - for obj in objects: - - Blender.Window.DrawProgressBar(PBidx / objCount, "Importing Objects...") - - if obj.objType == 'Mesh': - spawn_mesh(obj) - - PBidx += 1.0 - -import random - -def spawn_mesh(obj): - - objMe = obj.obj - #normal_flag = 1 - - row0 = obj.row0x, obj.row0y, obj.row0z - row1 = obj.row1x, obj.row1y, obj.row1z - row2 = obj.row2x, obj.row2y, obj.row2z - row3 = obj.row3x, obj.row3y, obj.row3z - - newMatrix = Blender.Mathutils.Matrix(row0, row1, row2, row3) - newMatrix.resize4x4() - - newObj = Blender.Object.New(obj.objType, obj.name) - newObj.setMatrix(newMatrix) - Blender.Scene.getCurrent().link(newObj) - - - newMesh = Blender.Mesh.New(obj.objName) - newMesh.getFromObject(newObj.name) - - newMesh.vertexUV = 1 - newObj.link(newMesh) - - del objMe.verts[:] - objMe.vCount = 0 - - vertDict = {} - - #for face in objMe.faces: - #objMe.verts.append(face.v1) - #objMe.verts.append(face.v2) - #objMe.verts.append(face.v3) - #face.i1 = objMe.vCount - #objMe.vCount = objMe.vCount + 1 - #face.i2 = objMe.vCount - #objMe.vCount = objMe.vCount + 1 - #face.i3 = objMe.vCount - #objMe.vCount = objMe.vCount + 1 - - for face in objMe.faces: - if not face.v1.make_tuple() in vertDict: - vertDict[face.v1.make_tuple()] = objMe.vCount - objMe.verts.append(face.v1) - objMe.vCount = objMe.vCount + 1 - if not face.v2.make_tuple() in vertDict: - vertDict[face.v2.make_tuple()] = objMe.vCount - objMe.verts.append(face.v2) - objMe.vCount = objMe.vCount + 1 - if not face.v3.make_tuple() in vertDict: - vertDict[face.v3.make_tuple()] = objMe.vCount - objMe.verts.append(face.v3) - objMe.vCount = objMe.vCount + 1 - face.i1 = vertDict[face.v1.make_tuple()] - face.i2 = vertDict[face.v2.make_tuple()] - face.i3 = vertDict[face.v3.make_tuple()] - - # Verts - for i in range(objMe.vCount): - xyz = Blender.Mathutils.Vector(objMe.verts[i].x, objMe.verts[i].y, objMe.verts[i].z) - newMesh.verts.extend(xyz) - - for i in range(objMe.vCount): - xyz = Blender.Mathutils.Vector(objMe.verts[i].x, objMe.verts[i].y, objMe.verts[i].z) - uv = Blender.Mathutils.Vector(objMe.verts[i].u, objMe.verts[i].v) - norm = Blender.Mathutils.Vector(objMe.verts[i].nx, objMe.verts[i].ny, objMe.verts[i].nz) - newMesh.verts[i].co = xyz; - newMesh.verts[i].uvco = uv; - newMesh.verts[i].no = norm; - - if objMe.animated: - objMe.frameCount -= 1 # do we always get an extra frame at the end? - for frame in objMe.frames: - for i in range(objMe.vCount): - xyz = Blender.Mathutils.Vector(frame[objMe.verts[i].origi].x, frame[objMe.verts[i].origi].y, frame[objMe.verts[i].origi].z) - - newMesh.verts[i].co = xyz; - newObj.insertShapeKey() - - for key in Key.Get() : - key.ipo = Ipo.New('Key', "bleh" + "_ipo") - index = 1 - for curveName in key.ipo.curveConsts : - # print curveName - key.ipo.addCurve(curveName) - key.ipo[curveName].interpolation = IpoCurve.InterpTypes.CONST - key.ipo[curveName].addBezier((0, 0)) - key.ipo[curveName].addBezier((index, 1)) - key.ipo[curveName].addBezier((index + 1, 0)) - index+=1 - - # Faces - for i in range(objMe.fCount): - face = [objMe.faces[i].i1, objMe.faces[i].i2, objMe.faces[i].i3] - newMesh.faces.extend(face) - - # UV - #if guiTable['UV'] == 1 and objMe.hasFUV == 1: - #newMesh.faceUV = 1 - #for f in objMe.uvFaces: - #uv1 = Blender.Mathutils.Vector(float(objMe.uvVerts[f.uv1].u), float(objMe.uvVerts[f.uv1].v)) - #uv2 = Blender.Mathutils.Vector(float(objMe.uvVerts[f.uv2].u), float(objMe.uvVerts[f.uv2].v)) - #uv3 = Blender.Mathutils.Vector(float(objMe.uvVerts[f.uv3].u), float(objMe.uvVerts[f.uv3].v)) - #newMesh.faces[f.index].uv = [uv1, uv2, uv3] - ## normals - #vertices = [coords for n, coords in sorted(objMe.normals)] - - #random.seed() - - #i = 0 - #for v in newMesh.verts: - #no = Blender.Mathutils.Vector(vertices[i][0], vertices[i][1], vertices[i][2]) - #v.no = no - #print 'vertice ', i, 'normal : ', v.no - ##v.no[0] = vertices[i][0] - ##v.no[1] = vertices[i][1] - ##v.no[2] = vertices[i][2] - #i = i + 1 - - newMesh.transform((newObj.getMatrix('worldspace').invert()), 1) - - Blender.Set("curframe", objMe.frameCount + 1) - - counts['verts'] += objMe.vCount - counts['tris'] += objMe.fCount - print 'Imported Mesh-Object: ', obj.name - - - -def read_ui(filename): - Window.WaitCursor(1) - - read_main(filename) - - Window.WaitCursor(0) - - -Blender.Window.FileSelector(read_ui, "Import ASE") \ No newline at end of file diff --git a/source/tools/src/bin2c.cpp b/source/tools/src/bin2c.cpp deleted file mode 100644 index 98741b232..000000000 --- a/source/tools/src/bin2c.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// BIN2C.CPP -// by Jonathon Fowler (jf@jonof.id.au) - -// Converts a binary file to C source -// This is a DOS program originally written with Borland Turbo C++ for DOS 3.1 - - -#include -#include -#include -#include -#include -#include - - -char defsrcext[] = ".DAT"; -char defoutext[] = ".C"; - -char source[MAXPATH], output[MAXPATH], bytesize; - - -int PathAddExt(char *path, char *ext); - - -int main(int argc, char *argv[]) -{ - printf("BIN2C - Binary to C data converter\n" - "Copyright (c) 1999 Jonathon Fowler\n\n"); - - if (argc < 4) - { - printf("Usage:\n" - " BIN2C source<.DAT> output<.C> b|w\n\n" - " source<.DAT> Binary source file\n" - " output<.C> Output C code file\n" - " b|w Byte or word-sized data\n\n"); - exit(0); - } - - int arg; - FILE *in, *out; - char datab1, datab2; - int across=0, maxacross; - int length, written=0; - - - // get the source file - strcpy(source, argv[1]); - strupr(source); - PathAddExt(source, defsrcext); - printf("þ Source file: %s\n", source); - - // get the output file - strcpy(output, argv[2]); - strupr(output); - PathAddExt(output, defoutext); - printf("þ Output file: %s\n", output); - - // get byte/word data - switch (tolower(argv[3][0])) - { - case 'b': - printf("þ Byte data.\n"); - bytesize=1; - break; - - case 'w': - printf("þ Word data.\n"); - bytesize=0; - break; - - default: - printf("þ Unknown data size specified. Defaulting to byte.\n"); - bytesize=1; - break; - } - - // open the input file - in = fopen(source, "rb"); - if (!in) - { - printf("Error opening %s\n", source); - exit(1); - } - - // open the output file - out = fopen(output, "w+t"); - if (!out) - { - printf("Error creating %s\n", output); - exit(1); - } - - length = filelength(fileno(in)); - - // write a header out to the output file - fprintf(out, "// %s\n\n// Generated by BIN2C.EXE\n// By Jonathon Fowler\n\n", output); - - // start a data block - fprintf(out, "%s datablock[] = {\n // %ld bytes", (bytesize) ? "char" : "unsigned", length); - - if (bytesize) - maxacross = 12; - else - maxacross = 9; - across = maxacross; - - // convert the data - for (written=0; written1) ? ',' : '\n'); - } else { - datab1 = fgetc(in); - datab2 = fgetc(in); - fprintf(out, " 0x%02X%02X%c", datab2, datab1, ((length-written)>2) ? ',' : '\n'); - } - - across++; - - if (!bytesize) written++; - } - - - fprintf(out, " };"); - - fclose(out); - fclose(in); - - return 0; -} - - -// Add an extention to a path if one doesn't exist -int PathAddExt(char *path, char *ext) -{ - char drive[MAXDRIVE], dir[MAXDIR], name[MAXFILE], extn[MAXEXT]; - int flags; - - flags = fnsplit(path, drive, dir, name, extn); - - if (!(flags & EXTENSION)) // tack on an extension - strcat(path, ext); - - return ((flags & EXTENSION) == 0); -} diff --git a/source/tools/src/bsuite.cpp b/source/tools/src/bsuite.cpp deleted file mode 100644 index 7e07cca14..000000000 --- a/source/tools/src/bsuite.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/* - Build Game Customization Suite - Copyright (c) 1999, 2004 Jonathon Fowler - - 15 September 2004 - - This is the source code to BCS. It was written in Borland Turbo C++ for DOS - and [was] a 16bit real-mode DOS application. I'm releasing the code because - I have no reason to keep it a secret. Some folks might find it interesting. - - BTW, you can use this code for any purpose you want. - - Jonathon Fowler - jf@jonof.id.au - http://www.jonof.id.au/ -*/ -/* - NOTE: This program does not fall under BUILDLIC. -*/ -// DOS 16-bit real mode UI --> portable command line conversion by Hendricks266 - -#include "compat.h" - -const char APP_NAME[] = "Build Game Customization Suite v0.2-EDuke32"; -const char APP_CPRT[] = "Copyright (c) 1999, 2004 Jonathon Fowler"; - -int bsExtractD3DPalette(int, const char*); -int bsUpdateD3DPalette(int, const char*); - -int bsExtractPalette(const char*); -int bsUpdatePalette(const char*); - -const char *MainMenuStrings[] = { - "Options:", - "Extract Duke Nukem 3D-specific Palettes", - "Update Duke Nukem 3D-specific Palettes", - "Extract Build Game Palette", - "Update Build Game Palette" -}; - -const char *D3DMenuStrings[] = { - "Sub-Option: Duke Nukem 3D-specific Palettes:", - "Water Palette", - "Night-Vision Palette", - "Title Screen Palette", - "3D Realms Logo Palette", - "Episode 1 Ending Animation Palette" -}; - -const char *pal_deffn[] = { - "GAME.PAL", - "D3DWATER.PAL", - "D3DNVIS.PAL", - "D3DTITLE.PAL", - "D3D3DR.PAL", - "D3DEP1.PAL" - }; - -int main(const int32_t argc, const char **argv) -{ - int opt = 0, d3dpal = 0, k = 0; - int16_t i = 1; - char const * filename = NULL; // This is only a pointer. Do not strcpy to it. - char const * c = NULL; - - Bprintf("%s\n%s\n\n", APP_NAME, APP_CPRT); - - if (argc > 1) - { - opt = Bstrtol(argv[i++],NULL,10); - if ((opt == 1 || opt == 2) && i < argc) // Duke-specific palettes - d3dpal = Bstrtol(argv[i++],NULL,10); - - while (i < argc) - { - c = (char const *)argv[i]; - if ((*c == '-') -#ifdef _WIN32 - || (*c == '/') -#endif - ) - { - ++c; - if (!Bstrcasecmp(c,"f")) - { - if (argc > i+1) - filename = (char const *)argv[++i]; - ++i; - continue; - } - - } - ++i; - } - } - - if (opt < 1 || opt > 4 || (opt < 3 && (d3dpal < 1 || d3dpal > 5))) - { - Bprintf("usage: %s